目录
一.前言
二.代码分析
2.1 引用头文件
2.2 静态成员变量
2.3 System函数
一.前言
这部分代码介绍引用头文件以及System类的函数定义文件。
二.代码分析
2.1 引用头文件
#include "System.h"
#include "Converter.h"
#include <thread>
#include <pangolin/pangolin.h>
#include <iomanip>
#include <openssl/md5.h>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/string.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
-
#include "System.h"
- 这是一个自定义头文件,可能包含了与系统相关的功能或类定义。
-
#include "Converter.h"
- 这也是一个自定义头文件,可能包含了转换功能或类定义。
-
#include <thread>
- 这是C++标准库中的线程头文件,提供了多线程编程的支持。
-
#include <pangolin/pangolin.h>
- Pangolin 是一个轻量级的 C++ 库,用于3D可视化和用户界面。此头文件是其主要接口。
-
#include <iomanip>
- 这是C++标准库中的一个输入输出流操作的头文件,提供了格式化输入输出的功能。
-
#include <openssl/md5.h>
- OpenSSL 是一个强大的安全套接字层密码库,此头文件提供了MD5哈希算法的支持。
-
#include <boost/serialization/base_object.hpp>
- Boost 是一个广泛使用的C++库,提供了许多实用的功能。这个头文件与序列化相关,用于支持对象的序列化。
-
#include <boost/serialization/string.hpp>
- 这是Boost库中关于字符串序列化的头文件。
-
#include <boost/archive/text_iarchive.hpp>、#include <boost/archive/text_oarchive.hpp>
- 这两个头文件与Boost的文本存档相关,分别用于从文本文件中反序列化和序列化对象。
-
#include <boost/archive/binary_iarchive.hpp>、#include <boost/archive/binary_oarchive.hpp>
- 这两个头文件与Boost的二进制存档相关,分别用于从二进制文件中反序列化和序列化对象。
- #include <boost/archive/xml_iarchive.hpp>、#include <boost/archive/xml_oarchive.hpp>
- 这两个头文件与Boost的XML存档相关,分别用于从XML文件中反序列化和序列化对象。
2.2 静态成员变量
Verbose::eLevel Verbose::th = Verbose::VERBOSITY_NORMAL;
这行代码的意思是,声明一个类型为Verbose::eLevel
的静态成员变量th
,并将其初始化为Verbose::VERBOSITY_NORMAL
。这通常是在类的定义外部进行的初始化,通常在源文件(.cpp文件)中而不是头文件(.h或.hpp文件)中。
这样的设置通常用于控制程序的日志记录或输出详细程度。例如,如果程序中有多个详细级别(如“简洁”、“正常”和“详细”),则可以通过更改th
变量的值来轻松地在这些级别之间进行切换。
2.3 System函数
System::System(const string &strVocFile, const string &strSettingsFile, const eSensor sensor,const bool bUseViewer, const int initFr, const string &strSequence):mSensor(sensor), mpViewer(static_cast<Viewer*>(NULL)), mbReset(false), mbResetActiveMap(false),mbActivateLocalizationMode(false), mbDeactivateLocalizationMode(false), mbShutDown(false)
{// Output welcome messagecout << endl <<"ORB-SLAM3 Copyright (C) 2017-2020 Carlos Campos, Richard Elvira, Juan J. Gómez, José M.M. Montiel and Juan D. Tardós, University of Zaragoza." << endl <<"ORB-SLAM2 Copyright (C) 2014-2016 Raúl Mur-Artal, José M.M. Montiel and Juan D. Tardós, University of Zaragoza." << endl <<"This program comes with ABSOLUTELY NO WARRANTY;" << endl <<"This is free software, and you are welcome to redistribute it" << endl <<"under certain conditions. See LICENSE.txt." << endl << endl;cout << "Input sensor was set to: ";if(mSensor==MONOCULAR)cout << "Monocular" << endl;else if(mSensor==STEREO)cout << "Stereo" << endl;else if(mSensor==RGBD)cout << "RGB-D" << endl;else if(mSensor==IMU_MONOCULAR)cout << "Monocular-Inertial" << endl;else if(mSensor==IMU_STEREO)cout << "Stereo-Inertial" << endl;else if(mSensor==IMU_RGBD)cout << "RGB-D-Inertial" << endl;//Check settings filecv::FileStorage fsSettings(strSettingsFile.c_str(), cv::FileStorage::READ);if(!fsSettings.isOpened()){cerr << "Failed to open settings file at: " << strSettingsFile << endl;exit(-1);}cv::FileNode node = fsSettings["File.version"];if(!node.empty() && node.isString() && node.string() == "1.0"){settings_ = new Settings(strSettingsFile,mSensor);mStrLoadAtlasFromFile = settings_->atlasLoadFile();mStrSaveAtlasToFile = settings_->atlasSaveFile();cout << (*settings_) << endl;}else{settings_ = nullptr;cv::FileNode node = fsSettings["System.LoadAtlasFromFile"];if(!node.empty() && node.isString()){mStrLoadAtlasFromFile = (string)node;}node = fsSettings["System.SaveAtlasToFile"];if(!node.empty() && node.isString()){mStrSaveAtlasToFile = (string)node;}}node = fsSettings["loopClosing"];bool activeLC = true;if(!node.empty()){activeLC = static_cast<int>(fsSettings["loopClosing"]) != 0;}mStrVocabularyFilePath = strVocFile;bool loadedAtlas = false;if(mStrLoadAtlasFromFile.empty()){//Load ORB Vocabularycout << 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;//Create KeyFrame DatabasempKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary);//Create the Atlascout << "Initialization of Atlas from scratch " << endl;mpAtlas = new Atlas(0);}else{//Load ORB Vocabularycout << 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;//Create KeyFrame DatabasempKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary);cout << "Load File" << endl;// Load the file with an earlier session//clock_t start = clock();cout << "Initialization of Atlas from file: " << mStrLoadAtlasFromFile << endl;bool isRead = LoadAtlas(FileType::BINARY_FILE);if(!isRead){cout << "Error to load the file, please try with other session file or vocabulary file" << endl;exit(-1);}//mpKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary);//cout << "KF in DB: " << mpKeyFrameDatabase->mnNumKFs << "; words: " << mpKeyFrameDatabase->mnNumWords << endl;loadedAtlas = true;mpAtlas->CreateNewMap();//clock_t timeElapsed = clock() - start;//unsigned msElapsed = timeElapsed / (CLOCKS_PER_SEC / 1000);//cout << "Binary file read in " << msElapsed << " ms" << endl;//usleep(10*1000*1000);}if (mSensor==IMU_STEREO || mSensor==IMU_MONOCULAR || mSensor==IMU_RGBD)mpAtlas->SetInertialSensor();//Create Drawers. These are used by the ViewermpFrameDrawer = 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 launchmpLocalMapper = 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();elsempLocalMapper->mThFarPoints = fsSettings["thFarPoints"];if(mpLocalMapper->mThFarPoints!=0){cout << "Discard points further than " << mpLocalMapper->mThFarPoints << " m from current camera" << endl;mpLocalMapper->mbFarPoints = true;}elsempLocalMapper->mbFarPoints = false;//Initialize the Loop Closing thread and launch// mSensor!=MONOCULAR && mSensor!=IMU_MONOCULARmpLoopCloser = new LoopClosing(mpAtlas, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR, activeLC); // mSensor!=MONOCULAR);mptLoopClosing = new thread(&ORB_SLAM3::LoopClosing::Run, mpLoopCloser);//Set pointers between threadsmpTracker->SetLocalMapper(mpLocalMapper);mpTracker->SetLoopClosing(mpLoopCloser);mpLocalMapper->SetTracker(mpTracker);mpLocalMapper->SetLoopCloser(mpLoopCloser);mpLoopCloser->SetTracker(mpTracker);mpLoopCloser->SetLocalMapper(mpLocalMapper);//usleep(10*1000*1000);//Initialize the Viewer thread and launchif(bUseViewer)//if(false) // TODO{mpViewer = new Viewer(this, mpFrameDrawer,mpMapDrawer,mpTracker,strSettingsFile,settings_);mptViewer = new thread(&Viewer::Run, mpViewer);mpTracker->SetViewer(mpViewer);mpLoopCloser->mpViewer = mpViewer;mpViewer->both = mpFrameDrawer->both;}// Fix verbosityVerbose::SetTh(Verbose::VERBOSITY_QUIET);}
这段代码是一个系统类的构造函数,它主要用于初始化ORB-SLAM3(一个用于视觉SLAM的开源库)的实例。这个构造函数接收一系列参数,并根据这些参数配置系统。
以下是对代码主要部分的详细解释:
-
参数解释:
const string &strVocFile
:ORB词汇表的文件路径,用于特征匹配。const string &strSettingsFile
:设置文件的路径,包含系统配置。const eSensor sensor
:传感器的类型(如单目、双目、RGB-D等)。const bool bUseViewer
:是否使用查看器。const int initFr
:初始化帧数(在这段代码中未使用)。const string &strSequence
:序列的文件路径(在这段代码中未使用)。
-
成员变量初始化:初始化一系列成员变量,如传感器类型、查看器指针、各种标志等。
-
输出欢迎信息:输出ORB-SLAM3的版权和许可信息。
-
检查传感器类型:根据传入的传感器类型,输出相应的信息。
-
加载设置文件:使用OpenCV的
FileStorage
类加载设置文件,并检查文件是否可以打开。然后,检查文件版本,并根据版本加载相应的设置。 -
加载或创建地图:根据是否提供了加载地图的文件路径,决定是从文件中加载地图还是从零开始创建地图。
-
加载ORB词汇表:从给定的文件路径加载ORB词汇表。如果加载失败,则输出错误信息并退出程序。
-
创建关键帧数据库和地图集:创建关键帧数据库和地图集对象。如果提供了加载文件的路径并且成功加载了地图,那么就从加载的文件中恢复这些信息;否则,创建一个新的地图集。
-
加载或初始化地图集:如果提供了加载文件并且成功加载了地图集,就使用加载的数据初始化地图集;否则,创建一个新的地图集并从零开始初始化。
-
错误处理:在加载地图集或词汇表时,如果遇到错误,程序将输出错误信息并退出。
总的来说,这个构造函数的主要目的是根据提供的参数和设置文件来初始化ORB-SLAM3系统,包括加载或创建地图集、加载ORB词汇表、设置传感器类型等。它是整个系统运行的起点,为后续的视觉SLAM任务(如定位、建图等)做好准备。
代码的最后对多线程,传感器的数据进行了初始化。
// 如果传感器是IMU_STEREO、IMU_MONOCULAR或IMU_RGBD,则为Atlas设置惯性传感器
if (mSensor==IMU_STEREO || mSensor==IMU_MONOCULAR || mSensor==IMU_RGBD) mpAtlas->SetInertialSensor(); // 创建绘制器。这些由查看器使用
mpFrameDrawer = new FrameDrawer(mpAtlas); // 创建一个帧绘制器
mpMapDrawer = new MapDrawer(mpAtlas, strSettingsFile, settings_); // 创建一个地图绘制器 // 初始化跟踪线程
//(它将在调用此构造函数的主执行线程中运行)
cout << "Seq. Name: " << strSequence << endl;
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);
// ... 一些设置和条件检查 ... // 初始化闭环线程并启动
// mSensor!=MONOCULAR && mSensor!=IMU_MONOCULAR
mpLoopCloser = new LoopClosing(mpAtlas, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR, activeLC); // mSensor!=MONOCULAR);
mptLoopClosing = new thread(&ORB_SLAM3::LoopClosing::Run, mpLoopCloser); // 在线程之间设置指针,以便它们可以相互通信和访问
mpTracker->SetLocalMapper(mpLocalMapper);
mpTracker->SetLoopClosing(mpLoopCloser);
mpLocalMapper->SetTracker(mpTracker);
mpLocalMapper->SetLoopCloser(mpLoopCloser);
mpLoopCloser->SetTracker(mpTracker);
mpLoopCloser->SetLocalMapper(mpLocalMapper); // 如果使用查看器,则初始化查看器线程并启动
if(bUseViewer)
{ mpViewer = new Viewer(this, mpFrameDrawer,mpMapDrawer,mpTracker,strSettingsFile,settings_); mptViewer = new thread(&Viewer::Run, mpViewer); // ... 设置查看器与其他线程的关联 ...
} // 设置详细级别为“安静”,即不输出太多信息
Verbose::SetTh(Verbose::VERBOSITY_QUIET);