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