1. slam 是什么
定义:SLAM是Simultaneous Localization And Mapping的缩写,即同时定位与地图构建(我在什么地方?周围环境是怎么样的?)。
它是指搭载特定传感器的主题,在没有环境先验信息的情况下,于运动过程中建立环境的模型,同时估计自己的运动。
梦想:在计算机视觉创立之初,人们就想象着有朝一日计算机将和人一样,通过眼睛去观察世界,理解周遭的物体,探索未知的领域——这是一个美妙而又浪漫的梦想,吸引了无数的科研人员日夜为之奋斗。
应用:在许多地方,我们都希望知道自身的位置。室内的扫地机和移动机器人需要定位,野外的自动驾驶汽车需要定位,空中的无人机需要定位,虚拟现实和增强现实的设备也需要定位。
作者的意见:再漂亮的数学理论,如果不能转化为可以运行的代码,就仍是可望不可即的空中阁楼,没有实际意义。
2. SLAM基本模块
SLAM主要分为几个模块:
- **视觉里程计** (visual odometry,VO)
- **后端优化**
- **建图**
- **回环检测**
因为笔者是工科生,所以要勇敢地承认,某些做法只要经验上够用,没必要非得在数学上追求完备。
SLAM分类:激光slam和视觉slam
相机分类:单目相机monocular,双目相机stereo和深度相机RGB-D
3. 相机的种类
单目monocular:单目无法知道物体的深度,也无法知道尺度。所以,单目slam估计的轨迹和地图将于真是的轨迹和地图相差一个因子,也就是所谓的尺度(scale)。由于单目slam无法劲凭图像确定这个真是尺度,所以又称为尺度不确定性。
双目stereo:双目相机如人眼可通过图像的差距获取深度,两个相机之间的距离越远(基线),能够测量的物体越远。双目或多目相机的缺点是配置与标定都比较复杂,其深度量程和精度受双目的基线与分辨率首先,而且视差的计算非常消耗计算资源,需要GPU和FPGA的设备加速,才能实时输出每个像素即整张图像的深度信息。因此,在现有条件下,计算量是双目的主要问题之一。
深度RGB-D:深度相机不是通过软件计算来解决深度问题,而是通过物理的测量手段,这可以大大节约计算资源。但是目前深度相机有测量范围窄、噪声大、视野小、光照干扰等缺点,在slam方面主要用于室内。
4. 视觉slam基本流程
视觉slam流程主要包括以下步骤:
- 传感器信息读取
- 前端视觉里程计(visual odometry, vo)。
视觉里程计的任务是估算相邻图像间相机的运动,以及局部地图的样子。VO又称为前端(front end)。由于视觉里程计存在误差,不免出现累计漂移(accumulating drift),所以需要后端优化和回环检测。 - 后端(非线性)优化(optimization)
后端优化要考虑的问题,是如何从有噪声的数据中估计整个系统的状态,以及这个状态的不确定性有多大——这称为最大后验概率估计(maximum-a-posteriori, MAP)。这里的状态既包括机器人自身的轨迹,也包含地图。
在视觉SLAM中,前端和计算机视觉研究领域更为相关,比如图像的特征提取与匹配等,后端则主要是滤波与非线性优化算法。早期的SLAM问题是一个状态估计问题——正是后端优化要解决的。SLAM问题的本质是:对运动主体自身和周围环境空间不确定性的估计。 - 回环检测(loop closure detection)
简单来说就是消除漂移。可以通过环境中的传感器(二维码等),但我们更希望机器人能使用携带的传感器——也就是图像本身,来完成这一任务。比如利用图像的相似性来完成回环检测。 - 建图(mapping)
5. 非/线性系统、非/高斯系统
通过运动和观测方程是否为线性,可分为线性系统和非线性系统。
通过噪声是否为高斯分布,可分为高斯系统和非高斯系统。
最简单的线性高斯LG(linear gaussian),可使用卡尔曼滤波器(kalman filter, KF)
复杂的非线性非高斯NLNG,①可使用EKF扩展卡尔曼滤波器->粒子滤波器等;② 非线性优化、图优化。
6自由度的位姿(pose),包含了旋转rotation和平移translation
6. CMake
执行cmake的过程处理了工程文件之间的关系,而执行make过程实际调用了g++来编译程序。虽然这个过程多了cmake和make的步骤,但我们对项目的编译管理工作,从输入一串g++命令,变成了维护若干个比较直观的CMakeLists.txt文件,这将明显降低维护整个工程的难度。
Linux中,库文件分为静态库和共享库两种。静态库以.a作为后缀名,共享库以.so结尾。所有库都是一些函数打包后的集合,差别在于静态库每次被调用都会生成一个副本,而共享库则只有一个副本,更省空间。
带有main的源文件可编译成可执行程序。没有main就编译成库,或者一起添加到库执行文件列表里面
cmake自带一些编译相关的内部变量,它们可以对编译过程进行更精细的控制。对于编译类型,通常有调用的debug模式与发布用的release模式。在debug模式中,程序运行较慢,但可以进行断电调试,而release模式的运行速度较快,但没有调试信息。