ORB-SLAM(1) --- 让程序飞起来

1. ORB SLAM简介

      ORBSLAM是15年出的比较完备的单目slam算法,orb指的是一种旋转不变性特征,整个算法均是基于orb特征实现的,不同于基于稠密或半稠密地图的slam,orbslam是一个基于特征点地图的slam。最新的orbslam的进展是基于orbslam的关键帧做了半稠密场景重建,新的研究成果可持续关注下面的项目主页:

  http://webdiis.unizar.es/~raulmur/orbslam/

  以下为英文介绍:

  ORB-SLAM is a versatile and accurate Monocular SLAM solution able to compute in real-time the camera trajectory and a sparse 3D reconstruction of the scene ina wide variety of environments, ranging from small hand-held sequences of a desk to a car driven around several city blocks. It is able toclose large loops and perform global relocalisation in real-time andfrom wide baselines. It includes an automatic and robust initialization fromplanar and non-planar scenes. See the related publication [1] for moredetails. Demostrating videos, code and related publications are shown below.

2. 准备工作

2.1 源码下载

      orbslam是基于ros运行的,故先得准备好ubuntu和ros环境,这里就不再赘述了,本文介绍的是基于ubuntu 14.04和ros indigo环境下的orbslam运行事例!

     首先在项目主页上找到下载链接,将orbslam工程下载至本地

   https://github.com/raulmur/ORB_SLAM

       打开文件夹,可以看到以下内容:

  

  首先我们应该关注它的README.txt,里边关于orbslam怎么编译,怎么运行讲得已经很清楚了。当然对于熟悉ros的人很容易啦,但是对于ros小白们可能还是有点费劲的,所以这里会把具体的编译执行,再详细的介绍一遍。

2.2 测试数据集准备

        http://webdiis.unizar.es/~raulmur/orbslam/downloads/Example.bag.tar.gz  

       上面的链接为测试数据集的下载链接,可以下下着,比较大了,会很慢。。

       下载完解压 得到Example.bag文件

3. ORB SLAM编译

3.1 依赖库的安装

       ORB SLAM依赖于另外两个第三方库g2o(执行图优化的一个通用求解器,这里可以简单理解位姿求解,位姿优化、地图优化就基本上靠它啦),DBOW库(主要用于place recognition,场景识别,在ORB SLAM中主要用于闭环检测)。这两个库ORB SLAM已经打包在一块了,在ThirdParty文件夹下。

 当然这两个库也是需要依赖其他库的,所以呢,先安装一些其它的库,就按照readme中来就好啦。。。

    sudo apt-get install libboost-all-dev
    sudo apt-get install libsuitesparse-dev
    sudo apt-get install libblas-dev
    sudo apt-get install liblapack-dev
    sudo apt-get install libeigen3-dev

3.2 第三方库的编译

 上面的库安装好了之后,那么后面就好办了:

 1. 终端进入到g2o文件夹,执行

   mkdir build
   cd build
   cmake ..
  make 

      执行完这四个指令,若没报错就噢啦,对于DBOW2同样的道理,到这步还是按照README的第二节介绍的就好啦

     注意:这里README没有介绍要安装Opencv,ORBSLAM是依赖它的,大家不要忘了安装opencv了,下个新版本按照说明装就好了,这里就不在介绍了。

3.3 ORB_SLAM的编译

  到这里终于到源码的编译了,编译过程与两个第三方库相似,不过还是有些区别的。

 若ORB_SLAM是在你的ros工作空间目录下,可以跳过以下步骤:

 将ORB_SLAM路径加入ROS的环境变量ROS_PACKAGE_PATH中去,

  执行 export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:(你的ORB_SLAM文件夹绝对路径)

 然后执行

   mkdir build
  cd build
  cmake ..
  make

        正常情况下会没错的,若编译成功,则可以执行下一步了。本人在这一步cmake时报错了,说是找不到opencv2,其实这里直接将文件manifest.xml中 <depend package="opencv2"/> 删除就好了。

4. 运行程序

     说到运行程序,orbslam是基于ros的,因此首先必须得运行roscore,启动ros服务。随后逐一运行图片显示,地图显示,orb slam主体程序,rosbag图片发布程序。

       关于启动各个程序,无论是ORB本体程序还是可视化程序还是图片发布程序,大致有两种方法:

4.1 逐一手动启动各个程序

      (1) 开启新的终端,执行

   roscore   #启动ros服务

      (2) 开启新的终端,执行

   export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:(你的ORB_SLAM文件夹绝对路径)#添加环境变量,如果ORB_SLAM位于ROS工作空间的话,则忽略
 rosrun image_view image_view image:=/ORB_SLAM/Frame _autosize:=true #启动图片查看程序,到时可以看到特征点跟踪情况

         (3) 打开新的终端,执行

   export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:(你的ORB_SLAM文件夹绝对路径)#添加环境变量,如果ORB_SLAM位于ROS工作空间的话,则忽略
    rosrun rviz rviz -d Data/rviz.rviz   #启动地图视图窗口,显示轨迹及特征点地图

(4) 打开新的终端,执行

   export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:(你的ORB_SLAM文件夹绝对路径)#添加环境变量,如果ORB_SLAM位于ROS工作空间的话,则忽略
    rosrun ORB_SLAM ORB_SLAM Data/ORBvoc.yml Data/Settings.yaml   #运行ORB_SLAM , 其中ORBvoc.yml需要先解压

(5) 打开新的终端执行,进入Example.bag所在文件夹,执行

       rosbag play --pause Example.bag  #执行图片发布程序,执行后,按空格键开始

4.2 使用launch文件启动程序

使用launch文件就比较简单了,ORB_SLAM包中包含两个launch文件,对应不同的ROS版本

       

    根据你的ROS版本,选择对应的launch文件即可,launch文件相当于将上一小节的2,3,4步集成在一块,通过一个脚本文件顺序执行:

       (1) 开启新的终端,执行

   roscore   #启动ros服务

      (2) 开启新的终端,执行

   export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:(你的ORB_SLAM文件夹绝对路径)#添加环境变量,如果ORB_SLAM位于ROS工作空间的话,则忽略
    roslaunch ExampleGroovyHydro.launch

(3) 打开新的终端执行,进入Example.bag所在文件夹,执行

       rosbag play --pause Example.bag  #执行图片发布程序,执行后,按空格键开始

5. 问题及解决方法

  前面介绍的仅仅是如何把程序运行起来,然而在运行时使用不同的数据集可能会有一些问题,以下将本人在执行ORB SLAM遇到的问题整理下:

5.1 为什么跑数据集时老是出现跟踪失败?

      本人在使用Example.bag时并未出现什么问题,然而在运行自己的数据集时,常常会出现Tracking失败的现象,而且通常是开始时都没问题,运行一段时间后出现的。将数据集中的图片打开感觉前后帧变化不大啊,后来测了一下程序每步执行的时间,稍微看了一下他的代码实现,大致的推论是这样的:
     1). 在用rosbag发布图像时,很多时候都用的30帧每秒的发送速率,然而电脑性能未特别好的情况下,是不能及时处理的,因此读取图像端可能会出现丢帧现象,导致图像不连续,造成跟踪失败;
     2).ORB_SLAM在程序执行时,多个线程共享同一份地图关键帧,造成每个线程可能运行的时间不固定,这个也是导致不能及时处理图片的一个原因吧。
     解决方法:一般跑代码的人是先想看看代码的功能性,效率可以作为接下来考量的东西,因此最简单的办法是将rosbag发布的帧率调低或调到很低,具体方法是在使用BagFromImages工具打包时将帧率参数设置为比较小的数值,而不是通常地30帧。

5.2 为什么跑文献中那个kitti最大场景(sequence 00)的结果与文献中给出的不一致?

      可能对于比较小的数据集出现个跟踪失败现象使用将图像发布速度降低的方法能解决一部分问题,然而想跑一个大场景的数据集时,比如说文献中那个比较庞大的数据集时(如下图),发现前面跑的还好,后面咋就还是由于跟踪失败,导致在回到之前到过场景之前地图一直处于丢失状态。


      开始时本人也是相当困惑的,后来一想ORB_SLAM使用的多线程,资源共享机制还有增量式地图会导致两个因素:一是算法时间不稳定,二是对内存的消耗会越来越大,一旦真实的物理内存用尽了,大家都知道Linux会使用交换分区作为内存的扩展空间,这样的话程序的执行效率会降低不少的,后来通过系统监视器发现4G的内存根本就不够他用,最后通过加了个4G内存然后将图片发布速度控制到很低的帧率,慢吞吞的跑完,终于达到作者所描述的效果(看来科研是有一台性能好的电脑还是有优势的)。

5.3 设置自己相机相关参数

     当使用自己的数据集时,相机的内参数和畸变参数会有不同,因此可在Data下的 Settings.yaml中修改:
ORB-SLAM(1) --- 让程序飞起来_第1张图片

6 .结语

    本文只是简单的介绍了如何将ORB-SLAM跑起来的步骤,下一篇会逐步介绍本人对于ORB-SLAM算法的理解和自己的一些思考!



你可能感兴趣的:(ORB-SLAM(1) --- 让程序飞起来)