过滤加速度计数据的噪声(Filtering accelerometer data noise)

2019-09-02 00:43发布

如何过滤在Android上的加速度计数据的噪音? 我想为我的样本数据创建一个高通滤波器,这样我就可以消除低频分量,并专注于高频成分。 我已阅读,卡尔曼滤波可能是我们的最佳人选,但如何整合或使用我的应用程序这种方法,将主要写的Android的Java? 或者可以将它摆在首位做些什么呢? ,或利用Android NDK? 是否有任何机会,这可以实时完成?

任何想法将非常感激。 谢谢!

Answer 1:

从苹果公司的SDK样品实际实现滤波,它是利用斜坡的更简单的方法:

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


Answer 2:

下面是适用于Android的代码,改编自苹果自适应高通滤波器的例子。 只需插入这个和实施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]);
}


Answer 3:

:对于那些想知道什么规范()和钳位()方法从rbgrn答案做,你可以看到他们在这里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;
}


Answer 4:

我似乎记得这个被苹果公司为iPhone示例代码来完成。 让我们来看看...

寻找在谷歌AccelerometerFilter.h / .M(或抢苹果的AccelerometerGraph样品)和此链接: http://en.wikipedia.org/wiki/High-pass_filter (这是苹果的代码是基于)。

有一个在维基一些伪代码,太。 但是数学是相当简单的翻译成代码。



Answer 5:

IMO,设计卡尔曼滤波器作为你的第一次尝试是过于复杂什么是可能是一个相当简单的问题。 我用一个简单的FIR滤波器开始,只有当/如果你已经测试过,并以合理的确定性发现,它不能提供你想要尝试更复杂的东西。 我的猜测,但问题在于,它能够做你需要的一切,并做到这一点更容易和更有效。



文章来源: Filtering accelerometer data noise