Measuring Tilt Angle

By: scott_d

2010-09-18 21:51:35

One of the main reasons I have been interested in gyroscopes and accelerometers is to measure tilt angle for things like balancing robots. So after building Paul's board with the three axis accelerometer and two axis gyro, I moved on to doing the software to use the board to measure tilt. At first blush, it would seem like two accelerometer axis readings would be enough to measure tilt angle (relative to gravity) since you just need two vectors (say X and Z) to compute the angle via atan2(X,Z) for example. But this neglects the fact that an accelerometer can't tell the difference between acceleration due to gravity and acceleration due to movement of any other kind. So in dynamic situations, like UAVs or robots, an accelerometer cannot give reliable angles. On the other hand, a gyroscope is unaffected by external forces and always give a readout of the rate of angular change. Therefore, you can derive the change in angle by integrating a gyroscope reading over time. The problem with a gyro is that integration over any length of time is inherently unstable if there is any drift or non-constant offset. Thus, a gyroscope is more useful on short time scales whereas an accelerometer is more useful on longer time scales. The trick is to combine the two sensors to give the best angle estimate while coping with sensor noise, instability and motion artifacts. This is a well established problem and the solution is generally something called a Kalman filter. I'm not going to try to explain Kalman filters, mainly because I haven't really gone through the math behind them in detail, but the basic idea is that a Kalman filter combines noisy data sources to give the statistically optimum estimate of the true value of the state variables of a system. Kalman filters are iterative and involve a prediction step followed by a correction step where the weights on the input data values are adjusted. Because it is a common problem, it turns out there is a nice piece of C code (originally from Trammell Hudson ) which computes a tilt angle from accelerometer and gyro readings. I'm using an adaptation of Hudson's code (into an Arduino library) by Dr. Rainer Hessmer (http://www.hessmer.org/blog/2010/07/06/building-a-self-balancing-robot-part-4/). I've attached my sketch which uses Hessmer's library to compute and display both the accelerometer only and the Kalman filtered tilt angles. The photos show my test setup, based on my LCD/Dorkboard design, connected to Paul's gyro/accelerometer board. When the board is stable, the angles agree but when you move the board around, the Kalman filtered angle stays stable while the accelerometer based angle bounces around wildly. So the Kalman filter seems to be doing its job.  