從零開始學習SLAM(三)

旋轉向量

#include <Eigen/Geometry>
#include <Eigen/Core>

AngleAxisd 類有幾種構造函數,其中最常用的是:

Eigen::AngleAxisd(const Scalar& angle, const Axis& axis);
  • angle 是旋轉的角度,通常以弧度表示。
  • axis 是旋轉的軸,通常是一個單位向量,表示旋轉的方向。

例如,要創建一個圍繞 Z 軸順時針旋轉 π/4 弧度(45度)的 AngleAxisd 對象,可以這樣寫:

Eigen::AngleAxisd rotation_angle_axis(M_PI / 4.0, Eigen::Vector3d::UnitZ());

或者是

Eigen::AngleAxisd rotation_angle_axis(M_PI / 4.0, Eigen::Vector3d(::UnitZ(0,0,1));

使用

使用 AngleAxisd 對象可以執行以下操作:

  • 將其應用于向量或點進行旋轉:

    // 通過將 rotation_angle_axis 應用到 point 上得到的旋轉后的新點
    Eigen::Vector3d point(1.0, 0.0, 0.0);
    Eigen::Vector3d rotated_point = rotation_angle_axis * point;
    
  • 轉換為旋轉矩陣或四元數:

    // 通過 toRotationMatrix() 方法從 rotation_angle_axis 轉換而來,用于表示相同旋轉的旋轉矩陣
    Eigen::Matrix3d rotation_matrix = rotation_angle_axis.toRotationMatrix();
    // 通過直接將 rotation_angle_axis 賦值給 Eigen::Quaterniond 類型得到,也表示了同樣旋轉的四元數
    Eigen::Quaterniond quaternion = rotation_angle_axis;
    
  • 進行組合和插值操作:

    // rotation_angle_axis 和 another_rotation 相乘(組合)得到的新的 Eigen::AngleAxisd 對象,它代表了先進行 rotation_angle_axis 的旋轉,然后進行 another_rotation 的旋轉。
    Eigen::AngleAxisd another_rotation(M_PI / 3.0, Eigen::Vector3d::UnitY());
    Eigen::AngleAxisd combined_rotation = rotation_angle_axis * another_rotation;
    // interpolated_rotation 是通過 slerp() 方法進行球面線性插值(Slerp)得到的 Eigen::AngleAxisd 對象。這種方法可以在兩個旋轉之間進行平滑的過渡,第一個參數是插值參數,通常是一個介于0到1之間的值,表示兩個旋轉的相對比例。
    Eigen::AngleAxisd interpolated_rotation = rotation_angle_axis.slerp(0.5, another_rotation);
    

歐氏變換

Eigen::Isometry3d 是 Eigen 庫中用于表示三維歐氏空間中的等距變換(Isometry)的類。它繼承自 Eigen::Transform,具體表示了包括平移和旋轉在內的等距變換。

主要特點和用途:

  • Identity Isometry(單位等距變換):單位等距變換表示沒有任何旋轉或平移,即一個點經過單位等距變換后位置不變。在三維空間中,單位等距變換的旋轉部分是單位矩陣,平移部分是零向量。
  • 靜態成員函數 Identity():這個函數是通過 Isometry3d 類訪問的靜態函數,它返回一個默認的單位等距變換對象。通過調用 Eigen::Isometry3d::Identity(),可以獲得一個已經初始化為單位變換的 Isometry3d 對象,通常用于開始定義其他具體的變換。
  1. 等距變換(Isometry)Isometry3d 能夠表示旋轉和平移的組合,保持點之間的距離不變。在計算機圖形學、機器人學和幾何計算等領域中,等距變換非常重要。
  2. 旋轉和平移的組合:通過 Isometry3d,可以方便地表示和操作三維空間中的物體的姿態和位置。
  3. Eigen 庫支持:Eigen 是一個開源的線性代數庫,專注于高性能的矩陣和向量運算。Isometry3d 類充分利用了 Eigen 的矩陣和向量運算優勢,提供了高效的數學運算。

示例:

以下是一個簡單的示例,展示如何使用 Isometry3d 類創建和操作等距變換:

#include <Eigen/Geometry>int main() {// 創建一個 Isometry3d 對象Eigen::Isometry3d T = Eigen::Isometry3d::Identity();// 設置旋轉部分(繞Z軸旋轉90度)T.rotate(Eigen::AngleAxisd(M_PI/2, Eigen::Vector3d::UnitZ()));// 設置平移部分(平移向量)T.pretranslate(Eigen::Vector3d(1, 2, 3));// 使用 Isometry3d 進行點變換Eigen::Vector3d point(1, 0, 0);Eigen::Vector3d transformed_point = T * point;// 輸出變換后的點std::cout << "Transformed point: " << transformed_point.transpose() << std::endl;return 0;
}
#include <Eigen/Dense>
#include <iostream>int main() {// 假設我們有一個4x4的仿射變換矩陣Eigen::Affine3d T;T.matrix() << 1, 0, 0, 1, // 旋轉矩陣部分0, 1, 0, 0, // 旋轉矩陣部分0, 0, 1, 0, // 旋轉矩陣部分1, 2, 3, 1; // 平移向量// 提取旋轉矩陣Eigen::Matrix3d R = T.linear();// 提取平移向量Eigen::Vector3d t = T.translation();// 打印旋轉矩陣和平移向量std::cout << "Rotation matrix:\n" << R << std::endl;std::cout << "Translation vector:\n" << t.transpose() << std::endl;return 0;}

T.linear()

這個成員函數返回仿射變換中的線性部分,即旋轉矩陣。它返回的是一個Eigen::Matrix3d類型的引用,代表3x3的旋轉矩陣。

T.translation()

這個成員函數返回仿射變換中的平移向量。它返回的是一個Eigen::Vector3d類型的引用,代表3D空間中的平移。

T.rotate()

這個成員函數是用來設置仿射變換的旋轉部分的。你可以傳遞一個3x3的旋轉矩陣給這個函數,它會更新T的線性部分。

旋轉矩陣

Eigen::Matrix3d 在實際應用中有許多用途,以下是幾個常見的例子:

1. 旋轉矩陣表示旋轉操作

#include <Eigen/Dense>
#include <iostream>int main() {// 定義一個旋轉矩陣,將向量繞Z軸旋轉45度Eigen::Matrix3d rotation_matrix;double angle = M_PI / 4.0; // 45度rotation_matrix << cos(angle), -sin(angle), 0,sin(angle), cos(angle), 0,0, 0, 1;// 定義一個向量Eigen::Vector3d vector(1.0, 0.0, 0.0);// 將向量應用旋轉Eigen::Vector3d rotated_vector = rotation_matrix * vector;// 輸出結果std::cout << "Original vector: " << vector.transpose() << std::endl;std::cout << "Rotated vector: " << rotated_vector.transpose() << std::endl;return 0;
}

這個例子中,我們定義了一個 Eigen::Matrix3d 類型的 rotation_matrix,表示繞Z軸旋轉45度的旋轉矩陣。然后,我們定義了一個 Eigen::Vector3d 類型的向量 vector,并將其通過 rotation_matrix 進行旋轉操作,得到 rotated_vector。最后輸出了旋轉前后的向量。

2. 坐標變換

#include <Eigen/Dense>
#include <iostream>int main() {// 定義一個坐標變換矩陣,將點從局部坐標系變換到全局坐標系Eigen::Matrix3d coordinate_transform;coordinate_transform << 1, 0, 0,0, -1, 0,0, 0, 1;// 定義一個局部坐標系下的點Eigen::Vector3d local_point(2.0, 3.0, 1.0);// 應用坐標變換Eigen::Vector3d global_point = coordinate_transform * local_point;// 輸出結果std::cout << "Local point: " << local_point.transpose() << std::endl;std::cout << "Global point: " << global_point.transpose() << std::endl;return 0;
}

在這個例子中,我們定義了一個 Eigen::Matrix3d 類型的 coordinate_transform,表示一個坐標系的變換矩陣,用來將局部坐標系下的點 local_point 轉換到全局坐標系下的 global_point。這種方式在計算機圖形學和仿真中經常使用,用于物體的位置和姿態變換。

3. 矩陣運算

#include <Eigen/Dense>
#include <iostream>int main() {// 定義兩個矩陣Eigen::Matrix3d A, B;A << 1, 2, 3,4, 5, 6,7, 8, 9;B << 9, 8, 7,6, 5, 4,3, 2, 1;// 計算矩陣乘法Eigen::Matrix3d result = A * B;// 輸出結果std::cout << "Matrix A:\n" << A << std::endl;std::cout << "Matrix B:\n" << B << std::endl;std::cout << "Result of A * B:\n" << result << std::endl;return 0;
}

當使用Eigen庫進行旋轉表示的轉換時,可以如下操作:

1. 旋轉矩陣轉換為旋轉向量

#include <Eigen/Dense>
#include <iostream>int main() {// 定義一個旋轉矩陣,例如繞Y軸旋轉30度Eigen::Matrix3d rotation_matrix;double angle = M_PI / 6.0; // 30度rotation_matrix << cos(angle), 0, sin(angle),0, 1, 0,-sin(angle), 0, cos(angle);// 將旋轉矩陣轉換為旋轉向量Eigen::AngleAxisd rotation_vector(rotation_matrix);// 輸出結果std::cout << "Rotation matrix:\n" << rotation_matrix << std::endl;std::cout << "Equivalent rotation vector:\n" << rotation_vector.axis().transpose()<< " " << rotation_vector.angle() << " radians" << std::endl;return 0;
}

在這個例子中,我們定義了一個旋轉矩陣 rotation_matrix,表示繞Y軸旋轉30度。然后,使用 Eigen::AngleAxisd 類型的構造函數將旋轉矩陣轉換為對應的旋轉向量 rotation_vector。通過 rotation_vector.axis() 獲取旋轉向量的軸向量,通過 rotation_vector.angle() 獲取旋轉角度。

2. 旋轉矩陣轉換為四元數

Eigen::Matrix3d rotation_matrix;
// 填充旋轉矩陣Eigen::Quaterniond quaternion(rotation_matrix);

這段代碼示例已經在前面提供過,展示了如何將旋轉矩陣 rotation_matrix 轉換為對應的四元數 quaternion

3. 旋轉矩陣轉換為歐拉角

Eigen庫中沒有直接提供將旋轉矩陣轉換為歐拉角的函數,但可以通過以下步驟手動實現歐拉角的計算:

#include <Eigen/Dense>
#include <iostream>int main() {// 定義一個旋轉矩陣,例如繞Z軸旋轉60度Eigen::Matrix3d rotation_matrix;double angle = M_PI / 3.0; // 60度rotation_matrix << cos(angle), -sin(angle), 0,sin(angle), cos(angle), 0,0, 0, 1;// 計算歐拉角(ZYX順序)double phi = atan2(rotation_matrix(1, 0), rotation_matrix(0, 0));double theta = atan2(-rotation_matrix(2, 0), sqrt(rotation_matrix(2, 1) * rotation_matrix(2, 1) + rotation_matrix(2, 2) * rotation_matrix(2, 2)));double psi = atan2(rotation_matrix(2, 1), rotation_matrix(2, 2));// 輸出結果std::cout << "Rotation matrix:\n" << rotation_matrix << std::endl;std::cout << "Equivalent Euler angles (ZYX order):\n"<< "Phi (roll): " << phi << " radians\n"<< "Theta (pitch): " << theta << " radians\n"<< "Psi (yaw): " << psi << " radians" << std::endl;return 0;
}

在這個例子中,我們定義了一個旋轉矩陣 rotation_matrix,表示繞Z軸旋轉60度。然后,通過手動計算歐拉角(ZYX順序),即 roll (phi), pitch (theta), yaw (psi),從旋轉矩陣中提取這些角度信息。

這些例子展示了如何使用 Eigen 庫進行旋轉表示的各種轉換,從而在不同的場景中方便地處理旋轉操作。

四元數

Eigen::Quateriond

Eigen::Quaterniond 是 Eigen 庫中用于表示雙精度(double)的四元數的類。四元數在計算機圖形學和機器人學等領域中廣泛用于表示旋轉。讓我展示如何使用 Eigen::Quaterniond 類來創建和操作四元數:

創建一個四元數

#include <Eigen/Dense>
#include <iostream>int main() {// 創建一個四元數,表示繞Z軸旋轉45度Eigen::Quaterniond quaternion;double angle = M_PI / 4.0; // 45度quaternion = Eigen::Quaterniond(cos(angle / 2), 0, 0, sin(angle / 2));// 輸出四元數的信息std::cout << "Quaternion:\n" << quaternion.coeffs().transpose() << std::endl;return 0;
}

在這個例子中,我們創建了一個四元數 quaternion,它表示繞Z軸旋轉45度。四元數的構造方法 Eigen::Quaterniond 接受四個參數 (w, x, y, z),分別表示四元數的實部和虛部(三個虛部分量)。在這里,我們使用角度 angle 計算實部 w 和虛部 z

操作四元數

#include <Eigen/Dense>
#include <iostream>int main() {// 創建一個四元數,表示繞Z軸旋轉45度Eigen::Quaterniond quaternion(cos(M_PI / 8), 0, 0, sin(M_PI / 8));// 獲取旋轉矩陣Eigen::Matrix3d rotation_matrix = quaternion.toRotationMatrix();// 輸出旋轉矩陣std::cout << "Rotation matrix:\n" << rotation_matrix << std::endl;return 0;
}
#include <Eigen/Dense>
#include <iostream>int main() {// 創建一個四元數,表示繞Z軸旋轉45度Eigen::Quaterniond quaternion(cos(M_PI / 8), 0, 0, sin(M_PI / 8));// 獲取旋轉矩陣Eigen::Matrix3d rotation_matrix = quaternion.toRotationMatrix();// 輸出旋轉矩陣std::cout << "Rotation matrix:\n" << rotation_matrix << std::endl;return 0;
}

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/40901.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/40901.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/40901.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

element-ui el-select選擇器組件下拉框增加自定義按鈕

element-ui el-select選擇器組件下拉框增加自定義按鈕 先看效果 原理&#xff1a;在el-select下添加禁用的el-option&#xff0c;將其value綁定為undefined&#xff0c;然后覆蓋el-option禁用狀態下的默認樣式即可 示例代碼如下&#xff1a; <template><div class…

【 VIPKID-注冊安全分析報告】

前言 由于網站注冊入口容易被黑客攻擊&#xff0c;存在如下安全問題&#xff1a; 暴力破解密碼&#xff0c;造成用戶信息泄露短信盜刷的安全問題&#xff0c;影響業務及導致用戶投訴帶來經濟損失&#xff0c;尤其是后付費客戶&#xff0c;風險巨大&#xff0c;造成虧損無底洞 …

黑馬點評項目難點-動態代理,sychronized,@Transactional失效的情況

文章目錄 難點1&#xff1a;synchronizesynchronized 的底層實現鎖的具體操作舉例說明結論 難點2&#xff1a;動態代理和Transactional失效問題Transactional 工作原理關鍵點示例分析正確的使用方式結論建議 難點所在代碼塊 Overridepublic Result seckillVoucher(Long voucher…

AI胡言亂語

復合矢量場在多維時空折疊過程中生成了高維拓撲映射&#xff0c;使得納米級別的存儲單元能夠在低能耗狀態下實現高效數據交換。基于相位調制的光子流動控制確保了全息影像的即時重構&#xff0c;同時動態適應不同頻段的干擾信號&#xff0c;達到最佳信噪比。 異相態轉化算法在…

基于Istio的多網關運行時:配置、部署和應用

1. 引言 Istio是一個開源的服務網格&#xff0c;主要應用于簡化微服務架構中的服務間通信、提供強大的監控能力以及加強服務的安全管理。通過利用Sidecar模式部署的Envoy代理&#xff0c;Istio能夠在幾乎無需修改服務代碼的情況下&#xff0c;實現服務發現、負載均衡、加密通信…

【LinuxC語言】管理者線程函數

文章目錄 前言工作者工作流程函數實現實現原理函數代碼概況總結前言 在并發編程中,管理者線程函數是一個重要的組成部分,它負責管理和調度工作線程。在Linux C語言環境下,我們可以使用POSIX線程庫(pthread)來創建和控制管理者線程。管理者線程通常負責添加任務到任務隊列…

WRF學習——使用CMIP6數據驅動WRF/基于ncl與vdo的CMIP6數據處理

動力降尺度 國際耦合模式比較計劃&#xff08;CMIP&#xff09;為研究不同情景下的氣候變化提供了大量的模擬數據&#xff0c;而在實際研究中&#xff0c;全球氣候模式輸出的數據空間分辨率往往較低&#xff08;>100Km&#xff0c;缺乏區域氣候特征&#xff0c;為了更好地研…

有哪些在本地運行大模型的方法

前言 在本文中&#xff0c;我們將看到在本地運行任何 LLM 的不同方法 1/ LMStudio LM Studio 是一款桌面應用程序&#xff0c;用于在計算機上運行本地 LLM。鏈接&#xff1a;https://lmstudio.ai/ 2/ Ollama Ollama 是一款工具&#xff0c;可讓您在機器上本地運行開源大型語…

vue項目靜態圖片下載

正常情況下只需要傳入圖片路徑就可以進行下載 methods: {downs(path, name) {//必須同源才能下載var alink document.createElement("a");alink.href path;alink.download name; //圖片名alink.click();},}, 但是當我們downs方法中直接傳入"/assets/load/xx…

二、分布式軟總線是如何高效的傳輸數據和任務的

分布式軟總線在HarmonyOS中高效傳輸數據和任務主要依靠以下幾個關鍵技術點和設計原則: 設備快速發現與連接: 利用多種通信技術(如Wi-Fi、藍牙、有線連接等),結合廣播、多播及服務發現協議,實現設備間的快速發現與穩定連接。這包括設備的唯一標識管理、網絡條件自適應選擇…

【pytorch14】感知機

單層感知機模型 對于單層的感知機&#xff0c;它的激活函數是一個sigmoid 對于符號的定義做一個規范化&#xff0c;輸入層每一層進行一個編號 輸入是第0層&#xff0c;上標0表示屬于輸入層&#xff0c;下標0到n表示一共有n個節點(這里嚴格來說應該是0~n-1&#xff0c;為了書寫…

一站式廣告監測新體驗,Xinstall助你廣告投放更精準

在這個移動互聯網飛速發展的時代&#xff0c;App推廣與運營成為了每個開發者與廣告主關注的焦點。然而&#xff0c;面對琳瑯滿目的廣告平臺和復雜的投放環境&#xff0c;如何精準評估廣告效果、優化投放策略&#xff0c;成為了擺在面前的一道難題。今天&#xff0c;我們就來聊聊…

Jemeter--關聯接口壓測

Jemeter–獨立不變參接口壓測 Jemeter–獨立變參接口壓測 Jemeter–關聯接口壓測 案例分析 比如&#xff1a;有個波次復核接口很慢&#xff0c;優化后需要壓測。但是波次復核接口數據是由另外兩個接口&#xff08;配單詳情、內盒信息&#xff09;的數據組合而來&#xff0c;而…

排序題目:三個數的最大乘積

文章目錄 題目標題和出處難度題目描述要求示例數據范圍 解法一思路和算法代碼復雜度分析 解法二思路和算法代碼復雜度分析 題目 標題和出處 標題&#xff1a;三個數的最大乘積 出處&#xff1a;628. 三個數的最大乘積 難度 3 級 題目描述 要求 給定一個整數數組 nums …

fastadmin最新版導出數據時 表格中會有 html標簽的解決辦法

fastadmin 自帶的導出方法&#xff0c; 是一個純前端的導出&#xff0c; 沒有請求后臺的接口 當我們使用導出功能時&#xff0c; 有些數據&#xff0c; 我們在設計的時候&#xff0c;配置的是 枚舉類型的 但是當我們導出數據的時候&#xff0c; 居然導出的數據中帶有 html 的…

使用el-col和el-row布局,有版心,一頁有兩欄布局 三欄布局 四欄布局 使用vue動態渲染元素

使用Vue結合Element UI的el-row和el-col組件來實現版心布局&#xff0c;并動態渲染不同欄數的布局&#xff0c;可以通過以下步驟實現&#xff1a; 定義版心容器&#xff1a;使用el-container來定義整個頁面的容器&#xff0c;其中el-header、el-main、el-footer分別定義頭部、主…

k8s-第十節-Ingress

Ingress 介紹 Ingress 為外部訪問集群提供了一個 統一 入口&#xff0c;避免了對外暴露集群端口&#xff1b;功能類似 Nginx&#xff0c;可以根據域名、路徑把請求轉發到不同的 Service。可以配置 https 跟 LoadBalancer 有什么區別&#xff1f; LoadBalancer 需要對外暴露…

Promise解決異步編程問題

一個典型的異步編程問題&#xff1a;即您嘗試在循環中發起多個異步請求&#xff0c;并希望在所有請求都完成后執行某些操作。然而&#xff0c;由于JavaScript的異步性質&#xff0c;num和total的比較在循環結束時立即執行&#xff0c;而不是在所有請求都完成后執行。這可能導致…

【12321騷擾電話舉報受理中心-短信驗證安全分析報告】

前言 由于網站注冊入口容易被黑客攻擊&#xff0c;存在如下安全問題&#xff1a; 暴力破解密碼&#xff0c;造成用戶信息泄露短信盜刷的安全問題&#xff0c;影響業務及導致用戶投訴帶來經濟損失&#xff0c;尤其是后付費客戶&#xff0c;風險巨大&#xff0c;造成虧損無底洞…

開發常識:命令行終端、庫源碼、開發環境階段

目錄 命令行終端 集成開發環境&#xff08;IDE &#xff09;&#xff1a;有插件校驗等限制&#xff0c;成功率低于操作系統 庫源碼 github上搜 官網 UNPKG托管開源的包 專業名詞 環境 開發&#xff1a;本地機 開發和調試 生產&#xff1a;最終部署 測試&#xff1a;…