四元数是否会翻转符号以实现非常相似的旋转? [英] Quaternion is flipping sign for very similar rotations?

查看:97
本文介绍了四元数是否会翻转符号以实现非常相似的旋转?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下最小工作示例:

Consider the following minimal working example:

#include <iostream>
#include <math.h>
#include <eigen3/Eigen/Dense>

int main() {
  // Set the rotation matrices that give an example of the problem
  Eigen::Matrix3d rotation_matrix_1, rotation_matrix_2;
  rotation_matrix_1 << 0.15240781108708346, -0.98618841818279246, -0.064840288106743013,
                       -0.98826031445019891, -0.1527775600229907, 0.00075368177315370682,
                       -0.0106494132438156, 0.063964216524108775, -0.99789536976680049;
  rotation_matrix_2 << -0.12448670851248633, -0.98805453458380521, -0.090836645094957508,
                       -0.99167686914182451, 0.12086367053038971, 0.044372968742129482,
                       -0.03286406263376359, 0.095604444636749664, -0.99487674792051639;

  // Convert to Euler angles
  Eigen::Vector3d euler_angles_1 = rotation_matrix_1.eulerAngles(2, 1, 0)*180.0f/M_PI;
  Eigen::Vector3d euler_angles_2 = rotation_matrix_2.eulerAngles(2, 1, 0)*180.0f/M_PI;

  // Convert to quaternion
  Eigen::Quaternion<double> quaternion_1(rotation_matrix_1);
  Eigen::Quaternion<double> quaternion_2(rotation_matrix_2);

  // Print out results
  std::cout << "Euler angles 1:\nyaw = " << euler_angles_1[0] << "\npitch = " << euler_angles_1[1] << "\nroll = " << euler_angles_1[2] << std::endl;
  std::cout << "Quaternion 1:\nw = " << quaternion_1.w() << "\nx = " << quaternion_1.x() << "\ny = " << quaternion_1.y() << "\nz = " << quaternion_1.z() << std::endl;
  std::cout << std::endl;
  std::cout << "Euler angles 2:\nyaw = " << euler_angles_2[0] << "\npitch = " << euler_angles_2[1] << "\nroll = " << euler_angles_2[2] << std::endl;
  std::cout << "Quaternion 2:\nw = " << quaternion_2.w() << "\nx = " << quaternion_2.x() << "\ny = " << quaternion_2.y() << "\nz = " << quaternion_2.z() << std::endl;
}

其输出是:

Euler angles 1:
yaw = 98.767
pitch = 179.39
roll = -3.66759
Quaternion 1:
w = 0.020826
x = 0.758795
y = -0.650521
z = -0.0248716

Euler angles 2:
yaw = 82.845
pitch = 178.117
roll = -5.48908
Quaternion 2:
w = -0.0193663
x = -0.661348
y = 0.748369
z = 0.0467608

两个旋转几乎相同(由欧拉角给出).预期的行为是quaternion_2具有与quaternion_1相同的符号的值,即输出为:

Both rotations are nearly identical (as given by the Euler angles). The expected behavior is that quaternion_2 will have values with same sign as quaternion_1, i.e. for the output to be:

Quaternion 2:
w = 0.0193663
x = 0.661348
y = -0.748369
z = -0.0467608

但是,Eigen似乎翻转"了四元数.我知道q和-q表示相同的旋转-但是,从外观上看,四元数会在其每个值中翻转符号,这在视觉上并不吸引人,而且很烦人.在一般情况下该如何纠正(即四元数始终保留其手性",而不是在某些旋转时翻转符号)?

However, Eigen appears to "flip" the quaternion. I am aware that q and -q represent the same rotation - however, it is visually not appealing, and frankly annoying, that the quaternion would flip sign in each of its values. How can this be rectified for the general case (i.e. that the quaternion always preserves its "handedness", rather than flipping sign for certain rotations)?

推荐答案

使用单位四元数表示3d旋转时,有两种方法可以表示每个实际旋转-如果不避免,则无法避免出现负"旋转在空间中创造出人为的不连续性.

When unit quaternions are used to represent 3d rotations, there are two ways to represent each actual rotation - and you can't avoid the 'negative' ones occuring without creating an artificial discontinuity in the space.

与在单位圆上使用复数的2d旋转不同,单位超球面上距"0旋转"最远的点必须是"360度旋转",而不是"180度";因为存在需要表示180度旋转的2d空间,而所有360度旋转都是等效的,而与轴无关.

Unlike 2d rotations using complex numbers on a unit circle, the farthest point on the unit hypersphere from '0 rotation' has to be '360 degree rotation', not '180 degree'; since there is a 2d-space of possible 180 rotations which needs to be represented, whereas all 360-degree rotations are equivalent regardless of axis.

当w分量为负时,您可以通过更改整个符号来始终进行规范化". 仍然会有w = 0的情况,这些都代表旋转180度-例如(0,0,1,0)和(0,0,-1,0)表示相同的旋转.

You can always 'canonicize' by changing the sign of the whole thing when the w component is negative. There will still be cases where w = 0, these all represent rotations by 180 - e.g. (0,0,1,0) and (0,0,-1,0) represent the same rotation.

并且(0.01,0.99995,0,0,0)和(-0.01,0.99995,0,0)表示旋转非常接近,但是如果将第二个旋转更改为等效的(0.01,-0.99995,0 ,0),然后它们在4d向量空间中相距很远.

And, (0.01, 0.99995,0,0,0) and (-0.01, 0.99995,0,0) represent rotations very close together, but if you change the second one to the equivalent (0.01,-0.99995,0,0) then they are far apart in the 4d vector space.

因此,实际上,当您想找到两个旋转之间的差异来查看它们之间有多接近时,您仍然会有所顾虑.分别规范化这两者可能无济于事; 您通常需要根据需要翻转标志,以使其尽可能接近.

So, practically speaking, you can still have a concern when you want to find the difference between two rotations to see how close they are. Canonicizing the two individually may not help; you would generally want to flip signs as needed to make them as close as possible.

或者,比较旋转q1,q2:找到四元数乘积q1 * q2.conj();这样就可以将差异作为旋转四元数;如果它有w< 0,更改其标志.对于q1和q2靠近在一起(无论初始符号差异如何),结果将始终非常接近(1,0,0,0).

Or, to compare rotations q1,q2 : find the quaternion product q1 * q2.conj(); this gives the difference as a rotation quaternion; if it has w < 0, change its signs. For q1 and q2 close together (regardless of initial sign diffs) the result will always be fairly close to (1,0,0,0).

如果只想检查它们是否在彼此的某个角度"th"内,则只需要结果的实部.这等效于找到q1,q2的点积(将其作为4空间中的单位矢量进行处理),然后检查abs是否为abs.结果的值> = cos(th/2).

If you only want to check if they are within a certain angle 'th' of each other, you only need the real part of the result. This is equivalent to finding the dot product of q1,q2 (treating them as unit vectors in 4-space), then you check if the abs. value of the result >= cos(th/2).

找到相对角度的另一种方法:找到两个单位矢量的矢量差,然后找到该差矢量的大小"m"(平方和的平方根),其范围为[0, 2].然后找到

Another way to find the relative angle: find the vector difference of the two unit vectors, and find the magnitude 'm' of that difference vector, (square root of the sum of squares) which will be in range [0,2]. Then find

th = 4*arcsin(m/2)

...这将是0 ... 2 * pi.

... and this will be 0 ... 2*pi.

在m> sqrt(2),th> pi的情况下,您会得到错误的一面"结果(而且,当m接近2.0时,计算将具有可怕的数值精度).因此,在这种情况下,请更改符号之一(即,使m为输入的 sum 的向量长度,而不是差值);您将拥有m< = sqrt(2),th< = pi.

In cases where m > sqrt(2), th > pi and you are getting the 'wrong side' result (also, the computation will have terrible numeric accuracy as m gets close to 2.0). So, in such cases, change one of the signs (i.e. make m the vector length of the sum of the inputs, rather than the difference); you will then have m <= sqrt(2), th <= pi.

对于 small m,反正弦公式具有泰勒级数

For small m, the arcsin formula has the taylor series

th ~=~ 2*m + (m^3)/12 + ...

因此,对于较小的增量,相对旋转角度大约是矢量差大小的两倍(并且在数值上比在w接近1时使用w的反余弦值要可靠得多).

So, for small deltas, the relative rotation angle is approximately twice the magnitude of the vector difference (and this is numerically much more reliable than using an inverse-cosine-of-w when w is nearly 1).

这篇关于四元数是否会翻转符号以实现非常相似的旋转?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆