用一个四元数的偏航部分校正另一个四元数的偏航部分

发布于 2024-11-10 08:04:30 字数 389 浏览 0 评论 0原文

我有以下问题:来自运动捕捉设备的四元数(q1)需要通过第二个跟踪对象导出的另一个方向四元数(q2)的偏航角(并且只有偏航!)进行校正,以便俯仰和滚动q1 的偏航角与之前相同,但 q1 具有 q2 的偏航角。

工作解决方案是将季铵化合物转换为矩阵,然后进行计算以提取旋转角度,然后进行航向校正。但是,当直接沿某个轴的方向(例如,0° - 359°之后)时,这会导致“翻转”。还尝试了其他不方便的转换。

是否有可能直接对四元数进行数学计算,而无需转换为矩阵或欧拉角(即,我可以将校正后的四元数设置为跟踪对象的四元数)?

如上所述 - 校正应包括仅绕上轴旋转(偏航)。关于数学类,我没有太多的编程可能性(不幸的是,Virtools 的 VSL 脚本在这方面非常有限)。有人有什么建议吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心如荒岛 2024-11-17 08:04:30

对于此任务,欧拉角是最好的选择,因为它们的优点(唯一的优点)在于围绕正交轴分离成单独的旋转。因此,将两个四元数转换为适合您需要的欧拉角约定,只需将 q1 的偏航角替换为 q2 的偏航角即可。

当然,您需要使用匹配的欧拉角约定,其中其他旋转不依赖于偏航角(因此在变换点时首先应用偏航旋转?),这样您就可以仅更改角度而不影响其他轴。当将生成的欧拉角三元数转换回四元数时,您应该再次获得唯一的表示形式,还是我遗漏了一些东西?

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?

孤凫 2024-11-17 08:04:30

您可以通过计算偏航部分然后应用其逆来删除四元数的偏航部分。假设您的四元数是 quat(w,x,y,z) == w + xi + yj + zk),并且偏航是围绕 Z 轴定义的(来自 本文)。

请注意,在这些帧中,绕 Z 轴 yaw 的旋转由四元数 quat(cos(yaw/2), 0, 0, sin(yaw/2))< 表示/代码>。

将四元数分解为欧拉角,我们的偏航为:

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)

由此我们可以得出

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

将四元数的角度减半的一种简单方法是将其添加到恒等四元数并标准化:

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

回答您原来的问题 - 我们想要获取偏航来自q1,并用它替换q2的偏航。我们可以这样做:

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

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;
傾旎 2024-11-17 08:04:30

简短回答:是的,这是可能的。您可以制定旋转(绕任意轴)并使用四元数运算来执行它。

长答案:请参阅有关四元数和旋转的维基百科文章。我猜你描述的问题是万向节锁。

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.

少女七分熟 2024-11-17 08:04:30

如果您有四元数 Q1Q2 并且您的“向上”方向是 y,那么如果您取出 y > Q1 的分量并重新归一化,然后您将得到一个没有偏航分量的四元数。同样,如果您取出 Q2xz 分量,那么您将得到一个四元数,偏航分量。将第二个乘以第一个(使用四元数乘法)即可。

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

当然,您可能需要检查特殊情况,即旋转了恰好(或接近)180 度,因为当您尝试对幅度非常小的向量进行归一化时,这可能会使数值不稳定。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文