激光雷达和相机标定方法按是否需要特定的标志物分为target-based和targetless两种,前者需要专门的控制场,有代表ground truth的target标志物,比如典型的棋盘格平面板和圆点标定板,标志物通常需要专门定制,无论是棋盘格还是圆点标定板,都是精密仪器加工出来的高精度标定板,标定板各圆点,棋盘格之间的距离精准到丝级。标定板价格也从几十到几千元不等。;后者则可以在自然环境中进行,约束条件少,不需要用专门的target标志物,相对更方便,但是鲁棒性和精度通常差一点;
按照人为参与的程度可以分为手动、半自动和全自动。一般来讲自动化程度越高越方便易用,但是有人工的介入通常会使得标定结果更加鲁棒。
相机与激光雷达标定
autoware_camera_lidar标定工具链是手动、targetless标定方法。具体原理为手动标记图像和点云中的对应点,通过PnP方法首先解线性方程组得到初解(最少需要9对点),再经由优化算法精细求解。
autoware雷达相机联合标定程序的结果是Camera->Lidar
。
本人在autoware的标定程序基础上加入手动动态调参功能,可能人工微调达到理想效果。代码链接
激光雷达与IMU标定
手眼标定:参考文章
浙大LI_Calib
雷达 IMU 标定程序:浙大 Li_Calib 结果为IMU->Lidar
点云的运动畸变校正和数据关联是LIDAR-IMU标定的两个难点。
对于运动畸变校正,大多数现有工作采用短时间内的匀速运动假设或匀加速运动假设进行插值去畸变。
参考链接
港大Lidar_IMU_Init
港大lidar_imu_init:标定结果为Lidar->IMU
使用匀速运动模型去畸变的Fast-lio2得到激光里程计,通过将激光雷达原始帧分割成多个子帧来提高激光里程计的频率。
激光里程计输出每帧扫描结束时刻
t
k
t_k
tk雷达的角速度
ω
L
k
\bm{\omega}_{L_k}
ωLk和线速度
G
v
L
k
^{G}\bold{v}_{L_k}
GvLk。IMU原始数据提供角速度
ω
m
i
\bm{\omega}_{m_i}
ωmi和线加速度
a
m
i
\bold{a}_{m_i}
ami。当满足足够激励的数据收集完毕,就启动初始化模块,输出时间偏移
I
t
L
∈
R
^{I}t_L\in\mathbb{R}
ItL∈R,外参
I
T
L
=
(
I
R
L
,
I
p
L
)
∈
S
E
(
3
)
^{I}\bold{T}_{L}=(^{I}\bold{R}_L,^{I}\bold{p}_{L})\in SE(3)
ITL=(IRL,IpL)∈SE(3),IMU偏置
b
ω
,
b
a
∈
R
3
\bold{b}_{\omega},\bold{b}_{a}\in \mathbb{R}^3
bω,ba∈R3和世界坐标系下的重力向量
G
g
∈
R
3
^{G}\bold{g}\in \mathbb{R}^3
Gg∈R3
- 数据处理部分: 使用non-causal zero phase low-pass filter非因果零相位低通滤波器对激光里程计估计的角速度和线速度以及IMU测量的角速度和加速度进行去噪(主要是高频噪声)
原始IMU测量:
ω m i = ω i g t + b ω + n ω i a m i = a i g t + b a + n a i \begin{aligned} \bm{\omega}_{m_i}&=\bm{\omega}_{i}^{\rm gt}+\bold{b}_{\omega}+\bold{n}_{\omega_i}\\ \bold{a}_{m_i}&=\bold{a}_{i}^{\rm gt}+\bold{b}_{a}+\bold{n}_{a_i} \end{aligned} ωmiami=ωigt+bω+nωi=aigt+ba+nai
去噪IMU测量:
ω I i = ω i g t + b ω a I i = a i g t + b a \begin{aligned} \bm{\omega}_{I_i}&=\bm{\omega}_{i}^{\rm gt}+\bold{b}_{\omega}\\ \bold{a}_{I_i}&=\bold{a}_{i}^{\rm gt}+\bold{b}_{a} \end{aligned} ωIiaIi=ωigt+bω=aigt+ba - 通过non-causal central difference来从LiDAR Odometry的角速度和线速度推算它的角加速度和线性加速度,以及从IMU的角速度差分得到角加速度。
L k = { ω L k , G v L k , Ω L k , G a L k } I i = { ω I i , Ω I i , a I i } \mathcal{L}_k=\{\bm{\omega}_{L_k},{}^{G}\bold{v}_{L_k},\bold{\Omega}_{L_k},{}^{G}\bold{a}_{L_k}\}\\ \mathcal{I}_i=\{\bm{\omega}_{I_i},\bold{\Omega}_{I_i},\bold{a}_{I_i}\} Lk={ωLk,GvLk,ΩLk,GaLk}Ii={ωIi,ΩIi,aIi} - 数据对齐:由于LiDAR和IMU频率不一致,还需要将IMU数据通过插值并降采样得到每个LiDAR odometry时刻
t
k
t_k
tk的IMU数据:
I k = { ω I k , Ω I k , a I k } \mathcal{I}_k=\{\bm{\omega}_{I_k},\bold{\Omega}_{I_k},\bold{a}_{I_k}\} Ik={ωIk,ΩIk,aIk}
最大互相关时间初始化
使用最大互相关(Cross-Correlation)得到时间的偏移的粗略估计(以一个子帧的时间间隔
Δ
t
\Delta t
Δt为单位)。
准确的时间偏移
I
t
L
=
d
∗
Δ
t
+
δ
t
^{I}t_L=d^{*}\Delta t+\delta t
ItL=d∗Δt+δt,
d
d
d为整数
经过最大互相关得到最优的
d
∗
d^{*}
d∗
外参旋转和时间标定
参考IMU模型的角速度式:
ω
=
s
R
v
v
ω
v
i
\boldsymbol{\omega} ={^{\rm{s}}}\bm{R}_{{\rm{v}}}{^{\rm{v}}}\bm{\omega}_{{\rm{vi}}}
ω=sRvvωvi
将sensor系对应IMU系
s
→
I
{\rm s}\to I
s→I,载具系对应Lidar系
v
→
L
{\rm v} \to L
v→L,与文章中变量的对应关系:
- ω → ω I g t = ω ˉ I k − b ω = ω I ( t k + d ∗ Δ t + δ t ) − b ω \boldsymbol{\omega}\to \boldsymbol{\omega}^{\rm gt}_I=\bar{\boldsymbol{\omega}}_{I_k}-\bold{b}_{\omega} =\bm{\omega}_I(t_k+d^{*}\Delta t+\delta t)-\bold{b}_{\omega} ω→ωIgt=ωˉIk−bω=ωI(tk+d∗Δt+δt)−bω
- s R v → I R L {^{\rm s}}\bm{R}_{\rm v}\to {}^{I}\bold{R}_L sRv→IRL
- v ω v i → ω L k {^{\rm{v}}}\bm{\omega}_{{\rm{vi}}}\to\bm{\omega}_{L_k} vωvi→ωLk
得到
ω
I
(
t
k
+
d
∗
Δ
t
+
δ
t
)
−
b
ω
=
I
R
L
ω
L
k
\bm{\omega}_I(t_k+d^{*}\Delta t+\delta t)-\bold{b}_{\omega}={}^{I}\bold{R}_L\bm{\omega}_{L_k}
ωI(tk+d∗Δt+δt)−bω=IRLωLk
假设匀加速运动,在
t
k
+
d
∗
Δ
t
t_k+d^{*}\Delta t
tk+d∗Δt展开
ω
I
(
t
k
+
d
∗
Δ
t
+
δ
t
)
≈
ω
I
k
+
d
+
δ
t
Ω
I
k
+
d
\bm{\omega}_I(t_k+d^{*}\Delta t+\delta t)\approx \bm{\omega}_{I_{k+d}}+\delta t\bold{\Omega}_{I_{k+d}}
ωI(tk+d∗Δt+δt)≈ωIk+d+δtΩIk+d
则有
ω
I
k
′
+
δ
t
Ω
I
k
′
=
I
R
L
ω
L
k
+
b
ω
\bm{\omega}_{I_k'}+\delta t\bold{\Omega}_{I_k'}={}^{I}\bold{R}_L\bm{\omega}_{L_k}+\bold{b}_{\omega}
ωIk′+δtΩIk′=IRLωLk+bω
基于上述约束进行优化求解
I
R
L
,
b
ω
,
δ
t
{}^{I}\bold{R}_L,\bold{b}_{\omega},\delta t
IRL,bω,δt:
arg
min
I
R
L
,
b
ω
,
δ
t
∑
∥
I
R
L
ω
L
k
+
b
ω
−
ω
I
k
′
−
δ
t
Ω
I
k
′
∥
2
(opt 1)
\underset{{}^{I}\bold{R}_L,\bold{b}_{\omega},\delta t}{\arg \min}\sum\Vert{}^{I}\bold{R}_L\bm{\omega}_{L_k}+\bold{b}_{\omega}- \bm{\omega}_{I_k'}-\delta t\bold{\Omega}_{I_k'}\Vert^2\tag{opt 1}
IRL,bω,δtargmin∑∥IRLωLk+bω−ωIk′−δtΩIk′∥2(opt 1)
外参偏移和重力初始化
上一步算出
d
∗
d^{*}
d∗和
δ
t
\delta t
δt之后就可以计算出与
ω
L
k
\bm{\omega}_{L_k}
ωLk对应的IMU角速度
ω
ˉ
I
k
\bar{\bm{\omega}}_{I_k}
ωˉIk和
a
ˉ
I
k
\bar{\bold{a}}_{I_k}
aˉIk
ω
ˉ
I
k
=
ω
I
(
t
k
+
d
∗
Δ
t
+
δ
t
)
≈
ω
I
k
+
d
+
δ
t
Ω
I
k
+
d
a
ˉ
I
k
=
a
I
(
t
k
+
d
∗
Δ
t
+
δ
t
)
≈
a
I
k
+
d
+
δ
t
Δ
t
(
a
I
k
+
d
+
1
−
a
I
k
+
d
)
\bar{\bm{\omega}}_{I_k}=\bm{\omega}_I(t_k+d^{*}\Delta t+\delta t)\approx \bm{\omega}_{I_{k+d}}+\delta t\bold{\Omega}_{I_{k+d}}\\ \bar{\bold{a}}_{I_k}=\bold{a}_I(t_k+d^{*}\Delta t+\delta t)\approx \bold{a}_{I_{k+d}}+\dfrac{\delta t}{\Delta t}(\bold{a}_{I_{k+d+1}}-\bold{a}_{I_{k+d}})
ωˉIk=ωI(tk+d∗Δt+δt)≈ωIk+d+δtΩIk+daˉIk=aI(tk+d∗Δt+δt)≈aIk+d+Δtδt(aIk+d+1−aIk+d)
论文中出现的公式参考IMU模型的acc fixed frame式
A
R
B
a
B
=
a
A
+
ω
A
∧
2
A
p
B
+
Ω
A
∧
A
p
B
{}^{A}\bold{R}_B \bold{a}_B=\bold{a}_A+\bm{\omega}_A^{\wedge2}{}^{A}\bold{p}_B+\bold{\Omega}_A^{\wedge}{}^{A}\bold{p}_B
ARBaB=aA+ωA∧2ApB+ΩA∧ApB
- a A \bold{a}_A aA是A坐标系相对惯性系的加速度在A坐标系下表示
- a B \bold{a}_B aB是B坐标系相对惯性系的加速度在B坐标系下表示
- ω A \bm{\omega}_A ωA是A坐标系相对惯性系的角速度在A坐标系下的表
- Ω A \bold{\Omega}_A ΩA是A坐标系相对惯性系的角加速度在A坐标系下的表示
- A p B {}^{A}\bold{p}_{B} ApB是B坐标系相对于A坐标系的偏移
对于Lidar-inertial system,我们有两个选择A for IMU and B for LiDAR或者相反。由于IMU的角速度和角加速度会被陀螺仪噪声和偏置影响,所以选择A as LiDAR and B as IMU。
LIO得到的雷达的加速度是在全局坐标系描述的
G
a
L
k
{}^{G}\bold{a}_{L_k}
GaLk,计算其等效的IMU测量加速度(假设有一个相同的IMU安装在雷达处)。
a
L
k
=
L
R
L
T
(
G
a
L
k
−
G
g
)
\bold{a}_{L_k}={}^{L}\bold{R}^{T}_L\left( {}^{G}\bold{a}_{L_k}-{}^{G}\bold{g} \right)
aLk=LRLT(GaLk−Gg)
ps:---------------------------------------------------------------------------------------------------
我觉得论文中的这段公式推导有点不好理解,可以直接参考IMU模型的加速度式:
a
=
s
R
v
[
v
R
i
(
i
r
¨
v
i
−
i
g
)
+
(
v
ω
v
i
∧
2
+
v
ω
˙
v
i
∧
v
)
v
r
s
v
]
\bold{a}={}^{\rm s}\bm{R}_{\rm v}\left[ {}^{\rm v}\bm{R}_{\rm i} \left({\rm ^i}\ddot{\bm{r}}_{{\rm{vi}}}-{\rm ^i}\bm{g}\right)+ \left( {^{\rm{v}}}\bm{\omega}_{{\rm{vi}}}^{\wedge 2}+{^{\rm{v}}}\dot{\bm{\omega}}^{\wedge}_{{\rm{vi}}}{^{\rm{v}}}\right){^{\rm{v}}}\bm{r}_{{\rm{s}}{\rm{v}}}\right]
a=sRv[vRi(ir¨vi−ig)+(vωvi∧2+vω˙vi∧v)vrsv]
将sensor系对应IMU系
s
→
I
{\rm s}\to I
s→I,载具系对应Lidar系
v
→
L
{\rm v} \to L
v→L,与文章中变量的对应关系:
- a → a k g t = a ˉ I k − b a \bold{a}\to \bold{a}^{\rm gt}_k=\bar{\bold{a}}_{I_k}-\bold{b}_a a→akgt=aˉIk−ba
- s R v → I R L {^{\rm s}}\bm{R}_{\rm v}\to {}^{I}\bold{R}_L sRv→IRL
- v R i → L R G {^{\rm v}}\bm{R}_{\rm i}\to {}^{L}\bold{R}_G vRi→LRG
- i r ¨ v i → G a L k {\rm ^i}\ddot{\bm{r}}_{{\rm{vi}}}\to {}^{G}\bold{a}_{L_k} ir¨vi→GaLk
- i g → G g {^i}\bm{g}\to{}^{G}\bold{g} ig→Gg
- v ω v i → ω L k {^{\rm{v}}}\bm{\omega}_{{\rm{vi}}}\to\bm{\omega}_{L_k} vωvi→ωLk
- v ω ˙ v i → Ω L k {^{\rm{v}}}\dot{\bm{\omega}}_{{\rm{vi}}}\to\bold{\Omega}_{L_k} vω˙vi→ΩLk
- v r s v → L p I {^{\rm{v}}}\bm{r}_{{\rm{s}}{\rm{v}}}\to {^L}\bold{p}_I vrsv→LpI
变换得到等式:
I
R
L
T
(
a
ˉ
I
k
−
b
a
)
=
L
R
G
(
G
a
L
k
−
G
g
)
+
(
ω
L
k
∧
2
+
Ω
L
k
∧
)
L
p
I
{}^{I}\bold{R}_L^{T}\left(\bar{\bold{a}}_{I_k}-\bold{b}_a\right)= {}^{L}\bold{R}_G\left({}^{G}\bold{a}_{L_k}-{}^{G}\bold{g} \right)+\left(\bm{\omega}_{L_k}^{\wedge 2}+\bold{\Omega}_{L_k}^{\wedge}\right){^L}\bold{p}_I
IRLT(aˉIk−ba)=LRG(GaLk−Gg)+(ωLk∧2+ΩLk∧)LpI
最后可以得到与论文相同的优化问题:
arg
min
L
p
I
,
b
a
,
G
g
∑
∥
I
R
L
T
(
a
ˉ
I
k
−
b
a
)
−
L
R
G
(
G
a
L
k
−
G
g
)
−
(
ω
L
k
∧
2
+
Ω
L
k
∧
)
L
p
I
∥
2
(opt 2)
\underset{{^L}\bold{p}_I,\bold{b}_a,{}^{G}\bold{g}}{\arg\min}\sum\Vert {}^{I}\bold{R}_L^{T}\left(\bar{\bold{a}}_{I_k}-\bold{b}_a\right)- {}^{L}\bold{R}_G\left({}^{G}\bold{a}_{L_k}-{}^{G}\bold{g} \right)-\left(\bm{\omega}_{L_k}^{\wedge 2}+\bold{\Omega}_{L_k}^{\wedge}\right){^L}\bold{p}_I \Vert^2\tag{opt 2}
LpI,ba,Ggargmin∑∥IRLT(aˉIk−ba)−LRG(GaLk−Gg)−(ωLk∧2+ΩLk∧)LpI∥2(opt 2)
计算得到
L
p
I
,
b
a
,
G
g
{^L}\bold{p}_I,\bold{b}_a,{}^{G}\bold{g}
LpI,ba,Gg
激励评估
初始化需要设备充足的运动激励,那么如何评估激励是否充分了呢?
对于最小二乘优化问题,使用高斯-牛顿法求解增量时:
Δ
x
=
−
(
J
(
x
)
T
J
(
x
)
)
−
1
J
(
x
)
T
e
(
x
)
\Delta \boldsymbol{x}=-(\boldsymbol{J}(\boldsymbol{x})^T\boldsymbol{J}(\boldsymbol{x}))^{-1}\boldsymbol{J}(\boldsymbol{x})^T\boldsymbol{e}(x)
Δx=−(J(x)TJ(x))−1J(x)Te(x)
需要求解
J
T
J
\boldsymbol{J}^T\boldsymbol{J}
JTJ的逆,如果其不可逆或者可逆性质不好(即数值求解逆矩阵误差很大),则优化效果会大打折扣。
所以理想的方法是评估优化问题
o
p
t
1
\rm opt1
opt1对于
(
L
R
I
,
b
ω
,
δ
t
)
({}^{L}\bold{R}_I,\bold{b}_{\omega},\delta t)
(LRI,bω,δt)的Jacobian矩阵和
o
p
t
2
\rm opt2
opt2对于
L
p
I
,
b
a
,
G
g
{^L}\bold{p}_I,\bold{b}_a,{}^{G}\bold{g}
LpI,ba,Gg的Jacobian矩阵的秩。
但是论文中说只需评估对于外参旋转
I
R
L
,
{}^{I}\bold{R}_L,
IRL,和外参偏移
L
p
I
,
{}^{L}\bold{p}_I,
LpI,的Jacobian矩阵足矣。
J
r
=
[
⋮
−
I
R
L
ω
L
k
∧
⋮
]
,
J
t
=
[
⋮
ω
L
k
∧
2
+
Ω
L
k
∧
⋮
]
\bold{J}_r=\begin{bmatrix}\vdots\\ -{}^{I}\bold{R}_L\bm{\omega}_{L_k}^{\wedge} \\\vdots\end{bmatrix},\bold{J}_t=\begin{bmatrix}\vdots\\ \bm{\omega}_{L_k}^{\wedge2}+\bold{\Omega}_{L_k}^{\wedge} \\\vdots\end{bmatrix}
Jr=
⋮−IRLωLk∧⋮
,Jt=
⋮ωLk∧2+ΩLk∧⋮
最后问题转化为求
J
r
T
J
r
=
∑
ω
L
k
∧
T
ω
L
k
∧
\bold{J}_r^T\bold{J}_r=\sum{\bm{\omega}_{L_k}^{\wedge}}^T\bm{\omega}_{L_k}^{\wedge}
JrTJr=∑ωLk∧TωLk∧和
J
t
T
J
t
=
∑
(
ω
L
k
∧
2
+
Ω
L
k
∧
)
T
(
ω
L
k
∧
2
+
Ω
L
k
∧
)
\bold{J}_t^T\bold{J}_t=\sum\left({\bm{\omega}_{L_k}^{\wedge2}+\bold{\Omega}_{L_k}^{\wedge}}\right)^T\left(\bm{\omega}_{L_k}^{\wedge2}+\bold{\Omega}_{L_k}^{\wedge}\right)
JtTJt=∑(ωLk∧2+ΩLk∧)T(ωLk∧2+ΩLk∧)的奇异值。最小奇异值要足够大才能保证充分的运动激励。
相机-IMU标定
Kalibr标定原理详解
Kalibr使用参考
遇到问题:ModuleNotFoundError: No module named ‘wx’
标定完的结果检验
autoware标定完的结果是相机相对雷达的坐标变换,求一下逆转换为雷达相对于相机的坐标变换,IMU的标定结果也转换为相机到IMU的坐标变换,然后通过static_transform_publisher发布出去,就可以在rviz中查看标定的外参结果了。
<launch>
<arg name="model" default="$(find xsens_mti_driver)/urdf/MTi_6xx.urdf"/>
<arg name="rvizconfig" default="$(find xsens_mti_driver)/rviz/display.rviz" />
<!-- 发布雷达到相机的tf坐标变换 -->
<node name="tf_pub2" pkg="tf2_ros" type="static_transform_publisher" args="0.0444635 -0.0991606 -0.183957 0.0601806 -1.22453 1.50543 camera rslidar"/>
<!-- 发布相机到IMU的tf坐标变换 -->
<node name="tf_cam2imu" pkg="tf2_ros" type="static_transform_publisher" args="0.162062 0.106803 0.113255 -0.571888 0.402432 -0.410687 0.585167 imu_link camera"/>
<!-- IMU驱动自带的urdf文件,不必要 -->
<param name="robot_description" command="$(find xacro)/xacro --inorder $(arg model)" />
<node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" />
</launch>