用螺距,偏航,使用特征滚动创建旋转矩阵

Creating a rotation matrix with pitch, yaw, roll using Eigen

本文关键字:创建 旋转 滚动 偏航 特征      更新时间:2023-10-16

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

看到我找不到这样做的预构建函数,我构建了一个,以防万一有人在将来找到这个问题

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

凯撒答案还可以,但是正如戴维·哈蒙(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;
}

如何使用音高,偏航,用特征库来创建旋转矩阵?

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

  • 外在的固有。
    是固定系统轴(外部)轴的旋转,还是围绕旋转轴(固有)?
  • 旋转与转换。
    您是否要表示物理旋转某些对象的矩阵,还是要表示将向量从一个参考帧转换为另一个参考框的矩阵?


  • 天文序列。
    有六个基本的天文序列。规范的Euler序列涉及围绕Z轴的旋转,然后围绕(旋转)X轴旋转,然后是第三个旋转(再次旋转)Z轴。这些天文学风格的序列中还有五个( x-y-x x-z-z-x y-x-y-x-y y-z-y-z-y z-y-z )除了这个规范 z-x-z 序列。


  • 航空航天序列。
    为了加上混乱,还有六个基本航空航天序列。例如,俯仰 - 滚子序列与滚动式偏合序列相比。尽管天文学界几乎已经解决了A Z-X-Z序列,但航空航天社区的说法也不能说。在此过程中,您发现人们使用六个可能的序列中的每一个。该组的六个序列是 x-y-z x-z-z-y y-z-z-x y-x-z-z >和 z-y-x

创建一个旋转矩阵所需的只是螺距,偏航,滚动和执行矩阵乘法的能力。

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

音高矩阵:

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

接下来,将所有这些都乘在一起。这里的顺序很重要。对于正常旋转,您将需要先将滚动矩阵乘以偏航矩阵,然后将产品乘以螺距矩阵。但是,如果您试图通过向后"撤消"旋转,则需要反向顺序执行乘法(除了具有相反值的角度)。

i将其Java实现转换为来自此站点的C :Euler Angle可视化工具

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

这是使用标准ZYX订单的实现,如Wikipedia

所示
template <typename T>
Eigen::Matrix3<T> eulerZYX_2_rot(T roll_rad, T pitch_rad, T yaw_rad) {
  // ZYX order, same as rot_z(yaw_rad) * rot_y(pitch_rad) * rot_x(roll_rad)
  static_assert(std::is_floating_point_v<T>, "Floating point required.");
  T sx = sin(roll_rad);
  T cx = cos(roll_rad);
  T sy = sin(pitch_rad);
  T cy = cos(pitch_rad);
  T sz = sin(yaw_rad);
  T cz = cos(yaw_rad);
  Eigen::Matrix3<T> rot(3, 3);
  rot(0, 0) = cz * cy;
  rot(0, 1) = cz * sy * sx - sz * cx;
  rot(0, 2) = cz * sy * cx + sz * sx;
  rot(1, 0) = sz * cy;
  rot(1, 1) = sz * sy * sx + cz * cx;
  rot(1, 2) = sz * sy * cx - cz * sx;
  rot(2, 0) = -sy;
  rot(2, 1) = cy * sx;
  rot(2, 2) = cy * cx;
  return rot;
}