群和李群
群(Group)是一种集合加上一种运算的代数结构,我们把集合记作A,运算记作 · ,那么群可以记作 G = ( A , ⋅ ) G=(A, \cdot) G=(A,⋅)。群要求这个运算满足以下几个条件:
- 封闭性: ∀ a , b ∈ A , a ⋅ b ∈ A ; \forall a, b \in A, a \cdot b \in A ; ∀a,b∈A,a⋅b∈A;
- 结合律: ∀ a , b , c ∈ A , ( a ⋅ b ) ⋅ c = a ⋅ ( b ⋅ c ) ; \forall a, b, c \in A,(a \cdot b) \cdot c=a \cdot(b \cdot c); ∀a,b,c∈A,(a⋅b)⋅c=a⋅(b⋅c);
- 幺元: ∃ e ∈ A \exists e \in A ∃e∈A, s.t. ∀ a ∈ A , e ⋅ a = a ⋅ e = a \forall a \in A, e \cdot a=a \cdot e=a ∀a∈A,e⋅a=a⋅e=a
- 逆: ∀ a ∈ A , ∃ a − 1 ∈ A \forall a \in A, \exists a^{-1} \in A ∀a∈A,∃a−1∈A, s.t. a ⋅ a − 1 = e i a \cdot a^{-1}=e_{i} a⋅a−1=ei
李群是指具有连续(光滑)性质的群。像整数Z那样离散的群没有连续性质,所以不是李群。
在之前介绍旋转矩阵和变换矩阵的定义时,说三维旋转矩阵构成了特殊正交群SO(3),同时变换矩阵构成了特殊欧式群SE(3),具体为:
S
O
(
3
)
=
{
R
∈
R
3
×
3
∣
R
R
T
=
I
,
det
(
R
)
=
1
}
S
E
(
3
)
=
{
T
=
[
R
t
0
T
1
]
∈
R
4
×
4
∣
R
∈
S
O
(
3
)
,
t
∈
R
3
}
\begin{aligned} &\mathrm{SO}(3)=\left\{\boldsymbol{R} \in \mathbb{R}^{3 \times 3} \mid \boldsymbol{R} \boldsymbol{R}^{\mathrm{T}}=\boldsymbol{I}, \operatorname{det}(\boldsymbol{R})=1\right\} \\ &\mathrm{SE}(3)=\left\{T=\left[\begin{array}{ll} \boldsymbol{R} & \boldsymbol{t} \\ 0^{\mathrm{T}} & 1 \end{array}\right] \in \mathbb{R}^{4 \times 4} \mid \boldsymbol{R} \in \mathrm{SO}(3), \boldsymbol{t} \in \mathbb{R}^{3}\right\} \end{aligned}
SO(3)={R∈R3×3∣RRT=I,det(R)=1}SE(3)={T=[R0Tt1]∈R4×4∣R∈SO(3),t∈R3}
在这里SO(n)和SE(n)在实数空间上是连续的。我们能够直观地想象一个刚体能够连续地在空间中运动,所以他们都是李群。
关于这两个李群,我们知道他们对加法是不封闭的也就是说:
R
1
+
R
2
∉
S
O
(
3
)
,
T
1
+
T
2
∉
S
E
(
3
)
\boldsymbol{R}_{1}+\boldsymbol{R}_{2} \notin \mathrm{SO}(3), \quad \boldsymbol{T}_{1}+\boldsymbol{T}_{2} \notin \mathrm{SE}(3)
R1+R2∈/SO(3),T1+T2∈/SE(3)
但是,他们对乘法是封闭的,即:
R
1
R
2
∈
S
O
(
3
)
,
T
1
T
2
∈
S
E
(
3
)
\boldsymbol{R}_{1} \boldsymbol{R}_{2} \in \mathrm{SO}(3), \quad \boldsymbol{T}_{1} \boldsymbol{T}_{2} \in \mathrm{SE}(3)
R1R2∈SO(3),T1T2∈SE(3)
所以对这两个李群来说,他们的运算即为乘法。
李代数so(3)
我们知道
R
˙
(
t
)
R
(
t
)
T
\dot{R}(t) R(t)^{\mathrm{T}}
R˙(t)R(t)T是一个反对称矩阵,我们可以找到一个三维向量
ϕ
(
t
)
∈
R
3
\phi(t) \in \mathbb{R}^{3}
ϕ(t)∈R3与之对应:
R
˙
(
t
)
R
(
t
)
T
=
ϕ
(
t
)
∧
\dot{R}(t) R(t)^{\mathrm{T}}=\phi(t)^{\wedge}
R˙(t)R(t)T=ϕ(t)∧
又因为
R
(
t
)
T
R
(
t
)
=
I
R(t)^{\mathrm{T}}R(t)=I
R(t)TR(t)=I,正交阵。因此得到:
R
˙
(
t
)
=
ϕ
(
t
)
∧
R
(
t
)
=
[
0
−
ϕ
3
ϕ
2
ϕ
3
0
−
ϕ
1
−
ϕ
2
ϕ
1
0
]
R
(
t
)
\dot{R}(t)=\phi(t)^{\wedge} R(t)=\left[\begin{array}{ccc} 0 & -\phi_{3} & \phi_{2} \\ \phi_{3} & 0 & -\phi_{1} \\ -\phi_{2} & \phi_{1} & 0 \end{array}\right] R(t)
R˙(t)=ϕ(t)∧R(t)=⎣⎡0ϕ3−ϕ2−ϕ30ϕ1ϕ2−ϕ10⎦⎤R(t)
这样对
R
(
t
)
R(t)
R(t)求导时,只用直接左乘一个
ϕ
(
t
)
∧
\phi(t)^{\wedge}
ϕ(t)∧即可,当
R
(
t
)
=
I
R(t)=I
R(t)=I时,那么它的导数就是
ϕ
(
t
)
∧
\phi(t)^{\wedge}
ϕ(t)∧,一个反对称矩阵。
只有反对称矩阵组成的空间,即 so(3),我们称之为在单位矩阵处的正切空间tangent space。
ϕ
(
t
)
\phi(t)
ϕ(t)正是对应到SO(3)上的李代数so(3)。 给定某时刻的R,我们就能求得一个
ϕ
\phi
ϕ,它描述了 R在局部的导数关系。所以说它在SO(3)的正切空间上。
每个李群都有与之对应的李代数。李代数描述了李群的局部性质,准确地说,是单位元附近的正切空间。
为什么这么称呼它?二维曲线在某处的导数是一条切线,三维曲线在某处的导数是一个切面,所以正切空间,实际上是导数所组成的空间。
具体的李代数的四个性质1.封闭性 2.双线性 3.自反性 4.雅可比等价 。这个四个性质在这里就不过多的介绍了。
由于向量 ϕ ( t ) \phi(t) ϕ(t)与反对称矩阵是一一对应的,在不引起歧义的情况下,就说so(3)的元素是三维向量或者三维反对称矩阵,不加区别:
s o ( 3 ) = { ϕ ∈ R 3 , Φ = ϕ ∧ ∈ R 3 × 3 } s o(3)=\left\{\phi \in \mathbb{R}^{3}, \Phi=\phi^{\wedge} \in \mathbb{R}^{3 \times 3}\right\} so(3)={ϕ∈R3,Φ=ϕ∧∈R3×3}
至此,已经清楚了so(3)的内容。他们是一个由三维向量组成的集合,每个向量对应一个反对称矩阵,可以用于表达旋转矩阵的导数。它与SO(3)的关系又指数映射给定:
R = exp ( ϕ ∧ ) \boldsymbol{R}=\exp \left(\phi^{\wedge}\right) R=exp(ϕ∧)
任意矩阵的指数映射可以写成一个泰勒展开,但是只有在收敛的情况下才会有结果,其结果仍是一个矩阵(学过工程矩阵的应该都知道):
exp
(
ϕ
∧
)
=
∑
n
=
0
∞
1
n
!
(
ϕ
∧
)
n
\exp \left(\phi^{\wedge}\right)=\sum_{n=0}^{\infty} \frac{1}{n !}\left(\phi^{\wedge}\right)^{n}
exp(ϕ∧)=n=0∑∞n!1(ϕ∧)n
在这里,由于
ϕ
\phi
ϕ是三维向量,我们可以定义它的模长和方向,分别记作
θ
\theta
θ和
a
a
a。于是
ϕ
=
θ
a
\phi=\theta a
ϕ=θa这里
a
a
a是一个长度为1的方向向量。这样经过化简就会得到罗德里格斯公式(旋转轴的向量与旋转矩阵的关系):
exp
(
θ
a
∧
)
=
cos
θ
I
+
(
1
−
cos
θ
)
a
a
T
+
sin
θ
a
∧
\exp \left(\theta \boldsymbol{a}^{\wedge}\right)=\cos \theta \boldsymbol{I}+(1-\cos \theta) \boldsymbol{a} \boldsymbol{a}^{\mathrm{T}}+\sin \theta \boldsymbol{a}^{\wedge}
exp(θa∧)=cosθI+(1−cosθ)aaT+sinθa∧
因此就表面了so(3)就是由所谓的旋转向量组成的空间,即指数映射就是罗德里格斯公式。反之,如果定义对数映射,也能把SO(3)中的元素对应到so(3)中:
ϕ = ln ( R ) ∨ = ( ∑ n = 0 ∞ ( − 1 ) n n + 1 ( R − I ) n + 1 ) ∨ \phi=\ln (\boldsymbol{R})^{\vee}=\left(\sum_{n=0}^{\infty} \frac{(-1)^{n}}{n+1}(\boldsymbol{R}-\boldsymbol{I})^{n+1}\right)^{\vee} ϕ=ln(R)∨=(n=0∑∞n+1(−1)n(R−I)n+1)∨
计算旋转向量不需要使用对数映射,因为对数映射过于麻烦。
对于转角
θ
\theta
θ,有:
tr
(
R
)
=
cos
θ
tr
(
I
)
+
(
1
−
cos
θ
)
tr
(
n
n
T
)
+
sin
θ
tr
(
n
∧
)
=
3
cos
θ
+
(
1
−
cos
θ
)
=
1
+
2
cos
θ
\begin{aligned} \operatorname{tr}(R) &=\cos \theta \operatorname{tr}(I)+(1-\cos \theta) \operatorname{tr}\left(n n^{\mathrm{T}}\right)+\sin \theta \operatorname{tr}\left(n^{\wedge}\right) \\ &=3 \cos \theta+(1-\cos \theta) \\ &=1+2 \cos \theta \end{aligned}
tr(R)=cosθtr(I)+(1−cosθ)tr(nnT)+sinθtr(n∧)=3cosθ+(1−cosθ)=1+2cosθ
因此:
θ = arccos tr ( R ) − 1 2 \theta=\arccos \frac{\operatorname{tr}(\boldsymbol{R})-1}{2} θ=arccos2tr(R)−1
关于转轴 n n n,旋转轴上的向量在旋转后不发生改变,说明:
R
n
=
n
R n=n
Rn=n
意思是让旋转轴按照旋转矩阵的方式进行旋转,得到的还是旋转轴,(旋转轴经过旋转之后不变)
因此,转轴
n
n
n是矩阵
R
R
R特征值1对应的特征向量。求解此方程,在归一化,就得到了旋转轴。
指数映射只是一个满射,并不是单射。这意味这每个SO(3)中的元素,都可以找到一个so(3)元素与之对应;但是可能存在多个so(3)中的元素,对应到同一个SO(3).至少对于旋转角
θ
\theta
θ,我们知道多转360°和没有转是一样的———它具有周期性。但是,如果我们把旋转角度固定在
±
π
\pm \pi
±π之间,那么李群和李代数元素是一一对应的。
旋转矩阵的导数可以由旋转向量指定,指导着如何在旋转矩阵中进行微积分运算。
李代数se(3)
对于SE(3),它的对应的李代数se(3)为:
se
(
3
)
=
{
ξ
=
[
ρ
ϕ
]
∈
R
6
,
ρ
∈
R
3
,
ϕ
∈
σ
0
(
3
)
,
ξ
∧
=
[
ϕ
∧
ρ
0
⊤
0
]
∈
R
4
×
4
}
\operatorname{se}(3)=\left\{\xi=\left[\begin{array}{l} \rho \\ \phi \end{array}\right] \in \mathbb{R}^{6}, \rho \in \mathbb{R}^{3}, \phi \in \sigma 0(3), \xi^{\wedge}=\left[\begin{array}{ll} \phi^{\wedge} & \rho \\ 0^{\top} & 0 \end{array}\right] \in \mathbb{R}^{4 \times 4}\right\}
se(3)={ξ=[ρϕ]∈R6,ρ∈R3,ϕ∈σ0(3),ξ∧=[ϕ∧0⊤ρ0]∈R4×4}
se(3)为于
R
6
\mathbb{R}^{6}
R6空间中,它是一个六维向量,前三维为平移(但含义与变换矩阵中的平移不同,因为在进行指数映射之后,需要进行一次以
J
J
J为系数矩阵的线性变换。即
t
=
J
ρ
t=J\rho
t=Jρ),记作
ρ
\rho
ρ;后三维为旋转,记作
ϕ
\phi
ϕ,实质上是so(3)元素。
在这里的se(3)中的这个符号 ∧ ^{\wedge} ∧并不表示反对称了,而是为了与so(3)中的这个符号相对应,也使用了这个符号,在这里这个符号是将一个六维向量转换成四维矩阵.(这里。我们应该仔细地想一下,为什么这个符号表示的不是反对称了,因为这个是对旋转来说的,对平移并不是这样,变换分为旋转和平移,这是两种性质不同的变换。而为什么是变换成四维矩阵,因为在之前的变换矩阵那里,为了整合平移和旋转,设计了一种这样四维矩阵的格式,也就是变换矩阵 T T T。也就只有这种格式才能每进行一次变换(平移+旋转)直接左乘即可。虽然这个四维矩阵和那个变换矩阵 T T T不一样,因为这正是李代数与李群,之间有一个指数映射关系)
se(3)的指数映射为:
exp ( ξ ∧ ) = [ ∑ n = 0 ∞ 1 n ! ( ϕ ∧ ) n ∑ n = 0 ∞ 1 ( n + 1 ) ! ( ϕ ∧ ) n ρ ] ≜ [ R J ρ 0 T 1 ] = T . \begin{aligned} \exp \left(\xi^{\wedge}\right) &=\left[\sum_{n=0}^{\infty} \frac{1}{n !}\left(\phi^{\wedge}\right)^{n} \sum_{n=0}^{\infty} \frac{1}{(n+1) !}\left(\phi^{\wedge}\right)^{n} \rho\right] \\ & \triangleq\left[\begin{array}{cc} R & J \rho \\ 0^{\mathrm{T}} & 1 \end{array}\right]=T . \end{aligned} exp(ξ∧)=[n=0∑∞n!1(ϕ∧)nn=0∑∞(n+1)!1(ϕ∧)nρ]≜[R0TJρ1]=T.
从上式可以看出: ξ \xi ξ的指数映射左上角的 R R R是我们熟知的SO(3)中的元素,与se(3)中的旋转部分 θ \theta θ对应。而右上角的 J J J推导得出:
J = sin θ θ I + ( 1 − sin θ θ ) a a T + 1 − cos θ θ a ∧ J=\frac{\sin \theta}{\theta} I+\left(1-\frac{\sin \theta}{\theta}\right) a a^{\mathrm{T}}+\frac{1-\cos \theta}{\theta} a^{\wedge} J=θsinθI+(1−θsinθ)aaT+θ1−cosθa∧
该式与罗德里格斯公式有些相似,但不完全一样。
同样也可以使用对数映射求se(3)中的元素,但是没必要且复杂,可以从左上角的
R
R
R计算旋转向量,而右上角的
t
t
t满足:
t
=
J
ρ
t=J\rho
t=Jρ。由于
J
J
J可以由
ϕ
\phi
ϕ得到,所以
ρ
\rho
ρ也可以由此线性方程解得。
最终的李代数的定义与相互转换关系为:
在这里放几张图供大家好好理解理解李群和李代数之间的关系和李代数要发挥的作用。
李代数求导和扰动模型
在这里,就显示出李代数的作用了。在SLAM 中,我们要估计一个相机的位置和姿态,该位姿是由SO(3)上的旋转矩阵或SE(3)上的变换矩阵描述的。设相机的位姿为
T
T
T。它观察到了一个世界坐标位于
p
p
p的点,产生了一个数据z。那么,由坐标变换关系知:
z
=
T
p
+
w
z=Tp+w
z=Tp+w
其中
w
w
w为随机噪声。由于它的存在,
z
z
z往往不可能精确地满足
z
=
T
p
z=Tp
z=Tp的关系。所以,我们通常会计算理想的观测与实际数据的误差:
e
=
z
−
T
p
e=z-Tp
e=z−Tp
有
N
N
N个这样的路标点就有
N
N
N个这样的式子:
min T J ( T ) = ∑ i = 1 N ∥ z i − T p i ∥ 2 2 \min _{T} J(T)=\sum_{i=1}^{N}\left\|z_{i}-T p_{i}\right\|_{2}^{2} TminJ(T)=i=1∑N∥zi−Tpi∥22
要得到最优的
T
T
T才能使误差最小,这就涉及对位姿的求导问题。
我们经常会构建与位姿有关的函数,然后讨论该函数关于位姿的导数,以调整当前的估计值
因为使用SO(3)或SE(3)求导会比较麻烦,并且没有良好定义加法,因此只能使用李代数求导(这就是李代数的意义所在),李代数求导又分为两种方式:
1.用李代数表示姿态,然后根据李代数加法对李代数求导。
2.对李群左乘或右乘微小扰动,然后对该扰动求导,称为左扰动和右扰动模型(重要)
第一种求导方式为
∂ ( R p ) ∂ R = ∂ ( exp ( ϕ ∧ ) p ) ∂ ϕ \frac{\partial(R p)}{\partial R}=\frac{\partial\left(\exp \left(\phi^{\wedge}\right) \boldsymbol{p}\right)}{\partial \phi} ∂R∂(Rp)=∂ϕ∂(exp(ϕ∧)p)
∂ ( exp ( ϕ ∧ ) p ) ∂ ϕ = lim δ ϕ → 0 exp ( ( ϕ + δ ϕ ) ∧ ) p − exp ( ϕ ∧ ) p δ ϕ \frac{\partial\left(\exp \left(\phi^{\wedge}\right) p\right)}{\partial \phi}=\lim _{\delta \phi \rightarrow 0} \frac{\exp \left((\phi+\delta \phi)^{\wedge}\right) p-\exp \left(\phi^{\wedge}\right) p}{\delta \phi} ∂ϕ∂(exp(ϕ∧)p)=δϕ→0limδϕexp((ϕ+δϕ)∧)p−exp(ϕ∧)p
然后使用BCH近似:
SO(3)
exp
(
Δ
ϕ
∧
)
exp
(
ϕ
∧
)
=
exp
(
(
ϕ
+
J
l
−
1
(
ϕ
)
Δ
ϕ
)
∧
)
\exp \left(\Delta \phi^{\wedge}\right) \exp \left(\phi^{\wedge}\right)=\exp \left(\left(\phi+J_{l}^{-1}(\phi) \Delta \phi\right)^{\wedge}\right)
exp(Δϕ∧)exp(ϕ∧)=exp((ϕ+Jl−1(ϕ)Δϕ)∧)
exp
(
(
ϕ
+
Δ
ϕ
)
∧
)
=
exp
(
(
J
1
Δ
ϕ
)
∧
)
exp
(
ϕ
∧
)
=
exp
(
ϕ
∧
)
exp
(
(
J
r
Δ
ϕ
)
∧
\exp \left((\phi+\Delta \phi)^{\wedge}\right)=\exp \left(\left(J_{1} \Delta \phi\right)^{\wedge}\right) \exp \left(\phi^{\wedge}\right)=\exp \left(\phi^{\wedge}\right) \exp \left(\left(J_{r} \Delta \phi\right)^{\wedge}\right.
exp((ϕ+Δϕ)∧)=exp((J1Δϕ)∧)exp(ϕ∧)=exp(ϕ∧)exp((JrΔϕ)∧
SE(3)
cxp ( Δ ξ ∧ ) exp ( ξ ∧ ) ≈ exp ( ( J i − 1 Δ ξ + ξ ) ∧ ) exp ( ξ ∧ ) exp ( Δ ξ ∧ ) ≈ exp ( ( J r − 1 Δ ξ + ξ ) ∧ ) \begin{aligned} &\operatorname{cxp}\left(\Delta \xi^{\wedge}\right) \exp \left(\xi^{\wedge}\right) \approx \exp \left(\left(\mathcal{J}_{i}^{-1} \Delta \xi+\xi\right)^{\wedge}\right) \\ &\exp \left(\xi^{\wedge}\right) \exp \left(\Delta \xi^{\wedge}\right) \approx \exp \left(\left(\mathcal{J}_{r}^{-1} \Delta \xi+\xi\right)^{\wedge}\right) \end{aligned} cxp(Δξ∧)exp(ξ∧)≈exp((Ji−1Δξ+ξ)∧)exp(ξ∧)exp(Δξ∧)≈exp((Jr−1Δξ+ξ)∧)
左乘BCH近似雅可比
J
l
J_l
Jl为:
J
l
=
J
=
sin
θ
θ
I
+
(
1
−
sin
θ
θ
)
a
a
T
+
1
−
cos
θ
θ
a
∧
J_{l}=J=\frac{\sin \theta}{\theta} I+\left(1-\frac{\sin \theta}{\theta}\right) a a^{\mathrm{T}}+\frac{1-\cos \theta}{\theta} a^{\wedge}
Jl=J=θsinθI+(1−θsinθ)aaT+θ1−cosθa∧
逆为:
J
l
−
1
=
θ
2
cot
θ
2
I
+
(
1
−
θ
2
cot
θ
2
)
a
a
T
−
θ
2
a
∧
J_{l}^{-1}=\frac{\theta}{2} \cot \frac{\theta}{2} I+\left(1-\frac{\theta}{2} \cot \frac{\theta}{2}\right) a a^{\mathrm{T}}-\frac{\theta}{2} a^{\wedge}
Jl−1=2θcot2θI+(1−2θcot2θ)aaT−2θa∧
右乘雅可比仅需要对自变量取负号:
J
r
(
ϕ
)
=
J
l
(
−
ϕ
)
J_{r}(\phi)=J_{l}(-\phi)
Jr(ϕ)=Jl(−ϕ)
并使用泰勒展开舍去高阶项后得到:
∂
(
R
p
)
∂
ϕ
=
(
−
R
p
)
∧
J
l
\frac{\partial(\boldsymbol{R} p)}{\partial \phi}=(-\boldsymbol{R} p)^{\wedge} J_{l}
∂ϕ∂(Rp)=(−Rp)∧Jl
因为有需要计算复杂的雅可比
J
l
J_l
Jl因此,这种方式比较复杂,使用较少。
第二种方式:(扰动模型(左乘))
另一种求导方式使对
R
\boldsymbol{R}
R进行一次扰动
Δ
R
\Delta \boldsymbol{R}
ΔR,看结果相对于扰动的变化率。(这一部分可以这样理解:对自变量进行小量扰动,然后求出对小量的偏导,令其为0,看看小量在什么时候能够求得极值,求出的这个小量再加回到自变量,这时自变量加上小量后,会使整个带有自变量的误差函数的值达到最小)
具体的公式为:
∂
(
R
p
)
∂
φ
=
lim
φ
→
0
exp
(
φ
∧
)
exp
(
ϕ
∧
)
p
−
exp
(
ϕ
∧
)
p
φ
=
lim
φ
→
0
(
I
+
φ
∧
)
exp
(
ϕ
∧
)
p
−
exp
(
ϕ
∧
)
p
φ
=
lim
φ
→
0
φ
∧
R
p
φ
=
lim
φ
→
0
−
(
R
p
)
∧
φ
φ
=
−
(
R
p
)
∧
\begin{aligned} \frac{\partial(R p)}{\partial \varphi} &=\lim _{\varphi \rightarrow 0} \frac{\exp \left(\varphi^{\wedge}\right) \exp \left(\phi^{\wedge}\right) \boldsymbol{p}-\exp \left(\phi^{\wedge}\right) \boldsymbol{p}}{\varphi} \\ &=\lim _{\varphi \rightarrow 0} \frac{\left(\boldsymbol{I}+\varphi^{\wedge}\right) \exp \left(\phi^{\wedge}\right) \boldsymbol{p}-\exp \left(\phi^{\wedge}\right) \boldsymbol{p}}{\varphi} \\ &=\lim _{\varphi \rightarrow 0} \frac{\varphi^{\wedge} \boldsymbol{R} p}{\varphi}=\lim _{\varphi \rightarrow 0} \frac{-(\boldsymbol{R} p)^{\wedge} \varphi}{\varphi}=-(\boldsymbol{R} p)^{\wedge} \end{aligned}
∂φ∂(Rp)=φ→0limφexp(φ∧)exp(ϕ∧)p−exp(ϕ∧)p=φ→0limφ(I+φ∧)exp(ϕ∧)p−exp(ϕ∧)p=φ→0limφφ∧Rp=φ→0limφ−(Rp)∧φ=−(Rp)∧
可见,相比于第一种方式,直接对李代数求导,省去了一个雅可比 J l J_l Jl的计算。这样的方式更简单,这个扰动模型更为实用。
对SE(3)上的李代数求导,同样使用扰动模型:
∂
(
T
p
)
∂
δ
ξ
=
[
I
−
(
R
p
+
t
)
∧
0
T
0
T
]
=
def
(
T
p
)
⊙
\frac{\partial(\boldsymbol{T} \boldsymbol{p})}{\partial \delta \boldsymbol{\xi}}=\left[\begin{array}{cc} I & -(R p+t)^{\wedge} \\ 0^{\mathrm{T}} & 0^{\mathrm{T}} \end{array}\right] \stackrel{\text { def }}{=}(T p)^{\odot}
∂δξ∂(Tp)=[I0T−(Rp+t)∧0T]= def (Tp)⊙
这里把最后的结果定义成了一个算符 ⊙ ^{\odot} ⊙,它把一个齐次坐标的空间点变换成一个4X6的矩阵。
Sophus的使用
#include <iostream>
#include <cmath>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include "sophus/se3.hpp"
using namespace std;
using namespace Eigen;
/// 本程序演示sophus的基本用法
int main(int argc, char **argv) {
// 沿Z轴转90度的旋转矩阵
Matrix3d R = AngleAxisd(M_PI / 2, Vector3d(0, 0, 1)).toRotationMatrix();
// 或者四元数
Quaterniond q(R);
Sophus::SO3d SO3_R(R); // Sophus::SO3d可以直接从旋转矩阵构造
Sophus::SO3d SO3_q(q); // 也可以通过四元数构造
// 二者是等价的
cout << "SO(3) from matrix:\n" << SO3_R.matrix() << endl;
cout << "SO(3) from quaternion:\n" << SO3_q.matrix() << endl;
cout << "they are equal" << endl;
// 使用对数映射获得它的李代数
Vector3d so3 = SO3_R.log();
cout << "so3 = " << so3.transpose() << endl;
// hat 为向量到反对称矩阵
cout << "so3 hat=\n" << Sophus::SO3d::hat(so3) << endl;
// 相对的,vee为反对称到向量
cout << "so3 hat vee= " << Sophus::SO3d::vee(Sophus::SO3d::hat(so3)).transpose() << endl;
// 增量扰动模型的更新
Vector3d update_so3(1e-4, 0, 0); //假设更新量为这么多
Sophus::SO3d SO3_updated = Sophus::SO3d::exp(update_so3) * SO3_R;
cout << "SO3 updated = \n" << SO3_updated.matrix() << endl;
cout << "*******************************" << endl;
// 对SE(3)操作大同小异
Vector3d t(1, 0, 0); // 沿X轴平移1
Sophus::SE3d SE3_Rt(R, t); // 从R,t构造SE(3)
Sophus::SE3d SE3_qt(q, t); // 从q,t构造SE(3)
cout << "SE3 from R,t= \n" << SE3_Rt.matrix() << endl;
cout << "SE3 from q,t= \n" << SE3_qt.matrix() << endl;
// 李代数se(3) 是一个六维向量,方便起见先typedef一下
typedef Eigen::Matrix<double, 6, 1> Vector6d;
Vector6d se3 = SE3_Rt.log();
cout << "se3 = " << se3.transpose() << endl;
// 观察输出,会发现在Sophus中,se(3)的平移在前,旋转在后.
// 同样的,有hat和vee两个算符
cout << "se3 hat = \n" << Sophus::SE3d::hat(se3) << endl;
cout << "se3 hat vee = " << Sophus::SE3d::vee(Sophus::SE3d::hat(se3)).transpose() << endl;
// 最后,演示一下更新
Vector6d update_se3; //更新量
update_se3.setZero();
update_se3(0, 0) = 1e-4;
Sophus::SE3d SE3_updated = Sophus::SE3d::exp(update_se3) * SE3_Rt;
cout << "SE3 updated = " << endl << SE3_updated.matrix() << endl;
return 0;
}
代码在这里。
参考
1.从零开始一起学习SLAM | 为啥需要李群与李代数?
2.SLAM笔记(九)再谈李代数
3.SLAM14讲学习笔记(一) 李群李代数基础
4.【视觉SLAM十四讲】李群与李代数
5.旋转矩阵、变换矩阵,李群(Lie Group)、李代数(Lie Algebra)及扰动模型
6.视觉SLAM十四讲