簡體   English   中英

使用 Eigen 創建具有俯仰、偏航、滾轉的旋轉矩陣

[英]Creating a rotation matrix with pitch, yaw, roll using Eigen

如何使用 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 種方法可以做到這一點。 你想要哪一個? 以下是因素:

  • 外在對內在。
    是圍繞固定系統的軸(外在)旋轉還是圍繞旋轉軸(內在)旋轉?

  • 旋轉與變換。
    您是要表示物理旋轉某個對象的矩陣,還是要表示將向量從一個參考系轉換為另一個參考系的矩陣?

  • 天文序列。
    有六個基本的天文序列。 規范的歐拉序列包括繞 z 軸旋轉,然后繞(旋轉)x 軸旋轉,然后繞(再次旋轉)z 軸進行第三次旋轉。 除了這個規范的zxz序列之外,還有五個這些天文風格的序列( xyxxzxyxyyzyzyz )。

  • 航空航天序列。
    更令人困惑的是,還有六個基本的航空航天序列。 例如,俯仰-偏航-滾轉序列與滾轉-俯仰-偏航序列。 雖然天文學界幾乎已經確定了zxz序列,但航空界卻並非如此。 一路上,你會發現人們使用六種可能的序列中的每一種。 此組中的六個序列是XYZ,XZY,YZX,YXZ,ZXY,ZYX。

創建旋轉矩陣所需的只是俯仰、偏航、滾動和執行矩陣乘法的能力。

首先,創建三個旋轉矩陣,一個用於每個旋轉軸(即一個用於俯仰,一個用於偏航,一個用於滾動)。 這些矩陣將具有以下值:

音高矩陣:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM