ORB-slam2源码分析(2)- 程序入口system类

ORB-slam2源码分析(2)- 程序入口system类

  • system构造函数
  • TrackMonocular 单目相机入口
  • 其他类型摄像头入口

orb-slam2支持单目,双目,rgbd三种类型摄像机进行slam,其整个程序入口和出口均在system类中。因此如果需要将orb-slam2在ros中运行,可将system类进行重新封装(其他都可不做修改),在ros节点中调用system类即可,这点非常友好。

system构造函数

system函数为整个算法的入口,包括所有线程的开辟,各个模块的初始化,及其摄像机类型的选择;

//构建函数
/*
input:
字典, 类型(mono,rgbd,stereo),参数,mapfile, 是否导入地图
 */
System::System(const string strVocFile, const eSensor sensor, ORBParameters& parameters,
               const std::string & map_file, bool load_map): // map serialization addition
               mSensor(sensor), mbReset(false),mbActivateLocalizationMode(false), mbDeactivateLocalizationMode(false),
               map_file(map_file), load_map(load_map)

system构造函数参数包括离线训练的词袋字典文件名,camera类型,ORB特征点提取参数,也可以增加已知地图纯定位功能。

    //Load ORB Vocabulary
    cout << endl << "Loading ORB Vocabulary." << endl;
    // 创建字典
    mpVocabulary = new ORBVocabulary();

    //try to load from the binary file,导入2进制文件
    bool bVocLoad = mpVocabulary->loadFromBinFile(strVocFile+".bin");

原始开源代码调用词典为txt文本,众所周知读入txt的文本的速度十分耗时,导致slam启动较慢。已有人将其改进为bin文件存储和读取,以此可提高启动速度。

    // begin map serialization addition
    // load serialized map
    // 是否载入已有地图
    if (load_map && LoadMap(map_file)) {
        std::cout << "Using loaded map with " << mpMap->MapPointsInMap() << " points\n" << std::endl;
    }
    else {
        // 新建地图,则需创建一个空的地图对象,
        //Create KeyFrame Database
        // 初始化关键帧数据对象,主要存储字典里包含的值,用于重定位和闭环
        mpKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary);
        //Create the Map
        // 创建map数据,应该是特征点和对应的keypose
        mpMap = new Map();
    }
    // end map serialization addition

orb-slam2开始slam时需创建一个新的空的map对象。同时更为重要创建一个KeyFrameDatabase对象,此对象用于存储关键帧的在词典中的词袋向量,后续的闭环和重定位也是基于此词袋数据进行搜索匹配。

    //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,
                             mpMap, mpKeyFrameDatabase, mSensor, parameters);

初始化三个线程中tracking线程;

    //Initialize the Local Mapping thread and launch
    // 初始化建图线程
    mpLocalMapper = new LocalMapping(mpMap, mSensor==MONOCULAR);
    mptLocalMapping = new thread(&ORB_SLAM2::LocalMapping::Run,mpLocalMapper);

初始化三个线程中Local Mapping线程;

    //Initialize the Loop Closing thread and launch
    // 初始化闭环线程
    mpLoopCloser = new LoopClosing(mpMap, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR);
    mptLoopClosing = new thread(&ORB_SLAM2::LoopClosing::Run, mpLoopCloser);

初始化三个线程中loop closing线程;

    //Set pointers between threads
    // 三个线程间存在联系
    mpTracker->SetLocalMapper(mpLocalMapper);
    mpTracker->SetLoopClosing(mpLoopCloser);

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

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

    currently_localizing_only_ = false;
}

由于三个线程需要存在联系,没有采用的全局同一变量进行共享,而是将每个线程都可访问另外两个其他线程;

TrackMonocular 单目相机入口

void System::TrackMonocular(const cv::Mat &im, const double ×tamp)

单目入口参数仅有一个mat图像入口和对应时间戳;

        // 是否更改纯定位模式
        if(mbActivateLocalizationMode)
        {
            mpLocalMapper->RequestStop();

            // Wait until Local Mapping has effectively stopped
            while(!mpLocalMapper->isStopped())
            {
                std::this_thread::sleep_for(std::chrono::microseconds(1000));
            }

            mpTracker->InformOnlyTracking(true);
            mbActivateLocalizationMode = false;
        }
        // 取消重定位
        if(mbDeactivateLocalizationMode)
        {
            mpTracker->InformOnlyTracking(false);
            mpLocalMapper->Release();
            mbDeactivateLocalizationMode = false;
        }

orbslam支持纯定位模式,当已有图时(可以外部读入的地图,也可是刚刚新建的地图),可不再更新地图,仅输出定位。在slam过程中支持动态模式切换;

    if(mbReset)
    {
        mpTracker->Reset();
        mbReset = false;
    }

支持slam过程中重新reset整个SLAM,即重新开始slam。

    // 开始slam,传入图像,输出位姿
    cv::Mat Tcw = mpTracker->GrabImageMonocular(im,timestamp);

开启单目跟踪功能;

其他类型摄像头入口

双目摄像机入口

void System::TrackStereo(const cv::Mat &imLeft, const cv::Mat &imRight, const double ×tamp)

rgbd 摄像机入口

void System::TrackRGBD(const cv::Mat &im, const cv::Mat &depthmap, const double ×tamp)

三种摄像机slam入口初始化基本一致,主要区别在图片类型不一样。

你可能感兴趣的:(slam,自动驾驶,人工智能,机器学习)