# System.cpp
### System::System()
在[Main()](#Main())中引用
#### 函式流程:
1. 加載ORB詞袋,構建Vocabulary,以及關鍵幀數據集庫。
2. 初始化追踪主線程,但是未運行。
3. 初始化局部建圖,回環閉合及創建線程。
4. 創建可視化線程,並且與追踪主線程關聯起來。
#### 流程詳解
1. 加載ORB詞袋,構建Vocabulary,以及關鍵幀數據集庫。
```
載入詞袋
cv::FileStorage fsSettings(strSettingsFile.c_str(), cv::FileStorage::READ);
構建詞袋
mpVocabulary = new ORBVocabulary();
創建關鍵幀數據庫,主要保存ORB描述子倒排索引(即根據描述子查找擁有該描述子的關鍵幀)
mpKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary);
用pangolin創建地圖
mpMap = new Map();
mpFrameDrawer = new FrameDrawer(mpMap);
mpMapDrawer = new MapDrawer(mpMap, strSettingsFile);
```
2. 初始化追踪主線程,但是未運行。
```
創建Tracking主線程
mpTracker = new Tracking(this, mpVocabulary, mpFrameDrawer, mpMapDrawer, mpMap, mpKeyFrameDatabase, strSettingsFile, mSensor);
```
跳到[Tracking::Tracking](#Tracking::Tracking)
3. 初始化局部建圖,回環閉合及創建線程。
```
創建LocalMapping線程及mpLocalMapper
mpLocalMapper = new LocalMapping(mpMap, mSensor==MONOCULAR);
mptLocalMapping = new thread(&ORB_SLAM2::LocalMapping::Run,mpLocalMapper);
創建LoopClosing線程及mpLoopCloser
mpLoopCloser = new LoopClosing(mpMap, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR);
//创建回环检测线程
mptLoopClosing = new thread(&ORB_SLAM2::LoopClosing::Run, mpLoopCloser);
```
new LocalMapping(): 跳到[LocalMapping::LocalMapping()](#LocalMapping::LocalMapping())
ORB_SLAM2::LocalMapping::Run : 跳到[LocalMapping::Run()](#LocalMapping::Run())
4. 創建可視化線程,並且與追踪主線程關聯起來。
```
//創建可視化線程
if(bUseViewer) //當要可視化視窗時
{
mpViewer = new Viewer(this, mpFrameDrawer,mpMapDrawer,mpTracker,strSettingsFile);
mptViewer = new thread(&Viewer::Run, mpViewer);
mpTracker->SetViewer(mpViewer);
}
// 設置線程間溝通
mpTracker->SetLocalMapper(mpLocalMapper);
mpTracker->SetLoopClosing(mpLoopCloser);
mpLocalMapper->SetTracker(mpTracker);
mpLocalMapper->SetLoopCloser(mpLoopCloser);
mpLoopCloser->SetTracker(mpTracker);
mpLoopCloser->SetLocalMapper(mpLocalMapper);
```
new Viewer: 跳到[Viewer::Viewer()](#Viewer::Viewer())
Viewer::Run: 跳到[Viewer::Run()](#Viewer::Run())
### System::TrackMonocular()
開始追蹤
#### 函式流程:
1. 判斷模式是否為單目
2. 線程模式切換
3. 檢查tracking線程是否要重啟
4. 獲取相機位置的估計結果
5. 更新狀態
#### 流程詳解
1. 判斷模式是否為單目
```
if(mSensor!=MONOCULAR)
{
cerr << "ERROR: you called TrackMonocular but input sensor was not set to Monocular." << endl;
exit(-1);
}
```
2. 線程切換
```
{
//防止 mbActivateLocalizationMode 與 mbDeactivateLocalizationMode 混亂
unique_lock<mutex> lock(mMutexMode);
//mbActivateLocalizationMode為true,會關閉local mapping線程
if(mbActivateLocalizationMode)
{
mpLocalMapper->RequestStop();
// Wait until Local Mapping has effectively stopped
while(!mpLocalMapper->isStopped())
{
//usleep(1000);
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
// local mapping線程關閉後,只做tracking
mpTracker->InformOnlyTracking(true);
mbActivateLocalizationMode = false;// 防止重複執行
}
//mbDeactivateLocalizationMode為true,local mapping線程會被釋放,關鍵幀從局部地圖中刪除
if(mbDeactivateLocalizationMode)
{
mpTracker->InformOnlyTracking(false);
mpLocalMapper->Release();
mbDeactivateLocalizationMode = false;// 防止重複執行
}
}
```
3. 檢查tracking線程是否要重啟
```
{
unique_lock<mutex> lock(mMutexReset);
if(mbReset)
{
mpTracker->Reset();
mbReset = false;
}
}
```
4. 獲取相機位置的估計結果
```
cv::Mat Tcw = mpTracker->GrabImageMonocular(im,timestamp);
```
跳到 [Tracking::GrabImageMonocular](#Tracking::GrabImageMonocular) 執行
5. 更新狀態
```
unique_lock<mutex> lock2(mMutexState);
mTrackingState = mpTracker->mState;
mTrackedMapPoints = mpTracker->mCurrentFrame.mvpMapPoints;
mTrackedKeyPointsUn = mpTracker->mCurrentFrame.mvKeysUn;
```