orb_slam整體編程思路及代碼解析
都說,看別人寫的代碼就是根據別人的排泄物,來分析他的早餐是什麼,這個工作既困難由噁心。
這裡不貼詳細的代碼注釋,只是根據個人的理解,揣測了一番大佬們的心思,盡量做到詳細,難免有錯誤,歡迎交流。
PAGE1:mono_?_ccp
這個page中主要完成的是LoadImages,創建System(SLAM),配合時間戳循環地把圖像傳給mpTracker,最後統計跟蹤所花費的時間的中間值和平均值。
LoadImages的目的主要是把資料庫進行解析,變成了圖像向量,和時間戳向量。
SLAM.TrackMonocular(im,tframe)在傳送圖像時,在這個函數中,完成跟蹤,得出位姿,我們注意到用chrono來計時跟蹤的時間,並計算出兩個處理的時間差,如果傳送時間小的話則usleep等待下個圖像捕獲,當然了,如果跟蹤的時間長的話,那麼就不等待了,直接獲取下一幀。這部分要注意的是數據集的時間戳是以秒為單位的,而usleep的單位是微秒,所以要乘以10^6。
當把所有的圖像都傳送進去後,就終止所有的線程。並把相機的軌跡保存成文件格式。
PAGE2:System.ccp
在這裡完成對整個項目的資源配置
FUCTION1:System
System構造函數完成了對整個項目的資源配置,包括
1.讀入配置文件,
2.讀取orb詞袋(用於定位和特徵匹配)(判斷傳入的參數中有沒有".txt"或者".bin",這是對應的orb字典的兩種格式),
3.創建關鍵幀資料庫(用於定位和閉環檢測)
4.創建地圖對象(用於儲存KeyFrames 和 MapPoints的指針)
5.創建用於Viewer的mpFrameDrawer(圖像窗口)和mpMapDrawer(軌跡窗口)對象
6.新建Tracking對象,他是主線程,即調用該構造函數的線程為主線程
注意,當創建的線程載入的是類方法時,我們需要同時傳遞類對象
7.新建mpLocalMapper對象(通過BA來管理本地地圖),新建線程,線程運行ORB_SLAM2::LocalMapping::Run函數,
8.新建LoopClosing對象(尋找閉環,當找到閉環時優化位姿,並執行全局BA優化),新建線程,線程運行ORB_SLAM2::LoopClosing::Run函數,
9.新建Viewer對象(做圖),新建線程,線程運行Viewer::Run函數,
10.指定各個線程中的指針關係,說明各個線程的所訪問的數據之間的關係
(mSensor、mpVocabulary、mpKeyFrameDatabase、mpMap、mpTracker、mpLocalMapper、mpLoopCloser、mpViewer)(mpFrameDrawer、mpMapDrawer)
FUCTION2:TrackMonocular
該函數是system.cc里的,所以這是在主線程里的函數,相當於跟蹤線程的入口。這個函數里有3個互斥量控制著三個過程:
1.首先利用模式狀態量mbActivateLocalizationMode和mbDeactivateLocalizationMode來控制是否執行局部地圖功能,局部地圖關閉以後,只進行追蹤的線程,只計算相機的位姿,沒有對局部地圖進行更新,設置mbOnlyTracking為真,這裡的互斥量是mMutexMode;
2.用互斥量mMutexReset來保護對重置跟蹤線程的操作;接下來的部分才是最重要的部分,獲取數據,對各個線程的數據進行更新, 對地圖重新進行計算;
3.用互斥量mMutexState來保護更新跟蹤中的狀態量的過程,其中包括mTrackingState,mTrackedMapPoints,mTrackedKeyPointsUn三個狀態量,並返回位姿。
FUCTION3:SaveKeyFrameTrajectoryTUM
這個函數用於保存地圖中相機的姿態,其中時間戳保存小數點後六位,位姿為小數點後七位的精確度。
這個函數就相當於完成了跟蹤的視覺里程計部分,主線程就結束了。


※MySQL的壓測工具
※資料庫學習計劃——learning plan
TAG:程序員小新人學習 |