关于 Eigen C++ 库的 EulerAngles 转换

About EulerAngles Conversion from Eigen C++ Library

假设我有一个 3 维框架,旋转 roll = 0,pitch = 0 和 yaw = 0,分别关于 x、y 和 z 轴。

我希望框架绕 x 轴旋转 3.14159 (Pi) 或 roll = Pi。

下面是上述情况的代码。

问题是,当我想将旋转矩阵转换回滚动、俯仰和偏航时,代码给出了不同的答案。

而不是 roll = Pi,结果是 roll = 0,pitch = pi,yaw = pi。

我认为 Peter Corke 在 Matlab 上的 RVC 工具箱给出了正确的答案。

也许我的程序有问题,或者 Eigen 中的 eulerAngles 工作方式不同?请帮忙。

代码:

#include <iostream>
#include <Eigen/Dense>

const double PI = 3.14159265359;

int main()
{
    using ::Eigen::AngleAxisd;
    using ::Eigen::Matrix3d;
    using ::Eigen::Vector3d;
    using ::std::cout;
    using ::std::endl;

    Matrix3d R,Rx;

    R = AngleAxisd(PI, Vector3d::UnitX())
        * AngleAxisd(0, Vector3d::UnitY())
        * AngleAxisd(0, Vector3d::UnitZ());
    Rx = AngleAxisd(PI, Vector3d::UnitX());

    cout << R << endl << endl;
    cout << Rx << endl << endl;

    Vector3d ea = R.eulerAngles(0,1,2); 
    Vector3d eax = Rx.eulerAngles(0,1,2); 

    cout << ea << endl << endl;
    cout << eax << endl << endl;

    std::cin.ignore();
    return 0;
}

输出(我将小到零的数字四舍五入):

1 0 0
0 -1 0
0 0 -1

1 0 0
0 -1 0
0 0 -1

0
3.14159
3.14159

0
3.14159
3.14159

欧拉角不是唯一的。在您的 XYZ 约定中,(0, pi, pi)(pi,0,0) 都代表相同的旋转,并且都是正确的。 Eigen::eulerAngles 方法始终选择最小化第一角。

请参考documentation of Eigen:eulerAngles. Details on various conventions of Euler-angles is well documented in Wikipedia and MathWorld

编辑:

  1. 如果使用内部定义的 M_PI,而不是 PI 的截断值,您将获得准确的结果。

  2. 欧拉角表示存在奇异性。您尝试比较的测试用例是一个单一的位置。

  3. 如果你想克服奇点,你可能想使用四元数或轴角表示。

不同阶的欧拉角(roll1, pitch1, yaw1 or pitch2, yaw2, roll2, ...)可以产生相同的旋转矩阵。

其实Eigen文档给出了答案。 仔细阅读Eigen document的函数声明,你就会得到答案。 Matrix< typename MatrixBase< Derived >::Scalar, 3, 1 > Eigen::MatrixBase< Derived >::eulerAngles ( Index a0, Index a1, Index a2 ) const 三个参数 a0,a1,a2 中的每一个都将各自的旋转轴表示为 {0,1,2} 中的整数。例如,在:

Vector3f ea = mat.eulerAngles(2, 0, 2);

“2”代表z轴,“0”代表x轴等