Correction of a part of Yaw of one quaternion by part of Yaw of another

I have the following problem: the quaternion (q1) from the motion capture device should be corrected by the yaw angle (and only the yaw!) From another orientation quaternion (q2) obtained by the second tracked object, so the step and roll q1 are the same as before but q1 has a yaw of q2.

A working solution converts the quarts to matrices, then I do the calculations to extract the angle of rotation, and then adjust the cursor. But this leads to "turning over" when right in the direction of a certain axis (for example, after 0 ยฐ - 359 ยฐ). Also tried other conversions that are not convenient.

Is it possible to do math directly on quaternions without conversion to Euler matrices or angles (i.e. I can set the corrected quaternion as a quaternion for a tracked object)?

As said, the correction should include only rotation around the axis (yaw). I have few programming options regarding math classes (Virtools VSL Script, unfortunately, is quite limited in this direction). Does anyone have any advice?

+6
source share
4 answers

For this task, it is best to use Euler angles, since their advantage (the only advantage in general) is the separation into separate rotations around orthogonal axes. Therefore, convert both quaternions into a corner element agreement that suits your needs and simply replace q1's angle of rotation with q2's.

Of course, you need to use a suitable conditional angle of the Euler angle, where other rotations are not dependent on the yaw angle (so does yaw rotation apply first when converting the point?), So you can simply change the angle without affecting other axes. When converting the resulting Euler angle to three back to the quaternion, should you get a unique view again, or am I missing something?

+1
source

Short answer: Yes, it is possible. You can formulate a rotation (about an arbitrary axis) and execute it using quaternions.

Long answer: see Wikipedia article on quaternions and rotations . I assume that the problem you are describing is a cardan lock.

0
source

If you have the quaternions Q1 and Q2 , and your upward direction is y, then if you select the y-component Q1 and renormalize, then you get a quaternion without a yaw component. Similarly, if you select the x and z components of Q2 , you get a quaternion with only the yaw component. Multiply the second by the first (using multiplication of quaternions), and you are there.

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

Of course, you can check out a special case where the rotation was exactly (or close to) 180 degrees, as this can make things numerically unstable when you try to normalize a vector with a very small value.

0
source

You can remove part of the yaw of the quaternion by calculating the part of yaw and then applying it back. Suppose your quaternions are quat(w,x,y,z) == w + xi + yj + zk) , and yaw is defined around the Z axis (123 or 213 Euler from this article ).

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

By decomposing quaternions into Euler angles, we have a 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 it can be obtained 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 quaternion angle is to add it to the identical quaternion and normalize it:

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

To answer your initial question - we want to take the jerk from q1 and replace it with q2 . We can do this as follows:

 q2 = get_quat_yaw(q1) * get_quat_yaw(q2).conj() * q2; 
0
source

Source: https://habr.com/ru/post/889376/


All Articles