Eigen中的刚体变换表达

在Eigen中,旋转矩阵、变换矩阵、欧拉角都可以表示为Eigen库中的特定类型的矩阵。

1、旋转矩阵

旋转矩阵通常用于表示三维空间中的旋转操作。在Eigen中,可以使用Eigen::Matrix3d类型来表示三维的旋转矩阵。通常,旋转矩阵是一个正交矩阵,其转置等于逆,因此可以使用Eigen中的Rotation3D模块来创建和操作旋转矩阵。

例如,创建一个绕z轴旋转45度的旋转矩阵可以这样做:

#include <Eigen/Dense>int main() {Eigen::Matrix3d rotation_matrix;double angle = M_PI / 4; // 45度转弧度rotation_matrix = Eigen::AngleAxisd(angle, Eigen::Vector3d::UnitZ());return 0;
}

2、变换矩阵

变换矩阵用于表示在欧几里得空间中的平移、旋转和缩放操作。在三维情况下,通常使用4x4的变换矩阵来表示这些变换。Eigen中可以使用Eigen::Transform模板来创建和操作这样的变换矩阵。

例如,创建一个绕z轴旋转45度并沿x轴平移(1, 2, 3)的变换矩阵可以这样做:

#include <Eigen/Dense>int main() {Eigen::Affine3d transformation_matrix = Eigen::Affine3d::Identity();double angle = M_PI / 4; // 45度转弧度transformation_matrix.rotate(Eigen::AngleAxisd(angle, Eigen::Vector3d::UnitZ()));transformation_matrix.translation() << 1, 2, 3;return 0;
}

3、欧拉角转旋转矩阵(zyx)

// 使用eigen库,欧拉角转旋转矩阵Eigen::Matrix3d rotation_matrix1, rotation_matrix2;rotation_matrix1 =Eigen::AngleAxisd(euler_angle[2], Eigen::Vector3d::UnitZ()) *Eigen::AngleAxisd(euler_angle[1], Eigen::Vector3d::UnitY()) *Eigen::AngleAxisd(euler_angle[0], Eigen::Vector3d::UnitX());cout << "\nrotation matrix1 =\n" << rotation_matrix1 << endl << endl;

4、旋转矩阵转欧拉角

// 使用egigen将旋转矩阵转换为欧拉角
Eigen::Vector3d eulerAngle1 = rotation_matrix1.eulerAngles(2, 1, 0); //zyx顺序
cout << "roll_2 pitch_2 yaw_2 = " << eulerAngle1[2] << " " << eulerAngle1[1]<< " " << eulerAngle1[0] << endl << endl;

5、实战案例

#include<iostream>
#include<Eigen/Core>
#include<Eigen/Geometry>using namespace std;Eigen::Matrix3d eulerAnglesToRotationMatrix(Eigen::Vector3d& theta);
bool isRotationMatrix(Eigen::Matrix3d R);
Eigen::Vector3d rotationMatrixToEulerAngles(Eigen::Matrix3d& R);const double ARC_TO_DEG = 57.29577951308238;
const double DEG_TO_ARC = 0.0174532925199433;int main()
{// 设定车体欧拉角,绕固定轴double roll_deg = 0.5; // 绕x轴double pitch_deg = 0.8; // 绕y轴double yaw_deg = 108.5; // 绕z轴// 转换为弧度double roll_arc = roll_deg * DEG_TO_ARC;double pitch_arc = pitch_deg * DEG_TO_ARC; double yaw_arc = yaw_deg * DEG_TO_ARC; cout << endl;cout << "roll_arc = " << roll_arc << endl;cout << "pitch_arc = " << pitch_arc << endl;cout << "yaw_arc = " << yaw_arc << endl;// 初始化欧拉角Eigen::Vector3d euler_angle(roll_arc, pitch_arc, yaw_arc);// 使用eigen库,欧拉角转旋转矩阵Eigen::Matrix3d rotation_matrix1, rotation_matrix2;rotation_matrix1 =Eigen::AngleAxisd(euler_angle[2], Eigen::Vector3d::UnitZ()) *Eigen::AngleAxisd(euler_angle[1], Eigen::Vector3d::UnitY()) *Eigen::AngleAxisd(euler_angle[0], Eigen::Vector3d::UnitX());cout << "\nrotation matrix1 =\n" << rotation_matrix1 << endl << endl;// 使用自定义函数,欧拉角转旋转矩阵rotation_matrix2 = eulerAnglesToRotationMatrix(euler_angle);cout << "rotation matrix2 = \n" << rotation_matrix2 << endl << endl;// 使用egigen将旋转矩阵转换为欧拉角Eigen::Vector3d eulerAngle1 = rotation_matrix1.eulerAngles(2, 1, 0); //zyx顺序cout << "roll_2 pitch_2 yaw_2 = " << eulerAngle1[2] << " " << eulerAngle1[1]<< " " << eulerAngle1[0] << endl << endl;// 使用自定义函数将旋转矩阵转换为欧拉角Eigen::Vector3d eulerAngle2 = rotationMatrixToEulerAngles(rotation_matrix1);cout << "roll_2 pitch_2 yaw_2 = " << eulerAngle2[0] << " " << eulerAngle2[1]<< " " << eulerAngle2[2] << endl << endl;return 0;
}Eigen::Matrix3d eulerAnglesToRotationMatrix(Eigen::Vector3d& theta)
{Eigen::Matrix3d R_x;R_x <<1, 0, 0,0, cos(theta[0]), -sin(theta[0]),0, sin(theta[0]), cos(theta[0]);Eigen::Matrix3d R_y;R_y <<cos(theta[1]), 0, sin(theta[1]),0, 1, 0,-sin(theta[1]), 0, cos(theta[1]);Eigen::Matrix3d R_z;R_z <<cos(theta[2]), -sin(theta[2]), 0,sin(theta[2]), cos(theta[2]), 0,0, 0, 1;Eigen::Matrix3d R = R_z * R_y * R_x;return R;
}bool isRotationMatrix(Eigen::Matrix3d R)
{double err = 1e-6;Eigen::Matrix3d shouldIdentity;shouldIdentity = R * R.transpose();Eigen::Matrix3d I = Eigen::Matrix3d::Identity();return (shouldIdentity - I).norm() < err;
}Eigen::Vector3d rotationMatrixToEulerAngles(Eigen::Matrix3d& R)
{assert(isRotationMatrix(R));double sy = sqrt(R(0, 0) * R(0, 0) + R(1, 0) * R(1, 0));bool singular = sy < 1e-6;double x, y, z;if (!singular) {x = atan2(R(2, 1), R(2, 2));y = atan2(-R(2, 0), sy);z = atan2(R(1, 0), R(0, 0));}else {x = atan2(-R(1, 2), R(1, 1));y = atan2(-R(2, 0), sy);z = 0;}return { x,y,z };
}

结果

roll_arc = 0.00872665
pitch_arc = 0.0139626
yaw_arc = 1.89368rotation matrix1 =-0.317274  -0.948326 0.003845480.948231  -0.317177  0.0160091
-0.0139622 0.00872568   0.999864rotation matrix2 =-0.317274  -0.948326 0.003845480.948231  -0.317177  0.0160091
-0.0139622 0.00872568   0.999864roll_2 pitch_2 yaw_2 = 0.00872665 0.0139626 1.89368roll_2 pitch_2 yaw_2 = 0.00872665 0.0139626 1.89368

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/9119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络新手如何上手水牛社软件?我的建议与看法

水牛社是一款专为电脑用户设计的软件&#xff0c;拥有明确的著作权&#xff0c;其核心功能在于发布和整合各类网络活动任务资源、教程等&#xff0c;内容多元且不设固定分类。其靠谱程度取决于你对软件的了解程度和个人需求的适配性。 软件内部包含五个主要栏目&#xff0c;大…

轮廓提取、矩形标记时,点的位置需要重标

在下图中的0&#xff0c;3&#xff0c;1&#xff0c;2位置如何变换成0&#xff0c;1&#xff0c;2&#xff0c;3 先显示结果&#xff1a; 变换之后图&#xff1a; 这边提供两种解决方案&#xff1a; 第一种&#xff1a;将坐标值相加求和&#xff0c;采用冒泡排序实现从小到大…

使用固定公网地址远程访问开源服务器运维管理面板1Panel管理界面

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

顺序表的实现(迈入数据结构的大门)(完整代码)

seqlist.h #pragma once typedef int SLDataType;#include<stdio.h> #include<stdlib.h> #include<assert.h>typedef struct SeqList {SLDataType* a;int size; // 有效数据个数int capacity; // 空间容量 }SL;//初始化和销毁 void SLInit(SL* ps); void SL…

ReentrantLock的原理

总结&#xff1a; ReentrantLock 的基本实现可以概括为&#xff1a;先通过 CAS 尝试获取锁。如果此时已经有线程占据了锁&#xff0c;那就加入 AQS 队列并且被挂起。当锁被释放之后&#xff0c;排在 CLH 队列队首的线程会被唤醒&#xff0c;然后 CAS 再次尝试获取锁。在这个时候…

reqwest - Rust HTTP Client

文章目录 关于 reqwest使用添加依赖Get 请求Post 请求FormsJSON 关于 reqwest An easy and powerful Rust HTTP Client github : https://github.com/seanmonstar/reqwest文档&#xff1a;https://docs.rs/reqwest/latest/reqwest/ 特点 Async and blocking ClientsPlain bo…

c语言循环题目

c语言循环题目 已知sinx的近似计算公式如下sin xx- x3/3! x’/5!-x7/7!.(-1)n-1x2n-1/(2n-1)!其中x为弧度&#xff0c;n为正整数。编写程序根据用户输入的x和n的值&#xff0c;利用上述近似计算公式计算sinx的近似值&#xff0c;要求输出结果小数点后保留8位 int main() {in…

Excel文件解析---超大Excel文件读写

1.使用POI写入 当我们想在Excel文件中写入100w条数据时&#xff0c;使用XSSFWorkbook进行写入时会发现&#xff0c;只有将100w条数据全部加载到内存后才会用write()方法统一写入&#xff0c;效率很低&#xff0c;所以我们引入了SXXFWorkbook进行超大Excel文件读写。 通过设置 …

C语言leetcode刷题笔记1

C语言leetcode刷题笔记1 第1题&#xff1a;136.只出现一次的数字两次遍历&#xff08;O(numsSize^2)&#xff09;位运算 第2题&#xff1a;202.快乐数快慢指针记录历史数据 第3题&#xff1a;53.最大子数组和暴力求解&#xff08;超时&#xff09;动态规划分治 第1题&#xff1…

每日Attention学习3——Cross-level Feature Fusion

模块出处 [link] [code] [PR 23] Cross-level Feature Aggregation Network for Polyp Segmentation 模块名称 Cross-level Feature Fusion (CFF) 模块作用 双级特征融合 模块结构 模块代码 import torch import torch.nn as nnclass BasicConv2d(nn.Module):def __init__(…

LeetCode 16.最接近的三数之和

文章目录 题目思路代码 题目 16.最接近的三数之和 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1&#xff1a; 输入&#xff1a;n…

spring注解之—— @Resource与@ Autowired

Resource 和 Autowired 都是 Java 框架中用于注入依赖的注解。尽管它们在功能上相似&#xff0c;但仍有一些区别&#xff1a; Resource 来自 Java 的 javax.annotation 包&#xff08;需要 Java EE 支持&#xff09;。支持 name 和 type 属性&#xff0c;用于在注入时确定具体…

PLC学习笔记

PLC学习笔记 前言一、一些基操知识二、GX works2编程2.1 位逻辑1.2 中间寄存器1.3 PLC的扫描方式 总结 前言 我这个人真的是太渴望知识了~ 一、一些基操知识 一般X表示输入&#xff0c;Y表示输出。一般八个为一组X0~X7M表示中间寄存器&#xff0c;M0~M7时间T、计数C 二、GX …

BiTCN:基于卷积网络的多元时间序列预测

在时间序列预测领域中&#xff0c;模型的体系结构通常依赖于多层感知器(MLP)或Transformer体系结构。 基于mlp的模型&#xff0c;如N-HiTS, TiDE和TSMixer&#xff0c;可以在保持快速训练的同时获得非常好的预测性能。基于Transformer的模型&#xff0c;如PatchTST和ittransfo…

【面经】网络

了解TCP/IP协议,了解常用的网络协议&#xff1a;study-area 一、TCP/IP协议 TCP/IP协议是一组网络通信协议&#xff0c;旨在实现不同计算机之间的信息传输。 1、TCP/IP四层模型&#xff1a; 网络接口层、网络层、传输层和应用层。 网络接口层&#xff1a;定义了数据的格式和…

Python | Leetcode Python题解之第67题二进制求和

题目&#xff1a; 题解&#xff1a; class Solution:def addBinary(self, a, b) -> str:return {0:b}.format(int(a, 2) int(b, 2))

python面向函数

组织好的&#xff0c;可重复利用的&#xff0c;用来实现单一&#xff0c;或相关联功能的代码段&#xff0c;避免重复造轮子&#xff0c;增加程序复用性。 定义方法为def 函数名 (参数) 参数可动态传参&#xff0c;即使用*args代表元组形式**kwargs代表字典形式&#xff0c;代替…

python编程“常识”【pip安装路径、计算、pycharm中的terminal运行前面的PS修改成自己环境】

一、默认的pip install包路径&#xff1a; pip show pip 二、计算 打开cmd&#xff0c;输入&#xff1a; ipython 例如你要计算2的13次方&#xff1a; ok. 三、pycharm中的terminal运行前面的PS修改成自己环境 未修改前&#xff1a; 修改过程&#xff1a; 打开设置找到too…

Linux Kernel入门到精通系列讲解(OpenSBI 篇) 3.3 OpenSBI 源码分析之domain

1. 概述 上一章节我们讲完了整个OpenSBI的初始化流程,这一章节我们单独把domain挑出来讲解,因为domain涉及到了多核可以实现smp和amp的分别boot,比较重要。 2. 设备树分析 由于我们使用了设备树,先来看一下设备树中,是怎么去配置domain的。 opensbi-config设备树中该属性…

vscode中配置 leetcode 插件

1. 环境准备 插件安装介绍 介绍 VS Code 1.23.0 Node.js 10 注意&#xff1a;请确保Node在PATH环境变量中。您也可以通过设定 leetcode.nodePath 选项来指定 Node.js 可执行文件的路径。 1.1 Node.js 安装 首先&#xff0c;您需要解压下载的 .tar.xz 文件。您可以使用以下…