从零开始学习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.mzph.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;…