第2讲 初识slam
2.1 引子:小萝卜的例子
实现自主移动需要知道两件事情:
- 自身的状态(位置)
- 外在的环境(地图)
传感器分类:
- 携带于机器人本体上:轮式编码器、相机、激光
- 安装于环境中:导轨、二维码标志
相机分类:
- 单目相机:
- 优点:结构简单,成本低
- 缺点:平移之后才能确定深度(或距离),以及无法确定真实尺度,即尺度不确定性
- 双目相机:
- 优点:距离估计是比较左右眼的图像获得的,并不依赖其他传感设备;室内室外都可应用
- 缺点:配置与标定均较为复杂,其深度量程和精度受双目的基线与分辨率所限,而且视差的计算非常消耗计算资源,需要使用GPU和FPGA设备加速后,才能实时输出整张图像的距离信息。
- 深度相机
- 利用红外结构光或Time-of-Flight(ToF)原理,通过主动向物体发射并接收返回的光,测出物体与相机之间的距离。通过物理的测量手段计算距离,相对于双目相机可节省大量的计算。
- 缺点:存在测量范围窄、噪声大、视野小、易受日光干扰、无法测量投射材质等诸多问题。
- 应用场景:主要是室内,室外较难应用
2.2 经典视觉slam框架
- 传感器信息读取。主要为相机图像信息的读取和预处理。
- 视觉里程计(Visual Odometry,VO,前端)。任务是估算相邻图像间相机的运动,以及局部地图的样子。
- 后端优化(Optimization,后端)。后端接受不同时刻视觉里程计测量的相机位姿,以及回环检测的信息,对它们进行优化,得到全局一致的轨迹和地图。
- 回环检测(Loop Closing)。回环检测判断机器人是否到达先前的位置。如果检测到回环,它会把信息提供给后端进行处理。
- 建图(Mapping)。根据估计的轨迹,建立与任务要求对应的地图。
2.2.1 视觉里程计
视觉里程计关心的是相邻图像之间的相机运动,最简单的情况是两张图像之间的运动关系。
VO能够通过相邻帧间的图像估计相机运动,并恢复场景的空间结构。
假定我们已有一个视觉里程计,估计了两张图像间的相机运动。那么,只要把相邻时刻的运动串起来,就构成了机器人的运动轨迹,从而解决了定位问题。另一方面,我们根据每个时刻的相机位置,计算出各像素对应的空间点的位置,就得到了地图。
存在问题:累积漂移
解决方案:回环检测和后端优化
2.2.2 后端优化
前端给后端提供待优化的数据,以及这些数据的初始值。
而后端负责整体的优化过程,它往往面对的只有数据。
后端主要是滤波和非线性优化算法。
2.2.3 回环检测
主要解决位置估计随时间漂移的问题
可以判断图像间的相似性来完成回环检测
消除累积误差,得到全局一致的轨迹和地图。
2.2.4 建图
指构建地图的过程
分类:
- 度量地图(Metric Map)
- 稀疏(Sparse):由路标组成的地图
- 稠密(Dense):着重于建模所有能看到的东西。用于导航
- 拓扑地图(Topological Map)
- 强调地图元素之间的关系;由结点和边组成,只考虑结点间的连通性
2.3 SLAM问题的数学描述
运动方程和观测方程
2.4 实践:编程基础
2.4.1 安装Linux操作系统
安装git
克隆slam14讲源代码,这里连接不上就多试几遍
下面我把每小节用到的代码贴上去,当前小节没用到的就不贴
2.4.2 Hello SLAM
slambook/ch2/2.4.2/helloSLAM.cpp
终端如下:
2.4.3 使用cmake
安装cmake
slambook/ch2/2.4.3/helloSLAM.cpp
slambook/ch2/2.4.3/CMakeLists.txt
编译
运行
2.4.4 使用库
静态库:以.a
作为后缀名
slambook/ch2/2.4.4/helloSLAM.cpp
slambook/ch2/2.4.4/libHelloSLAM.cpp
slambook/ch2/2.4.4/CMakeLists.txt
最后生成libhello.a文件
共享库:以.so
作为后缀名
在上面静态库代码基础上修改了CMakeLists.txt
slambook/ch2/2.4.4_2/CMakeLists.txt
最后生成libhello_shared.so文件
使用共享库
在上面代码基础上添加了libHelloSLAM.h
slambook/ch2/2.4.4_3/libHelloSLAM.h
并修改了CMakeLists.txt
slambook/ch2/2.4.4_3/CMakeLists.txt