Sorry for the confusion. I am using the MPU6050 which is a 6 axis imu. The MPU spits out quaternion readings which can then be further converted to Euler angles or gravity for different computations. Here is the Arduino sketch where quaternions are read from the MPU6050 and conversion to gravity takes place:
This is the library I am using https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050 and this file has the function for gravity calculation from quaternions:
The specific function is:
uint8_t MPU6050::dmpGetGravity(VectorFloat *v, Quaternion *q)
v -> x = 2 * (q -> x*q -> z - q -> w*q -> y);
v -> y = 2 * (q -> w*q -> x + q -> y*q -> z);
v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z;
I am unable to understand the conversion from quaternions to gravity here.
I was actually looking into the same problem a couple of weeks ago and after some back-off-the-envelope calculations I was able to derive it for myself. I will share it here just in case someone else is looking into the same problem.
As explained on Wikipedia (https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation) the rotation of a vector v can expressed using the quaternion q as v' = qvp where p is the reciprocal of q. What is done in the calculations is to take the z unit vector in the rotated frame and rotating it back to the initial frame by calculating pzq. If you go through the exercise of the multiplications, you will find the code in the dmpGetGravity function. You will also notice that what is called the gravity vector is actually in the direction of the positive z-axis, which I actually think is a misstake. The sign however cancels out in the other calculations.
If you go through the math in detail you will also find that there is a misstake in the ypr calculations. If anyone is interested in the derivations, I can dig up my notes. The correct equations can however be found on wikipedia.