其他章节:
第二讲:初识SLAM
第三讲:三维空间刚体运动
李群与李代数
李群李代数基础
三维旋转矩阵构成了特殊正交群:
三维变换矩阵构成了特殊欧式群:
其中,群是一种集合加上一个运算的代数结构。群需要满足以下性质:
常见的群有:
李群是具有连续(光滑)性质的群,它既是群也是流形。直观上看,一个刚体能够连续地在空间中运动,故SO(3)和SE(3)都是李群。但是,SO(3)和SE(3)只有定义良好的乘法,没有加法,所以难以进行取极限、求导等操作。
由于每个李群都有李代数,李代数事实上是李群单位元处的正切空间。其引出:
可以看出这是一个反对称矩阵,记:
R
˙
(
t
)
R
(
t
)
T
=
ϕ
(
t
)
∧
\dot{R}(t)R(t)^T=\phi(t)^\land
R˙(t)R(t)T=ϕ(t)∧。两侧右乘
R
(
t
)
R(t)
R(t),得
R
˙
(
t
)
=
ϕ
(
t
)
∧
R
(
t
)
\dot{R}(t)=\phi(t)^\land R(t)
R˙(t)=ϕ(t)∧R(t)。也就是说,对
R
R
R求导后,左侧多出一个
ϕ
(
t
)
\phi(t)
ϕ(t)。
这个可以当做一个微分方程来求解,那么初始条件,就是设
t
0
=
0
t_0=0
t0=0,在0时刻旋转是个单位旋转(0时刻不动),旋转矩阵
R
(
0
)
=
I
R(0)=I
R(0)=I。一阶泰勒展开:
ϕ
\phi
ϕ反映了
R
R
R的导数性质,故称它在SO(3)原点附近的正切空间上。在
t
0
t_0
t0附件,假设
ϕ
\phi
ϕ不变,有微分方程:
R
˙
(
t
)
=
ϕ
(
t
0
)
∧
R
(
t
)
=
ϕ
0
∧
R
(
t
)
\dot{R}(t)=\phi(t_0)^\land R(t)=\phi_0^\land R(t)
R˙(t)=ϕ(t0)∧R(t)=ϕ0∧R(t)。在已知初始情况
R
(
0
)
=
I
R(0)=I
R(0)=I,可解:
该式说明,对任意
t
t
t,都可以找到一个
R
R
R和一个
ϕ
\phi
ϕ的对应关系,该关系称为指数映射,这里
ϕ
\phi
ϕ称为
S
O
(
3
)
SO(3)
SO(3)对应的李代数:
s
o
(
3
)
so(3)
so(3)
出现的问题:1.
s
o
(
3
)
so(3)
so(3)的定义和性质?2.指数映射如何求
第一件事情:李代数的介绍:
每个李群都有与之对应的李代数。李代数描述了李群单位元数的正切空间性质。
其中二元运算被称为李括号,直观上说,李括号表达了两个元素的差异
李代数
s
o
(
3
)
so(3)
so(3):
性质验证:
1.封闭性
Φ
1
Φ
2
−
Φ
2
Φ
1
=
−
(
Φ
1
Φ
2
−
Φ
2
Φ
1
)
T
仍为反对称矩阵,可对应
ϕ
\Phi_1\Phi_2-\Phi_2\Phi_1 = -(\Phi_1\Phi_2-\Phi_2\Phi_1)^T仍为反对称矩阵,可对应\phi
Φ1Φ2−Φ2Φ1=−(Φ1Φ2−Φ2Φ1)T仍为反对称矩阵,可对应ϕ
2.双线性
[
a
ϕ
1
+
b
ϕ
2
,
ϕ
3
]
=
(
(
a
ϕ
1
+
b
ϕ
2
)
ϕ
3
−
ϕ
3
(
a
ϕ
1
+
b
ϕ
2
)
)
∧
=
a
(
ϕ
1
ϕ
3
−
ϕ
3
ϕ
1
)
∧
+
b
(
ϕ
2
ϕ
3
−
ϕ
3
ϕ
2
)
∧
=
a
[
ϕ
1
,
ϕ
3
]
+
b
[
ϕ
2
,
ϕ
3
]
\begin{aligned} [a\phi_1+b\phi_2, \phi_3] &=((a\phi_1+b\phi_2)\phi_3-\phi_3(a\phi_1+b\phi_2))^\land\\ &=a(\phi_1\phi_3-\phi_3\phi_1)^\land + b(\phi_2\phi_3-\phi_3\phi_2)^\land\\ &=a[\phi_1,\phi_3]+b[\phi_2,\phi_3]\\ \end{aligned}
[aϕ1+bϕ2,ϕ3]=((aϕ1+bϕ2)ϕ3−ϕ3(aϕ1+bϕ2))∧=a(ϕ1ϕ3−ϕ3ϕ1)∧+b(ϕ2ϕ3−ϕ3ϕ2)∧=a[ϕ1,ϕ3]+b[ϕ2,ϕ3]
3.自反性
[
ϕ
1
,
ϕ
1
]
=
(
ϕ
1
ϕ
1
−
ϕ
1
ϕ
1
)
∧
=
0
[\phi_1,\phi_1]=(\phi_1\phi_1-\phi_1\phi_1)^\land=0
[ϕ1,ϕ1]=(ϕ1ϕ1−ϕ1ϕ1)∧=0
4.雅可比等价
[
ϕ
1
,
[
ϕ
2
,
ϕ
3
]
]
+
[
ϕ
3
,
[
ϕ
2
,
ϕ
1
]
]
+
[
ϕ
2
,
[
ϕ
3
,
ϕ
1
]
]
=
(
ϕ
1
ϕ
2
ϕ
3
−
ϕ
1
ϕ
3
ϕ
2
−
ϕ
2
ϕ
3
ϕ
1
+
ϕ
3
ϕ
2
ϕ
1
)
∧
+
+
(
ϕ
3
ϕ
1
ϕ
2
−
ϕ
3
ϕ
2
ϕ
1
−
ϕ
1
ϕ
2
ϕ
3
+
ϕ
2
ϕ
1
ϕ
3
)
∧
+
(
ϕ
2
ϕ
3
ϕ
1
−
ϕ
2
ϕ
1
ϕ
3
−
ϕ
3
ϕ
1
ϕ
2
+
ϕ
1
ϕ
3
ϕ
2
)
∧
=
0
\begin{aligned} [\phi_1,[\phi_2,\phi_3]]+[\phi_3,[\phi_2,\phi_1]]+[\phi_2,[\phi_3,\phi_1]] &=(\phi_1\phi_2\phi_3-\phi_1\phi_3\phi_2-\phi_2\phi_3\phi_1+\phi_3\phi_2\phi_1)^\land+\\ &+(\phi_3\phi_1\phi_2-\phi_3\phi_2\phi_1-\phi_1\phi_2\phi_3+\phi_2\phi_1\phi_3)^\land\\ &+(\phi_2\phi_3\phi_1-\phi_2\phi_1\phi_3-\phi_3\phi_1\phi_2+\phi_1\phi_3\phi_2)^\land\\ &=0 \end{aligned}
[ϕ1,[ϕ2,ϕ3]]+[ϕ3,[ϕ2,ϕ1]]+[ϕ2,[ϕ3,ϕ1]]=(ϕ1ϕ2ϕ3−ϕ1ϕ3ϕ2−ϕ2ϕ3ϕ1+ϕ3ϕ2ϕ1)∧++(ϕ3ϕ1ϕ2−ϕ3ϕ2ϕ1−ϕ1ϕ2ϕ3+ϕ2ϕ1ϕ3)∧+(ϕ2ϕ3ϕ1−ϕ2ϕ1ϕ3−ϕ3ϕ1ϕ2+ϕ1ϕ3ϕ2)∧=0
李代数
s
e
(
3
)
se(3)
se(3):
指数与对数映射
指数映射反映了从李代数到李群的对应关系:
R
=
e
x
p
(
ϕ
∧
)
R=exp(\phi^\land)
R=exp(ϕ∧)。
ϕ
∧
\phi^\land
ϕ∧是一个矩阵,矩阵的指数运算可以写成泰勒展开:
由于
ϕ
\phi
ϕ是向量,定义其角度和模长:
ϕ
=
θ
a
\phi=\theta a
ϕ=θa。其中,
a
a
a有性质:
a
∧
a
∧
=
a
a
T
−
I
a^\land a^\land=aa^T-I
a∧a∧=aaT−I以及
a
∧
a
∧
a
∧
=
−
a
∧
a^\land a^\land a^\land = -a^\land
a∧a∧a∧=−a∧。这样泰勒展开化简可得:
这其实就是罗德里格斯公式;这说明
s
o
(
3
)
so(3)
so(3)的物理意义就是旋转向量。反之,给定旋转矩阵时,亦能求李代数:
s
e
(
3
)
se(3)
se(3)到
S
E
(
3
)
SE(3)
SE(3)的指数映射:
左上角表示李代数的平移部分到矩阵的平移部分相差一个线性变换,由
J
J
J给出:
最后的总结:
李代数求导与扰动模型
在实际中,我们经常需要对位姿进行估计,但李群元素只有乘法,无从定义导数,直观的想法就是利用李代数上的加法定义李群元素的导数,然后利用指数映射和对数映射完成变换关系。其基本问题就是:当在李代数中做加法时,是否等价于在李群上做乘法?
两个李代数指数映射乘积的完整形式,有BCH公式给出。由于完整的形式较复杂,因此,特别地,当其中一个量为最小量,忽略其高阶项,BCH具有线性近似形式:
那么旋转可以简单写成:
加法可以近似为:
通过BCH线性近似,可以定义李代数上的导数;由于旋转R没有加法,导数无从定义。书中提出的思路有:
1.对R对应的李代数加上小量,求相对小量的变化率(导数模型)----------
∂
(
R
p
)
∂
ϕ
=
(
−
R
P
)
∧
J
l
\dfrac{\partial(Rp)}{\partial\phi}=(-RP)^\land J_l
∂ϕ∂(Rp)=(−RP)∧Jl
2.对R左乘或右乘一个小量,求相对于小量的李代数的变化率(扰动模型)----------
∂
(
R
p
)
∂
φ
=
(
−
R
P
)
∧
\dfrac{\partial(Rp)}{\partial\varphi}=(-RP)^\land
∂φ∂(Rp)=(−RP)∧
实际中,扰动模型更简洁,因此更实用。
S
E
(
3
)
SE(3)
SE(3)上的扰动模型:
实践:Sophus
Sophus的安装可以参考书上:
git clone https://github.com/strasdat/Sophus.git
cd Sophus
git checkout a621ff
mkdir build
cd build
cmake ..
make
我编译中报的错:
去对应文件夹下修改so2.cpp:
SO2::SO2()
{
// unit_complex_.real() = 1.;
// unit_complex_.imag() = 0.;
unit_complex_.real(1.);
unit_complex_.imag(0.);
}
运行结果如下: