Hi Everyone,
I'm currently using Madgwick's popular filter for my own AHRS project. After some experimentation with sensors and adjusting the beta gain, I've noticed some unpredictable behavior of the filter. For example, euler angles computed from the quaternion changed unexpectedly to 20 degrees off the reference angle (in a static scenario!).
After setting the magnetometer input to (0,0,0) the problem stayed the same. Then I removed the gyroscope inputs (0,0,0) and the problem stayed the same. My conclusion was that it must have been related to the accelerometer inputs.
After experimenting with real sensors I moved to artificial ACC input data and set up a test bed for Madgwick's algorithm (MadgwickTests on GitHub). I've figured out that in Madgwick's algorithm the fast inverse square root leads to huge instabilities when noisy measurements are applied. As an example, consider the pitch and roll angles shown in the following image:
The input for the filter was: gyro = (0,0,0), acc = (2.5, 2.5, 9.15) +- 0.1 uniform noise (see test.c for details). As you can see, the pitch and roll angles (red/green, in degrees) of the original implementation show unacceptable variations.
Remarkably more stable and accurate pitch/roll angles (blue/magenta) were achieved by exchanging the inverse square root implementation. I used the following code from Accurate and Fast InvSqrt for computing the inverse square root of float x:
unsigned int i = 0x5F1F1412 - (*(unsigned int*)&x >> 1);
float tmp = *(float*)&i;
float y = tmp * (1.69000231f - 0.714158168f * x * tmp * tmp);
Cheers, Tobias
Replies
Hi, I noticed the error builds up under continuous external vibrations(<0.3g) in either pitch or roll axis. The error is around 1 deg per second. Is there anyway to mitigate this? I tried to set beta to improve dynamic performance but
Hi, 0.3g should not be a problem. We have acceleration around +-3g on our UAV; we have beta set to 0.025 and no error builds up. Is everying alright with your sensor data?
The static error on accelerometer is +-0.02g, on gyro is +-0.4deg/s, on magetometer is +-0.01guass. My sampling rate is around 160HZ. Maybe it's too low? I checked Madgwick's paper and it looks like there is no big difference once the sampling rate is above 100HZ. When I just lay everything flat on the table and slide it continuously in all directions, the pitch and roll errors build up but converge to 0 slowly(in 3sec) once I stop sliding.
Tim
The sampling rate should be no problem. What is your set-up?
Are you using a 32 bit or a 64 bit processor?
Which kind of sensors are you using? Is the axis alignment correct?
Did you calibrate the gyro upon start-up?
I'm playing with a board that has an mpu60X0 and shoehorned the Madgwick algorithm onto it with a lot of trial and error. You guys are talking about overshoot and I have undershoot/lag. I increased the integration time and it almost looks right. It takes a lot of memory to run it too.
All my playing and I haven't found anything that improves on the DIYdrones DCM.
I have to retract that a bit, FreeIMU uses the Madgwick AHRSupdate and is just as good as DCM, if not better and is about the same size in memory. I'm testing it now and it has none of the molasses effect that my attempt did. It's also much smoother than the DCM. My implementation is screwy because I'm a beginner programmer. If I tweak the sampling frequency it might be ok, but it will still be 6k bigger than FreeIMU.
OK, the problem was my 64 bit machine. Long is not 4 bytes wide and thus, the following code line fails:
https://github.com/TobiasSimon/MadgwickTests/blob/master/MadgwickAH...
The portable solution for this is:
Thank you for this optimisation. I will test it this evening.
I would have some question about using this algorithm.
I plan to use it with an atmel board (xmega-a1 or xmega-b1) and atavrsbin1 9dof board (http://www.atmel.com/Images/doc8354.pdf) :
* How fast should I read the sensor and make the DCM update?
* Should I do this using interrupt based code?
* How to choose the "right" parameters for the filter?
Thank your for your help.