从零开始学习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.mfbz.cn/a/772031.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库表导出到excel

数据库表导出到excel:前置知识1 ALL_TAB_COLS 数据库表导出到excel:前置知识2 Quartz基本使用 数据库表导出到excel:前置知识3 项目封装的Quartz实现动态定时任务 数据库表导出到excel:前置知识4 业务和效果 发起清单下载control层InventoryDownloadLogController /* * */ pa…

#### golang中【堆】的使用及底层 ####

声明&#xff0c;本文部分内容摘自&#xff1a; Go: 深入理解堆实现及应用-腾讯云开发者社区-腾讯云 数组实现堆 | WXue 堆&#xff08;Heap&#xff09;是实现优先队列的数据结构&#xff0c;Go提供了接口和方法来操作堆。 应用 package mainimport ("container/heap&q…

LVS-DR群集

LVS-DR集群 LVS-DR(Linux Virtual Server DIrector Server)工作模式&#xff0c;是生产环境中最常用的一种工作模式。 LVS-DR工作原理 LVS-DR模式&#xff0c;Director Server作为群集的访问入口&#xff0c;不作为网关使用&#xff0c;节点DirectorServer与Real Server需要…

光速入门 Tailwind CSS

文章目录 入门安装IDE 设置使用预编译器生产环境优化 基础概念分层指令tailwindlayerapplyconfig 函数theme()screen() 基础案例怎么设置属性任意值&#xff1f;hover 父元素时&#xff0c;怎么选中子元素添加样式&#xff1f;添加 animation 动画 配置主题 Tailwind CSS 中文网…

性能测试-JMeter学习

1、给不同的访问口分配访问占比&#xff1b;例&#xff1a;登录30%&#xff0c;首页&#xff1a;20%&#xff0c;新增&#xff1a;50% 不同业务放到不同线程组里&#xff0c;实现不同业务的分配 使用吞吐量控制器&#xff0c;设置不同的占比 使用if控制器&#xff0c;设置不同…

HX4004A-MFC 低噪声、稳压电荷泵DC/DC转换器芯片IC

一般描述 该HX4004A是一个低噪声开关电容电压倍。它产生一个调节输出电压从2.7V到4.5V的输入。低的外部零件数量(VIN和VOUT处一个飞行电容和两个小型旁路电容)使HX4004A非常适合小型电池供电应用。 该HX4004A具有热关断能力&#xff0c;可以生存从VOUT到GND的连续…

【pytorch13】激活函数及梯度

什么是激活函数 计算机科学家借鉴生物的神经元机制发明了计算机上的模型&#xff0c;这个模型与生物的神经元非常类似 激活的意思就是z变量要大于0&#xff0c;这一个节点才会激活&#xff0c;否则就会处于睡眠状态不会输出电平值 该激活函数在z0处不可导&#xff0c;因此不能…

地级市空气质量指数AQI、环境污染PM2.5、SO2

2015-2021年地级市月度空气质量数据&#xff08;AQI、SO2、NO2、PM2.5、PM10、O3、CO&#xff09; 目录 探究环境污染对经济增长的影响 一、引言 二、数据来源与描述性统计 三、实证模型 &#xff08;一&#xff09;模型设定 &#xff08;二&#xff09;变量说明 四、程…

混元大模型加持,微信输入法开启AI问答新体验

在人工智能技术飞速发展的今天&#xff0c;微信作为全球最大的社交平台之一&#xff0c;一直在不断地探索和创新&#xff0c;以提供更智能、更便捷的用户体验。 最近&#xff0c;微信官方宣布了一个令人兴奋的消息&#xff1a;微信输入法正式上线了“一键AI问答”功能&#xf…

【Python机器学习】算法链与管道——通用的管道接口

Pipeline类补单可以用于预处理和分类&#xff0c;实际上还可以将任意数量的估计器连接在一起。例如&#xff0c;我们可以构建一个包含特征提取、特征选择、缩放和分类的管道&#xff0c;总共有4个步骤。同样的&#xff0c;最后一步可以用聚类或回归代替。 对于管道中估计器的唯…

【机器学习】Datawhale-AI夏令营分子性质AI预测挑战赛

参赛链接&#xff1a;零基础入门 Ai 数据挖掘竞赛-速通 Baseline - 飞桨AI Studio星河社区 一、赛事背景 在当今科技日新月异的时代&#xff0c;人工智能&#xff08;AI&#xff09;技术正以前所未有的深度和广度渗透到科研领域&#xff0c;特别是在化学及药物研发中展现出了巨…

警翼警用记录仪视频格式化后恢复方法

警翼是国内较大的一家警用记录仪厂商&#xff0c;此品牌我们恢复过很多&#xff0c;此次遇到的是一个典型的误格式化的情况&#xff0c;我们来看看误格式化后如何恢复。 故障存储: 32G卡/fat32 故障现象: 客户提供的信息是在交接设备后没有及时备份而做出了初始化设备的操…

fluwx插件实现微信支付

Flutter开发使用fluwx插件实现微信支付&#xff0c;代码量不多&#xff0c;复杂的是安卓和iOS的各种配置。 在 pubspec.yaml 文件中添加fluwx依赖 fluwx: ^4.5.5 使用方法 通过fluwx注册微信Api await Fluwx().registerApi(appId: wxea7a1c53d9e5849d, universalLink: htt…

机器人控制系列教程之Delta机器人动力学分析

动力学简介 机器人动力学分析是已知各运动构件的尺寸参数和惯性参数的情况下,求解末端运动状态与主驱动力矩之间的函数关系。 意义:对并联机器人动力学分析的意义体现在: 为伺服电机的选型提供理论依据;获得动力学参数为目标函数的最优问题做性能评价指标;为高精度控制提…

内容为王:揭秘顶尖品牌的内容营销制胜法宝

内容营销是当今互联网市场推广领域的热门话题&#xff0c;因为它可以帮助企业更好地与受众沟通、建立品牌口碑&#xff0c;增加销售量。 根据咱们何策网的资源库里的SocialBeta2024年最新《2024 内容营销 10 大趋势》的报告来看&#xff0c;品牌在未来内容营销中最应该注重的是…

2024亚太杯中文赛数学建模B题【洪水灾害的数据分析与预测】思路详解

2024 年第十四届 APMCM 亚太地区大学生数学建模竞赛 B题 洪水灾害的数据分析与预测 附件 train.csv 中提供了超过 100 万的洪水数据&#xff0c;其中包含洪水事件的 id、季风强度、地形排水、河流管理、森林砍伐、城市化、气候变化、大坝质量、淤积、农业实践、侵蚀、无效防灾、…

Unity 之基于URP使用UniStorm Weather System天气系统

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity 之基于URP使用UniStorm Weather System天气系统 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、…

Linux和mysql中的基础知识

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

智能猫砂盆到底哪家好用?自费实测聚宠、糯雪、CEWEY真实反馈!

快到夏天了&#xff0c;是不是还有人因为没挑选到喜欢的智能猫砂盆而苦恼着&#xff1f;太便宜怕不好用&#xff0c;太贵怕质量比不上价格。来来去去拖到现在还没决定&#xff0c;我作为养了四年猫的资深铲屎官&#xff0c;今天就来给大家传授经验&#xff0c;关于我是怎么从好…

从源码到应用:直播电商系统与短视频带货APP开发指南

本篇文章&#xff0c;笔者将从源码到应用&#xff0c;详细探讨如何开发一个直播电商系统和短视频带货APP。 一、系统架构设计 在开始开发之前&#xff0c;首先需要对系统进行整体架构设计。一个完整的直播电商系统和短视频带货APP主要包括以下几个模块&#xff1a; 1.用户管理…