I recently talked about getting informations from the FreeIMU board. This gives us raw data from acceleroscope and gyroscope. Both of them can give some informations about the attitude (pitch, roll) of the board, but they both have some flaws, even if they are perfect sensors (which they aren’t):

The gyroscope only gives the rotation speed, so the software has to integrates the value, which means there will most likely have integration errors, and thus a drift.

The accelerometer gives the acceleration + g, so when the device is not moving, we get g, which gives us pitch and roll. But when there is some acceleration, the values can’t be used.

The gyroscope’s drift is mostly slow, whereas there is an acceleration only on short period of times, so we can combine both of those sensors to get the actual attitude.

One usual way to merge them is to use a Kalman filter. It is a very effective way of merging, and the result can be quite incredible. But it is really complicated to understand and implement. The theory behind it assumes the knowledge of physics of the problem, which doesn’t help its complexity. It actually works without this knowledge, so it’s still a possible solution.

Anyway, as I mentioned before, the noise from the gyroscope and from the accelerometer is not a white noise, but has some specific spectrum, and gyroscope and accelerometer’s noises have quite a complementary spectrum, which leads to another possible filter to merge gyroscope and accelerometer informations (it can also filter magnetometer informations actually): It’s called a complementary filter.

The idea is to apply a low-pass filter on accelerometer, since its values are correct only at low frequencies, and add the complementary (ie the sum of the high-pass filter’s transfer function and the one of the low-pass filter is equal to one) on gyroscope’s data. That way, we filter out high frequency noise of the accelerometer, and low frequency noise of the gyroscope.

So, that’s the theory. To implement such a thing, an easy way we’ve chosen is to use an exponential filter: v_{n+1} = v_n*t + x_n*(1-t), where t is a number between 0 and 1. I’ve chosen t = 10/11 for a sensor frequency of 60Hz. The complementary filter is w_n = x_n-v_{n+1}.

Again, to have as simple code as possible, the current implementation doesn’t even use a FQA, which obviously leads to problems on some specific angles. For our bot, this is no problem, since the range of possible pitch and roll are short, we can take care of being in a safe area.

Today, we also got the Kalman filter to work, so we could compare both approaches. Even thoguh Kalman is still working better, the complementary filter is working properly, and should be enough to control the bot properly, at a way lower cpu processing cost.

Possibly related posts:

## Recent Comments