很不幸Cartographer是個很複雜的系統,各個參數之間可能互相影響,這份指南試圖通過幾個實際的例子來一些解釋原則性的方法。
自帶工具包
[待使用] cartographer自帶的一些工具包可以幫助你來測量局部SLAM的品質,這部分可以參考下面的文檔
Cartographer Read the Docs Evaluation site
使用這些工具前假設你已經知道如何将SLAM儲存到.pbstream中,你可以調用assets_writer來儲存SLAM結果到.pbstream格式。
例子:調試局部SLAM(local SLAM)
我們測試的資料包是b2-2016-04-27-12-31-41.bag,可以點選評論aba4575和評論99c23b6檢視一些細節。
在經過德意志博物館的一個斜坡時(這違背了雷射2D平整地面的假設),我們發現SLAM運作時的定位有一些滑動(位移),這明顯SLAM前端遇到了問題,究其原因是我們太過于相信雷射比對的結果而忽略了其他傳感器的作用。我們的目的就是改善這個問題。
我們隻看這個發生問題的子圖,因為這個錯誤包含在這個子圖中,我們也看到随着時間的運作,全局SLAM發現了一些異常也嘗試修正它,但是一但這個子圖包含了錯誤則永遠包含在子圖中,全局SLAM無法糾正。
因為這個問題發生在子圖中,是以這是一個局部SLAM問題,是以我們關掉全局SLAM,防止它幹擾我們的調試,關閉方法如下:
POSE_GRAPH.optimize_every_n_nodes = 0
矯正合适大小的子圖
通過這個參數,之前提到過,檢視每個獨立的子圖内部沒有太大的累計誤差時,則可确定,不宜過大或過小。
TRAJECTORY_BUILDER_2D.submaps.num_range_data
調試CeresScanMatcher
在我們的例子中,雷射比對可以任意的前後左右進行比對不會影響得分,我們想增加這樣一種政策,就是當比對偏離初始值時,要付出更多的代價,離初始值越遠,代價越大,就是如果要接受更遠距離的比對結果就需要更高比對得分。可以通過這兩個參數調試
TRAJECTORY_BUILDER_2D.ceres_scan_matcher.translation_weight
TRAJECTORY_BUILDER_2D.ceres_scan_matcher.rotation_weight
為了明顯的看到這種懲罰效果可以設定的權重大一些,如下:
TRAJECTORY_BUILDER_2D.ceres_scan_matcher.translation_weight = 1e3
實驗結果顯示1e3高昂代價使得與深度傳感器探測的及其不符,明顯發生斷裂,當translation_weight為2e2時才能顯示出較好的效果,
這裡掃描比對使用旋轉仍然帶來了一些幹擾,我們這裡設定rotation_weight為4e2,可以看出一個合理的結果。
驗證
為了驗證我們沒有過度調整這個特定的問題,我們把調試的結果用其他資料集驗證一下,在這個例子(translation_weight = 2e2、rotation_weight = 4e2)中,驗證的資料包發生了滑動(位移),是以我們再降低translation_weight為1e2,這樣設定可能會糟糕但是沒有發生滑動(位移),權重是個無機關的量,在使用之前會進行歸一化,因為它隻有相對的概念。
[為什麼?] 那如何解決長廊問題?可以通過調節這裡的translation_weight、rotation_weight來解決嗎?答案是不能的,為什麼不能?因為translation_weight、rotation_weight隻能降低誤比對的機率,對于長廊這種毫無特征的環境,純雷射通過比對是解決不了的,需要加入其他資訊,如在地上或牆上添加二維碼。
特殊案例
上面的預設配置和調試步驟是為了得到高品質的地圖,下面我們的案例是在我們已經得到高品質地圖後,需要進一步考慮的其他案例。
低延時
低延遲意味着我們在接收到傳感器輸入後不久(通常在一秒鐘内)獲得優化的姿态,并且全局優化線程裡沒有任務積壓。比如機器人實時定位就需要低延時,作為前端局部SLAM直接影響延遲。全局SLAM建立了一系列背景任務, 當全局SLAM無法跟上隊列時,漂移(錯誤位姿)可能會無限期累積,是以應将全局SLAM調整為實時工作。
有很多參數可以調節不同元件的速度,我們從建議的、簡單的、到更深層的參數來分别介紹,我們建議一次隻更改一種參數,更多參數的介紹在Cartographer documentation。
為了調試全局SLAM來實作低延時,我們降低計算量直到實作輸出能保持一緻地跟上輸入,在這之後我們我們不再降低,因為我們盡可能的保持輸出地圖品質,為了降低全局SLAM延時,我們可以:
- 降低 optimize_every_n_nodes
- 增大 MAP_BUILDER.num_background_threads至可利用的邏輯線程數
- 降低 global_sampling_ratio [帶解決問題]
- 降低 constraint_builder.sampling_ratio
- 增加 constraint_builder.min_score
- 對于自适應體素濾波(采樣),降低 .min_num_points, .max_range,增加.max_length
- 增加 voxel_filter_size、submaps.resolution,降低submaps.num_range_data
- 降低搜尋視窗,.linear_xy_search_window, .linear_z_search_window, .angular_search_window。
- 增加 global_constraint_search_after_n_seconds
- 降低 max_num_iterations
對于降低局部SLAM的延時,我們可以:
- 增加 voxel_filter_size
- 增加 submaps.resolution
- 對于自适應體素濾波(采樣),降低 .min_num_points, .max_range,增加.max_length
- 降低 max_range(特别是資料有噪聲)
- 降低 submaps.num_range_data
注意:大的網格的副作用是會稍微增加比對的得分,是以比對門檻值也要相應的增加。
已知地圖的純定位
純定位不同于建圖,第一點,我們希望全局SLAM和局部SLAM都能保持低延時,第二點,全局SLAM通常要計算已知地圖和建立地圖之間大量的内部限制。
為了調試純定位,我們首先會打開TRAJECTORY_BUILDER.pure_localization = true同時大幅度降低POSE_GRAPH.optimize_every_n_nodes數量以接收實頻資料。當這樣設定後,全局SLAM通常會變得很慢,是以下一步我們大幅度降低global_sampling_ratio和constraint_builder.sampling_ratio來降低要計算的限制量。然後,如上所述,為降低延遲,我們調整直到系統能夠可靠地實時運作。
運作純定位時,submaps.resolution的分辨率要和加載地圖的分辨率一緻,我們沒有對分辨率未對應的情況進行驗證,可能不能很好的工作。
全局優化與裡程計(齒輪編碼器)[待解決問題]
如果一個獨立的裡程計資料源被作為輸入傳入局部SLAM(use_odometry = true),我們同樣可以用這個資料源來調試全局SALM。
總的來說我們有4個獨立的權重可以用來調試局部SLAM和裡程計的全局優化
POSE_GRAPH.optimization_problem.local_slam_pose_translation_weight
POSE_GRAPH.optimization_problem.local_slam_pose_rotation_weight
POSE_GRAPH.optimization_problem.odometry_translation_weight
POSE_GRAPH.optimization_problem.odometry_rotation_weight
我們可以設定這些權重依賴于我們對局部SLAM和裡程計的信任程度。預設的,裡程計被權重到全局優化中,這與局部SLAM相似。但是,齒輪編碼器通常在旋轉方面具有很高的不确定性。 在這種情況下,旋轉權重甚至可以減小到零。
還有問題?
可以在Github上面提問,但是請按照正确的請求格式進行,務必把你用的配置檔案、資料離線包發給我們。
當然也可以在這篇CSDN下面提問,很高興解答您的問題。
[待解決問題] 是我自己本身還有些不太清楚的地方,待明白後再來更新。不影響您的閱讀。