从零开始学习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;造成亏损无底洞 …

基于Istio的多网关运行时:配置、部署和应用

1. 引言 Istio是一个开源的服务网格&#xff0c;主要应用于简化微服务架构中的服务间通信、提供强大的监控能力以及加强服务的安全管理。通过利用Sidecar模式部署的Envoy代理&#xff0c;Istio能够在几乎无需修改服务代码的情况下&#xff0c;实现服务发现、负载均衡、加密通信…

WRF学习——使用CMIP6数据驱动WRF/基于ncl与vdo的CMIP6数据处理

动力降尺度 国际耦合模式比较计划&#xff08;CMIP&#xff09;为研究不同情景下的气候变化提供了大量的模拟数据&#xff0c;而在实际研究中&#xff0c;全球气候模式输出的数据空间分辨率往往较低&#xff08;>100Km&#xff0c;缺乏区域气候特征&#xff0c;为了更好地研…

【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;而…

fastadmin最新版导出数据时 表格中会有 html标签的解决办法

fastadmin 自带的导出方法&#xff0c; 是一个纯前端的导出&#xff0c; 没有请求后台的接口 当我们使用导出功能时&#xff0c; 有些数据&#xff0c; 我们在设计的时候&#xff0c;配置的是 枚举类型的 但是当我们导出数据的时候&#xff0c; 居然导出的数据中带有 html 的…

k8s-第十节-Ingress

Ingress 介绍 Ingress 为外部访问集群提供了一个 统一 入口&#xff0c;避免了对外暴露集群端口&#xff1b;功能类似 Nginx&#xff0c;可以根据域名、路径把请求转发到不同的 Service。可以配置 https 跟 LoadBalancer 有什么区别&#xff1f; LoadBalancer 需要对外暴露…

【12321骚扰电话举报受理中心-短信验证安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

交流负载箱的主要功能有哪些?

交流负载箱可以模拟各种实际用电设备的功率、电流、电压等参数&#xff0c;使得电源系统在运行过程中能够承受实际负载的考验&#xff0c;确保电源系统的稳定运行。通过交流负载箱对电源设备进行测试&#xff0c;可以检测出电源设备在过载、短路等异常情况下的保护功能是否正常…

Linux和mysql中的基础知识

cpu读取的指令大部分在内存中&#xff08;不考虑缓存&#xff09; 任何程序在运行之前都的加入到内存。 eip->pc指针&#xff0c;指明当前指令在什么位置。 代码大概率是从上往下执行的&#xff0c;基于这样的基本理论。既可以将一部分指令加载到CPU对应的缓存中&#xf…

【CSAPP】-datalab实验

实验原理与内容 本实验每位学生拿到一个datalab-handout.tar文件。学生可以通过U盘、网盘、虚拟机共享文件等方式将其导入到Unbuntu实验环境中&#xff0c;选择合适位置存放。然后在Ubuntu环境下解压。解压后&#xff0c;根据文件中的叙述和要求更改bits.c文件。本次实验的主要…

【全网最全】2024年APMCM第十四届亚太地区大学生数学建模竞赛(中文赛项)完整思路解析+代码+论文

我是Tina表姐&#xff0c;毕业于中国人民大学&#xff0c;对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在&#xff0c;我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

云计算【第一阶段(26)】Linux网络设置

一、查看网络配置 1.查看网络接口信息ifconfig 查看所有活动的网络接口信息 2.ifconfig命令 查看指定网络接口信息 ifconfig 网络接口 &#xff08;1&#xff09;第一行&#xff1a;以太网卡的名字 ens33其中en代表以太网卡&#xff0c; centos6的是eth0&#xff0c; e…

中国算力网络市场发展分析

中国算力网络市场发展现状 算力涵盖计算、内存、存储等全方位能力&#xff0c;广泛分布于网络边缘、云计算中心、联网设备及转发节点。随着数字化技术革新&#xff0c;算力与网络正深度融合&#xff0c;推动“算网一体化”的演进。这一新型基础设施日渐凸显其重要性&#xff0c…

精准畜牧业:多维传感监测及分析动物采食行为

全球畜牧业呈现出一个动态且复杂的挑战。近几十年来&#xff0c;它根据对动物产品需求的演变进行了适应&#xff0c;动物生产系统需要提高其效率和环境可持续性。在不同的畜牧系统中有效行动取决于科学技术的进步&#xff0c;这允许增加照顾动物健康和福祉的数量。精准畜牧业技…

Samtec汽车电子 | 汽车连接器如何在高要求、极端的环境中工作

【摘要/前言】 汽车电子&#xff0c;这些年来始终是极具流量的热门话题&#xff0c;目前不断发展的智能座驾、辅助驾驶等赛道都是对相关产业链需求的进一步刺激&#xff0c;这里蕴含着一片广阔的市场。 同样&#xff0c;广阔的市场里有着极高的准入门槛和事关安全的技术挑战。…

Windows安全认证机制——Windows常见协议

一.LLMNR协议 1.LLMNR简介 链路本地多播名称解析&#xff08;LLMNR&#xff09;是一个基于域名系统&#xff08;DNS&#xff09;数据包格式的协议&#xff0c;使用此协议可以解析局域网中本地链路上的主机名称。它可以很好地支持IPv4和IPv6&#xff0c;是仅次于DNS解析的名称…

代谢组数据分析(十三):评估影响代谢物的重要临床指标

欢迎大家关注全网生信学习者系列: WX公zhong号:生信学习者Xiao hong书:生信学习者知hu:生信学习者CDSN:生信学习者2介绍 相关性分析是通过计算两个变量之间的相关系数来评估它们之间线性关系的强度和方向。最常用的是皮尔逊相关系数(Pearson correlation coefficient),…