Fast-Lio
2021.2 IEEE Robotics and Automation Letters Wei Xu 港大火星实验室
1、论文
1.1 系统框架
• 雷达输入到预处理模块,经过一段时间的累积后进行特征提取,提取出面点和角点
• IMU 输入进行前向传播 (积分得到粗略位姿估计),反向传播进行运动补偿
• 计算雷达里程计的残差,利用迭代卡尔曼滤波估计位姿变换,直到收敛。最后根据位姿建图,并更新特征地图。
缺陷:为了防止构建地图的k-d树的时间不断增加,该系统只能在较小的环境中工作,虽然使用卡尔曼增益新的计算公式可以进行scan-to-map的匹配,但是随着地图的增大map的维护无法保证实时性
运算符号定义
⊞ : M × R n → M ; ⊟ : M × M → R n M = S O ( 3 ) : R ⊞ r = R E x p ( r ) ; R 1 ⊟ R 2 = L o g ( R 2 T R 1 ) M = R n : a ⊞ b = a + b ; a ⊟ b = a − b \begin{align*} \begin{aligned} &\ \ \ \ \ \ \ \ \ \ \ \boxplus \!:\! \mathcal {M}\! \times \! \mathbb {R}^n \!\!\rightarrow \!\! \mathcal {M}; \ \ \ \ \ \ \boxminus \!:\!\mathcal {M} \!\times \! \mathcal {M} \!\rightarrow \!\mathbb {R}^n\\ &\mathcal {M}=SO(3): \mathbf {R}\!\boxplus \!\mathbf {r}\!=\!\mathbf {R} \rm {Exp}(\mathbf {r});\ \ \ \ \mathbf {R}_1\!\!\boxminus \!\mathbf {R}_2\!=\!\rm {Log} (\mathbf {R}_2^{T} \mathbf {R}_1\!) \\ &\mathcal {M}\!\!=\!\mathbb {R}^n: \ \ \ \ \ \mathbf {a}\!\boxplus \!\mathbf {b}\!=\mathbf {a} \!+\! \mathbf b;\ \ \ \ \ \ \ \ \ \mathbf {a}\boxminus \mathbf {b}=\mathbf {a}\!-\!\mathbf {b} \end{aligned} \end{align*} ⊞:M×Rn→M; ⊟:M×M→RnM=SO(3):R⊞r=RExp(r); R1⊟R2=Log(R2TR1)M=Rn: a⊞b=a+b; a⊟b=a−b
关于流型的解释
流形学的观点是认为:我们所能观察到的数据实际上是由一个低维流形映射到高维空间上的,即这些数据所在的空间是“嵌入在高维空间的低维流形”。由于数据内部特征,用高维空间表示低维流型会产生维度上的冗余,只需要较低的维度就可以位移表示该维度下的流行
1.2 数据预处理
imu预积分
imu物理模型
G
p
˙
I
=
G
v
I
,
G
v
˙
I
=
G
R
I
(
a
m
−
b
a
−
n
a
)
+
G
g
,
G
g
˙
=
0
G
R
˙
I
=
G
R
I
⌊
ω
m
−
b
ω
−
n
ω
⌋
∧
,
b
˙
ω
=
n
b
ω
,
b
˙
a
=
n
b
a
\begin{equation*} \begin{aligned} ^G\dot{\mathbf p}_I&={}^G\mathbf v_I,\ ^G\dot{\mathbf v}_I={}^G{\mathbf R}_I \left(\mathbf a_m - \mathbf b_{\mathbf a} - \mathbf n_{\mathbf a} \right) + {}^G\mathbf g,\ ^G\dot{\mathbf g} = \mathbf 0\\ ^G\dot{\mathbf R}_I&={}^G{\mathbf R}_I \lfloor \boldsymbol \omega _m - \mathbf b_{\boldsymbol \omega } - \mathbf n_{\boldsymbol \omega } \rfloor _\wedge,\ \dot{\mathbf b}_{\boldsymbol \omega }=\mathbf n_{\mathbf b\boldsymbol \omega }, \ \dot{\mathbf b}_{\mathbf a}=\mathbf n_{\mathbf b\mathbf a} \end{aligned} \tag{1} \end{equation*}
Gp˙IGR˙I=GvI, Gv˙I=GRI(am−ba−na)+Gg, Gg˙=0=GRI⌊ωm−bω−nω⌋∧, b˙ω=nbω, b˙a=nba(1)
IMU的状态传播,其中
f
δ
t
f \delta_t
fδt对应着帧内的积分
x
i
+
1
=
x
i
⊞
(
Δ
t
f
(
x
i
,
u
i
,
w
i
)
)
\begin{equation*} \begin{aligned} \mathbf x_{i+1} &= \mathbf x_{i} \boxplus \left(\Delta t \mathbf f(\mathbf x_i, \mathbf u_i, \mathbf w_i) \right) \end{aligned} \tag{2} \end{equation*}
xi+1=xi⊞(Δtf(xi,ui,wi))(2)
M = S O ( 3 ) × R 15 , dim ( M ) = 18 x ≐ [ G R I T G p I T G v I T b ω T b a T G g T ] T ∈ M u ≐ [ ω m T a m T ] T , w ≐ [ n ω T n a T n b ω T n b a T ] T f ( x i , u i , w i ) = [ ω m i − b ω i − n ω i G v I i G R I i ( a m i − b a i − n a i ) + G g i n b ω i n b a i 0 3 × 1 ] \begin{align*} \mathcal {M} &= SO(3) \times \mathbb {R}^{15}, \ \text{dim}(\mathcal {M}) = 18 \\ \mathbf x &\doteq \begin{bmatrix}^G{\mathbf R}_I^T&^G\mathbf p_I^T&^G\mathbf v_I^T&\mathbf b_{\boldsymbol \omega }^T&\mathbf b_{\mathbf a}^T&^G\mathbf g^T\end{bmatrix}^T \in \mathcal {M} \\ \mathbf u &\doteq \begin{bmatrix}\boldsymbol \omega ^T_m & {\mathbf a}^T_m\end{bmatrix}^T,\ \mathbf w \doteq \begin{bmatrix}\mathbf n_{\boldsymbol \omega }^T&\mathbf n_{\mathbf a}^T&\mathbf n_{\mathbf b\boldsymbol \omega }^T&\mathbf n_{\mathbf b\mathbf a}^T\end{bmatrix}^T \\ \mathbf f&\left(\mathbf x_{i}, \mathbf u_i, \mathbf w_i\right) = \begin{bmatrix}\boldsymbol \omega _{m_i} - \mathbf b_{\boldsymbol \omega _i} - \mathbf n_{\boldsymbol \omega _i} \\ {}^G\mathbf v_{I_i} \\ {}^G{\mathbf R}_{I_i}\left(\mathbf a_{m_i} - \mathbf b_{\mathbf a_i}- \mathbf n_{\mathbf a_i}\right) + {}^G\mathbf g_i \\ \mathbf n_{\mathbf b \boldsymbol \omega _i} \\ \mathbf n_{\mathbf b \mathbf a_i} \\ \mathbf 0_{3\times 1} \end{bmatrix} \tag{3} \end{align*} Mxuf=SO(3)×R15, dim(M)=18≐[GRITGpITGvITbωTbaTGgT]T∈M≐[ωmTamT]T, w≐[nωTnaTnbωTnbaT]T(xi,ui,wi)= ωmi−bωi−nωiGvIiGRIi(ami−bai−nai)+Gginbωinbai03×1 (3)
优化的状态量是18维的,包含了世界坐标系下的重力向量
雷达特征提取
- 使用Livox的固态雷达,20W个点/s,每20ms取一次扫描点集作为一次scan
- 与LOAM一样提取平面点和边缘点,记录每个特征点的时间戳,最后一个特征点是一次 scan 的终点
1.3 误差卡尔曼滤波
使用ESKF完成运动方程的线性化,
卡尔曼滤波的时间复杂度 O ( m 2 ) \mathcal {O}(m^2) O(m2),m是测量的维度
x x x表示真值, x ~ \widetilde{\mathbf x} x 表示误差, x ˉ \bar{\mathbf x} xˉ表示最优估计值(后验), x ^ \widehat{ \mathbf x} x 表示先验值
第k-1帧(已经完全优化完了)的误差:误差值 = 真值 “—” 优化完的估计值
x
~
k
−
1
≐
x
k
−
1
⊟
x
ˉ
k
−
1
=
[
δ
θ
T
G
p
~
I
T
G
v
~
I
T
b
~
ω
T
b
~
a
T
G
g
~
T
]
T
\begin{align*} \widetilde{\mathbf x}_{k-1} \!\doteq \! {\mathbf x}_{k-1} \boxminus \bar{\mathbf x}_{k-1} \!=\! \begin{bmatrix}\delta \boldsymbol \theta ^T \!\!&\!\! {}^G\widetilde{\mathbf p}_I^T \!&\! {}^G\widetilde{\mathbf v}^T_I&\widetilde{\mathbf b}_{\boldsymbol \omega }^T \!&\! \widetilde{\mathbf b}_{\mathbf a}^T \!&\! {}^G\widetilde{\mathbf g}^T\end{bmatrix}^T\end{align*}
x
k−1≐xk−1⊟xˉk−1=[δθTGp
ITGv
ITb
ωTb
aTGg
T]T
误差状态的前向传播
通过每两个雷达帧之间的IMU预积分得到一个
x
k
x_k
xk的估计值,并使用估计值进行运动补偿
x
^
i
+
1
=
x
^
i
⊞
(
Δ
t
f
(
x
^
i
,
u
i
,
0
)
)
;
x
^
0
=
x
ˉ
k
−
1
.
\begin{equation*} \begin{aligned} \widehat{ \mathbf x}_{i+1} &= \widehat{ \mathbf x}_{i} \boxplus \left(\Delta t \mathbf f (\widehat{\mathbf x}_i, \mathbf u_i, \mathbf 0) \right); \ \widehat{\mathbf x}_{0} = \bar{\mathbf x}_{k-1}. \end{aligned} \tag{4} \end{equation*}
x
i+1=x
i⊞(Δtf(x
i,ui,0)); x
0=xˉk−1.(4)
线性化的误差的传递:
x
~
i
+
1
≃
F
x
~
x
~
i
+
F
w
w
i
.
\begin{align*} \widetilde{\mathbf x}_{i+1} &\overset{}{\simeq } \mathbf F_{\widetilde{\mathbf x}} \widetilde{\mathbf x}_i + \mathbf F_{\mathbf w} \mathbf w_i.\tag{5} \end{align*}
x
i+1≃Fx
x
i+Fwwi.(5)
推导F矩阵有两种方式,基于误差随时间变化的递推方程,和基于一阶泰勒展开的误差传递方法,最后推导出来的公式
F
x
~
=
[
Exp
(
−
ω
^
i
Δ
t
)
0
0
−
A
(
ω
^
i
Δ
t
)
T
Δ
t
0
0
0
I
I
Δ
t
0
0
0
−
G
R
^
I
i
⌊
a
^
i
⌋
∧
Δ
t
0
I
0
−
G
R
^
I
i
Δ
t
I
Δ
t
0
0
0
I
0
0
0
0
0
0
I
0
0
0
0
0
0
I
]
,
F
w
=
[
−
A
(
ω
^
i
Δ
t
)
T
Δ
t
0
0
0
0
0
0
0
0
−
G
R
^
I
i
Δ
t
0
0
0
0
I
Δ
t
0
0
0
0
I
Δ
t
0
0
0
0
]
\begin{align*} \mathbf F_{\widetilde{\mathbf x}}\!\!=\!\!\begin{bmatrix}\text{Exp}\left(-\widehat{\boldsymbol \omega }_i\Delta t\right)\!\! & \mathbf 0 & \mathbf 0 &\!\!\!\!-\mathbf A\!\!\left(\widehat{\boldsymbol \omega }_i\Delta t\right)^{T}\!\!\Delta t\!\!\!\!& \mathbf 0 & \mathbf 0 \\ \mathbf 0 & \mathbf I &\!\!\!\!\mathbf I\Delta t & \mathbf 0 & \mathbf 0 & \mathbf 0 \\ {-}^G\widehat{\mathbf R}_{I_i}\lfloor \widehat{\mathbf a}_{i}\rfloor _{\wedge }\Delta t & \mathbf 0 & \mathbf I & \mathbf 0 & \!\!-{}^G\widehat{\mathbf R}_{I_i}\Delta t\!\!& \!\!\mathbf I\Delta t \\ \mathbf 0 & \mathbf 0 & \mathbf 0 & \mathbf I & \mathbf 0 & \mathbf 0 \\ \mathbf 0 & \mathbf 0 & \mathbf 0 & \mathbf 0 & \mathbf I & \mathbf 0 \\ \mathbf 0 & \mathbf 0 & \mathbf 0 & \mathbf 0 & \mathbf 0 & \mathbf I \end{bmatrix}\!,\ \mathbf F_{\mathbf w}\!\!=\!\! \begin{bmatrix}-\mathbf A\left(\widehat{\boldsymbol \omega }_i \Delta t\right)^{T}\Delta t & \mathbf 0 & \mathbf 0 & \mathbf 0 \\ \mathbf 0 & \mathbf 0 & \mathbf 0 & \mathbf 0 \\ \mathbf 0 & -{}^G\widehat{\mathbf R}_{I_i}\Delta t & \mathbf 0 & \mathbf 0 \\ \mathbf 0 & \mathbf 0 & \mathbf I\Delta t & \mathbf 0 \\ \mathbf 0 & \mathbf 0 & \mathbf 0 & \mathbf I\Delta t \\ \mathbf 0 & \mathbf 0 & \mathbf 0 & \mathbf 0 \end{bmatrix} \tag{7} \end{align*}
Fx
=
Exp(−ω
iΔt)0−GR
Ii⌊a
i⌋∧Δt0000I00000IΔtI000−A(ω
iΔt)TΔt00I0000−GR
IiΔt0I000IΔt00I
, Fw=
−A(ω
iΔt)TΔt0000000−GR
IiΔt000000IΔt000000IΔt0
(7)
协方差的传播
P
^
i
+
1
=
F
x
~
P
^
i
F
x
~
T
+
F
w
Q
F
w
T
;
P
^
0
=
P
ˉ
k
−
1
.
\begin{equation*} \begin{split} \widehat{\mathbf P}_{i+1} = \mathbf F_{\widetilde{\mathbf x}}\widehat{\mathbf P}_{i}\mathbf F_{\widetilde{\mathbf x}}^T + \mathbf F_{\mathbf w} \mathbf Q \mathbf F_{\mathbf w}^T; \ \widehat{\mathbf P}_{0} = \bar{\mathbf P}_{k-1}. \end{split} \tag{8} \end{equation*}
P
i+1=Fx
P
iFx
T+FwQFwT; P
0=Pˉk−1.(8)
反向传播,雷达运动补偿
目的是每个IMU时刻的积分相对于此帧点云结束时刻的位姿
先把 L 坐标系的特征点转到 I 坐标系,然后乘上反向传播的补偿矩阵,再转回 L 坐标系。所有的投影点都像这样转好后,就可以开始计算残差了。计算残差的时候把补偿后的特征点投影到世界坐标系
KaTeX parse error: Got group of unknown type: 'internal'
把点畸变矫正投影到这个雷达帧的结束时刻,然后在投影到世界坐标系,待估计位姿
G
p
^
f
j
κ
{}^G \widehat{\mathbf p}_{f_j}^\kappa
Gp
fjκ
L
k
p
f
j
=
I
T
L
−
1
I
k
T
ˇ
I
j
I
T
L
L
j
p
f
j
,
\begin{equation*} \begin{split} {}^{L_k}{\mathbf p}_{f_j}={}^{I}{\mathbf T}_{L}^{-1} {}^{I_k}\check{\mathbf T}_{I_j} {}^{I}{\mathbf T}_{L} {}^{L_j}{\mathbf p}_{f_j}, \end{split} \tag{10} \end{equation*}
Lkpfj=ITL−1IkTˇIjITLLjpfj,(10)
G
p
^
f
j
κ
=
G
T
^
I
k
κ
I
T
L
L
k
p
f
j
;
j
=
1
,
…
,
m
.
(11)
\begin{split} {}^G \widehat{\mathbf p}_{f_j}^\kappa = {}^G\widehat{\mathbf T}_{I_k}^\kappa {}^I\mathbf T_L {}^{L_k} \mathbf p_{f_j}; \ j= 1,\ldots, m. \end{split} \tag{11}
Gp
fjκ=GT
IkκITLLkpfj; j=1,…,m.(11)
残差计算就是点到线的距离和点到面的距离,(fast-lio2 以及代码中,都省去了特征提取,只计算面点的残差)
1.4 IEKF迭代卡尔曼滤波
IEKF 可以证明和高斯牛顿 GN 法是等价的,IEKF迭代过程不会更新协方差矩阵 P,但是文章中更新了,由于每迭代一次后
x
~
\widetilde{x}
x
就会发生一次变化,理论上其协方差矩阵并不是初始的
P
k
P _k
Pk 了,因此协方差矩阵可通过
P
=
(
J
k
)
−
1
P
^
k
(
J
k
)
−
T
P = (J^k )^{-1}\widehat{P}_k(J^k)^{-T}
P=(Jk)−1P
k(Jk)−T 在迭代过程中更新。
J
κ
=
[
A
(
G
R
^
I
k
κ
⊟
G
R
^
I
k
)
−
T
0
3
×
15
0
15
×
3
I
15
×
15
]
\begin{equation*} \begin{split} \mathbf J^\kappa \!=\!\begin{bmatrix}\mathbf A\!\left(^G \widehat{\mathbf R}_{I_k}^\kappa \!\boxminus \! {}^G \widehat{\mathbf R}_{I_k}\!\right)^{-T} \!\!& \mathbf 0_{3\times 15} \\ \mathbf 0_{15\times 3} & \mathbf I_{15\times 15} \end{bmatrix} \end{split} \tag{16} \end{equation*}
Jκ=[A(GR
Ikκ⊟GR
Ik)−T015×303×15I15×15](16)
求解MAP问题(一个最小二乘问题)
min
x
~
k
κ
(
∥
x
k
⊟
x
^
k
∥
P
^
k
−
1
2
+
∑
j
=
1
m
∥
z
j
κ
+
H
j
κ
x
~
k
κ
∥
R
j
−
1
2
)
\begin{align*} \min _{\widetilde{\mathbf x}_{k}^\kappa } \left(\Vert \mathbf x_k \boxminus \widehat{\mathbf x}_k \Vert ^2_{ \widehat{\mathbf P}^{-1}_k} + \sum \limits _{j=1}^{m} \Vert \mathbf z_j^\kappa + \mathbf H_j^\kappa \widetilde{\mathbf x}_{k}^\kappa \Vert ^2_{\mathbf R^{-1}_j} \right) \tag{17} \end{align*}
x
kκmin(∥xk⊟x
k∥P
k−12+j=1∑m∥zjκ+Hjκx
kκ∥Rj−12)(17)
计算卡尔曼增益,H是观测残差关于状态量扰动的偏导,R是观测的协方差,P是ESKF推导出来的运动方程的协方差,
z
k
z_k
zk就是每个点匹配的残差
K
=
P
H
T
(
H
P
H
T
+
R
)
−
1
,
x
^
k
κ
+
1
=
x
^
k
κ
⊞
(
−
K
z
k
κ
−
(
I
−
K
H
)
(
J
κ
)
−
1
(
x
^
k
κ
⊟
x
^
k
)
)
.
\begin{align*} \mathbf K & = {\mathbf P} \mathbf H^T(\mathbf H {\mathbf P} \mathbf H^T \!+\! \mathbf R)^{-1}, \\ \widehat{\mathbf x}_{k}^{\kappa +1} &= \ \widehat{\mathbf x}_{k}^{\kappa } \! \boxplus \! \left(-\mathbf K {\mathbf z}_k^\kappa - (\mathbf I - \mathbf K \mathbf H) (\mathbf J^\kappa)^{-1} \left(\widehat{\mathbf x}_{k}^{\kappa } \boxminus \widehat{\mathbf x}_{k} \right) \right). \tag{18} \end{align*}
Kx
kκ+1=PHT(HPHT+R)−1,= x
kκ⊞(−Kzkκ−(I−KH)(Jκ)−1(x
kκ⊟x
k)).(18)
论文给出了一种求卡尔曼增益的等效方式,前面K计算过程中矩阵求逆的维度是观测的维度,后面K的计算过程矩阵求逆的维度就是状态量的维度
K
=
(
H
T
R
−
1
H
+
P
−
1
)
−
1
H
T
R
−
1
.
\begin{equation*} \begin{split} \mathbf K \!\!=\!\! \left(\mathbf H^T {\mathbf R}^{-1} \mathbf H \!+\! {\mathbf P}^{-1} \right)^{-1}\!\mathbf H^T \mathbf R^{-1}. \end{split} \tag{20} \end{equation*}
K=(HTR−1H+P−1)−1HTR−1.(20)
H矩阵:
经过k次迭代后得到最终的结果
x
ˉ
k
=
x
^
k
κ
+
1
,
P
ˉ
k
=
(
I
−
K
H
)
P
\begin{equation*} \begin{split} \bar{\mathbf x}_{k} &= \widehat{\mathbf x}_{k}^{\kappa +1},\ \bar{\mathbf P}_k = \left(\mathbf I - \mathbf K \mathbf H \right) {\mathbf P} \end{split} \tag{19} \end{equation*}
xˉk=x
kκ+1, Pˉk=(I−KH)P(19)
地图更新:使用迭代之后的位姿将地图点投影到全局世界坐标系,初始化静止2s,初始化IMU零偏和重力向量
1.5 实验效果
32 米轨迹上的漂移为 0.08 米。漂移小于 0.05%(140 米轨迹上的漂移为 0.07 米),10HZ, 平均处理时间为 25ms,平均有效特征点为 1497 个