Question

Comment filtrer le bruit des données de l'accéléromètre sous Android? J'aimerais créer un filtre passe-haut pour mes échantillons de données afin d'éliminer les composants basse fréquence et de me concentrer sur les composants haute fréquence. J'ai lu que le filtre de Kalman pourrait être le meilleur candidat pour cela, mais comment puis-je intégrer ou utiliser cette méthode dans mon application qui sera principalement écrite en Java Android? ou peut-il être fait en premier lieu? ou via Android NDK? Est-il possible que cela se fasse en temps réel?

Toute idée sera très appréciée. Merci!

Était-ce utile?

La solution

Les exemples du SDK d’Apple implémentent le filtrage d’une manière encore plus simple en utilisant la rampe:

//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];

Autres conseils

Voici le code pour Android, adapté de l'exemple de filtre adaptatif passe-haut adaptatif apple. Il suffit de le brancher et de l’appliquer 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]);
}

Pour ceux qui se demandent ce que font les méthodes norm () et clamp () dans la réponse de rbgrn, vous pouvez les voir ici: 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;
}

Je crois me souvenir que cela a été fait dans l'exemple de code fourni par Apple pour l'iPhone. Voyons voir ...

Recherchez AccelerometerFilter.h / .m sur Google (ou prenez l'exemple AccelerometerGraph d'Apple) et ce lien: http://fr.wikipedia.org/wiki/High-pass_filter (le code d'Apple est basé sur ce code).

Il existe également un pseudo-code dans le wiki. Mais le calcul est assez simple à traduire en code.

IMO, concevoir un filtre de Kalman dès votre première tentative complique de manière excessive ce qui est probablement un problème assez simple. Je commencerais par un simple filtre FIR et n'essaierai que quelque chose de plus complexe si / si vous avez testé cela et constaté avec une certitude raisonnable qu'il ne peut pas fournir ce que vous voulez. Cependant, je pense qu’il sera capable de faire tout ce dont vous avez besoin, et beaucoup plus facilement et efficacement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top