ORB_SLAM3源码阅读笔记(一)

发布时间 2023-03-30 15:05:45作者: Shang-Zhi

本文参考赵旭辉博士的ORB_SLAM3源码阅读记录以及自己的源码阅读进行随笔记录,详细内容可参考链接

一、结构

  算法整体上需要关注的是三个线程,阅读源码的过程中也始终以这三个线程为主。

  • Tracking 跟踪线程
  • LocalMapping 定位与建图线程
  • LoopClosing 回环检测优化线程
    这三个对象均在System构造函数中创建。

二、主函数

  此处从ORB_SLAM3源码中的单目视觉部分开始逐步对ORB_SLAM3的整个工作过程进行分析。

ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::MONOCULAR, false);

  该语句是主函数中最关键的一句代码,目的是创建SLAM系统,初始化系统所有线程,准备开始处理数据,其中SLAM()中第一个参数argv[1]表示的是输入的ORBvoc.txt即ORB词袋模型数据,第二个参数argv[2]表示的相机参数的yaml文件,显而易见,第三个参数表示相机的类型,第四个参数是一个bool类型,该参数控制是否进行数据的可视化,在运行程序的过程中如果将该参数设置为false则不会有任何的可视化。
  进入System构造函数对该函数执行的一些操作进行分析:

  • 1 读取配置文件
cv::FileNode node = fsSettings["File.version"];
……
cv::FileNode node = fsSettings["System.LoadAtlasFromFile"];
……
node = fsSettings["loopClosing"];

可以看出读取配置文件的过程中,ORB_SLAM3算法是根据输入yaml文件中的关键字进行不同的操作的,此处可以看出输入的参数可以是相机参数文件,也可以是地图文件和回环检测相关的文件。在ORB_SLAM3的单目部分输入的只是相机配置文件,因此不需要去考虑外部地图以及回环的相关问题。

  • 2 载入ORB词袋模型
    进入TemplatedVocabulary.h查看载入词袋模型函数具体的内容,需要注意的是这里是以.txt的形式进行读取的,在实际的应用过程中随着模型的增大载入时间也会变长,所以有学者已经将此处词袋模型的载入方式修改为二进制文件形式读取,大大的提高了词袋模型的载入效率,具体可参考链接。词袋模型是以kd树的形式进行存储的。

  • 3 创建地图集
    在载入词袋模型后,由于并没有载入外部的地图所以此时需要新建一个,maAtlas = new Atlas(0)该语句创建并初始化地图,地图编号为0。

  • 4 检查传感器
    传感器的模式一共有三种:

    • 双目+IMU
    • 单目+IMU
    • RGBD+IMU
      此处进行了一个判断,不同组合传感器对应不同初始化。
  • 5 创建对象

mpFrameDrawer = new FrameDrawer(mpAtlas);
mpMapDrawer = new MapDrawer(mpAtlas, strSettingsFile, settings_);
mpTracker = new Tracking(this, mpVocabulary, mpFrameDrawer, mpMapDrawer,
                             mpAtlas, mpKeyFrameDatabase, strSettingsFile, mSensor, settings_, strSequence);
mpLocalMapper = new LocalMapping(this, mpAtlas, mSensor==MONOCULAR || mSensor==IMU_MONOCULAR,
                                     mSensor==IMU_MONOCULAR || mSensor==IMU_STEREO || mSensor==IMU_RGBD, strSequence);
mptLocalMapping = new thread(&ORB_SLAM3::LocalMapping::Run,mpLocalMapper);
mpLoopCloser = new LoopClosing(mpAtlas, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR, activeLC); // mSensor!=MONOCULAR);
mptLoopClosing = new thread(&ORB_SLAM3::LoopClosing::Run, mpLoopCloser);

该部分创建了显示过程中“画帧的对象”mpFframDrawer,“画地的对象”mpMapDrawer,追踪线程对象mpTracker。同时创建了定位与建图对象mpLocalMapper与回环检测对象mpLoopCloser并开启了线程。
最后在三个线程之间建立指针:

    mpTracker->SetLocalMapper(mpLocalMapper);
    mpTracker->SetLoopClosing(mpLoopCloser);
    mpLocalMapper->SetTracker(mpTracker);
    mpLocalMapper->SetLoopCloser(mpLoopCloser);
    mpLoopCloser->SetTracker(mpTracker);
    mpLoopCloser->SetLocalMapper(mpLocalMapper);

此处引用赵旭辉博士文章中的图片对三个线程之间的关系进行描述
image

  • 6 结束
    该部分主要是线程的结束与数据的保存,线程结束通过调用 SLAM.Shutdown();函数完成。后续再对本文中的一些细节进行描述。

三、小结

  第一部分主要对ORB_SLAM3的主函数的大致工作过程进行说明,可以看出基本上也就是外部配置文件读取载入、初始化地图、传感器,创建线程与启动等等。