解读《视觉SLAM十四讲》,带你一步一步入门视觉SLAM—— 第 3 讲 三维刚体运动 (下)

2024-06-05 17:38

本文主要是介绍解读《视觉SLAM十四讲》,带你一步一步入门视觉SLAM—— 第 3 讲 三维刚体运动 (下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

陪女朋友为期五天的农村调研终于结束,终于可以回到大魔都享受城市生活了。在高铁上闲来无事再写点吧!(由于我肩部肌肉劳损,太疼了,所以本篇博客是我口述,女朋友代写的,感谢她的鼎力相助)
  
  在上一篇博客中我们介绍了三维刚体运动的旋转矩阵和变换矩阵,下面我要带你解读这一讲的下半部分内容:

  • 旋转向量、欧拉角、四元数;

解读

这一讲中的很多概念都比较抽象,我尽量给大家总结的通俗一些,但是大家还是要自己仔细去理解和体会这些几何变换的意义,有些东西如果实在难以理解,你也别着急,咱们先学会用,慢慢的就理解了。
  
  前面我们介绍了旋转矩阵和变换矩阵,它们的矩阵描述分别为:
R = [ a 11 a 12 a 13 a 21 a 22 a 23 a 31 a 32 a 33 ] (0) R = \left[\begin{matrix}a_{11}&a_{12}&a_{13}\\ a_{21}&a_{22}&a_{23}\\a_{31}&a_{32}&a_{33} \end{matrix}\right] \tag0 R=a11a21a31a12a22a32a13a23a33(0)

T = [ R 3 ∗ 3 t 3 ∗ 1 0 T 1 ] (1) T = \left[\begin{matrix}R_{3*3}&t_{3*1}\\ 0^T&1\end{matrix}\right] \tag1 T=[R330Tt311](1)
  我们观察(0)式可以发现,在旋转矩阵中一共有9个变量,也就是说旋转矩阵有9个自由度,而实际上我们空间当中的一次旋转变换只需要3个自由度,也就是3个变量,所以我们使用旋转矩阵表示旋转变换时,额外引入了6个变量,就会造成表达的冗余。
  
  我们再观察(1)式,在变换矩阵中一共有16个量,实际上一次変换只有6个自由度,也就只需要6个变量,那么变换矩阵实际也是冗余的。
  
  另外一方面,旋转矩阵和变换矩阵都是正交矩阵,并且行列式的值为1,这在运算和优化中就会引入额外的限制,因为我们的优化结果必须要满足旋转矩阵和变换矩阵的形式。
  
  于是我们就想能不能有更好的表达方法去表达旋转和变换,能够一方面变量很紧凑,另一方面不会引入额外的约束。那么我们就要探索下面的一些方法。

旋转向量

因为前面所述的问题,所以作者在书中提出了旋转向量。旋转向量实际上并不难理解的,一个旋转轴 n ⃗ = [ a 1 , a 2 , a 3 ] \vec n=[a_1,a_2,a_3] n =[a1,a2,a3]加上一个旋转角度 θ \theta θ就可以达到旋转的效果。关于旋转向量,它和旋转矩阵一样也表示一种旋转变换,那么它们之间一定可以相互转换,转换可以使用罗德里格斯公式:
R = c o s θ I ⃗ + ( 1 − c o s θ ) n ⃗ n ⃗ T + s i n θ [ 0 − a 3 a 2 a 3 0 − a 1 − a 2 a 1 0 ] R = cos\theta \vec I +(1-cos\theta)\vec n \vec n^T+sin\theta \left[\begin{matrix}0&-a_3&a_{2}\\ a_{3}&0&-a_{1}\\-a_{2}&a_{1}&0 \end{matrix}\right] R=cosθI +(1cosθ)n n T+sinθ0a3a2a30a1a2a10
同样,旋转矩阵也可以转换为旋转向量,转换公式大家可以参考书中的公式。
  
  尽管旋转向量已经比旋转矩阵直观了很多,但是还是不够直观,于是又提出了欧拉角。

欧拉角

我们可以想象一下:对于一个三维坐标系,变换它的姿态,我们可以分为三步,第一步,我们先选择任意一个轴,以它为旋转轴进行旋转,第二步,在剩下的两个轴中选择一个轴作为旋转轴,然后旋转一定的角度,第三步,再以最后一根轴为旋转轴进行旋转,这样的过程就可以把一个坐标系旋转为另外的姿态。
  
  欧拉角虽然很直观,但是有很大的局限性,它常常会发生万向锁问题,也称为奇异性问题。当我们选择XYZ轴不同顺序进行依次旋转时常常发生万向锁问题,所以在SLAM中欧拉角的应用并不多,这里不再细说,大家看书就可以。关于万向锁问题大家可以参考这个视频了解一下《“欧拉角旋转”产生“万向锁”的来源,以及如何避免万向锁》
  
  我们不妨总结一下前面说的几种表示旋转的方法:欧拉角虽然直观,但是会导致万向锁问题,它很可能就不可用了,所以它在SLAM问题中很少使用;旋转矩阵参数冗余而且还会引入额外的约束,虽然使用会带来一些麻烦,但是至少不会失效;旋转向量使用旋转轴加上旋转角,好像还挺好的,没有带来什么不便和问题。那么还有更好的表示旋转的方法吗?答案是有的!

四元数

我是在学习SLAM的时候,才第一次接触到四元数,当时第一次接触也是一头雾水,尽管现在也没有完全理解,但是算是会用了。
  
  前面我们说到的一些表示旋转的方法,或多或少都存在一些问题,所以为了解决这些问题,就有人想到了四元数。这个东西我确实没有深入的去了解,所以靠我现在的理解,还是很难讲清楚,大家还是以《十四讲》为主要去理解四元数。
  
  我有一些认识在这里和大家分享一下:我们在学习一些几何的时候总是想直观的去理解一些定理或概念,多数情况下这样是行得通的,但是在四元数上若想直观的理解它的旋转还是有些困难的,如果你实在不能理解四元数,那就暂且将它放一边,就把它当做一个工具使用就行,记住它的一些性质和用法,对于它的理解你就边用边深入。关于四元数我推荐一个英文教程你可以阅读一下《四元数数学基础》提取码:q2x3

最后,无论是四元数、旋转矩阵还还是旋转向量,它们都可以用来描述同一个旋转。我们应该在实际中选择最为方便的形式,而不必拘泥于某种特定的形式。《视觉SLAM十四讲 从理论到实践》

扩展阅读:关于的旋转矩阵、旋转向量(轴角)、欧拉角、四元数的优缺点,可以看一下这篇博客:《矩阵、欧拉角、轴-角对、四元数随笔》

实践

我建议你按照书中的代码把实践部分内容多打几遍,不要嫌麻烦,一开始写代码都是这样先重复,再模仿,最后就能自己写了。

代码部分有两个地方还是值得你去注意的:

  • 注意四元数在Eigen中的表示顺序,在书本理论部分四元数的实部在前,形式是(w, x, y, z),而在Eigen库中形式是(x, y, z, w)。你要注意一下。我在公司实习的时候,有一个工程师就因为这个顺序搞反了,导致一个BUG找了一星期。
  • 有一行代码v_rotated = q*v;,这个是用四元数计算旋转,而书上理论部分使用的计算公式是: p ′ = q p q − 1 p'=qpq^{-1} p=qpq1,但是在代码中直接用q*v,因为Eigen库重载了*号,所以你以后使用的时候,直接用*就能表示四元数的旋转了。

无论你犯了多少错,或者进步得有多慢,你都走在了那些不曾尝试的人的前面。

这篇关于解读《视觉SLAM十四讲》,带你一步一步入门视觉SLAM—— 第 3 讲 三维刚体运动 (下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1033729

相关文章

Java Lettuce 客户端入门到生产的实现步骤

《JavaLettuce客户端入门到生产的实现步骤》本文主要介绍了JavaLettuce客户端入门到生产的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目录1 安装依赖MavenGradle2 最小化连接示例3 核心特性速览4 生产环境配置建议5 常见问题

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

MySQL之搜索引擎使用解读

《MySQL之搜索引擎使用解读》MySQL存储引擎是数据存储和管理的核心组件,不同引擎(如InnoDB、MyISAM)采用不同机制,InnoDB支持事务与行锁,适合高并发场景;MyISAM不支持事务,... 目录mysql的存储引擎是什么MySQL存储引擎的功能MySQL的存储引擎的分类查看存储引擎1.命令

Spring的基础事务注解@Transactional作用解读

《Spring的基础事务注解@Transactional作用解读》文章介绍了Spring框架中的事务管理,核心注解@Transactional用于声明事务,支持传播机制、隔离级别等配置,结合@Tran... 目录一、事务管理基础1.1 Spring事务的核心注解1.2 注解属性详解1.3 实现原理二、事务事

Linux五种IO模型的使用解读

《Linux五种IO模型的使用解读》文章系统解析了Linux的五种IO模型(阻塞、非阻塞、IO复用、信号驱动、异步),重点区分同步与异步IO的本质差异,强调同步由用户发起,异步由内核触发,通过对比各模... 目录1.IO模型简介2.五种IO模型2.1 IO模型分析方法2.2 阻塞IO2.3 非阻塞IO2.4

MySQL8.0临时表空间的使用及解读

《MySQL8.0临时表空间的使用及解读》MySQL8.0+引入会话级(temp_N.ibt)和全局(ibtmp1)InnoDB临时表空间,用于存储临时数据及事务日志,自动创建与回收,重启释放,管理高... 目录一、核心概念:为什么需要“临时表空间”?二、InnoDB 临时表空间的两种类型1. 会话级临时表

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

史上最全MybatisPlus从入门到精通

《史上最全MybatisPlus从入门到精通》MyBatis-Plus是MyBatis增强工具,简化开发并提升效率,支持自动映射表名/字段与实体类,提供条件构造器、多种查询方式(等值/范围/模糊/分页... 目录1.简介2.基础篇2.1.通用mapper接口操作2.2.通用service接口操作3.进阶篇3