I2Cdevlib Forums

# Understanding Quaternions

## Recommended Posts

I was hoping someone in this forum could help me understand the quaternion data output from the MPU-6050 when using the MPU6050-DMP6 code by Jeff Rowberg.

I'm working on a project that contiuously records 3D positioning. Previously I had been recording euler angles, however, I ran into problems with Gimbal lock. Now I've started recording quaternions to avoid Gimbal lock, but the math involved is a little beyond me at the moment. I'm having a hard time making sense of the quaternion values I get from the device and relating them to real world dimensions. I want to be able to tilt the device sensor 90 degrees and confirm in the device data that this was accurately recorded.

Here is some recorded quaternion data using the Arduino Pro Mini 3.3V, 8MHz ATmega 328 board:

MPU-6050 at baseline pointing straight (after waiting 10 seconds)

quaternion_straight: .4337, .2398, -.4392, -.7495

MPU-6050 pointing 90 degrees downward (attitude/pitch =-90 degrees)

quaternion_down:  -.1815, .4730, -.1089, -.8553

MPU-6050 pointing 90 degrees upward (attitude/pitch =+90 degrees)

quaternion_up: .8190, -.1508, -.4704, -.2919

MPU-6050 tilted 90 degrees right (banking/roll =+90 degrees)
quaternion_right: .0665, .5426, -.8361, -.0451
MPU-6050 tilted -90 degrees left  (banking/roll =-90 degrees)
quaternion_left: .5125, -.0204, -.0079, -.8584

In an attempt to make sense of the data I have tried to convert the quaternion values to euler angles by using the following formula (http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles):

When I apply this formula I get euler values. As I believe the formula above gives me radian values all euler values below are already *(180/pi) to convert radian -> degrees.

MPU-6050 at baseline pointing straight (after waiting 10 seconds)
euler_straight: .60.04, -1.23, -120.61
MPU-6050 pointing 90 degrees downward (attitude/pitch =-90 degrees)
euler_down: 1.58,  58.06, 156.92
MPU-6050 pointing 90 degrees upward (attitude/pitch =+90 degrees)
euler_up: 3.087, -59.15, -40.98
MPU-6050 tilted 90 degrees right (banking/roll =+90 degrees)
euler_right: 171.50, -3.57, -113.77
MPU-6050 tilted -90 degrees left  (banking/roll =-90 degrees)

euler_left: -0.42, -2.47, -118.31

The above values do not seem to correlate with the movements of the sensor described - e.g. the calculated euler values report movement in >1 dimensions (φ pitch -1.23 -> 58.06 and ψ roll -120.61 -> 156.92)

In an attempt to calibrate the device to match up with real world dimensions I've tried:
quaternion_straight*inverse(quaternion_straight)= 1, 0, 0, 0
quaternion_down*inverse(quaternion_straight)= 0.7236, 0.5427, -0.2764, -0.3254
euler conversion(quaternion_down*inverse(quaternion_straight))= 75.02, -2.68, -50.49

Once again 75.02, -2.68, -50.49 does not correspond to a 90  tilt in one direction/dimension.

And I've also tried:
euler_straight-euler_straight= 0, 0, 0
euler_down-euler_straight= -58.47, 59.30, 277.53

-58.47, 59.30, 277.53 does not correspond to a 90 tilt in one direction and does not match with the above mentioned 75.02, -2.68, -50.49 which I might have expected.

As you might be able to see from what I have tried above, I have so far been unsuccessful in demonstrating that the device data is recorded accurately when I move the device 90 degrees in one direction.

Do you have any suggestions of things to try and/or read up on? Does anyone see any obvious mistakes in my calculations above or how I'm approaching the problem?

Let me know if my explanations above need further elaboration.

I know everyone is very busy but any ideas or help would be greatly appreciated if you have time.
##### Share on other sites

Ok, so I now have reason to believe the setup I've working with has been faulty. I have more than one Arduino Pro Mini + MPU-6050 so here is new data that in my opinion is more trustworthy.

MPU-6050 at baseline pointing straight (after waiting 10 seconds)
quaternion_straight: 0.4355, 0.4761, 0.5391, 0.5412
MPU-6050 pointing 90 degrees downward (attitude/pitch =-90 degrees)
quaternion_down: 0.4355, 0.4761, 0.5391, 0.5412
MPU-6050 pointing 90 degrees upward (attitude/pitch =+90 degrees)
quaternion_up: 0.0142, 0.7282, 0.0013, 0.6852
MPU-6050 tilted 90 degrees right (banking/roll =+90 degrees)
quaternion_right: -0.0285, 0.7866, 0.6168, 0.0032
MPU-6050 tilted -90 degrees left  (banking/roll =-90 degrees)
quaternion_left: 0.8310, 0.0016, -0.0294, 0.5554

Euler values using previous equation:

MPU-6050 at baseline pointing straight (after waiting 10 seconds)
euler_straight: 91.99, -2.62, 99.63
MPU-6050 pointing 90 degrees downward (attitude/pitch =-90 degrees)
euler_down: -146.01, 88.20, -130.72
MPU-6050 pointing 90 degrees upward (attitude/pitch =+90 degrees)
euler_up: 159.65, -86.28, 19.29
MPU-6050 tilted 90 degrees right (banking/roll =+90 degrees)
euler_right: -177.65, -2.30, 76.16
MPU-6050 tilted -90 degrees left  (banking/roll =-90 degrees)
euler_left: -1.72, -2.90, 67.55

These above values do seem to correlate with the movements of the sensor described more so than in my previous post. Eg. φ pitch  -2.62 -> 88.20 which is the 90 degrees angle I've been hoping to register.
It will take me some time to figure out how and if I'm registering the banking/roll correctly.

Comments and advice are still welcome. This updated dataset should, however, hopefully drive everyone a little less crazy than the numbers I sent previously.
##### Share on other sites

Hello,

I was using axis (vector at given point) and rotation angle in my 3D applications so far, so no problem with gimbal lock.

If I have two vectors A and B in 3D space i can calculate angle between them:

alfa=acos( (Ax*Bx+Ay*By+Az*Bz)/(|A|*|B|) )

While I do not need Euler angles,  I'd like to convert quaternions calculated in MPU6050 to simply 3D vector notation (Vx,Vy,Vz), verify that I have correct readings in all 3 axes (X,Y,Z vectors where X=(1,0,0), Y=(0,1,0) Z=(0,0,1) ) and than go beyond - try to deal with quaternions transformations.

Simply, I'd like to ensure first I have good readings from MPU-6050 in all axes and nice calibrated sensor.

##### Share on other sites

• 2 weeks later...

if you are interested in quaternions and their relationship to rotations, go to my website, noelhughes.net.  If you have any questions, you can contact me at noel.h.hughes@gmail.com

##### Share on other sites

I found easier and maybe faster solution for my project using Maxima algebra CAS when mpu is not moveing:

/* G: 9.81; */  /* [m/s^2] */

a: matrix([Ax],[Ay],[Az]);

g: matrix([0],[0],[-G]);

p: matrix([cos(alfa)],[0],[sin(alfa)]);  /// pitch versor in X direction
xp: p;

yxp: axb(Y,p); /// cross product: Y x p

r: cos(-beta)*Y+sin(-beta)*yxp;  /// Magic roll  (rotation around pitch versor) is there and we get rolled Y versor yr;
yr: r;

zpr: trigsimp(axb(r,p));  ///  cross product: r x p  gives new Z axis versor needed to find Az component of Earth gravity acceleration at given pitch & roll

/// Now we have xp,yr,zpr versors based on pitch & roll angles

/// We need gravity acceleration to solve it for alfa & beta

I use asin() while Taylor series can be used to obtain nice pitch & roll +/- angles and it can be optimized for speed for smaller pitch & roll angles we expect (+/-45 degrees max each).

Maybe later I will need quaternions, but for the moment I've got good results using above solution with simply low pass filter and it looks like it fits my project requirements.

##### Share on other sites

• 8 months later...

Hi Markalberti,

I am currently facing the same problem as what described in your post. Could you please share with me your solution of this problem?

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.