2

I found a formula online to extract yaw from a quaternion like so:

double x = quat[0];
double y = quat[1];
double z = quat[2];
double w = quat[3];

return atan2(2.0f * (w * z + x * y), 1.0f - 2.0f * (y * y + z * z));

I wanted to verify if this is the right way to do it. I created a loop that gets the body's current rotation (i.e quat variable above), calculates the Yaw from it (as like the formula above) and prints it out. I then started rotating the body along all three axis. I was expecting the printed value to stay the same when I roll or pitch and only change when I yaw. However, when I roll or pitch I see that the value changes, so I assume that the formula above is not correct.

What is the right way to get the rotation around z-axis (i.e Yaw) from a quaternion? I don't care about pitch or roll but only the yaw.

Maybe the test I am doing is non-sense, but ideally what I would like to do is to observe the body's orientation only in terms of the z-axis. If I am given a quaternion of a body, how can I found out the theta value of the body in respect to itself or the world frame. Assuming that I can get the body's x, y position, I would also like to capture the theta value of that body, so I was thinking that I need to extract the Yaw from the quaternion. The result I am looking for is a value that I can use to represent the state of the body (x, y and theta). I already found the x, y and now I am only left with a quaternion that I need to find the theta of the body. I hope this make sense.

Phrixus
  • 165
  • 1
  • 5

1 Answers1

2

The equation that you used requires that you have a unit quaternion, so $w^2+x^2+y^2+z^2 = 1$. If your quaternion is not of unit length, then you can either normalize it, or use the following expression instead:

return atan2(2.0f * (w * z + x * y), w * w + x * x - y * y - z * z);

Another source for an error might be how a quaternion is defined in your software. Namely it could also be that the first element of the quaternion is $w$, which would mean that you would have to use this instead:

double w = quat[0];
double x = quat[1];
double y = quat[2];
double z = quat[3];
fibonatic
  • 941
  • 6
  • 10