orb-slam3主要由跟踪(Tracking)、局部建图(LocalMapping)、回环检测(loopclosing)三个线程组成。
先看mono_tum的主函数部分,创建了一个system类的对象SLAM,system类是初始化和控制整个slam系统的类。
ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::MONOCULAR,true);
查看system类的构造函数,system类在构造的时候传建了一个setting对象,setting类配置系统的各种参数
if(!node.empty() && node.isString() && node.string() == "1.0"){
settings_ = new Settings(strSettingsFile,mSensor);
mStrLoadAtlasFromFile = settings_->atlasLoadFile();
mStrSaveAtlasToFile = settings_->atlasSaveFile();
cout << (*settings_) << endl;
}
在来看setting类的构造函数,读取的相机参数和ORB特征提取器的行为
Settings::Settings(const std::string &configFile, const int& sensor) :
bNeedToUndistort_(false), bNeedToRectify_(false), bNeedToResize1_(false), bNeedToResize2_(false) {
sensor_ = sensor;
//Open settings file
cv::FileStorage fSettings(configFile, cv::FileStorage::READ);
if (!fSettings.isOpened()) {
cerr << "[ERROR]: could not open configuration file at: " << configFile << endl;
cerr << "Aborting..." << endl;
exit(-1);
}
else{
cout << "Loading settings from " << configFile << endl;
}
//Read first camera 根据不同的相机模型导入参数
readCamera1(fSettings);
cout << "\t-Loaded camera 1" << endl;
//Read second camera if stereo (not rectified)
if(sensor_ == System::STEREO || sensor_ == System::IMU_STEREO){
readCamera2(fSettings);
cout << "\t-Loaded camera 2" << endl;
}
//Read image info 更新参数,如imageScale
readImageInfo(fSettings);
cout << "\t-Loaded image info" << endl;
if(sensor_ == System::IMU_MONOCULAR || sensor_ == System::IMU_STEREO || sensor_ == System::IMU_RGBD){
readIMU(fSettings);
cout << "\t-Loaded IMU calibration" << endl;
}
if(sensor_ == System::RGBD || sensor_ == System::IMU_RGBD){
readRGBD(fSettings);
cout << "\t-Loaded RGB-D calibration" << endl;
}
// YAML 配置文件中的参数用于设置 ORB 特征提取器的行为,尺度金字塔中相邻层之间的缩放因子、层数,最多提取的特征点数、Fast角点检测阈值
readORB(fSettings);
cout << "\t-Loaded ORB settings" << endl;
//读取可视化相关参数
readViewer(fSettings);
cout << "\t-Loaded viewer settings" << endl;
//读取与加载和保存 Atlas(地图数据)相关的参数
readLoadAndSave(fSettings);
cout << "\t-Loaded Atlas settings" << endl;
readOtherParameters(fSettings);
cout << "\t-Loaded misc parameters" << endl;
if(bNeedToRectify_){
precomputeRectificationMaps();
cout << "\t-Computed rectification maps" << endl;
}
cout << "----------------------------------" << endl;
}
将配置文件传入setting类成为内参后,定义了tracking对象,并开了localmapping和loopclosing两个新线程
mpFrameDrawer = new FrameDrawer(mpAtlas);
mpMapDrawer = new MapDrawer(mpAtlas, strSettingsFile, settings_);
//Initialize the Tracking thread
//(it will live in the main thread of execution, the one that called this constructor)
cout << "Seq. Name: " << strSequence << endl;
mpTracker = new Tracking(this, mpVocabulary, mpFrameDrawer, mpMapDrawer,
mpAtlas, mpKeyFrameDatabase, strSettingsFile, mSensor, settings_, strSequence);
//Initialize the Local Mapping thread and launch
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);
mpLocalMapper->mInitFr = initFr;
if(settings_)
mpLocalMapper->mThFarPoints = settings_->thFarPoints();
else
mpLocalMapper->mThFarPoints = fsSettings["thFarPoints"];
if(mpLocalMapper->mThFarPoints!=0)
{
cout << "Discard points further than " << mpLocalMapper->mThFarPoints << " m from current camera" << endl;
mpLocalMapper->mbFarPoints = true;
}
else
mpLocalMapper->mbFarPoints = false;
//Initialize the Loop Closing thread and launch
// mSensor!=MONOCULAR && mSensor!=IMU_MONOCULAR
mpLoopCloser = new LoopClosing(mpAtlas, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR, activeLC); // mSensor!=MONOCULAR);
mptLoopClosing = new thread(&ORB_SLAM3::LoopClosing::Run, mpLoopCloser);
//Set pointers between threads
mpTracker->SetLocalMapper(mpLocalMapper);
mpTracker->SetLoopClosing(mpLoopCloser);
mpLocalMapper->SetTracker(mpTracker);
mpLocalMapper->SetLoopCloser(mpLoopCloser);
mpLoopCloser->SetTracker(mpTracker);
mpLoopCloser->SetLocalMapper(mpLocalMapper);