【问题标题】:Creating a rotation matrix with pitch, yaw, roll using Eigen使用 Eigen 创建具有俯仰、偏航、滚动的旋转矩阵
【发布时间】:2014-02-20 03:21:10
【问题描述】:

如何通过 Eigen 库使用俯仰、偏航、滚动创建旋转矩阵?

【问题讨论】:

标签: c++ math matrix rotation eigen


【解决方案1】:

鉴于我无法找到执行此操作的预构建函数,我构建了一个,以防将来有人发现此问题

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

【讨论】:

  • 不错的答案,但正如@narcispr 所说,轴将取决于您拥有的应用程序。您能否在回答中说明您的目标是飞机应用以避免混淆?
【解决方案2】:

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

【讨论】:

【解决方案3】:

如何通过 Eigen 库使用俯仰、偏航、滚动创建旋转矩阵?

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

  • 外在与内在。
    是围绕固定系统的轴旋转(外部)还是围绕旋转轴(内部)?

  • 旋转与变换。
    您想表示物理旋转某个对象的矩阵,还是表示将向量从一个参考系转换到另一个参考系的矩阵?

  • 天文序列。
    有六个基本的天文序列。典型的欧拉序列涉及围绕 z 轴的旋转,然后围绕(旋转的)x 轴的旋转,然后是围绕(再次旋转的)z 轴的第三次旋转。这些天文风格的序列还有五个(xyxxzxyxyyzyzyz) 除了这个规范的 zxz 序列。

  • 航空航天序列。
    更令人困惑的是,还有六个基本的航空航天序列。例如,俯仰-偏航-滚动序列与滚动-俯仰-偏航序列。虽然天文学界几乎已经确定了 z-x-z 序列,但航空界却不能这样说。一路走来,您会发现人们使用六种可能的序列中的每一种。该组中的六个序列分别为xyzxzyyzxyxzzxyzyx

【讨论】:

  • 你是怎么得到 48 的? (6 天文 + 6 航空航天)*(2 用于内部,外部)= 24 旋转与变换仍然使用相同的矩阵。
  • @DylanMadisetti - 除非您认为矩阵的转置与原始矩阵相同,否则旋转(又名主动旋转)和变换(又名被动旋转)不使用相同的矩阵。旋转/平移矩阵很少是自伴的。
【解决方案4】:

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

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

音高矩阵:

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

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

【讨论】:

  • 谢谢你的回答,我已经知道了,但我希望库有一个预建的函数来做这个。
  • @MohammedMajeed 我不相信有内置函数,但请参阅 stackoverflow.com/a/15043888/1530508 了解使用四元数的非常简洁的技术。
  • 这已记录在案there
  • 这是我假设的左手坐标系?要将其应用于右手系统,您只需更改输入值符号。即设置 roll = - roll , yaw = - yaw, pitch = -pitch
  • @user183833 是的,如果没记错的话,这是左撇子。
【解决方案5】:

我从这个站点将他们的 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    相关资源
    最近更新 更多