rbpf粒子滤波slam matlab程序_视觉slam第二版

  1. 第1讲是预备知识,介绍本书的基本信息,习题部分主要包括一些自测题。
  2. 第2讲为SLAM系统概述,介绍一个SLAM系统由哪些模块组成,各模块的具体工作是什么。实践部分介绍编程环境的搭建过程及IDE的使用。
  3. 第3讲介绍三维空间刚体运动,你将接触到旋转矩阵、欧拉角、四元数的相关知识,并且在Eigen中使用它们。
  4. 第4讲介绍李群与李代数。即便你现在不懂李代数为何物,也没有关系。你将学到李代数的定义和使用方式,然后通过Sophus操作它们。
  5. 第5讲介绍针孔相机模型及图像在计算机中的表达。你将用OpenCV调取相机的内外参数。
  6. 第6讲介绍非线性优化,包括状态估计理论基础、最小二乘问题、梯度下降方法。你会完成一个使用Ceres和g2o进行曲线拟合的实验。
  7. 第7讲为特征点法的视觉里程计。该讲内容比较多,包括特征提取与匹配、对极几何约束的计算、PnP和ICP等。在实践中,你将用这些方法估计两个图像之间的运动。
  8. 第8讲为直接法的视觉里程计。你将学习光流和直接法的原理,然后实现一个简单的直接法运动估计。
  9. 第9讲为后端优化,主要为对Bundle Adjustment(BA)的深入讨论,包括基本的BA,以及如何利用稀疏性加速求解过程。你将用Ceres和g2o分别书写一个BA程序。
  10. 第10讲主要介绍后端优化中的位姿图。位姿图是表达关键帧之间约束的一种更紧凑的形式。我们会介绍SE(3)和Sim(3)的位姿图,同时你将使用g2o对一个位姿球进行优化。
  11. 第11讲为回环检测,主要介绍以词袋方法为主的回环检测。你将使用DBoW3书写字典训练程序和回环检测程序。
  12. 第12讲为地图构建。我们会讨论如何使用单目进行稠密深度图的估计(以及这是多么不可靠),然后讨论RGB-D的稠密地图构建过程。你会书写极线搜索与块匹配的程序,然后在RGB-D中遇到点云地图和八叉树地图的构建问题。
  13. 第13讲是工程实践,你将搭建一个双目视觉里程计框架,综合运用先前学过的知识,实现它的基本功能。在这个过程中,你会碰到一些问题,例如优化的必要性、关键帧的选择等。我们会在Kitti数据集上测试它的性能,讨论一些改进的手段。
  14. 第14讲主要介绍当前的开源SLAM方案及未来的发展方向。相信在阅读了前面的知识之后,你会更容易理解它们的原理,实现自己的新想法。

  1. 普通的摄像头能以每秒钟拍摄30张图片的速度采集图像,高速相机则更快一些。按照工作方式的不同,相机可以分为单目(Monocular)相机、双目(Stereo)相机和深度(RGB-D)相机三大类
  2. 激光SLAM相对成熟,比如2005年出版的《概率机器人》[5]中就介绍了许多关于激光SLAM的知识
  3. RGB-D的原理较复杂,除了能够采集到彩色图片,还能读出每个像素与相机之间的距离
  4. 此外,SLAM中还有全景相机[7]、Event相机[8]等特殊或新兴的种类
  5. 双目相机测量到的深度范围与基线相关。基线距离越大,能够测量到的物体就越远,所以无人车上搭载的双目相机通常会是个很大的家伙。
  6. 深度相机(又称RGB-D相机)是2010年前后兴起的一种相机,它最大的特点是可以通过红外结构光或Time-of-Flight(ToF)原理,像激光传感器那样,通过主动向物体发射光并接收返回的光,测出物体与相机之间的距离。它并不像双目相机那样通过软件计算来解决,而是通过物理的测量手段,所以相比于双目相机可节省大量的计算资源。目前常用的RGB-D相机包括Kinect/Kinect V2、Xtion Pro Live、RealSense等,在一些手机上人们也用它来识别人脸。不过,现在多数RGB-D相机还存在测量范围窄、噪声大、视野小、易受日光干扰、无法测量透射材质等诸多问题,在SLAM方面,主要用于室内,室外则较难应用。

2f879790e9a2876276c7cb122e1ae4fa.png

整个视觉SLAM流程包括以下步骤。

  1. 传感器信息读取。在视觉SLAM中主要为相机图像信息的读取和预处理。如果是在机器人中,还可能有码盘、惯性传感器等信息的读取和同步。
  2. 前端视觉里程计(Visual Odometry,VO)。视觉里程计的任务是估算相邻图像间相机的运动,以及局部地图的样子。VO又称为前端(Front End)。
  3. 后端(非线性)优化(Optimization)。后端接受不同时刻视觉里程计测量的相机位姿,以及回环检测的信息,对它们进行优化,得到全局一致的轨迹和地图。由于接在VO之后,又称为后端(Back End)。
  4. 回环检测(Loop Closure Detection)。回环检测判断机器人是否到达过先前的位置。如果检测到回环,它会把信息提供给后端进行处理。
  5. 建图(Mapping)。它根据估计的轨迹,建立与任务要求对应的地图。

  1. 视觉里程计关心相邻图像之间的相机运动,最简单的情况当然是两张图像之间的运动关系。
  2. 如何从这些带有噪声的数据中估计整个系统的状态,以及这个状态估计的不确定性有多大——这称为最大后验概率估计(Maximum-a-Posteriori,MAP)
  3. 在视觉SLAM中,前端和计算机视觉研究领域更为相关,比如图像的特征提取与匹配等,后端则主要是滤波与非线性优化算法。
  4. 为了解决SLAM问题,我们需要状态估计理论,把定位和建图的不确定性表达出来,然后采用滤波器或非线性优化,估计状态的均值和不确定性(方差)。
  5. 回环检测,又称闭环检测,主要解决位置估计随时间漂移的问题。
  6. 地图的形式随SLAM的应用场合而定。大体上讲,可以分为度量地图与拓扑地图两种。
  7. 度量地图强调精确地表示地图中物体的位置关系,通常用稀疏(Sparse)与稠密(Dense)对其分类。稀疏地图进行了一定程度的抽象,并不需要表达所有的物体。例如,我们选择一部分具有代表意义的东西,称之为路标(Landmark),那么一张稀疏地图就是由路标组成的地图,而不是路标的部分就可以忽略。相对地,稠密地图着重于建模所有看到的东西。定位时用稀疏路标地图就足够了。而用于导航时,则往往需要稠密地图(否则撞上两个路标之间的墙怎么办?)。
  8. 相比于度量地图的精确性,拓扑地图更强调地图元素之间的关系。拓扑地图是一个图(Graph),由节点和边组成,只考虑节点间的连通性,例如只关注A、B点是连通的,而不考虑如何从A点到达B点。
  9. 当知道运动测量的读数u,以及传感器的读数z时,如何求解定位问题(估计x)和建图问题(估计y)?这时,我们就把SLAM问题建模成了一个状态估计问题:如何通过带有噪声的测量数据,估计内部的、隐藏着的状态变量?
  10. 状态估计问题的求解,与两个方程的具体形式,以及噪声服从哪种分布有关。
  11. 按照运动和观测方程是否为线性,噪声是否服从高斯分布进行分类,分为线性/非线性和高斯/非高斯系统。其中线性高斯系统(Linear Gaussian,LG系统)是最简单的,它的无偏的最优估计可以由卡尔曼滤波器(Kalman Filter,KF)给出。而在复杂的非线性非高斯系统(Non-Linear Non-Gaussian,NLNG系统)中,我们会使用以扩展卡尔曼滤波器(Extended Kalman Filter,EKF)和非线性优化两大类方法去求解。
  12. 为了克服EKF的缺点(例如线性化误差和噪声高斯分布假设),人们开始使用粒子滤波器(Particle Filter)等其他滤波器,乃至使用非线性优化的方法。时至今日,主流视觉SLAM使用以图优化(Graph Optimization)为代表的优化技术进行状态估计[13]。我们认为优化技术已经明显优于滤波器技术,只要计算资源允许,通常都偏向于使用优化方法
  13. 安装完成后,请务必把软件源设置到离你较近的服务器上,以获得更快的下载速度。例如,笔者使用清华的软件源通常能以每秒10MB的速度安装软件[12]

  1. 们用编辑器输入了helloSLAM.cpp的源代码,然后调用g++编译器对它进行编译,得到了可执行文件。g++默认把源文件编译成a.out这个名字的程序
  2. 理论上,任意一个C++程序都可以用g++来编译。但当程序规模越来越大时,一个工程可能有许多个文件夹和源文件,这时输入的编译命令将越来越长。通常,一个小型C++项目可能含有十几个类,各类间还存在着复杂的依赖关系。其中一部分要编译成可执行文件,另一部分编译成库文件。如果仅靠g++命令,则需要输入大量的编译指令,整个编译过程会变得异常烦琐。因此,对于C++项目,使用一些工程管理工具会更加高效。在历史上,工程师们曾使用makefile进行自动编译,但下面要谈的cmake比它更加方便。并且cmake在工程上广泛使用,我们会看到后面提到的大多数库都使用cmake管理源代码。
  3. 在一个cmake工程中,我们会用cmake命令生成一个makefile文件,然后,用make命令根据这个makefile文件的内容编译整个工程。
  4. 在slambook2/ch2/中新建一个CMakeLists.txt文件,CMakeLists.txt文件用于告诉cmake要对这个目录下的文件做什么事情。
  5. 在当前目录下(slambook2/ch2/),调用cmake对该工程进行cmake编译
  6. cmake会输出一些编译信息,然后在当前目录下生成一些中间文件,其中最重要的就是MakeFile
  7. MakeFile是自动生成的,我们不必修改它。现在,用make命令对工程进行编译
  8. 先创建CMakeLists.txt,然后调用cmake,生成MakeFile,然后用make命令对工程进行编译
  9. 执行cmake的过程处理了工程文件之间的关系,而执行make过程实际调用了g++来编译程序
  10. 现在这个过程中唯一让我们不满的是,cmake生成的中间文件还留在我们的代码文件中。当想要发布代码时,我们并不希望把这些中间文件一同发布出去。这时我们还需要把它们一个个地删除,十分不便。一种更好的做法是让这些中间文件都放在一个中间目录中,在编译成功后,把这个中间目录删除即可。所以,更常见的编译cmake工程的做法如下:
  11. mkdir build
  12. cd build
  13. cmake ..
  14. make
  15. 我们新建了一个中间文件夹“build”,然后进入build文件夹,通过cmake..命令对上一层文件夹,也就是代码所在的文件夹进行编译。这样,cmake产生的中间文件就会生成在build文件夹中,与源代码分开。当发布源代码时,只要把build文件夹删掉即可。请读者自行按照这种方式对ch2中的代码进行编译,然后调用生成的可执行程序(请记得把上一步产生的中间文件删除)。
  16. 在一个C++工程中,并不是所有代码都会编译成可执行文件。只有带有main函数的文件才会生成可执行程序。而另一些代码,我们只想把它们打包成一个东西,供其他程序调用。这个东西叫作库(Library)。
  17. 我们要学习如何用 cmake 生成库,并且使用库中的函数。
  18. 这个库提供了一个printHello函数,调用此函数将输出一条信息。但是它没有main函数,这意味着这个库中没有可执行文件。我们在CMakeLists.txt里加上如下内容:add_library()
  19. 这条命令告诉cmake,我们想把这个文件编译成一个叫作“hello”的库。然后,和上面一样,使用cmake编译整个工程
  20. 这时,在build文件夹中就会生成一个libhello.a文件,这就是我们得到的库。
  21. 在Linux中,库文件分成静态库和共享库两种[17]。静态库以.a作为后缀名,共享库以.so结尾。所有库都是一些函数打包后的集合,差别在于静态库每次被调用都会生成一个副本,而共享库则只有一个副本,更省空间。如果想生成共享库而不是静态库,只需使用以下语句即可。SHARED
  22. 库文件是一个压缩包,里面有编译好的二进制函数。如果仅有.a或.so库文件,那么我们并不知道里面的函数到底是什么,调用的形式又是什么样的。为了让别人(或者自己)使用这个库,我们需要提供一个头文件,说明这些库里都有些什么。因此,对于库的使用者,只要拿到了头文件和库文件,就可以调用这个库。下面编写libhello的头文件。
  23. 程序代码由头文件和源文件组成。
  24. 带有main函数的源文件编译成可执行程序,其他的编译成库文件。
  25. 如果可执行程序想调用库文件中的函数,则它需要参考该库提供的头文件,以明白调用的格式。同时,要把可执行程序链接到库文件上。
  26. KDevelop原生支持cmake工程。具体做法是,在终端建立CMakeLists.txt后,用KDevelop中的“工程→打开/导入工程”打开CMakeLists.txt。软件会询问你几个问题,并默认建立一个build文件夹,帮你调用刚才的cmake和make命令。只要按下快捷键F8,这些都可以自动完成。图2-12中界面的下面部分就显示了编译信息。
  27. 阅读《cmake实践》,了解cmake的其他语法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值