I'm using compass heading to rotate an MKMapView. The rotation was a bit jerky so I'm trying to filter it like Google Maps on the iphone does (or appears to do some trickery).
I'm trying to filter the reading from the iphone compass using a moving average formula but it fails on the crossover between 359 adn 0 becuase it starts to average backwards from 35x to 0 and causes the map to rotate backwards as it approaches north from the west.
Any ideas what the best way is to filter this data so that it crosses from 359 back to zero and maintain the rolling average.
Code is here:
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
static float xd=0;
static float k = 0.22;
// Moving average formula
xd = k * xd + (1.0 - k) * newHeading.magneticHeading;
NSLog(@"%0.2f : %0.2f", newHeading.magneticHeading, xd);
[map setTransform:CGAffineTransformMakeRotation((-1 * xd * M_PI) /180)];}
Thanks for any help
If the previous moving average and the new heading are different by more than 180 degrees, add 360 to whichever is smaller. Then mod by 360 when storing the new moving average. So (without precise math):
My hope is that this works and is more efficient than the trigonometric method described in Averaging angles (credit to Mark Ransom for referring to that).
I just wanted to add my version of the code that d0n posted with a few tweaks.
My code is C code for an Arduino so I have used no libraries (for example I get the absolute value without abs function)...
This thread was very helpful to me. Thank you D0n and John...
In the end, this is what worked for me.