UPDATE:
You will find an updated version of this post HERE
So what happens if you designed your application to drive a bluetooth device using the Motion class (because the output is less noisy) and then you realize that on the Lumia 520 and Lumia 625 the Motion class is not supported and you have to use the accelerometer. In my case, as i only use pitch and roll, the solution was pretty simple as it is actually possible to calculate the pitch and roll values directly from the accelerometer data. This way I can still use the Motion class and when not available fallback on the data extracted from the accelerometer. To better understand the algorithm behind this transformation have a look at this LINK.
You will find an updated version of this post HERE
So what happens if you designed your application to drive a bluetooth device using the Motion class (because the output is less noisy) and then you realize that on the Lumia 520 and Lumia 625 the Motion class is not supported and you have to use the accelerometer. In my case, as i only use pitch and roll, the solution was pretty simple as it is actually possible to calculate the pitch and roll values directly from the accelerometer data. This way I can still use the Motion class and when not available fallback on the data extracted from the accelerometer. To better understand the algorithm behind this transformation have a look at this LINK.
Before applying the transformation I also apply a low-pass filter to remove short-term fluctuations. The difference between the Arduino sample is that the pitch and roll are inverted and also the pitch was 180 degrees off so I remapped the values (when holding in postion 0 it was telling 180 degrees). I also transformed from radians to degrees for easier visualization (the multiplication with 180/Math.Pi)
const double alpha = 0.5;
double fXg = 0;
double fYg = 0;
double fZg = 0;
void acc_ReadingChanged(Windows.Devices.Sensors.Accelerometer sender, AccelerometerReadingChangedEventArgs args)
{
//Low Pass Filter
fXg = args.Reading.AccelerationX * alpha + (fXg * (1.0 - alpha));
fYg = args.Reading.AccelerationY * alpha + (fYg * (1.0 - alpha));
fZg = args.Reading.AccelerationZ * alpha + (fZg * (1.0 - alpha));
//Roll & Pitch Equations
double pitch = (Math.Atan2(-fYg, fZg) * 180.0) / Math.PI;
double roll = (Math.Atan2(fXg, Math.Sqrt(fYg * fYg + fZg * fZg)) * 180.0) / Math.PI;
//rotate 180 degrees
pitch=(pitch>=0)?(180-pitch):(-pitch-180);
}
I have also built a small sample that does comparative plots of the two values using the motion class and the transformation from accelerometer data. Initially I have added also the Microsoft.Devices.Sensors.Accelerometer but the data is almost the same with Windows.Devices.Sensors.Accelerometer with small delays between updates.
No comments:
Post a Comment