SLAM——LIO-SAM

Lio-sam: https://github.com/TixiaoShan/LIO-SAM

Lio-sam has a similar code structure with A-LOAM (more similar to LeGO-LOAM, but without ground points). However, they are very different. A-LOAM doesn’t have a pose graph optimization in back-end. It uses current scan to matching the global map, which can lead to drift over a long distance scanning. LIO-SAM uses a lidar-IMU odometry, and it adopts a factor graph for multi-sensor fusion and global optimization. If you want to fuse other sensors it would be much easier. Also, it supports loop closure detection.

From the demo (https://www.youtube.com/watch?v=A0H8CoORZJU), we could see that LIO-SAM is really robust to arbitrary rotation and has high localization accuracy. At any time, the robot state can be formulated as:

𝑹\mathbf R is the rotation matrix, 𝒑\mathbf p is the position, 𝒗\mathbf v is the speed and 𝒃\mathbf b is the IMU bias.

𝒙=[𝑹𝑻,𝒑𝑻,𝒗𝑻,𝒃𝑻]𝑻 \mathbf{x}=\left[\mathbf{R}^{\mathbf{T}}, \mathbf{p}^{\mathbf{T}}, \mathbf{v}^{\mathbf{T}}, \mathbf{b}^{\mathbf{T}}\right]^{\mathbf{T}}

Untitled

There are 4 types of factors in LIO-SAM: (a) IMU preintegration factors, (b) lidar odometry factors,(c) GPS factors, and (d) loop closure factors.

We denote the world frame as 𝑾\mathbf W and the robot body frame as 𝑩\mathbf B. 𝑻t𝑩𝑾\mathbf T_t^{\mathbf {BW}} is the transformation from world

IMU Preintegration

IMU will provide angular velocity and acceleration:

ω̂t=ωt+𝒃tω+𝒏tω𝒂̂t=𝑹t𝑩𝑾(𝒂t𝒈)+𝒃t𝒂+𝒏t𝒂 \begin{array}{l}\hat{\omega}_ {t}=\omega_ {t}+\mathbf{b}_ {t}^{\omega}+\mathbf{n}_ {t}^{\omega} \\\hat{\mathbf{a}}_ {t}=\mathbf{R}_ {t}^{\mathbf{B W}}\left(\mathbf{a}_ {t}-\mathbf{g}\right)+\mathbf{b}_ {t}^{\mathbf{a}}+\mathbf{n}_ {t}^{\mathbf{a}}\end{array}

where ω̂t\hat{\omega}_t (angular velocity) and 𝒂̂t\hat{\mathbf{a}}_ {t} (acceleration) are the raw IMU measurements in 𝑩\mathbf B at time t.t. 𝒃t\mathbf b_t and 𝒏t\mathbf n_tare bias and white noise respectively. 𝑹t𝑩𝑾\mathbf R_t^{\mathbf{BW}} is the rotation matrix from 𝑾\mathbf W to 𝑩\mathbf B. 𝒈\mathbf g is the constant gravity vector in 𝑾\mathbf W. And based on those measurements we could infer the motion of robot. The velocity, position and rotation of the robot at time t+Δtt + \Delta t can be computed as follows:

𝒗t+Δt=𝒗t+𝒈Δt+𝑹t(𝒂̂t𝒃t𝒂𝒏t𝒂)Δt𝒑t+Δt=𝒑t+𝒗tΔt+12𝒈Δt2+12𝑹t(𝒂̂t𝒃t𝒂𝒏t𝒂)Δt2𝑹t+Δt=𝑹texp((ω̂t𝒃tω𝒏tω)Δt) \begin{array}{l}\mathbf{v}_ {t+\Delta t}=\mathbf{v}_ {t}+\mathbf{g} \Delta t+\mathbf{R}_ {t}\left(\hat{\mathbf{a}}_ {t}-\mathbf{b}_ {t}^{\mathbf{a}}-\mathbf{n}_ {t}^{\mathbf{a}}\right) \Delta t \\\mathbf{p}_ {t+\Delta t}=\mathbf{p}_ {t}+\mathbf{v}_ {t} \Delta t+\frac{1}{2} \mathbf{g} \Delta t^{2}+\frac{1}{2} \mathbf{R}_ {t}\left(\hat{\mathbf{a}}_ {t}-\mathbf{b}_ {t}^{\mathbf{a}}-\mathbf{n}_ {t}^{\mathbf{a}}\right) \Delta t^{2} \\\mathbf{R}_ {t+\Delta t}=\mathbf{R}_ {t} \exp \left(\left(\hat{\omega}_ {t}-\mathbf{b}_ {t}^{\omega}-\mathbf{n}_ {t}^{\omega}\right) \Delta t\right)\end{array}

where 𝑹t=𝑹t𝑾𝑩=𝑹t𝑩𝑾\mathbf{R}_ {t}=\mathbf{R}_ {t}^{\mathbf{W B}}=\mathbf{R}_ {t}^{\mathbf{B W}^{\top}}. The IMU preintegrated measurements between time ii and jj can be computed as following (Apparently, Δ𝒗ij\Delta \mathbf{v}_ {i j} is not vjviv_j - v_i ):

Δ𝒗ij=𝑹i(𝒗j𝒗i𝒈Δtij)Δ𝒑ij=𝑹i(𝒑j𝒑i𝒗iΔtij12𝒈Δtij2)Δ𝑹ij=𝑹i𝑹j. \begin{aligned}\Delta \mathbf{v}_ {i j} &=\mathbf{R}_ {i}^{\top}\left(\mathbf{v}_ {j}-\mathbf{v}_ {i}-\mathbf{g} \Delta t_ {i j}\right) \\\Delta \mathbf{p}_ {i j} &=\mathbf{R}_ {i}^{\top}\left(\mathbf{p}_ {j}-\mathbf{p}_ {i}-\mathbf{v}_ {i} \Delta t_ {i j}-\frac{1}{2} \mathbf{g} \Delta t_ {i j}^{2}\right) \\\Delta \mathbf{R}_ {i j} &=\mathbf{R}_ {i}^{\top} \mathbf{R}_ {j} .\end{aligned}

See https://arxiv.org/pdf/1512.02363.pdf for detailed derivation.

Lidar Odometry

The lidar odometry in LIO-SAM is similar to Lego-LOAM or A-LOAM. The difference is LIO-SAM adopt keyframe strategy. When a new keyframe 𝔽i\mathbb F_ {i} is registered, it will associate with a new robot state node xix_ {i} in the factor graph. The lidar frames between two keyframes will be discarded (Note that the position and rotation change thresholds for adding a new keyframe in LIO-LOAM are 1m1m and $10\degree$ respectively). The generation of a lidar odometry factor is described in the following step:

  1. Sub-keyframes for voxel map. Organize nn most recent keframes as a sub-keyframes and combines their scans as a voxel map 𝑴i={𝔽in,,𝔽i}\mathbf M_i = \left\{\mathbb{F}_ {i-n}, \ldots, \mathbb{F}_ {i}\right\}, which includes edge feature voxel map 𝑴ie\mathbf M^{e}_i and plane feature voxel map 𝑴ip\mathbf M^{p}_i. Note that 𝑴i\mathbf M_i will be down-sampled to remove duplicated features.
  2. Scan-matching. A new keyframe 𝔽i+1\mathbb F_ {i+1} will be matched to 𝑴i\mathbf M_ {i}. The initial transformation 𝑻̃i+1\tilde{\mathbf{T}}_ {i+1} is estimated through IMU. The matching process is similar to A-LOAM’s lidar mapping module.

GPS

System will still suffer from drift during long-distance navigation tasks. GPS is useful for correcting this long-distance-error. In LIO-SAM, a GPS factor is only added when the estimated position covariance is larger that the received GPS position covariance.

Loop Closure

LIO-SAM use a naive but effective method for loop closure detection based on the Euclidean distance. When a new node xi+1x_ {i+1} is registered, we search for the near nodes from the factor graph. For example, x3x_3 is selected, and we match 𝔽i+1\mathbb F_ {i+1} with the subkeframe voxel map {𝔽3m,,𝔽3,,𝔽3+m}\left\{\mathbb{F}_ {3-m}, \ldots, \mathbb{F}_ {3}, \ldots, \mathbb{F}_ {3+m}\right\}. If the matching succeed, a relative transformation Δ𝑻3,i+1\Delta \mathbf T_ {3, i+1} will be added into fact graph as a loop closure factor. In LIO-SAM,m=12m = 12 and the search radius is 15m15m.