Pregunta

¿Cómo filtro el ruido de los datos del acelerómetro en Android? Me gustaría crear un filtro de paso alto para mis datos de muestra para poder eliminar componentes de baja frecuencia y centrarme en los componentes de alta frecuencia. He leído que el filtro de Kalman podría ser el mejor candidato para esto, pero ¿cómo integro o uso este método en mi aplicación, que se escribirá principalmente en Android Java? o puede hacerse en primer lugar? o a través de Android NDK? ¿Existe alguna posibilidad de que esto se pueda hacer en tiempo real?

Cualquier idea será muy apreciada. ¡Gracias!

¿Fue útil?

Solución

Las muestras del SDK de Apple realmente implementan el filtrado de una manera aún más simple que es mediante el uso de rampas:

//ramp-speed - play with this value until satisfied
const float kFilteringFactor = 0.1f;

//last result storage - keep definition outside of this function, eg. in wrapping object
float accel[3]; 

//acceleration.x,.y,.z is the input from the sensor

//result.x,.y,.z is the filtered result

//high-pass filter to eliminate gravity
accel[0] = acceleration.x * kFilteringFactor + accel[0] * (1.0f - kFilteringFactor);
accel[1] = acceleration.y * kFilteringFactor + accel[1] * (1.0f - kFilteringFactor);
accel[2] = acceleration.z * kFilteringFactor + accel[2] * (1.0f - kFilteringFactor);
result.x = acceleration.x - accel[0];
result.y = acceleration.y - accel[1];
result.z = acceleration.z - accel[2];

Otros consejos

Aquí está el código para Android, adaptado del ejemplo de filtro de paso alto adaptativo de Apple. Simplemente conecte esto e implemente onFilteredAccelerometerChanged ()

private static final boolean ADAPTIVE_ACCEL_FILTER = true;
float lastAccel[] = new float[3];
float accelFilter[] = new float[3];

public void onAccelerometerChanged(float accelX, float accelY, float accelZ) {
    // high pass filter
    float updateFreq = 30; // match this to your update speed
    float cutOffFreq = 0.9f;
    float RC = 1.0f / cutOffFreq;
    float dt = 1.0f / updateFreq;
    float filterConstant = RC / (dt + RC);
    float alpha = filterConstant; 
    float kAccelerometerMinStep = 0.033f;
    float kAccelerometerNoiseAttenuation = 3.0f;

    if(ADAPTIVE_ACCEL_FILTER)
    {
        float d = clamp(Math.abs(norm(accelFilter[0], accelFilter[1], accelFilter[2]) - norm(accelX, accelY, accelZ)) / kAccelerometerMinStep - 1.0f, 0.0f, 1.0f);
        alpha = d * filterConstant / kAccelerometerNoiseAttenuation + (1.0f - d) * filterConstant;
    }

    accelFilter[0] = (float) (alpha * (accelFilter[0] + accelX - lastAccel[0]));
    accelFilter[1] = (float) (alpha * (accelFilter[1] + accelY - lastAccel[1]));
    accelFilter[2] = (float) (alpha * (accelFilter[2] + accelZ - lastAccel[2]));

    lastAccel[0] = accelX;
    lastAccel[1] = accelY;
    lastAccel[2] = accelZ;
    onFilteredAccelerometerChanged(accelFilter[0], accelFilter[1], accelFilter[2]);
}

Para aquellos que se preguntan qué hacen los métodos norm () y clamp () en la respuesta de rbgrn, pueden verlos aquí: http://developer.apple.com/library /IOS/samplecode/AccelerometerGraph/Listings/AccelerometerGraph_AccelerometerFilter_m.html

double norm(double x, double y, double z)
{
    return Math.sqrt(x * x + y * y + z * z);
}

double clamp(double v, double min, double max)
{
    if(v > max)
        return max;
    else if(v < min)
        return min;
    else
        return v;
}

Parece recordar que esto se hizo en el código de muestra de Apple para iPhone. A ver ...

Busque AccelerometerFilter.h / .m en Google (o tome la muestra de AccelerometerGraph de Apple) y este enlace: http://en.wikipedia.org/wiki/High-pass_filter (en eso se basa el código de Apple).

También hay algunos pseudocódigos en la Wiki. Pero las matemáticas son bastante simples de traducir al código.

En mi opinión, diseñar un filtro de Kalman como su primer intento complica demasiado lo que probablemente sea un problema bastante simple. Comenzaría con un filtro FIR simple, y solo probaría algo más complejo cuando / si lo ha probado y ha encontrado con certeza razonable que no puede proporcionar lo que desea. Sin embargo, supongo que podrá hacer todo lo que necesite y hacerlo de manera mucho más fácil y eficiente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top