关于 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。
编辑:
如果使用内部定义的 M_PI
,而不是 PI 的截断值,您将获得准确的结果。
欧拉角表示存在奇异性。您尝试比较的测试用例是一个单一的位置。
如果你想克服奇点,你可能想使用四元数或轴角表示。
不同阶的欧拉角(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轴等
假设我有一个 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。
编辑:
如果使用内部定义的
M_PI
,而不是 PI 的截断值,您将获得准确的结果。欧拉角表示存在奇异性。您尝试比较的测试用例是一个单一的位置。
如果你想克服奇点,你可能想使用四元数或轴角表示。
不同阶的欧拉角(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轴等