激光雷達slam之LOAM中的坐標轉換與IMU融合


需要用到的一些知識和假設:

(1)  來源於 github中的討論:

由於IMU累積推算位置的誤差大,程序中粗略地計算了IMU的位置漂移。

_imuPositionShift = _imuCur.position - _imuStart.position - _imuStart.velocity * relSweepTime;

上式成立的前提是認為一個掃描周期內,Lidar的運動是勻速的,上式計算出了非線性誤差部分。

 

(2) X、Y、Z軸對應俯仰(pitch)、航向(yaw)、橫滾(roll)機動,可知Lidar坐標系為“右下前”坐標系。

 

(3)  從Lidar系到global IMU系,類似於慣導系統中的C(b->n),即載體系到地理系的轉換。

旋轉順序為:橫滾->俯仰->航向

rotateZXY(point, roll, pitch, yaw);

從global IMU系到Lidar系,旋轉順序正好相反。

rotateYXZ(point, -yaw, -pitch, -roll);

 

(4)  transform代表將k時刻的點雲轉換到k+1時刻下,與視覺slam中的相對位姿定義相同。

 

坐標轉換與IMU融合

1、 transformToStartIMU

注冊點雲時(MultiScanRegistration.cpp中),當判斷有IMU數據時,會進行一步坐標轉換的預處理,體現在函數transformToStartIMU中。

這個函數進行了三步處理:

(1)       rotateZXY(point, _imuCur.roll, _imuCur.pitch, _imuCur.yaw);

將原始點雲從當前Lidar系轉換到global IMU系下;

(2)       補償了_imuPositionShift,也即估算的IMU位置漂移;

(3)       rotateYXZ(point, -_imuStart.yaw, -_imuStart.pitch, -_imuStart.roll);

將global IMU系下的點雲轉換到Start時刻的Lidar系下。

         經過這個函數的處理,點雲的position部分處於當前Lidar下一個相對准確的位置上(基於掃描周期內勻速運動的假設),但點雲的Rotation部分是Start時刻Lidar下觀察所得的,而非處於當前Lidar下。更清晰地來說,即此時觀察到的點雲坐標,是以當前Lidar的坐標(一個估計值)為原點,而坐標軸是與Start時刻的Lidar系的坐標軸對齊的。

 

2、  OD初始化:

根據第一次開始掃描時的IMU pitch與roll,作為累積位姿的初始值。  

 _transformSum.rot_x += _imuPitchStart;

_transformSum.rot_z += _imuRollStart;

Yaw角度和pos部分都未賦初值,即假設開始時刻的偏航角為0,位於global系下的原點位置。

 

3、  運動估計初值:

(1)       _transform.pos -= _imuVeloFromStart * _scanPeriod; 

其中,imuVeloFromStart的計算,可知imuVeloFromStart為Start時刻Lidar系下的速度變化矢量:

imuVelocityFromStart = _imuCur.velocity - _imuStart.velocity;

  rotateYXZ(imuVelocityFromStart, -_imuStart.yaw, -_imuStart.pitch, -_imuStart.roll);

對於勻速運動假設的一個補償,並且基於運動曲線的連續性,做了遞推形式的計算,可能乘以1/2會更合適?

(2)       _transform的rotation部分未賦初值,認為為0。

 

4、  transformToStart

在進行KDTree最近點搜索前,首先將進行畸變處理后的點雲轉換到每一次掃描的開始時刻。

先根據勻速運動假設計算出當前點時刻Lidar的位移和旋轉。

但這里其實是和前面的轉換transformToStartIMU有些沖突的。因為transformToStartIMU之后點雲所處的坐標軸是與Start時刻的Lidar系的坐標軸對齊的。現在又通過_transform將點雲轉換到start時刻。有一種轉了兩次的感覺。

有一種解釋:認為k次掃描中的旋轉部分大部分由IMU積分獲得,_transform中的旋轉估算的只是一個小量。

 

5、  transformToEnd

(1)       先進行transformToStart,此時點雲處於start時刻的Lidar系下;

(2)       通過_transform轉換到end時刻的Lidar系下;

(3)       rotateZXY(point, _imuRollStart, _imuPitchStart, _imuYawStart);

轉換到global系下

(4)       rotateYXZ(point, -_imuYawEnd, -_imuPitchEnd, -_imuRollEnd);

轉換到end時刻的Lidar系下。

 

總結點雲的旋轉過程從1->5, 可用公式表示為:

 

6、accumulateRotation

該函數的作用是將計算的兩幀之間的位姿“累加”起來,獲得相對於第一幀的旋轉矩陣,具體公式如下:

                                                                            

7、 pluginIMURotation

該函數與accumulateRotation,聯合起來完成了更新_transformSum的rotation部分的工作。該函數可視為transformToEnd的下部分的逆過程。具體公式如下:

                                                         

 

                                                                             


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM