一點(diǎn)Cartographer的調(diào)參心得:傳感器篇
Cartographer 的參數(shù)調(diào)整對(duì)建圖和定位都有很大的影響,怎么調(diào)參在網(wǎng)上相關(guān)的資料也很多,官方也有文檔介紹,不過(guò)我覺(jué)得都不夠?qū)嵱?,因?yàn)榇蠖喽紱](méi)有介紹調(diào)整這個(gè)參數(shù)需要出于什么而考慮,調(diào)整后又會(huì)產(chǎn)生什么影響。
最近無(wú)聊就寫寫文章記錄一下我在工作中根據(jù)實(shí)際場(chǎng)景調(diào)參的過(guò)程,同時(shí)也幫助一下有需要的小伙伴們。
參數(shù)文件分別散落在 cartographer 和 cartographer_ros 兩個(gè)項(xiàng)目里,小伙伴們可以自己搜索一下源碼找到對(duì)應(yīng)的位置。
Cartographer 接收的傳感器數(shù)據(jù)主要就三種:激光雷達(dá)、IMU 和里程計(jì)。Cartographer 是以激光雷達(dá)是作為主導(dǎo)的傳感器,另外兩個(gè)都只是輔助。
實(shí)際使用中,最好三種傳感器一起上,IMU 和里程計(jì)少了任意一個(gè)建圖效果都會(huì)不咋地,這是由于 Cartographer 對(duì)多傳感器融合的實(shí)現(xiàn)太過(guò)簡(jiǎn)單粗暴導(dǎo)致的。
這三種傳感器的數(shù)據(jù)在前端和后端中都有著不同的作用,我只用過(guò)carto的2d slam,所以我也就只介紹2d的情況:
前端部分
激光雷達(dá)
????點(diǎn)云直接用于生成?Submap,第一幀點(diǎn)云初始化第一幅 Submap,后續(xù)點(diǎn)云就和當(dāng)前生成中的 Submap 進(jìn)行 scan-to-map 的匹配,用于估算每一幀點(diǎn)云的位移。
????匹配的位移也會(huì)用于下一幀點(diǎn)云匹配前的位姿推算,carto 會(huì)根據(jù)兩次匹配位姿的距離和時(shí)間差估算角速度和線速度,用于計(jì)算下一幀點(diǎn)云可能的位置,新來(lái)的點(diǎn)云就直接在預(yù)估位置附近做匹配。
IMU
????參與下一個(gè)時(shí)間點(diǎn)的位姿估算,當(dāng)給 carto 輸入 IMU 數(shù)據(jù)后,點(diǎn)云匹配前將會(huì)用IMU的角速度和匹配位姿的線速度來(lái)估算下一幀點(diǎn)云可能的位置。
里程計(jì)
????也是參與下一個(gè)時(shí)間點(diǎn)的位姿估算,當(dāng)提供里程計(jì)數(shù)據(jù)后,不再使用匹配位姿來(lái)估算線速度,而是直接用里程計(jì)的線速度和IMU的角速度來(lái)估算下一幀點(diǎn)云可能的位置。
后端部分
激光雷達(dá)
????激光雷達(dá)在后端的作用主要是兩個(gè),一個(gè)是 scan-to-map 匹配做回環(huán)檢測(cè),一個(gè)是前端產(chǎn)生的匹配位姿之間的相對(duì)位姿作為約束參與后端的全局優(yōu)化,優(yōu)化的目的是為了盡可能消除累計(jì)誤差。
IMU
????2d slam 時(shí) IMU 數(shù)據(jù)在后端沒(méi)有任何戲份。
里程計(jì)
????使用倆幀里程計(jì)數(shù)據(jù)的相對(duì)位姿作為約束參與后端優(yōu)化,里程計(jì)數(shù)據(jù)短時(shí)間內(nèi)必須要足夠準(zhǔn)確,不然得到的相對(duì)位姿誤差大,會(huì)導(dǎo)致全局優(yōu)化出來(lái)的地圖效果更差。
下面就介紹一下這幾個(gè)傳感器的比較常用的參數(shù)配置和調(diào)整方式:
激光雷達(dá)
?????用于配置運(yùn)動(dòng)畸變矯正的?num_subdivisions_per_laser_scan 和?num_accumulated_range_data,num_subdivisions_per_laser_scan?用于指定將一幀點(diǎn)云切成 N 份,然后均勻估算每一份的時(shí)間戳,num_accumulated_range_data?又會(huì)將 N 份點(diǎn)云合并成 1 份,參數(shù)默認(rèn)值都是 10。合并的過(guò)程中會(huì)根據(jù)每一份點(diǎn)云的時(shí)間戳估算它應(yīng)該在的位置和角度。運(yùn)動(dòng)畸變矯正是非常依賴?yán)锍逃?jì)和IMU的,里程計(jì)估算線速度,IMU 估算角速度,如果沒(méi)有接入這兩個(gè)傳感器,或者其中一個(gè)的精度非常差,最好是把畸變矯正給關(guān)了,把兩個(gè)參數(shù)設(shè)置成 1,不然矯正后會(huì)比不矯正的偏差還大。關(guān)閉運(yùn)動(dòng)畸變的話需要在建圖時(shí)移動(dòng)速度盡可能慢,讓雷達(dá)掃描不會(huì)產(chǎn)生太大的畸變,從而減少累計(jì)誤差提高建圖質(zhì)量。
????TRAJECTORY_BUILDER_2D.min_range 和?TRAJECTORY_BUILDER_2D.max_range,用于限制點(diǎn)云的有效距離,最小距離一般是用來(lái)過(guò)濾掉雷達(dá)周圍的遮擋物的,最大距離的配置就比較依賴實(shí)際環(huán)境的面積,max_range 這個(gè)配置不是越大越好的,大了會(huì)增加計(jì)算量,也會(huì)因?yàn)闇y(cè)量距離較遠(yuǎn)時(shí)噪聲變大和點(diǎn)間距稀疏帶來(lái)更多的累計(jì)誤差,影響建圖質(zhì)量。可以在目標(biāo)工作場(chǎng)景下錄個(gè)包,反復(fù)測(cè)試觀察不影響 scan-to-map 匹配的最小距離作為參數(shù)值,可以通過(guò)觀察雷達(dá)移動(dòng)后 carto 匹配的點(diǎn)云位置有沒(méi)有做出相應(yīng)的移動(dòng)來(lái)判斷。
????voxel_filter_size 體素濾波的大小設(shè)置,體素濾波是用來(lái)降低點(diǎn)云密度的,限制兩個(gè)點(diǎn)之間的最小距離,把值調(diào)大了可以降低計(jì)算量,但建圖質(zhì)量也會(huì)被降低,一般是設(shè)置成 0.025 或者 0.05,也就是兩點(diǎn)之間間隔 2.5cm 或者是 5cm。
????rangefinder_sampling_ratio?點(diǎn)云數(shù)據(jù)輸入頻率限制?,一般維持在 12hz 左右的輸入就好了,如果雷達(dá)的輸出頻率比較高,例如 30hz,那就可以將這個(gè)參數(shù)設(shè)置為 0.33,僅保留 33%?的輸入,降低計(jì)算量,如果機(jī)器內(nèi)存和算力充足,越大越好,這個(gè)自己根據(jù)實(shí)際情況調(diào)整。
IMU
????use_odometry?打開(kāi)里程計(jì)數(shù)據(jù)輸入?,這個(gè)沒(méi)啥好說(shuō)的,看前面介紹的數(shù)據(jù)作用就行了。
里程計(jì)
????TRAJECTORY_BUILDER_2D.use_imu_date 打開(kāi) IMU 數(shù)據(jù)輸入,也是沒(méi)啥好說(shuō)的??。
最后再說(shuō)點(diǎn)題外話,根據(jù)這些傳感器的作用和參數(shù)配置方式,我們可以反推出 carto 對(duì)傳感器的要求,例如 IMU?數(shù)據(jù)只使用了角速度來(lái)估計(jì)旋轉(zhuǎn)運(yùn)動(dòng),那我們可以選擇對(duì)旋轉(zhuǎn)有著高精度測(cè)量的任意慣性器件,線速度的測(cè)量精度可以不在意。里程計(jì)也是,只需要關(guān)注線速度的測(cè)量精度,這里的里程計(jì)不一定只能是輪式里程計(jì),也可以是視覺(jué) SLAM 框架輸出的位姿作為里程計(jì)信息輸入到 cartographer 里,或者是別的啥都行,只要是數(shù)據(jù)的格式和表現(xiàn)形式跟輪式里程計(jì)一樣就可以了。?