# Getting relative pitch and roll

This may be more suited for another exchange site, but I thought it'd try here anyway. I'm trying to figure out how to get pitch and roll relative to the ground. Say my vehicle is going up a hill, but my vehicle is level with that hill as it goes up to a degree. How would I go about getting that pitch? I've been playing with the MPU6050 and this still boggles my mind.

• By "level with that hill" do you mean the vehicle plane is parallel to the ground plane? "Level" means parallel to the horizon. Jun 23, 2014 at 6:59
• Yes excuse me, I meant parallel to ground plane Jun 23, 2014 at 7:00
• I'm not sure what to recommend, but you might be able to use the gyro/accelerometer. You would just need to calibrate it first on level ground, then keep track of changes in incline as the vehicle moves. Jun 23, 2014 at 7:05

Orientation can be represented in a number of ways. In all cases you have the concept of a fixed "world" coordinate system from which your "local" coordinate system is defined. The easiest to understand is probably Euler angles, which is essentially the roll, pitch and yaw of an object. The 3 angles describe how much the object has rotated about each of its 3 axes. A rotation matrix can also be used to represent orientation. It's not as easy to intuitively understand exactly what the rotation the matrix represents looks like, but it's very easy to perform mathematical operations on a rotation matrix. Finally, quaternions also represent rotation, but are entirely unintuitive and quite hard to wrap your head around.

The MPU6050 (datasheet) is a combined accelerometer and gyro IC with an I2C interface.

You can actually use either of the sensors to work out orientation, but each have drawbacks on their own.

In theory, integrating gyroscope data (which tells you rotational speed in rads per second) will give you the rotation from your starting point in radians. Essentially, read the gyroscope at some time interval (say every 0.1 seconds) and multiply the reading by the timestep (0.1) and add it to your previously calculated orientation. Do this for each axis.

The major problem with this approach is that gyroscopes suffer from "drift". Over time, small errors in the measured rotation will add up and the calculated orientation will diverge from the actual physical orientation. The quality of the device will influence how quickly this error builds up - MEMS gyros like the one you have might only give a few seconds of accurate readings, while a laser gyro in an aircraft inertial navigation system could provide accurate readings for hours. The gyroscope does, however, give fairly smooth (noise-free) readings which, in the short term, are accurate.

You could also just use the accelerometer. When you're sitting still, the sensor will read a constant acceleration towards the earth. You can use this as a reference point for your roll and pitch orientation (yaw requires another reference - often the earth's magnetic field, read with a magnetometer). The major issue with this is that the moment you move it, even slightly, the gravitational reference will be overwhelmed by the movement vector and you'll lose your orientation reference. If your device is sitting still or moving in a fairly smooth manner then this might not be an issue. This SO question addresses calculating orientation from just accelerometer values.

What you need is to combine (or "fuse", in sensor parlance) the smooth but drifting gyroscope reading with the absolute reference to the outside world from your accelerometer. This is a complicated topic which can get quite maths heavy, but fortunately for a simple implementation you don't need to get too involved.

The first step is reading data from the IC. You haven't named your microcontroller, but I'll assume you've figured out its I2C library and are able to read data from it. If you haven't dealt with I2C ICs before, generally the steps needed are:

1. Read 1 or 2 bytes from the relevent register
2. If there's 2 bytes, join them together to produce a 16 bit integer
3. Multiply the result by some factor to get the value in SI units

It's not actually particularly complicated, but just reading the datasheet can seem daunting. I'd recommend reading a tutorial or two on reading I2C IC data (not necessarily for the chip in question) and comparing the tutorial to the relevant datasheet to get an idea of how they are generally written.

Looking at the datasheet linked above, you seem to have 2 options. Either you can individually read the accelerometer and gyroscope data from the IC, or you can use the inbuilt "Digital Motion Processor", which I imagine will also perform sensor fusion algorithms for you (the datasheet is a little light on details - perhaps there's an application note or some further documentation on what it actually does). If you do it yourself, the algorithm you use will be somewhat application dependent, but I'd try:

1. Use accelerometer data as outlined here
2. Use a "complementary filter" - gyroscope integration with some accelerometer readings taken into account.
3. Investigate the Kalman filter. Implementation gets a little bit trickier here, and tends to be more application dependent.

Try and gather data at a few hundred Hz (timestep of 0.01 seconds or smaller).

• This did everything but answer my question. Jun 23, 2014 at 15:54
• Perhaps ask a more focused question then? What have you tried to do? What microcontroller are you using? Have you managed to read any data from the IMU? Are you having trouble converting the read data into an acceleration or rotation rate value? Are you having trouble converting acceleration and gyroscope readings into orientation? If you ask a vague and broad question you get a vague and broad answer! (Or none at all).
– LeoR
Jun 23, 2014 at 16:00
• I asked a pretty specific question actually, I wasn't asking how to get pitch and roll, I was asking how to get them relative/parallel to ground plane Jun 23, 2014 at 16:13

For the task you describe, which is essentially a 3D inclinometer, the easiest way to go would be to calculate the orientation of the Gravity vector. The problem is getting rid of the impact of any accelerations the car might make, or centripetal accelerations made during arc-like motion. A fair first approximation would be to low-pass filter the acceleration signals at about 0.1Hz, but you'd be damping out transient tilts.

The point mentioned in LeoR's answer about Euler angles and quaternions has to do with the math of rotations, which don't commute. From https://physics.stackexchange.com/a/10368 :

For the types of rotation you're talking about, I don't think this will be important

• Just a note that referencing another answer (in this case, LeoR's) as above or below is subject to change based on voting. Jun 23, 2014 at 21:59