5

Could someone explain how one arrives at the equation below for high pass filtering of the accelerometer values? I don't need mathematical derivation, just an intuitive interpretation of it is enough.

    #define kFilteringFactor 0.1
    UIAccelerationValue rollingX, rollingY, rollingZ;

    - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {

        // Subtract the low-pass value from the current value to get a simplified high-pass filter

        rollingX = (acceleration.x * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));

        rollingY = (acceleration.y * kFilteringFactor) + (rollingY * (1.0 - kFilteringFactor));

        rollingZ = (acceleration.z * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor));

         float accelX = acceleration.x - rollingX;
         float accelY = acceleration.y - rollingY;
         float accelZ = acceleration.z - rollingZ;

       // Use the acceleration data.

    }
Boon
  • 40,656
  • 60
  • 209
  • 315

3 Answers3

15

While the other answers are correct, here is an simplistic explanation. With kFilteringFactor 0.1 you are taking 10% of the current value and adding 90% of the previous value. Therefore the value retains a 90% similarity to the previous value, which increases its resistance to sudden changes. This decreases noise but it also makes it less responsive to changes in the signal. To reduce noise and keep it responsive you would need non trivial filters, eg: Complementary, Kalman.

Community
  • 1
  • 1
Jano
  • 62,815
  • 21
  • 164
  • 192
  • Thanks, pretty intuitive explanation. Could you explain how the term high-pass filter fit into the context of your explanation and how a low-pass filter would behave using your line of explanation. – Boon Aug 04 '11 at 15:01
  • Thanks for mentioning Complementary and Kalman. Those are helpful for me. – mattorb Jul 25 '12 at 14:35
12

The rollingX, rollingY, rollingZ values are persistent across calls to the function. They should be initialised at some point prior to use. These "rolling" values are just low pass filtered versions of the input values (aka "moving averages") which are subtracted from the instantaneous values to give you a high pass filtered output, i.e. you are getting the current deviation from the moving average.

ADDITIONAL EXPLANATION

A moving average is just a crude low pass filter. In this case it's what is known as ARMA (auto-regressive moving average) rather than just a simple MA (moving average). In DSP terms this is a recursive (IIR) filter rather than a non-recursive (FIR) filter. Regardless of all the terminology though, yes, you can think of it as a smoothing function" - it's "smoothing out" all the high frequency energy and leaving you with a slowly varying estimate of the mean value of the signal. If you then subtract this smoothed signal from the instantaneous signal then the difference will be the content that you have filtered out, i.e. the high frequency stuff, hence you get a high pass filter. In other words: high_pass_filtered_signal = signal - smoothed_signal.

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • Thanks. I am having difficulty understanding "...just low pass filtered versions of the input value..." and "...to give you a high pass filtered output" It feels like a smoothing function of sort since 1 - kFilteringFunction keeps being applied to the rolling value. Anyway, I feel like I can get some good info from your explanation once I totally get what you mean. – Boon Aug 04 '11 at 15:08
  • 1
    See the "additional explanation" above for a hopefully clearer explanation of moving average and filtering etc. – Paul R Aug 05 '11 at 06:20
0

Okay, what that code is doing is calculating a low-pass signal and then substracting the current value.

Thing of a square wave that takes two values 5 and 10. In other words, it oscillates between 5 and 10. Then the low pass signal is trying to find the mean (7.5). The high-pass signal is then calculated as current value minus mean, i.e. 10 - 7.5 = 2.5, or 5 - 7.5 = -2.5.

The low-pass signal is computed by integrating over past values by adding a fraction of the current value to 90% of the past low-pass value.

Unapiedra
  • 15,037
  • 12
  • 64
  • 93