9

I have the following problem: A quaternion (q1) from a motion capturing device needs to be corrected by the yaw angle (and only yaw!) from another orientation quaternion (q2) derived by a second tracked object, so that the pitch and roll of q1 is the same as before but q1 has the yaw of q2.

The working solution is converting the quats to matrices, then I do the calculations to extract the rotation angle and then I do the heading correction. But this results in a "flipping" when directly in direction of a certain axis (e.g. after 0° - 359°). Also tried other conversions which are not convenient.

Is there any possibility to do the math directly on the quaternions without conversions to matrices or euler angles (i.e. so I can set the corrected quaternion as quaternion for the tracked object)?

As said - the correction should include only the rotation around the up-axis (yaw). I have not many programming possibilities regarding math classes (VSL Script from Virtools is unfortunately pretty limited in this direction). Anyone has some advice?

Raboon
  • 91
  • 1
  • 2

4 Answers4

2

For this task euler angles are the best thing to use, as their advantage (the only advantage at all) lies in the separation into individual roations around orthogonal axes. So convert both quaternions to an euler angle convention that fits your needs and just substitute q1's yaw angle by q2's.

Of course you need to use a matching euler angle convention, one where the other rotations don't depend on the yaw angle (so the yaw rotation is applied first when transforming a point?), so that you can just change the angle without influencing the other axes. When converting the resulting euler angle triple back to a quaternion, you should get a unique representation again, or am I missing something?

Christian Rau
  • 43,206
  • 10
  • 106
  • 177
  • Thanks for that answer. But with the conversion to the Euler-Angles and back I have the definition problem +90 to -90 degrees. What I need is a solution defined for 360°. Maybe I´m just getting it wrong. – Raboon Jun 15 '11 at 10:21
  • @Raboon It's just about factoring out the rotation about one axis and then changing this rotation. I'm not sure if you really run into ambiguity or gimbal lock problems, but I'm ready to be convinced of the opposite. – Christian Rau Jun 15 '11 at 10:49
  • 1
    Provided you pick an Euler angle convention such that yaw is applied first, you don't run into any ambiguity or gimbal lock problems with this approach. – Eric May 20 '17 at 18:44
1

You can remove the yaw part of the quaternion by calculating the yaw part, and then applying its inverse. Let's assume that your quaternions are quat(w,x,y,z) == w + xi + yj + zk), and yaw is defined around the Z axis (euler 123 or 213 from this paper).

Note that in these frames, a rotation by yaw around the Z axis is represented with the quaternion quat(cos(yaw/2), 0, 0, sin(yaw/2)).

Decomposing quaternions into euler angles, we have yaw as:

yaw = atan2(-2*x*y + 2*w*z, +w*w +x*x -y*y -z*z); // 123 angles (page 24)
yaw = atan2(-2*x*y + 2*w*z, +w*w -x*x +y*y -z*z); // 213 angles (page 28)

From which we can derive that

quat quat_2yaw = quat(w*w +x*x -y*y -z*z, 0, 0, -2*x*y + 2*w*z).normalize(); // 123 angles
quat quat_2yaw = quat(w*w -x*x +y*y -z*z, 0, 0, -2*x*y + 2*w*z).normalize(); // 213 angles

An easy way to halve the angle of a quaternion is to add it to the identity quaternion and normalize:

quat quat_yaw = (1 + quat_2yaw).normalize();

To answer your original question - we want to take the yaw from q1, and replace q2s yaw with it. We can do that as follows:

q2 = get_quat_yaw(q1) * get_quat_yaw(q2).conj() * q2;
Eric
  • 87,154
  • 48
  • 211
  • 332
  • From the paper that you link here, for the 123 representation, the expression in equation 290 for the 3rd element of the matrix (presumably yaw) is given as: `atan2(2*q1*q2 + 2*q0*q3, q1^2 +q0^2 −q3^2 −q2^2)` Wouldn't that make the yaw calculation this instead: `yaw = atan2(2*w*z + 2*x*y, +w*w +x*x -y*y -z*z); // 123 angles` It is basically the same except the `2*x*y` expression is positive, not negative. Am I missing something? – Jeff Rowberg Mar 12 '18 at 14:06
  • The paper mentioned in this answer moved to: https://www.astro.rug.nl/software/kapteyn/_downloads/fa29752e4cd69adcfa2fc03b1c020f4e/attitude.pdf – guga Nov 28 '19 at 14:44
0

Short answer: Yes it is possible. You can formulate rotations (about an arbitrary axis) and perform it with quaternion operations.

Long answer: See the Wikipedia article on Quaternions and rotations. I guess the problem you describe is the gimbal lock.

Eric
  • 87,154
  • 48
  • 211
  • 332
flolo
  • 14,007
  • 4
  • 30
  • 54
  • Thanks for the answer. I know that it has to be possible - i also know some of the quaternion math. However, for the special problem stated above I don´t know the best solution to start with it. – Raboon May 31 '11 at 10:16
0

If you have quaternions Q1 and Q2 and your 'up' direction is y, then if you take out the y component of Q1 and renormalize, then you get a quaternion with no yaw component. Likewise, if you take out the x and z components of Q2, then you get a quaternion with only the yaw component. Multiply the second to the first (using quaternion multiplication) and you're there.

Q1[2] = 0;
normalize4d(Q1);
Q2[1] = 0;
Q2[3] = 0;
normalize4d(Q2);
Q3 = quatMult(Q2,Q1);

Of course, you might want to check the special case where there has been a rotation by exactly (or close to) 180 degrees since that can make things numerically unstable when you try to normalize a vector with very small magnitude.

JCooper
  • 5,957
  • 1
  • 20
  • 31
  • Do you have a reference for why "taking out the y component" works? – Eric May 19 '17 at 22:56
  • This does not work - try a test case with a a `fromYawPitchRoll`, using the conventional euler angle ordering, and you'll see that it produces different results for pitch and roll before and after zeroing out that component – Eric May 20 '17 at 00:26
  • Namely, for a quaternion `(w, x, y, z)`, the rotation around the z axis is only zero if `w*z = x*y`, which can be deduced from equation 362 of [this paper](https://www.astro.rug.nl/software/kapteyn/_downloads/attitude.pdf) – Eric May 20 '17 at 00:41
  • The paper reference by @Eric has moved to https://www.astro.rug.nl/software/kapteyn/_downloads/fa29752e4cd69adcfa2fc03b1c020f4e/attitude.pdf – guga Nov 30 '19 at 17:03