使用Eigen创建具有俯仰,偏航,滚动的旋转矩阵

时间:2014-01-28 17:09:39

标签: c++ math matrix rotation eigen

如何使用俯仰,偏航,使用特征库创建旋转矩阵?

5 个答案:

答案 0 :(得分:21)

看到我怎么找不到这样做的预建功能,我建了一个,这是为了以后有人发现这个问题

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();

答案 1 :(得分:9)

  

如何使用俯仰,偏航,使用特征库创建旋转矩阵?

有48种方法可以做到这一点。你想要哪一个?以下是因素:

  • 外在的内在本征 围绕固定系统的轴旋转(外在的)还是绕旋转的轴(内在的)旋转?

  • 轮换与转换。
    您想表示物理旋转某个对象的矩阵,还是想表示将矢量从一个参考帧转换为另一个参考帧的矩阵?

  • 天文序列。
    有六个基本的天文序列。规范的欧拉序列涉及围绕z轴的旋转,然后围绕(旋转的)x轴旋转,然后围绕(再次旋转)z轴旋转。还有五个这样的天文风格序列( xyx xzx yxy yzy zyz )除了这个规范的 zxz 序列。

  • 航空航天序列 更令人困惑的是,还有六个基本的航空航天序列。例如,俯仰 - 横摆 - 滚动序列与滚动 - 倾斜 - 偏航序列。虽然天文学界几乎已经确定了 z-x-z 序列,但航空航天界却不能这样说。在某个地方,您会发现人们使用六种可能序列中的每一种。该组中的六个序列是 xyz xzy yzx yxz zxy ,和 zyx

答案 2 :(得分:8)

凯撒的回答还可以,但正如大卫·哈门所说,这取决于你的申请。对于我(水下或飞行器领域),获胜组合是:

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;
}

答案 3 :(得分:7)

创建旋转矩阵所需要的只是俯仰,偏航,滚动以及执行矩阵乘法的能力。

首先,创建三个旋转矩阵,一个用于每个旋转轴(即一个用于俯仰,一个用于偏航,一个用于滚动)。这些矩阵将具有以下值:

音高矩阵:

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

Roll Matrix:

cos(roll), sin(roll), 0, 0,
-sin(roll), cos(roll), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1

接下来,将所有这些相乘。这里的顺序很重要。对于正常旋转,您需要先将“滚动矩阵”乘以“偏航矩阵”,然后将乘积乘以“俯仰矩阵”。但是,如果您试图通过向后“撤消”旋转,则需要以相反的顺序执行乘法(除了具有相反值的角度之外)。

答案 4 :(得分:-2)

我从以下站点将其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;
}