Pergunta

Como faço para filtrar o ruído dos dados do acelerômetro em Android? Eu gostaria de criar um filtro passa-alto para os meus dados de exemplo para que eu pudesse eliminar componentes de baixa frequência e foco sobre os componentes de alta frequência. Eu li que filtro de Kalman pode ser o melhor candidato para este, mas como faço para integrar ou usar este método no meu aplicativo que irá principalmente escrito em Java Android? ou pode ser feito em primeiro lugar? ou através NDK Android? Existe por acaso que isso pode ser feito em tempo real?

Qualquer idéia será muito apreciado. Obrigado!

Foi útil?

Solução

As amostras de SDK da Apple realmente implementar a filtragem de uma forma ainda mais simples que é através da utilização de rampa:

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

Outras dicas

Aqui está o código para o Android, adaptado do adaptativa exemplo filtro de alta freqüência de maçã. Basta ligar este e implementar 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 aqueles que querem saber o que norma () e braçadeira () métodos de fazer na resposta de rbgrn, você pode vê-los aqui: 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;
}

Eu me lembro este que está sendo feito no código de exemplo da Apple para o iPhone. Vamos ver ...

Procure AccelerometerFilter.h / .m no Google (ou agarrar amostra AccelerometerGraph da Apple) e este link: http://en.wikipedia.org/wiki/High-pass_filter (que é o código da Apple é baseado em).

Há alguns pseudo-código no Wiki, também. Mas a matemática é bastante simples para traduzir o código.

IMO, projetando um filtro de Kalman como sua primeira tentativa é o excesso de complicar o que é provavelmente um problema bastante simples. Eu começaria com um filtro FIR simples, e apenas tentar algo mais complexo quando / se você testou que e encontrou com razoável certeza que ele não pode fornecer o que você quer. Meu palpite, porém, é que ele vai ser capaz de fazer tudo o que precisa, e fazê-lo muito mais fácil e eficiente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top