经过半年学习SLAM相关知识,对SLAM系统有了一些新的认识,故回看以前的学习记录,做总结和校正。
前三讲学习笔记如下:
视觉SLAM十四讲学习笔记-第一讲_goldqiu的博客-CSDN博客
视觉SLAM十四讲学习笔记-第二讲-初识SLAM_goldqiu的博客-CSDN博客
视觉SLAM十四讲学习笔记-第二讲-开发环境搭建_goldqiu的博客-CSDN博客
视觉SLAM十四讲学习笔记-第三讲-旋转矩阵和Eigen库_goldqiu的博客-CSDN博客
视觉SLAM十四讲学习笔记-第三讲-旋转向量、欧拉角、四元数_goldqiu的博客-CSDN博客
视觉SLAM十四讲学习笔记-第三讲-相似、仿射、射影变换和eigen程序、可视化演示_goldqiu的博客-CSDN博客
第一讲:
总结:SLAM的主要功能就是实时建图和定位,在整个机器人系统中处于感知这一部分,即机器人感知外界环境获得环境地图和自身定位。我的理解是感知分为广义的感知和狭义的感知。狭义的感知即是机器人感知物体(包括动态和静态的物体),能够分辨出物体大小、形状等,为后续相关决策提供数据。而广义的感知不只是分辨物体,还包括感知环境,同时也获得自己在环境中定位,也就是位姿信息。总而言之,广义的感知是离不开SLAM技术的,当然也离开物体感知等。
校正:作者代码有第一讲和第二讲的版本,我更多演示的是第二讲版本的代码。
https://github.com/gaoxiang12/slambook (第一版)
https://github.com/gaoxiang12/slambook2.git (第二版)
第二讲:
总结:
- 我的理解是,在SLAM中传感器分为直接和间接测量类型,像GPS和导轨属于直接测量位置信息的传感器,而IMU、激光雷达、相机属于间接测量,通过测得的物理量或者说是数据,经过一些数学方法间接得到机器人的位置信息,更重要的是能获得姿态信息,而对于直接测量的传感器是无法获得姿态信息的。在我看来,还有一种分类是主动式和被动式测量传感器,例如激光雷达是通过发射一组激光信息,接收反射回来的光信号进行距离测量,它获取外界信息是主动去获取的。而相机是直接对环境进行在成像平面的投影,属于被动式。
2. 视觉SLAM中,单目相机无法得到尺度信息,而双目相机和深度相机可以获得,但是双目相机的计算量远大于单目和深度相机。
3. 视觉SLAM流程: 传感器信息读取(相机图像信息的读取和预处理)--- 视觉里程计 (Visual Odometry, VO, 估算相邻图像间相机的运动, 以及局部地图的构建。VO 又称为前端(Front End)) --- 后端优化(Optimization , 接受不同时刻视觉里程计测量的相机位姿,以及回环检测的信息,对它们进行优化 , 得到全局一致的轨迹和地图, 称为后端(Back End)) --- 回环检测(Loop Closing, 判断机器人是否曾经到达过先前的位置。如果检测到回环,会把信息提供给后端进行处理 )--- 建图(Mapping,根据估计的轨迹,建立与任务要求对应的地图)
4. 对于建图 , 一般SLAM输出的地图是无序的点云地图, 而对于机器人来说, 进行运动规划需要的地图往往是栅格地图, 包括二维\2.5D高程\三维。
5. 在第二讲的开发环境搭建中演示了如何生成动态库和静态库,这对后面SLAM工程化很有帮助。静态库以.a作为后缀名,共享库以.so结尾。所有库都是一些函数打包后的集合,差别在于静态库每次被调用都会生成一个副本,而共享库则只有一个副本,更省空间。
校正:对于ros的开发环境,我目前推荐vscode, 里面有ros的插件支持。
goldqiu:四.开发记录之ubuntu系统安装ROS和开发环境
我的这篇文章写了vscode如何搭建ros的开发环境, 但是如何debug还没写, 我也没形成笔记。
在我看来 , clion比较适合跨平台的cmake工程,而qt比较适合跨平台的qmake工程, 做界面比较友好, vscode更适合开发ros。
第三讲:
总结:
- 通常我们用右手系来定义机器人的坐标系。
- 向量内积可以描述向量间的投影关系。
- 外积运算引入∧符号,可以将∧记成一个反对称符号。这样就把外积a×b写成了矩阵与向量的乘法a∧b,把它变成了线性运算。这意味着任意向量都对应着唯一的一个反对称矩阵,反之亦然。这里在后面李代数中很重要, 可以将矩阵的乘法当作向量的乘法。
- 旋转矩阵在多个传感器之间的外参和机器人自身坐标和世界坐标系的关系中都有很多的应用。行列式为1是它的约束, 这对于求解优化问题很不友好, 矩阵参数太多了, 冗余了。我们更多要注意的是旋转矩阵的旋转定义问题。定义坐标系1、坐标系2,那么向量a在两个系下坐标为 a1, a2 ,完整的写法:a1 = R12a2 + t12. R12是指把坐标系2的向量变换到坐标系1中。同理,如果要表达从1到2的旋转矩阵时,就写成R21。关于平移t12,实际对应的是坐标系1原点指向坐标系2原点的向量,在坐标系1下取的坐标,把它记作从1到2的向量。反过来的t21,即从2指向1的向量在坐标系2下的坐标,并不等于−t12,这里和两个系的旋转还有关系。将R和t结合起来的齐次坐标下的变换矩阵T也是一样的。
- 对于eigen库的使用是比较简单的, 遇到使用问题直接查找eigen官网或者上网搜基本都可以解决问题。
- 任意旋转都可以用一个旋转轴和一个旋转角来刻画。可以使用一个向量,其方向与旋转轴一致,而长度等于旋转角。这种向量称为旋转向量(或轴角/角轴,Axis-Angle)。对于变换矩阵,使用一个旋转向量和一个平移向量即可表达一次变换, 变量维数是六维。考虑某个用R表示的旋转, 假设旋转轴为一个单位长度的向量n,角度为 θ,那么向量θn也可以描述这个旋转。
- 欧拉角不适于插值和迭代,往往只用于人机交互中。很少在SLAM程序中直接使用欧拉角表达姿态,同样不会在滤波或优化中使用欧拉角表达旋转,因为它具有奇异性, 会碰到万向锁问题。还有 , 在标定两个传感器之间外参时,欧拉角的三个小角度误差的标定也是比较常用的。
- 三维空间点用一个纯虚四元数, 单位四元数来表示旋转,相乘后还是一个纯虚四元数,表示旋转后坐标系下的三维空间点。所以使用四元数来进行变换时需要归一化。
- 相似变换在相机模型中有用到。
- 可以利用Pangolin库来绘制SLAM轨迹和位姿。