Accelerometer Low Pass Filtering
Asked Answered
M

2

8

Still on the BigNerdRanch iOS Development book.

In the Accelerometer chapter, they first implement accelerometer tracking but it's fairly jumpy. They then suggest to apply a low pass filter to it by changing the original code:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    HypnosisView *hv = (HypnosisView *)[self view];

    [hv setXShift:10.0 * [acceleration x]];
    [hv setYShift:10.0 * [acceleration y]];

    [hv setNeedsDisplay];
}

to this:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    HypnosisView *hv = (HypnosisView *)[self view];

    float xShift = [hv xShift] * 0.8 + [accel x] * 2.0;
    float yShift = [hv yShift] * 0.8 + [accel y] * 2.0;

    [hv setXShift:xShift];
    [hv setYShift:yShift];

    [hv setNeedsDisplay];
}

Fairly simple question: where do they get these values from? I've been looking through the documentation and I found something about low pass filters, which suggests the following code:

   #define kFilteringFactor 0.1

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    // Use a basic low-pass filter to keep only the gravity component of each axis.
    accelX = (acceleration.x * kFilteringFactor) + (accelX * (1.0 - kFilteringFactor));
    accelY = (acceleration.y * kFilteringFactor) + (accelY * (1.0 - kFilteringFactor));
    accelZ = (acceleration.z * kFilteringFactor) + (accelZ * (1.0 - kFilteringFactor));

   // Use the acceleration data.
}

However, I first tried with that code and I got an error (by analyzing my app) saying 'the left value of '*' is a garbage value'. My accelerometer tracking didn't work either.

I'm fairly confused as to what these values mean. For example, in the first part of the code, why do they multiply the acceleration values by 10? To get a 'bigger' movement? I could make some sense out of that, but the second code with the low pass filter makes absolutely no sense to me.

Mccartan answered 4/8, 2011 at 13:51 Comment(1)
I think the reason for multiplying by 10 is that UIAcceleration gives you back values in G which 1G is 9.81 metres per second per second. 10 is an approximation of 9.81.Ri
A
15
accelX = (acceleration.x * kFilteringFactor) + (accelX * (1.0 - kFilteringFactor));

Whats happening in this code you are multiplying the acceleration at the moment by the Filtering factor 0.1 and then adding it to the filtered acceleration of the last time an update was called by 0.9.

This is pretty much getting the new value and adding it as 10% of the total accelX the other 90% is made up of the previous value which depends on the value before that, which depends on the value before that and so on. This cuts out high frequency values as only allows 10% of any change to go through to the new accelX value.

The KFilteringFactor of 0.1 makes this filter cut out all high frequencies. You will definitely want to experiment by changing this value to suit your particular application.

Aenneea answered 10/2, 2012 at 18:55 Comment(1)
what is the meaning of cut off frequency in this caseFelicitation
F
2

Since you're working through the Big Nerd Ranch Book - a good idea would be to go on to the Book's discussion forum.

For more information have a look at the Wikepedia article about low pass filters.

And for another example of filtering have a look at Apple's AccelerometerGraph example

Also - think if you take kFilteringFactor to be 0.2 which gives the multipliers for the current value to be 0.8 which is 1 - 0.2, and the multiplier for the new value is 2.0 because it's 0.2 x 10

I suppose 10 is the scaling factor to give reasonable values.

Figone answered 4/8, 2011 at 13:54 Comment(1)
Thanks. I checked the forum but nothing there about the low pass filter. The wiki article is far too advanced for me, I don't understand any of it.. I'll check out Apple's example, perhaps it clears things up. Thanks again.Mccartan

© 2022 - 2024 — McMap. All rights reserved.