文章目录
符号约定
-
点云中的点 p i c p_i^c pic:获取一激光点时,该点在获取时刻的局部坐标系中的坐标, i i i代表点的序号, c c c代表坐标系。0.1s内获取到的点 { p 0 c 0 , p 1 c 1 , ⋯ , p n c n } \{ p_0^{c_0}, p_1^{c_1}, \cdots ,p_n^{c_n}\} {p0c0,p1c1,⋯,pncn},组成了一帧点云。
-
位姿用 T a b T_a^b Tab表示,含义为 p b = T a b p a p^b = T_a^b p^a pb=Tabpa,具体地,
T a b = [ C a b r a b 0 1 ] T a b − 1 = [ C a b − 1 − C a b − 1 r a b 0 1 ] = [ C b a − C b a r a b 0 1 ] = [ C b a r b a 0 1 ] = T b a (1) T_a^b = \begin{bmatrix} C_a^b & r_a^b \\ 0 & 1\end{bmatrix}\\ {T_a^b}^{-1} = \begin{bmatrix} {C_a^b}^{-1} & -{C_a^b}^{-1}r_a^b \\ 0 & 1\end{bmatrix} = \begin{bmatrix} {C_b^a} & -{C_b^a} r_a^b \\ 0 & 1\end{bmatrix} = \begin{bmatrix} {C_b^a} & r_b^a \\ 0 & 1\end{bmatrix} = T_b^a \tag{1} Tab=[Cab0rab1]Tab−1=[Cab−10−Cab−1rab1]=[Cba0−Cbarab1]=[Cba0rba1]=Tba(1)
r a b r_a^b rab表示a系原点在b系中的坐标, r b a r_b^a rba表示b系原点在a系中的坐标。
- 关于坐标系符号,有以下约定,
w w w:世界坐标系;
c c c:获取激光点时的激光坐标系;
s s s:每帧点云的起始时刻坐标系;
e e e:每帧点云的终止时刻坐标系;
需要注意的是,loam中假设了imu和激光雷达的外参为 I \boldsymbol{I} I,也就是说,imu局部坐标系与激光局部坐标系是重合的,可以不区分imu系和激光系。
对于一帧点云,我们可以用
T
c
s
T_c^s
Tcs将点
p
i
c
p_i^c
pic转换到该帧点云的
s
s
s系,具体地,
p
i
s
=
T
c
s
p
i
c
=
T
s
w
−
1
T
c
w
p
i
c
p_i^s = T_c^s p_i^c = {T_s^w}^{-1} T_c^w p_i^c
pis=Tcspic=Tsw−1Tcwpic
其中,
T
s
w
=
[
C
s
w
r
s
w
0
1
]
,
T
s
w
−
1
=
[
C
w
s
−
C
w
s
r
s
w
0
1
]
,
T
c
w
=
[
C
c
w
r
c
w
0
1
]
T_s^w = \begin{bmatrix} C_s^w & r_s^w \\ 0 & 1\end{bmatrix},{T_s^w}^{-1} = \begin{bmatrix} C_w^s & -C_w^s r_s^w \\ 0 & 1\end{bmatrix},T_c^w = \begin{bmatrix} C_c^w & r_c^w \\ 0 & 1\end{bmatrix}
Tsw=[Csw0rsw1],Tsw−1=[Cws0−Cwsrsw1],Tcw=[Ccw0rcw1]
有,
T
s
w
−
1
T
c
w
=
[
C
w
s
C
c
w
C
w
s
(
r
c
w
−
r
s
w
)
0
1
]
{T_s^w}^{-1} T_c^w = \begin{bmatrix} C_w^s C_c^w & C_w^s(r_c^w - r_s^w)\\ 0 & 1 \end{bmatrix}
Tsw−1Tcw=[CwsCcw0Cws(rcw−rsw)1]
imu从
s
s
s系到
c
c
c系的平移运动,可以分成两部分,即匀速部分和非匀速部分,设匀速部分的位移为
r
u
n
i
f
∣
c
w
r_{unif |c}^w
runif∣cw,非匀速部分的位移为
r
s
h
i
f
t
∣
c
w
r_{shift | c}^w
rshift∣cw,有
r
c
w
−
r
s
w
=
r
u
n
i
f
∣
c
w
+
r
s
h
i
f
t
∣
c
w
r_c^w - r_s^w = r_{unif | c}^w + r_{shift | c}^w
rcw−rsw=runif∣cw+rshift∣cw,带入上式,有,
T
s
w
−
1
T
c
w
=
[
C
w
s
C
c
w
C
w
s
r
u
n
i
f
∣
c
w
+
C
w
s
r
s
h
i
f
t
∣
c
w
0
1
]
{T_s^w}^{-1} T_c^w = \begin{bmatrix} C_w^s C_c^w & C_w^s r_{unif | c}^w + C_w^s r_{shift | c}^w\\ 0 & 1 \end{bmatrix}
Tsw−1Tcw=[CwsCcw0Cwsrunif∣cw+Cwsrshift∣cw1]
如果我们可以得到上方公式中各个变量的值,那么就可以直接将点云中的畸变点转移到同一坐标系
s
s
s系中。但是实际中,我们不能直接得到
r
u
n
i
f
∣
c
w
r_{unif | c}^w
runif∣cw的值,我们将
r
u
n
i
f
∣
c
w
r_{unif | c}^w
runif∣cw剔除,得到以下公式,
T
c
s
=
T
s
w
−
1
T
c
w
=
[
C
w
s
C
c
w
C
w
s
r
s
h
i
f
t
∣
c
w
0
1
]
(2)
T_c^s = {T_s^w}^{-1} T_c^w = \begin{bmatrix} C_w^s C_c^w & C_w^s r_{shift | c}^w\\ 0 & 1 \end{bmatrix} \tag{2}
Tcs=Tsw−1Tcw=[CwsCcw0Cwsrshift∣cw1](2)
我们可以用
T
c
s
T_c^s
Tcs将点云转换到
s
s
s系,但此时的点云仍然是有畸变的,该畸变只由匀速运动造成,注意,可以认为这里没有旋转的畸变,只有平移的畸变。我们用
T
c
s
p
i
c
T_c^s p_i^c
Tcspic得到只有匀速运动畸变的
s
s
s系点云,这一步发生在代码的TransformToStartIMU
函数中。
对于匀速运动的畸变,我们可以设他的位姿矩阵为
T
s
e
′
T_s^{e'}
Tse′,具体如下,
T
s
e
′
=
[
C
s
e
′
r
s
e
′
0
1
]
C
s
e
′
=
C
r
o
l
l
C
p
i
t
c
h
C
y
a
w
=
C
z
C
x
C
y
T_s^{e'} = \begin{bmatrix}C_s^{e'} & r_s^{e'} \\ 0 & 1\end{bmatrix}\\ C_s^{e'} = C_{roll}C_{pitch}C_{yaw}=C_{z}C_{x}C_{y}
Tse′=[Cse′0rse′1]Cse′=CrollCpitchCyaw=CzCxCy
其中
C
s
e
′
C_s^{e'}
Cse′为
e
′
{e'}
e′系按
r
o
l
l
roll
roll(
z
z
z轴)->
p
i
t
c
h
pitch
pitch(
x
x
x轴)->
y
a
w
yaw
yaw(
y
y
y轴)得到与
s
s
s系“平行”的坐标系,
r
s
e
′
r_s^{e'}
rse′为
s
s
s系原点在
e
′
e'
e′系中的坐标。其中
e
′
e'
e′代表从
s
s
s开始,匀速运动的终点,前面提到的
r
o
l
l
,
p
i
t
c
h
,
y
a
w
roll,pitch,yaw
roll,pitch,yaw以及
r
s
e
′
r_s^{e'}
rse′就是odom中需要求解的位姿。根据
e
′
e'
e′的意义,我们有,
T
e
′
w
=
[
C
s
w
r
s
w
+
r
u
n
i
f
∣
e
w
0
1
]
T_{e'}^w = \begin{bmatrix} C_s^w & r_s^w + r_{unif | e}^w \\ 0 & 1\end{bmatrix}
Te′w=[Csw0rsw+runif∣ew1]
旋转矩阵使用
C
s
w
C_s^w
Csw是因为经过
T
c
s
p
i
c
T_c^s p_i^c
Tcspic的变换,只有平移上的位姿变换,没有旋转。
将点云转换到 e \boldsymbol{e} e系
利用 T c s p i c T_c^s p_i^c Tcspic,可以将原始激光点云,转换到 s s s系,且只有匀速运动畸变,设转换后的点为 p i c ′ p_i^{c'} pic′,这也是后面提取特征点以及odom、mapping使用的局部点云。
对于点
p
i
c
′
p_i^{c'}
pic′,我们用线性插值的方式将其转换到
s
s
s系中,如下,
p
i
s
=
(
α
T
s
e
′
)
−
1
p
i
c
′
=
[
(
α
C
s
e
′
)
−
1
−
(
α
C
s
e
′
)
−
1
r
s
e
′
0
1
]
[
p
i
c
′
1
]
(3)
p_i^s = {(\alpha T_s^{e'})}^{-1} p_i^{c'} = \begin{bmatrix} {(\alpha C_s^{e'})}^{-1} & -{(\alpha C_s^{e'})}^{-1} r_s^{e'} \\ 0 & 1\end{bmatrix} \begin{bmatrix}p_i^{c'} \\ 1 \end{bmatrix} \tag{3}
pis=(αTse′)−1pic′=[(αCse′)−10−(αCse′)−1rse′1][pic′1](3)
其中
α
\alpha
α是线性插值因子,上方公式中的转换发生在TransformToStart
中。
对于去掉运动畸变的
s
s
s系中的点
p
i
s
p_i^s
pis,转换到
e
e
e系的公式如下,
p
i
e
=
T
e
′
e
T
s
e
′
p
i
s
T
e
′
e
=
T
e
w
−
1
T
e
′
w
=
[
C
e
w
−
1
−
C
e
w
−
1
r
e
w
0
1
]
[
C
s
w
r
s
w
+
r
u
n
i
f
∣
e
w
0
1
]
=
[
C
e
w
−
1
C
s
w
C
e
w
−
1
(
r
s
w
+
r
u
n
i
f
∣
e
w
−
r
e
w
)
0
1
]
p_i^e = T_{e'}^e T_s^{e'} p_i^s \\ T_{e'}^e = {T_e^w}^{-1} T_{e'}^w = \begin{bmatrix} {C_e^w}^{-1} & -{C_e^w}^{-1}r_e^w \\ 0 & 1\end{bmatrix} \begin{bmatrix} {C_s^w} & r_s^w + r_{unif | e}^w \\ 0 & 1\end{bmatrix} = \begin{bmatrix} {C_e^w}^{-1}C_s^w & {C_e^w}^{-1}(r_s^w + r_{unif | e}^w - r_e^w) \\ 0 & 1 \end{bmatrix}
pie=Te′eTse′pisTe′e=Tew−1Te′w=[Cew−10−Cew−1rew1][Csw0rsw+runif∣ew1]=[Cew−1Csw0Cew−1(rsw+runif∣ew−rew)1]
因为
r
e
w
−
r
s
w
=
r
u
n
i
f
∣
e
w
+
r
s
h
i
f
t
∣
e
w
r_e^w - r_s^w = r_{unif | e}^w + r_{shift | e}^w
rew−rsw=runif∣ew+rshift∣ew,且
r
s
h
i
f
t
∣
e
w
=
C
s
w
r
s
h
i
f
t
∣
e
s
r_{shift | e}^w = C_s^w r_{shift | e}^s
rshift∣ew=Cswrshift∣es,因此
T
e
′
e
T_{e'}^e
Te′e如下,
T
e
′
e
=
[
C
e
w
−
1
C
s
w
−
C
e
w
−
1
C
s
w
r
s
h
i
f
t
∣
e
s
0
1
]
T_{e'}^e =\begin{bmatrix} {C_e^w}^{-1}C_s^w & -{C_e^w}^{-1}C_s^w r_{shift | e}^s \\ 0 & 1 \end{bmatrix}
Te′e=[Cew−1Csw0−Cew−1Cswrshift∣es1]
综上,将点
p
i
c
′
p_i^{c'}
pic′转到
e
e
e系的各个位姿矩阵都已经清楚了,直接带入即可。过程为:
p
i
c
′
→
p
i
s
→
p
i
e
′
→
p
i
e
p_i^{c'} \rightarrow p_i^s \rightarrow p_i^{e'} \rightarrow p_i^e
pic′→pis→pie′→pie
这一过程在TransformToEnd
函数中。
对于odom中全局位姿(transformSum)的计算
设前一帧的全局位姿为
T
s
u
m
∣
i
w
T_{sum | i}^w
Tsum∣iw,由于最后我们将无畸变的点云转换到了
e
e
e系,且前一帧的
e
e
e系就是当前帧的
s
s
s系,所以当前帧的全局位姿为,
T
s
u
m
∣
i
+
1
w
=
T
s
u
m
∣
i
w
T
e
s
=
T
s
u
m
∣
i
w
T
s
e
′
−
1
T
e
′
e
−
1
=
[
C
s
u
m
∣
i
w
r
s
u
m
∣
i
w
0
1
]
[
C
s
e
′
−
1
−
C
s
e
′
−
1
r
s
e
′
0
1
]
[
C
s
w
−
1
C
e
w
r
s
h
i
f
t
∣
e
s
0
1
]
=
[
C
s
u
m
∣
i
w
C
s
e
′
−
1
−
C
s
u
m
∣
i
w
C
s
e
′
−
1
r
s
e
′
+
r
s
u
m
∣
i
w
0
1
]
[
C
s
w
−
1
C
e
w
r
s
h
i
f
t
∣
e
s
0
1
]
=
[
C
s
u
m
∣
i
w
C
s
e
′
−
1
C
s
w
−
1
C
e
w
−
C
s
u
m
∣
i
w
C
s
e
′
−
1
(
r
s
e
′
−
r
s
h
i
f
t
∣
e
s
)
+
r
s
u
m
∣
i
w
0
1
]
(4)
\begin{split} T_{sum | i+1}^w &= T_{sum | i}^w T_e^s = T_{sum | i}^w {T_s^{e'}}^{-1} {T_{e'}^e}^{-1} \\ &=\begin{bmatrix}C_{sum | i}^w & r_{sum | i}^w \\ 0 & 1 \end{bmatrix} \begin{bmatrix}{C_s^{e'}}^{-1} & -{C_s^{e'}}^{-1}r_s^{e'} \\ 0 & 1 \end{bmatrix} \begin{bmatrix} {C_s^w}^{-1}{C_e^w} & r_{shift | e}^s \\ 0 & 1 \end{bmatrix} \\ &=\begin{bmatrix}C_{sum | i}^w {C_s^{e'}}^{-1} & -C_{sum | i}^w {C_s^{e'}}^{-1}r_s^{e'} + r_{sum | i}^w \\ 0 & 1 \end{bmatrix} \begin{bmatrix} {C_s^w}^{-1}{C_e^w} & r_{shift | e}^s \\ 0 & 1 \end{bmatrix} \\ &=\begin{bmatrix}C_{sum | i}^w {C_s^{e'}}^{-1} {C_s^w}^{-1}{C_e^w} & -C_{sum | i}^w {C_s^{e'}}^{-1} (r_s^{e'} - r_{shift | e}^s) + r_{sum | i}^w \\ 0 & 1 \end{bmatrix} \end{split} \tag{4}
Tsum∣i+1w=Tsum∣iwTes=Tsum∣iwTse′−1Te′e−1=[Csum∣iw0rsum∣iw1][Cse′−10−Cse′−1rse′1][Csw−1Cew0rshift∣es1]=[Csum∣iwCse′−10−Csum∣iwCse′−1rse′+rsum∣iw1][Csw−1Cew0rshift∣es1]=[Csum∣iwCse′−1Csw−1Cew0−Csum∣iwCse′−1(rse′−rshift∣es)+rsum∣iw1](4)
上方公式中的
C
s
u
m
∣
i
w
C
s
e
′
−
1
C_{sum | i}^w {C_s^{e'}}^{-1}
Csum∣iwCse′−1,在AccumulateRotation
函数中计算,
C
s
u
m
∣
i
w
C
s
e
′
−
1
C
s
w
−
1
C
e
w
C_{sum | i}^w {C_s^{e'}}^{-1} {C_s^w}^{-1}{C_e^w}
Csum∣iwCse′−1Csw−1Cew在PluginIMURotation
函数中计算。
−
C
s
u
m
∣
i
w
C
s
e
′
−
1
(
r
s
e
′
−
r
s
h
i
f
t
∣
e
s
)
+
r
s
u
m
∣
i
w
-C_{sum | i}^w {C_s^{e'}}^{-1} (r_s^{e'} - r_{shift | e}^s) + r_{sum | i}^w
−Csum∣iwCse′−1(rse′−rshift∣es)+rsum∣iw在代码中的计算如下,
float x1 = cos(rz) * (transform[3] - imuShiftFromStartX)
- sin(rz) * (transform[4] - imuShiftFromStartY);
float y1 = sin(rz) * (transform[3] - imuShiftFromStartX)
+ cos(rz) * (transform[4] - imuShiftFromStartY);
float z1 = transform[5] * 1.05 - imuShiftFromStartZ;
float x2 = x1;
float y2 = cos(rx) * y1 - sin(rx) * z1;
float z2 = sin(rx) * y1 + cos(rx) * z1;
//全局位姿的平移量
tx = transformSum[3] - (cos(ry) * x2 + sin(ry) * z2);
ty = transformSum[4] - y2;
tz = transformSum[5] - (-sin(ry) * x2 + cos(ry) * z2);
AccumulateRotation
的公式推导
由于从imu得到的欧拉角 y a w , p i t c h , r o l l yaw,pitch,roll yaw,pitch,roll的约定为,世界系 w w w为 x x x轴向前, y y y轴向左, z z z轴向上的坐标系,沿 z z z轴按右手系转 y a w yaw yaw角,按旋转后的坐标系沿 y y y轴按右手系转 p i t c h pitch pitch角,接着按旋转后的坐标系沿 x x x轴按右手系转 r o l l roll roll角,得到imu局部坐标系 b b b。
由于代码中采用的是
x
x
x轴向左,
y
y
y轴向上,
z
z
z轴向前的坐标系,我们仍按之前的
y
a
w
yaw
yaw,
p
i
t
c
h
pitch
pitch,
r
o
l
l
roll
roll的旋转,也就是,世界系
w
w
w先沿
y
y
y轴按右手系转
y
a
w
yaw
yaw(或记为
r
y
ry
ry)角,按旋转后的坐标系沿
x
x
x轴按右手系转
p
i
t
c
h
pitch
pitch(或记为
r
x
rx
rx)角,接着按旋转后的坐标系沿
z
z
z轴按右手系转
r
o
l
l
roll
roll(或记为
r
z
rz
rz)角,旋转矩阵
C
I
w
C_{I}^w
CIw如下,
C
I
w
=
R
r
y
R
r
x
R
r
z
R
r
y
=
[
cos
r
y
0
sin
r
y
0
1
0
−
sin
r
y
0
cos
r
y
]
R
r
x
=
[
1
0
0
0
cos
r
x
−
sin
r
x
0
sin
r
x
cos
r
x
]
R
r
z
=
[
cos
r
z
−
sin
r
z
0
sin
r
z
cos
r
z
0
0
0
1
]
C_{I}^w = R_{ry}R_{rx}R_{rz} \\ R_{ry} = \begin{bmatrix} \cos{ry} & 0 & \sin{ry}\\ 0 & 1 & 0 \\ -\sin{ry} & 0 & \cos{ry}\end{bmatrix}\\ R_{rx} = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos{rx} & -\sin{rx} \\ 0 & \sin{rx} & \cos{rx} \end{bmatrix}\\ R_{rz} = \begin{bmatrix} \cos{rz} & -\sin{rz} & 0\\ \sin{rz} & \cos{rz} & 0\\ 0 & 0 & 1\end{bmatrix}
CIw=RryRrxRrzRry=
cosry0−sinry010sinry0cosry
Rrx=
1000cosrxsinrx0−sinrxcosrx
Rrz=
cosrzsinrz0−sinrzcosrz0001
需要注意,使用上方公式时,需要先将获取的原始点转换到
x
x
x轴向左,
y
y
y轴向上,
z
z
z轴向前的局部坐标系。
由于
C
s
u
m
∣
i
w
C
s
e
′
−
1
=
C
s
u
m
∣
i
w
C
e
′
s
C_{sum | i}^w {C_s^{e'}}^{-1} = C_{sum | i}^w C_{e'}^s
Csum∣iwCse′−1=Csum∣iwCe′s,AccumulateRotation
中计算的是
C
s
u
m
∣
i
w
C
e
′
s
C_{sum | i}^w C_{e'}^s
Csum∣iwCe′s,设
C
s
u
m
∣
i
w
C_{sum | i}^w
Csum∣iw为
w
w
w系按
c
y
cy
cy,
c
x
cx
cx,
c
z
cz
cz转到
s
u
m
∣
i
sum|i
sum∣i系,
C
e
′
s
C_{e'}^s
Ce′s为
s
s
s系按
l
y
ly
ly,
l
x
lx
lx,
l
z
lz
lz(这里的量是
C
s
e
′
C_s^{e'}
Cse′中按三轴旋转量的负值,因为从
e
′
e'
e′系到
s
s
s系为按
r
o
l
l
roll
roll(
z
z
z轴)->
p
i
t
c
h
pitch
pitch(
x
x
x轴)->
y
a
w
yaw
yaw(
y
y
y轴)的旋转,所以从
s
s
s系到
e
′
e'
e′系就是按
−
y
a
w
-yaw
−yaw(
y
y
y轴)->
−
p
i
t
c
h
-pitch
−pitch(
x
x
x轴)->
−
r
o
l
l
-roll
−roll(
z
z
z轴))转到
e
′
e'
e′系。我们现在想得到
C
e
′
w
=
C
s
u
m
∣
i
w
C
e
′
s
C_{e'}^w = C_{sum | i}^w C_{e'}^s
Ce′w=Csum∣iwCe′s的
y
a
w
yaw
yaw,
p
i
t
c
h
pitch
pitch,
r
o
l
l
roll
roll(
o
y
oy
oy,
o
x
ox
ox,
o
z
oz
oz),即
R
o
y
R
o
x
R
o
z
=
R
c
y
R
c
x
R
c
z
R
l
y
R
l
x
R
l
z
R_{oy}R_{ox}R_{oz} = R_{cy}R_{cx}R_{cz}R_{ly}R_{lx}R_{lz}
RoyRoxRoz=RcyRcxRczRlyRlxRlz
AccumulateRotation
函数的输入为transformSum的
y
a
w
,
p
i
t
c
h
,
r
o
l
l
yaw,pitch,roll
yaw,pitch,roll,以及
C
e
′
s
C_{e'}^s
Ce′s的
y
a
w
,
p
i
t
c
h
,
r
o
l
l
yaw,pitch,roll
yaw,pitch,roll(也就是
C
s
e
′
C_s^{e'}
Cse′的
y
a
w
,
p
i
t
c
h
,
r
o
l
l
yaw,pitch,roll
yaw,pitch,roll的负值),所以函数的关于transfrom的输入是带负号的。
R
o
y
R
o
x
R
o
z
R_{oy}R_{ox}R_{oz}
RoyRoxRoz,
R
c
y
R
c
x
R
c
z
R
l
y
R
l
x
R
l
z
R_{cy}R_{cx}R_{cz}R_{ly}R_{lx}R_{lz}
RcyRcxRczRlyRlxRlz的计算使用matlab的符号表达式计算,m代码如下,
syms cx cy cz lx ly lz ox oy oz fout fin1 fin2 fin;
%C_{sum|i}^{w}
Rcx = [1,0,0;
0,cos(cx),-sin(cx);
0,sin(cx),cos(cx)];
Rcy = [cos(cy),0,sin(cy);
0,1,0;
-sin(cy),0,cos(cy)];
Rcz = [cos(cz),-sin(cz),0;
sin(cz),cos(cz),0;
0,0,1];
%C_{e'}^{s}
Rlx = [1,0,0;
0,cos(lx),-sin(lx);
0,sin(lx),cos(lx)];
Rly = [cos(ly),0,sin(ly);
0,1,0;
-sin(ly),0,cos(ly)];
Rlz = [cos(lz),-sin(lz),0;
sin(lz),cos(lz),0;
0,0,1];
%C_{e'}^{w}
Rox = [1,0,0;
0,cos(ox),-sin(ox);
0,sin(ox),cos(ox)];
Roy = [cos(oy),0,sin(oy);
0,1,0;
-sin(oy),0,cos(oy)];
Roz = [cos(oz),-sin(oz),0;
sin(oz),cos(oz),0;
0,0,1];
%R_out
fout = Roy*Rox*Roz
fin1 = Rcy*Rcx*Rcz
fin2 = Rly*Rlx*Rlz
%R_in
fin = fin1*fin2
为简化符号,记
R
o
y
R
o
x
R
o
z
R_{oy}R_{ox}R_{oz}
RoyRoxRoz为
R
o
u
t
R_{out}
Rout,
R
c
y
R
c
x
R
c
z
R
l
y
R
l
x
R
l
z
R_{cy}R_{cx}R_{cz}R_{ly}R_{lx}R_{lz}
RcyRcxRczRlyRlxRlz记为
R
i
n
R_{in}
Rin,矩阵中的行列序号从1开始,
R
o
u
t
(
1
,
1
)
R_{out}(1,1)
Rout(1,1)为第一行第一列,
R
o
u
t
R_{out}
Rout的计算结果如下,
R
o
u
t
=
[
cos
(
o
y
)
cos
(
o
z
)
+
sin
(
o
x
)
sin
(
o
y
)
sin
(
o
z
)
cos
(
o
z
)
sin
(
o
x
)
sin
(
o
y
)
−
cos
(
o
y
)
sin
(
o
z
)
cos
(
o
x
)
sin
(
o
y
)
cos
(
o
x
)
sin
(
o
z
)
cos
(
o
x
)
cos
(
o
z
)
−
sin
(
o
x
)
cos
(
o
y
)
sin
(
o
x
)
sin
(
o
z
)
−
cos
(
o
z
)
sin
(
o
y
)
sin
(
o
y
)
sin
(
o
z
)
+
cos
(
o
y
)
cos
(
o
z
)
sin
(
o
x
)
cos
(
o
x
)
cos
(
o
y
)
]
R_{out}=\begin{bmatrix} \cos(oy)\cos(oz) + \sin(ox)\sin(oy)\sin(oz) & \cos(oz)\sin(ox)\sin(oy) - \cos(oy)\sin(oz) & \cos(ox)\sin(oy) \\ \cos(ox)\sin(oz) & \cos(ox)\cos(oz) & -\sin(ox)\\ \cos(oy)\sin(ox)\sin(oz) - \cos(oz)\sin(oy) & \sin(oy)\sin(oz) + \cos(oy)\cos(oz)\sin(ox)& \cos(ox)\cos(oy)\end{bmatrix}
Rout=
cos(oy)cos(oz)+sin(ox)sin(oy)sin(oz)cos(ox)sin(oz)cos(oy)sin(ox)sin(oz)−cos(oz)sin(oy)cos(oz)sin(ox)sin(oy)−cos(oy)sin(oz)cos(ox)cos(oz)sin(oy)sin(oz)+cos(oy)cos(oz)sin(ox)cos(ox)sin(oy)−sin(ox)cos(ox)cos(oy)
用
R
i
n
(
2
,
3
)
=
R
o
u
t
(
2
,
3
)
R_{in}(2,3)=R_{out}(2,3)
Rin(2,3)=Rout(2,3)来计算
o
x
ox
ox,用下式计算
o
y
oy
oy,
tan
o
y
=
R
i
n
(
1
,
3
)
cos
o
x
R
i
n
(
3
,
3
)
cos
o
x
=
R
o
u
t
(
1
,
3
)
cos
o
x
R
o
u
t
(
3
,
3
)
cos
o
x
\tan{oy} = \frac{\frac{R_{in}(1,3)}{\cos{ox}}}{\frac{R_{in}(3,3)}{\cos{ox}}} = \frac{\frac{R_{out}(1,3)}{\cos{ox}}}{\frac{R_{out}(3,3)}{\cos{ox}}}
tanoy=cosoxRin(3,3)cosoxRin(1,3)=cosoxRout(3,3)cosoxRout(1,3)
R
o
u
t
(
1
,
3
)
R_{out}(1,3)
Rout(1,3)的matlab计算结果如下,
sin(lx)*(cos(cy)*sin(cz) - cos(cz)*sin(cx)*sin(cy)) + cos(lx)*sin(ly)*(cos(cy)*cos(cz) + sin(cx)*sin(cy)*sin(cz)) + cos(cx)*cos(lx)*cos(ly)*sin(cy)
R o u t ( 3 , 3 ) R_{out}(3,3) Rout(3,3)的matlab计算结果如下,
cos(cx)*cos(cy)*cos(lx)*cos(ly) - cos(lx)*sin(ly)*(cos(cz)*sin(cy) - cos(cy)*sin(cx)*sin(cz)) - sin(lx)*(sin(cy)*sin(cz) + cos(cy)*cos(cz)*sin(cx))
可以看到,该计算结果与代码中是一样的。
o
z
oz
oz的计算如下,
tan
o
z
=
R
i
n
(
2
,
1
)
cos
o
x
R
i
n
(
2
,
2
)
cos
o
x
=
R
o
u
t
(
2
,
1
)
cos
o
x
R
o
u
t
(
2
,
2
)
cos
o
x
\tan{oz} = \frac{\frac{R_{in}(2,1)}{\cos{ox}}}{\frac{R_{in}(2,2)}{\cos{ox}}} = \frac{\frac{R_{out}(2,1)}{\cos{ox}}}{\frac{R_{out}(2,2)}{\cos{ox}}}
tanoz=cosoxRin(2,2)cosoxRin(2,1)=cosoxRout(2,2)cosoxRout(2,1)
R
o
u
t
(
2
,
1
)
R_{out}(2,1)
Rout(2,1)的matlab计算结果如下,
sin(cx)*(cos(lz)*sin(ly) - cos(ly)*sin(lx)*sin(lz)) + cos(cx)*sin(cz)*(cos(ly)*cos(lz) + sin(lx)*sin(ly)*sin(lz)) + cos(cx)*cos(cz)*cos(lx)*sin(lz)
R o u t ( 2 , 2 ) R_{out}(2,2) Rout(2,2)的matlab计算结果如下,
cos(cx)*cos(cz)*cos(lx)*cos(lz) - cos(cx)*sin(cz)*(cos(ly)*sin(lz) - cos(lz)*sin(lx)*sin(ly)) - sin(cx)*(sin(ly)*sin(lz) + cos(ly)*cos(lz)*sin(lx))
可以看到,该计算结果与代码中是一样的。
PluginIMURotation
的公式推导
C
s
u
m
∣
i
w
C
s
e
′
−
1
C
s
w
−
1
C
e
w
C_{sum | i}^w {C_s^{e'}}^{-1} {C_s^w}^{-1}{C_e^w}
Csum∣iwCse′−1Csw−1Cew在PluginIMURotation
函数中计算,前面已经计算了
C
s
u
m
∣
i
w
C
s
e
′
−
1
C_{sum | i}^w {C_s^{e'}}^{-1}
Csum∣iwCse′−1的欧拉角,为与代码中的符号一致,这里记
C
s
u
m
∣
i
w
C
s
e
′
−
1
C_{sum | i}^w {C_s^{e'}}^{-1}
Csum∣iwCse′−1的欧拉角为
b
c
x
,
b
c
y
,
b
c
z
bcx,bcy,bcz
bcx,bcy,bcz,记
C
s
w
{C_s^w}
Csw的欧拉角为
b
l
x
,
b
l
y
,
b
l
z
blx,bly,blz
blx,bly,blz,记
C
e
w
C_e^w
Cew的欧拉角为
a
l
x
,
a
l
y
,
a
l
z
alx,aly,alz
alx,aly,alz。我们在PluginIMURotation
函数中计算得到的
C
s
u
m
∣
i
+
1
w
C_{sum|i+1}^w
Csum∣i+1w的欧拉角,记为
a
c
x
,
a
c
y
,
a
c
z
acx,acy,acz
acx,acy,acz,计算方法与AccumulateRotation
类似,都是找恒等关系,这里的恒等关系如下,
C
s
u
m
∣
i
+
1
w
=
C
e
′
w
C
s
w
−
1
C
e
w
R
a
c
y
R
a
c
x
R
a
c
z
=
R
b
c
y
R
b
c
x
R
b
c
z
R
b
l
z
−
1
R
b
l
x
−
1
R
b
l
y
−
1
R
a
l
y
R
a
l
x
R
a
l
z
C_{sum|i+1}^w = C_{e'}^w {C_s^w}^{-1}{C_e^w} \\ R_{acy}R_{acx}R_{acz} = R_{bcy}R_{bcx}R_{bcz}{R_{blz}}^{-1}{R_{blx}}^{-1}{R_{bly}}^{-1}R_{aly}R_{alx}R_{alz}
Csum∣i+1w=Ce′wCsw−1CewRacyRacxRacz=RbcyRbcxRbczRblz−1Rblx−1Rbly−1RalyRalxRalz
这里同样记等号左边为
R
o
u
t
R_{out}
Rout,等号右边为
R
i
n
R_{in}
Rin,matlab代码如下,
syms bcx bcy bcz blx bly blz alx aly alz acx acy acz fout fin1 fin2 fin3 fin;
%C_{e'}^{w}
Rbcx = [1,0,0;
0,cos(bcx),-sin(bcx);
0,sin(bcx),cos(bcx)];
Rbcy = [cos(bcy),0,sin(bcy);
0,1,0;
-sin(bcy),0,cos(bcy)];
Rbcz = [cos(bcz),-sin(bcz),0;
sin(bcz),cos(bcz),0;
0,0,1];
%C_{s}^{w}
Rblx = [1,0,0;
0,cos(blx),-sin(blx);
0,sin(blx),cos(blx)];
Rbly = [cos(bly),0,sin(bly);
0,1,0;
-sin(bly),0,cos(bly)];
Rblz = [cos(blz),-sin(blz),0;
sin(blz),cos(blz),0;
0,0,1];
%C_{e}^{w}
Ralx = [1,0,0;
0,cos(alx),-sin(alx);
0,sin(alx),cos(alx)];
Raly = [cos(aly),0,sin(aly);
0,1,0;
-sin(aly),0,cos(aly)];
Ralz = [cos(alz),-sin(alz),0;
sin(alz),cos(alz),0;
0,0,1];
%C_{sum|i+1}^{w}
Racx = [1,0,0;
0,cos(acx),-sin(acx);
0,sin(acx),cos(acx)];
Racy = [cos(acy),0,sin(acy);
0,1,0;
-sin(acy),0,cos(acy)];
Racz = [cos(acz),-sin(acz),0;
sin(acz),cos(acz),0;
0,0,1];
%R_out
fout = Racy*Racx*Racz
fin1 = Rbcy*Rbcx*Rbcz
fin2 = (Rblz.')*(Rblx.')*(Rbly.')
fin3 = Raly*Ralx*Ralz
%R_in
fin = fin1*fin2*fin3
%展开表达式,便于与代码对比
%求x
expand(fin(2,3))
%求y
expand(fin(1,3))
expand(fin(3,3))
%求z
expand(fin(2,1))
expand(fin(2,2))
用
R
i
n
(
2
,
3
)
=
R
o
u
t
(
2
,
3
)
R_{in}(2,3)=R_{out}(2,3)
Rin(2,3)=Rout(2,3)来计算
a
c
x
acx
acx,用下式计算
a
c
y
acy
acy,
tan
a
c
y
=
R
i
n
(
1
,
3
)
cos
a
c
x
R
i
n
(
3
,
3
)
cos
a
c
x
=
R
o
u
t
(
1
,
3
)
cos
a
c
x
R
o
u
t
(
3
,
3
)
cos
a
c
x
\tan{acy} = \frac{\frac{R_{in}(1,3)}{\cos{acx}}}{\frac{R_{in}(3,3)}{\cos{acx}}} = \frac{\frac{R_{out}(1,3)}{\cos{acx}}}{\frac{R_{out}(3,3)}{\cos{acx}}}
tanacy=cosacxRin(3,3)cosacxRin(1,3)=cosacxRout(3,3)cosacxRout(1,3)
a
c
z
acz
acz的计算如下,
tan
a
c
z
=
R
i
n
(
2
,
1
)
cos
a
c
x
R
i
n
(
2
,
2
)
cos
a
c
x
=
R
o
u
t
(
2
,
1
)
cos
a
c
x
R
o
u
t
(
2
,
2
)
cos
a
c
x
\tan{acz} = \frac{\frac{R_{in}(2,1)}{\cos{acx}}}{\frac{R_{in}(2,2)}{\cos{acx}}} = \frac{\frac{R_{out}(2,1)}{\cos{acx}}}{\frac{R_{out}(2,2)}{\cos{acx}}}
tanacz=cosacxRin(2,2)cosacxRin(2,1)=cosacxRout(2,2)cosacxRout(2,1)
经过对比,matlab的结果与代码相同。
mapping中transformAssociateToMap
的推导
对于第
i
i
i帧点云,我们有上一帧优化后的位姿
T
a
f
t
∣
i
−
1
w
T_{aft|i-1}^w
Taft∣i−1w,上一帧的odom结果
T
s
u
m
∣
i
−
1
w
T_{sum|i-1}^w
Tsum∣i−1w,当前帧的odom结果
T
s
u
m
∣
i
w
T_{sum|i}^w
Tsum∣iw,我们想得到当前帧的优化初值
T
t
o
b
e
∣
i
w
T_{tobe|i}^w
Ttobe∣iw,有
T
t
o
b
e
∣
i
w
=
T
a
f
t
∣
i
−
1
w
T
s
u
m
∣
i
−
1
w
−
1
T
s
u
m
∣
i
w
T_{tobe|i}^w = T_{aft|i-1}^w {T_{sum|i-1}^w}^{-1} T_{sum|i}^w
Ttobe∣iw=Taft∣i−1wTsum∣i−1w−1Tsum∣iw,具体如下,
[
C
t
o
b
e
∣
i
w
r
t
o
b
e
∣
i
w
0
1
]
=
[
C
a
f
t
∣
i
−
1
w
r
a
f
t
∣
i
−
1
w
0
1
]
[
C
s
u
m
∣
i
−
1
w
−
1
−
C
s
u
m
∣
i
−
1
w
−
1
r
s
u
m
∣
i
−
1
w
0
1
]
[
C
s
u
m
∣
i
w
r
s
u
m
∣
i
w
0
1
]
=
[
C
a
f
t
∣
i
−
1
w
r
a
f
t
∣
i
−
1
w
0
1
]
[
C
s
u
m
∣
i
−
1
w
−
1
C
s
u
m
∣
i
w
−
C
s
u
m
∣
i
−
1
w
−
1
(
r
s
u
m
∣
i
−
1
w
−
r
s
u
m
∣
i
w
)
0
1
]
=
[
C
a
f
t
∣
i
−
1
w
C
s
u
m
∣
i
−
1
w
−
1
C
s
u
m
∣
i
w
−
C
a
f
t
∣
i
−
1
w
C
s
u
m
∣
i
−
1
w
−
1
(
r
s
u
m
∣
i
−
1
w
−
r
s
u
m
∣
i
w
)
+
r
a
f
t
∣
i
−
1
0
1
]
=
[
C
a
f
t
∣
i
−
1
w
C
s
u
m
∣
i
−
1
w
−
1
C
s
u
m
∣
i
w
−
C
a
f
t
∣
i
−
1
w
C
s
u
m
∣
i
−
1
w
−
1
C
s
u
m
∣
i
w
C
s
u
m
∣
i
w
−
1
(
r
s
u
m
∣
i
−
1
w
−
r
s
u
m
∣
i
w
)
+
r
a
f
t
∣
i
−
1
0
1
]
\begin{split} \begin{bmatrix}C_{tobe|i}^w & r_{tobe|i}^w \\ 0 & 1\end{bmatrix} &= \begin{bmatrix}C_{aft|i-1}^w & r_{aft|i-1}^w \\ 0 & 1\end{bmatrix} \begin{bmatrix}{C_{sum|i-1}^w}^{-1} & -{C_{sum|i-1}^w}^{-1}r_{sum|i-1}^w \\ 0 & 1\end{bmatrix} \begin{bmatrix}C_{sum|i}^w & r_{sum|i}^w \\ 0 & 1\end{bmatrix}\\ &=\begin{bmatrix}C_{aft|i-1}^w & r_{aft|i-1}^w \\ 0 & 1\end{bmatrix} \begin{bmatrix}{C_{sum|i-1}^w}^{-1}C_{sum|i}^w & -{C_{sum|i-1}^w}^{-1}(r_{sum|i-1}^w - r_{sum|i}^w) \\ 0 & 1\end{bmatrix}\\ &=\begin{bmatrix}C_{aft|i-1}^w{C_{sum|i-1}^w}^{-1}C_{sum|i}^w & -C_{aft|i-1}^w{C_{sum|i-1}^w}^{-1}(r_{sum|i-1}^w - r_{sum|i}^w) + r_{aft|i-1} \\ 0 & 1\end{bmatrix}\\ &=\begin{bmatrix}C_{aft|i-1}^w{C_{sum|i-1}^w}^{-1}C_{sum|i}^w & -C_{aft|i-1}^w{C_{sum|i-1}^w}^{-1}{C_{sum|i}^w}{C_{sum|i}^w}^{-1}(r_{sum|i-1}^w - r_{sum|i}^w) + r_{aft|i-1} \\ 0 & 1\end{bmatrix} \end{split}
[Ctobe∣iw0rtobe∣iw1]=[Caft∣i−1w0raft∣i−1w1][Csum∣i−1w−10−Csum∣i−1w−1rsum∣i−1w1][Csum∣iw0rsum∣iw1]=[Caft∣i−1w0raft∣i−1w1][Csum∣i−1w−1Csum∣iw0−Csum∣i−1w−1(rsum∣i−1w−rsum∣iw)1]=[Caft∣i−1wCsum∣i−1w−1Csum∣iw0−Caft∣i−1wCsum∣i−1w−1(rsum∣i−1w−rsum∣iw)+raft∣i−11]=[Caft∣i−1wCsum∣i−1w−1Csum∣iw0−Caft∣i−1wCsum∣i−1w−1Csum∣iwCsum∣iw−1(rsum∣i−1w−rsum∣iw)+raft∣i−11]
C
s
u
m
∣
i
w
−
1
(
r
s
u
m
∣
i
−
1
w
−
r
s
u
m
∣
i
w
)
{C_{sum|i}^w}^{-1}(r_{sum|i-1}^w - r_{sum|i}^w)
Csum∣iw−1(rsum∣i−1w−rsum∣iw)就是transformAssociateToMap
中的transformIncre,
C
a
f
t
∣
i
−
1
w
C
s
u
m
∣
i
−
1
w
−
1
C
s
u
m
∣
i
w
C_{aft|i-1}^w{C_{sum|i-1}^w}^{-1}C_{sum|i}^w
Caft∣i−1wCsum∣i−1w−1Csum∣iw的计算与PluginIMURotation
中的计算公式一样。
至此,关于imu的推导结束。
附录
对于
C
X
w
C_X^w
CXw,其中
X
X
X为局部坐标系(如
e
,
s
,
s
u
m
∣
i
e,s,sum|i
e,s,sum∣i等),表示从
w
w
w系沿
y
a
w
yaw
yaw->
p
i
t
c
h
pitch
pitch->
r
o
l
l
roll
roll旋转得到
X
X
X系,也就是
C
X
w
=
R
y
a
w
R
p
i
t
c
h
R
r
o
l
l
C_X^w=R_{yaw}R_{pitch}R_{roll}
CXw=RyawRpitchRroll。对于上面提到的
s
s
s系以及
e
′
e'
e′系,我们可以认为是
s
s
s系沿
y
a
w
yaw
yaw->
p
i
t
c
h
pitch
pitch->
r
o
l
l
roll
roll旋转得到
e
′
e'
e′系,但是odom中优化的是
T
s
e
′
T_s^{e'}
Tse′,为了使约定保持一致,所以规定从
e
′
e'
e′系沿
r
o
l
l
roll
roll->
p
i
t
c
h
pitch
pitch->
y
a
w
yaw
yaw旋转得到
s
s
s系,这也解释了TransformToEnd
中
C
s
e
′
p
s
C_s^{e'} p^s
Cse′ps公式为什么是
R
r
o
l
l
/
r
z
R
p
i
t
c
h
/
r
x
R
y
a
w
/
r
y
p
s
R_{roll/rz}R_{pitch/rx}R_{yaw/ry}p^s
Rroll/rzRpitch/rxRyaw/ryps,对应TransformToEnd
下面这段代码,
//绕y轴旋转(ry)
float x4 = cos(ry) * x3 + sin(ry) * z3;
float y4 = y3;
float z4 = -sin(ry) * x3 + cos(ry) * z3;
//绕x轴旋转(rx)
float x5 = x4;
float y5 = cos(rx) * y4 - sin(rx) * z4;
float z5 = sin(rx) * y4 + cos(rx) * z4;
//绕z轴旋转(rz),再平移
float x6 = cos(rz) * x5 - sin(rz) * y5 + tx;
float y6 = sin(rz) * x5 + cos(rz) * y5 + ty;
float z6 = z5 + tz;