【发布时间】:2014-02-20 03:21:10
【问题描述】:
如何通过 Eigen 库使用俯仰、偏航、滚动创建旋转矩阵?
【问题讨论】:
标签: c++ math matrix rotation eigen
如何通过 Eigen 库使用俯仰、偏航、滚动创建旋转矩阵?
【问题讨论】:
标签: c++ math matrix rotation eigen
鉴于我无法找到执行此操作的预构建函数,我构建了一个,以防将来有人发现此问题
Eigen::AngleAxisd rollAngle(roll, Eigen::Vector3d::UnitZ());
Eigen::AngleAxisd yawAngle(yaw, Eigen::Vector3d::UnitY());
Eigen::AngleAxisd pitchAngle(pitch, Eigen::Vector3d::UnitX());
Eigen::Quaternion<double> q = rollAngle * yawAngle * pitchAngle;
Eigen::Matrix3d rotationMatrix = q.matrix();
【讨论】:
Caesar 的答案还可以,但正如 David Hammen 所说,这取决于您的申请。对我来说(水下或飞行器领域),获胜组合是:
Eigen::Quaterniond
euler2Quaternion( const double roll,
const double pitch,
const double yaw )
{
Eigen::AngleAxisd rollAngle(roll, Eigen::Vector3d::UnitX());
Eigen::AngleAxisd pitchAngle(pitch, Eigen::Vector3d::UnitY());
Eigen::AngleAxisd yawAngle(yaw, Eigen::Vector3d::UnitZ());
Eigen::Quaterniond q = yawAngle * pitchAngle * rollAngle;
return q;
}
【讨论】:
如何通过 Eigen 库使用俯仰、偏航、滚动创建旋转矩阵?
有 48 种方法可以做到这一点。你想要哪一个?以下是因素:
【讨论】:
创建旋转矩阵所需的只是俯仰、偏航、滚动以及执行矩阵乘法的能力。
首先,创建三个旋转矩阵,一个用于每个旋转轴(即一个用于俯仰,一个用于偏航,一个用于滚动)。这些矩阵将具有以下值:
音高矩阵:
1, 0, 0, 0,
0, cos(pitch), sin(pitch), 0,
0, -sin(pitch), cos(pitch), 0,
0, 0, 0, 1
偏航矩阵:
cos(yaw), 0, -sin(yaw), 0,
0, 1, 0, 0,
sin(yaw), 0, cos(yaw), 0,
0, 0, 0, 1
滚动矩阵:
cos(roll), sin(roll), 0, 0,
-sin(roll), cos(roll), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
接下来,将所有这些相乘。这里的顺序很重要。对于正常旋转,您需要先将滚动矩阵乘以偏航矩阵,然后再乘以俯仰矩阵。但是,如果您试图通过向后“撤消”旋转,则需要以相反的顺序执行乘法(除了具有相反值的角度之外)。
【讨论】:
我从这个站点将他们的 Java 实现翻译成 C++:Euler Angle Visualization Tool
#include <iostream>
#include <math.h>
#include <Eigen/Dense>
Eigen::Matrix3d rotation_from_euler(double roll, double pitch, double yaw){
// roll and pitch and yaw in radians
double su = sin(roll);
double cu = cos(roll);
double sv = sin(pitch);
double cv = cos(pitch);
double sw = sin(yaw);
double cw = cos(yaw);
Eigen::Matrix3d Rot_matrix(3, 3);
Rot_matrix(0, 0) = cv*cw;
Rot_matrix(0, 1) = su*sv*cw - cu*sw;
Rot_matrix(0, 2) = su*sw + cu*sv*cw;
Rot_matrix(1, 0) = cv*sw;
Rot_matrix(1, 1) = cu*cw + su*sv*sw;
Rot_matrix(1, 2) = cu*sv*sw - su*cw;
Rot_matrix(2, 0) = -sv;
Rot_matrix(2, 1) = su*cv;
Rot_matrix(2, 2) = cu*cv;
return Rot_matrix;
}
int main() {
Eigen::Matrix3d rot_mat = rotation_from_euler(0, 0, 0.5*M_PI);
std::cout << rot_mat << std::endl;
return 0;
}
【讨论】: