ORB SLAM2学习笔记之mono_kitti(二)

ORB SLAM2学习笔记之mono_kitti(二)

  • 一、流程—Part 2
    • 1. System.h的架构
    • 2. System 类
  • 二、实例化SLAM—System构造函数

一、流程—Part 2

本篇博客将主要记录用来实例化SLAM系统的System类的一些用法。

1. System.h的架构

System.h中包含了七个类,分别是Viewer,FrameDrawer,Map,Tracking,LocalMapping,LoopClosing的声明,和System类的定义,就像描述的一样,这些类组成了一个系统。

class Viewer;
class FrameDrawer;
class Map;
class Tracking;
class LocalMapping;
class LoopClosing;
class System;

2. System 类

System 类中的public成员包含一个sensor枚举和一些成员函数,主要有:

sensor枚举

// Input sensor
 enum eSensor{
     MONOCULAR=0,
     STEREO=1,
     RGBD=2
 };

0,1,2分别代表传感器的类型。

System构造函数

System(const string &strVocFile, const string &strSettingsFile, const eSensor sensor, const bool bUseViewer = true);

读入词包路径,读入YAML配置文件,设置SLAM为mono状态,启用viewer的线程。

Tracking函数

cv::Mat TrackStereo(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timestamp);
cv::Mat TrackRGBD(const cv::Mat &im, const cv::Mat &depthmap, const double &timestamp);
cv::Mat TrackMonocular(const cv::Mat &im, const double &timestamp);

针对不同传感器不同的Tracking。输入图像可以使rgb的也可以是grayscale的(最终读进去都会转化为grayscale的),函数返回值为camera的位姿pose。

定位模式函数

void ActivateLocalizationMode();
void DeactivateLocalizationMode();

调用前者终止mapping线程,开启定位模式,调用后者重启mapping线程。

重启与终止函数

void Reset();
void Shutdown();

前者可以清空map,后者可以终止所有线程,在 保存相机轨迹之前 需要调用此函数。

SaveTrajectory 函数

void SaveTrajectoryTUM(const string &filename);
void SaveKeyFrameTrajectoryTUM(const string &filename);
void SaveTrajectoryKITTI(const string &filename);

把相机轨迹存成相应数据集的格式,调用此函数时先shutdown SLAM系统,mono_kittti中save函数用的是SaveKeyFrameTrajectoryTUM,这个函数看起来像是只能用于TUM数据集,但三种传感器均适合。

除上述这些外,private成员里还有一些其他的变量就不一一列举,之后学习后再记录,大致看了一下,基本是各个类的指针,在成员函数中作为其他类的接口使用,可能用于线程之间互相通信吧。

二、实例化SLAM—System构造函数

前面说到System构造函数用于实例化一个SLAM系统,开启局部建图(Local Mapping),回环检测(Loop Closing),和可视化界面(Viewer)的线程。

  1. 首先,函数将形参一一传递到System类中的成员变量,用于之后的计算。

sensor → mSensor
static_cast(NULL) → mpViewer
mbReset 设置为 false
mbActivateLocalizationMode 设置为 false
mbDeactivateLocalizationMode 设置为 false

sensor是传进来的形参,是前面枚举体中三种传感器的一个,这里为MONOCULAR,它传递给了mSensor,这是一个System类的隐含成员变量,两种变量类型一样。
mpViewer是System类的隐含成员变量,Viewer类指针,这里赋空。
mbReset,mbActivateLocalizationMode,mbDeactivateLocalizationMode均为bool型,赋false。

  1. 读取传进来的文件路径:
    //Check settings file
    cv::FileStorage fsSettings(strSettingsFile.c_str(), cv::FileStorage::READ);
    if(!fsSettings.isOpened())
    {
       cerr << "Failed to open settings file at: " << strSettingsFile << endl;
       exit(-1);
    }


    //Load ORB Vocabulary
    cout << endl << "Loading ORB Vocabulary. This could take a while..." << endl;

    mpVocabulary = new ORBVocabulary();
    bool bVocLoad = mpVocabulary->loadFromTextFile(strVocFile);
    if(!bVocLoad)
    {
        cerr << "Wrong path to vocabulary. " << endl;
        cerr << "Falied to open at: " << strVocFile << endl;
        exit(-1);
    }
    cout << "Vocabulary loaded!" << endl << endl;

strSettingsFile这个途径中读取文件,类型为只读,接下来创建一个新类ORBVocabulary,用一个mpVocabulary指针指向它,调用类内的函数 loadFromTextFile() 将 strVocFile(字典路径)装载进去。(ORBVocabulary类是 typedef 成的,来源于 DBoW2 的TemplatedVocabulary类,类参数为 FORB::TDescriptor 和 FORB,现在还不知道什么意思,之后学习后会记录)

  1. 初始化各种线程和数据库
    ①用词袋初始化关键帧数据库( 用于 重定位回环检测

    ②初始化一个Map类,该类用于存储指向所有 关键帧地图点 的指针

    ③初始化画图工具,用于可视化。

    ④初始化 Tracking线程 ,主线程 ,使用this指针(只初始化不启动,启动在 main 函数里 TrackMonocular() 启动)

    ⑤初始化 Local Mapping线程 并启动(这里mSensor传入MONOCULAR)

    ⑥初始化 Loop Closing线程 并启动(这里mSensor传入的不是MONOCULAR)

    ⑦初始化 Viewer线程 并启动,也使用了this指针;给 Tracking线程设置Viewer

    ⑧三个线程每两个线程之间设置指针

    //Create KeyFrame Database
    mpKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary);

    //Create the Map
    mpMap = new Map();

    //Create Drawers. These are used by the Viewer
    mpFrameDrawer = new FrameDrawer(mpMap);
    mpMapDrawer = new MapDrawer(mpMap, strSettingsFile);

    //Initialize the Tracking thread
    //(it will live in the main thread of execution, the one that called this constructor)
    mpTracker = new Tracking(this, mpVocabulary, mpFrameDrawer, mpMapDrawer,
                             mpMap, mpKeyFrameDatabase, strSettingsFile, mSensor);

    //Initialize the Local Mapping thread and launch
    mpLocalMapper = new LocalMapping(mpMap, mSensor==MONOCULAR);
    mptLocalMapping = new thread(&ORB_SLAM2::LocalMapping::Run,mpLocalMapper);

    //Initialize the Loop Closing thread and launch
    mpLoopCloser = new LoopClosing(mpMap, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR);
    mptLoopClosing = new thread(&ORB_SLAM2::LoopClosing::Run, mpLoopCloser);

    //Initialize the Viewer thread and launch
    if(bUseViewer)
    {
        mpViewer = new Viewer(this, mpFrameDrawer,mpMapDrawer,mpTracker,strSettingsFile);
        mptViewer = new thread(&Viewer::Run, mpViewer);
        mpTracker->SetViewer(mpViewer);
    }

    //Set pointers between threads
    mpTracker->SetLocalMapper(mpLocalMapper);
    mpTracker->SetLoopClosing(mpLoopCloser);

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

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

接下来就是这几个线程的工作过程了,感觉有必要看一下有关多线程方面的知识了,还要看一下词袋怎么用来回环检测的,然后看看每个线程如何工作的,互相之间又是通信的。

你可能感兴趣的:(ORB SLAM2学习笔记之mono_kitti(二))