---
# System prepended metadata

title: System.cpp

---

# 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;
```