本文转载知乎任乾:ORB SLAM2源码解读(一):系统流程
ORB SLAM2的代码结构流程图:
这张图里可以看出orb一共有三个线程,分别负责跟踪(TRACKING)、局部建图(LOCAL MAPPING)和闭环(LOOP CLOSING)功能,同时又增加了重定位(PLACE RECOGNITION)功能。
系统流程的入口在system.cc文件中,这个文件中一共有四个函数:
System
TrackStereo
TrackRGBD
TrackMonocular
其中System是SLAM系统的构造函数,包括所有功能模块和所有线程的初始化,而TrackStereo、TrackRGBD和TrackMonocular分别是双目、RGBD和单目的数据入口,使用过程中,先调用System函数生成SLAM系统的对象,然后根据传感器类型,调用相应的入口函数,就可以执行SLAM的流程了。
下面对各个函数分别做介绍
构造函数的基本内容:
构造函数中和流程相关的一共有四个参数,分别是
strVocFile: ORB词袋数据。词袋是在做闭环检测和重定位时候做检索用的,从历史关键帧中检索出和当前帧最相似的一帧,以进行位姿匹配。
strSettingsFile: 配置文件的路径。配置文件中存放了相机参数和用户显示界面的设置
sensor: 传感器类型,这是一个枚举变量,一共有三种,分别是MONOCULAR、STEREO和RGBD,分别代表单目、双目和RGBD。
bUseViewer: true代表启动显示界面,false代表不显示
构造函数中一共初始化了以下内容:
mpVocabulary = new ORBVocabulary(); //初始化词袋对象
mpVocabulary->loadFromTextFile(strVocFile); //从词袋数据文件中读取数据
词袋是在做闭环检测和重定位时候做检索用的,从历史关键帧中检索出和当前帧最相似的一帧,以进行位姿匹配。关于词袋更详细的解释,可以参考文章
mpKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary); //使用词袋数据创建数据集对象
如果此处只是加载数据就没意思了,前面提到,这个数据主要用来做闭环检测和重定位,所以这个模块除了加载数据以外,还实现了闭环检测和重定位检测。对应的函数分别是
DetectLoopCandidates(KeyFrame* pKF, float minScore) //检测闭环向量
DetectRelocalizationCandidates(Frame *F) //检测重定位向量
这两个函数内部的内容会在讲解闭环模块时再详细讲解。
mpMap = new Map();
地图中主要存放关键帧和特征点
mpFrameDrawer = new FrameDrawer(mpMap); //画关键帧
mpMapDrawer = new MapDrawer(mpMap, strSettingsFile); //画地图
if (bUseViewer) {
//根据标志位判断是否需要显示
mpViewer = new Viewer(this, mpFrameDrawer,mpMapDrawer,mpTracker,strSettingsFile); //显示界面
mptViewer = new thread(&Viewer::Run, mpViewer);
mpTracker->SetViewer(mpViewer); //打开显示对应的线程
}
mpLocalMapper = new LocalMapping(mpMap, mSensor==MONOCULAR); //初始化局部地图
mptLocalMapping = new thread(&ORB_SLAM2::LocalMapping::Run,mpLocalMapper); //打开局部地图对应的线程
mpLoopCloser = new LoopClosing(mpMap, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR); //初始化闭环检测
mptLoopClosing = new thread(&ORB_SLAM2::LoopClosing::Run, mpLoopCloser); //打开对应的线程
mpTracker->SetLocalMapper(mpLocalMapper);
mpTracker->SetLoopClosing(mpLoopCloser);
mpLocalMapper->SetTracker(mpTracker);
mpLocalMapper->SetLoopCloser(mpLoopCloser);
mpLoopCloser->SetTracker(mpTracker);
mpLoopCloser->SetLocalMapper(mpLocalMapper);
该函数主要功能和流程列在下图中
从途中可以看出,每次输入数据以后,会执行三种操作:
判断是否需要进入或者退出纯定位模式,如果需要则执行
判断是否需要重启tracking,如果需要则执行
执行双目的跟踪程序。GrabImageStereo共有三个参数,分别是左目、右目和时间戳
整体流程和双目一样,唯一的区别是此处调用的入口是RGB函数的入口,它的三个参数分别是像素图、深度图和时间戳
整体流程仍然和双目一样,区别是入口变成了单目的入口,它的两个参数分别是像素图和时间戳。