Filtrando el ruido de datos del acelerómetro

¿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 enfocarme 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 puedo integrar o usar este método en mi aplicación, que en su mayoría está escrito en Android Java? o se puede hacer en primer lugar? o a través de Android NDK? ¿Hay alguna posibilidad de que esto se pueda hacer en tiempo real?

Cualquier idea será muy apreciada. ¡Gracias!

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

 // rampa de velocidad: juega con este valor hasta que esté satisfecho
 const float kFilteringFactor = 0.1f;

 // almacenamiento del último resultado: mantenga la definición fuera de esta función, p. ej.  en envolver objeto
 float accel [3]; 

 //acceleration.x,.y,.z es la entrada del sensor

 //result.x,.y,.z es el resultado filtrado

 // filtro de paso alto para eliminar la gravedad
 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];

Aquí está el código para Android, adaptado del ejemplo del filtro de paso alto adaptable a la manzana. Simplemente enchúfalo e implementa enFilteredAccelerometerChanged ()

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 de norma () y abrazadera () en la respuesta de rbgrn, puede verlos aquí: http://developer.apple.com/library/IOS/samplecode/AccelerometerGraph/Listings/AccelerometerGraph_AccelerometerFilter_m.html

Me parece recordar que esto se hizo en el código de muestra de Apple para el iPhone. Veamos…

Busque AccelerometerFilter.h / .m en Google (o tome la muestra 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 un pseudocódigo en Wiki. Pero la matemática es bastante simple de traducir al código.

IMO, el diseño de un filtro de Kalman como primer bash está complicando demasiado lo que probablemente sea un problema bastante simple. Comenzaría con un filtro FIR simple, y solo intentaré algo más complejo cuando / si lo haya probado y haya encontrado con razonable certeza que no puede proporcionar lo que desea. Mi suposición, sin embargo, es que podrá hacer todo lo que necesite y hacerlo de manera mucho más fácil y eficiente.