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.
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:
- Read 1 or 2 bytes from the relevent register
- If there's 2 bytes, join them together to produce a 16 bit integer
- 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:
- Use accelerometer data as outlined here
- Use a "complementary filter" - gyroscope integration with some accelerometer readings taken into account.
- 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).
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