Filtering accelerometer data noise

前端 未结 5 1256
误落风尘
误落风尘 2020-11-28 22:20

How do I filter noise of the accelerometer data in Android? I would like to create a high-pass filter for my sample data so that I could eliminate low frequency components a

相关标签:
5条回答
  • 2020-11-28 22:37

    The samples from Apple's SDK actually implement the filtering in an even simpler way which is by using ramping:

    //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];
    
    0 讨论(0)
  • 2020-11-28 22:43

    IMO, designing a Kalman filter as your first attempt is over-complicating what's probably a fairly simple problem. I'd start with a simple FIR filter, and only try something more complex when/if you've tested that and found with reasonable certainty that it can't provide what you want. My guess, however, is that it will be able to do everything you need, and do it much more easily and efficiently.

    0 讨论(0)
  • 2020-11-28 22:45

    For those wondering what norm() and clamp() methods do in the answer from rbgrn, you can see them here: 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;
    }
    
    0 讨论(0)
  • 2020-11-28 22:46

    Here's the code for Android, adapted from the apple adaptive high pass filter example. Just plug this in and implement 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]);
    }
    
    0 讨论(0)
  • 2020-11-28 22:47

    I seem to remember this being done in Apple's sample code for the iPhone. Let's see...

    Look for AccelerometerFilter.h / .m on Google (or grab Apple's AccelerometerGraph sample) and this link: http://en.wikipedia.org/wiki/High-pass_filter (that's what Apple's code is based on).

    There is some pseudo-code in the Wiki, too. But the math is fairly simple to translate to code.

    0 讨论(0)
提交回复
热议问题