解读《视觉SLAM十四讲》,带你一步一步入门视觉SLAM—— 第 4 讲 李群与李代数 (下)

在上一篇解读中《解读《视觉SLAM十四讲》,带你一步一步入门视觉SLAM—— 第 4 讲 李群与李代数 (上)》,我们先介绍了李群的定义,知道了我们前面介绍的旋转矩阵集合就是一个李群,然后我们通过一些推导得到了 R = e x p ( ϕ ∧ ) R = exp(\boldsymbol\phi^{\wedge}) R=exp(ϕ),知道了旋转矩阵可以用李代数(向量)的形式去表示。
  
  这一讲我将带你解读李群和李代数的指数和对数运算,以及李代数的求导与扰动模型。

解读

指数映射与对数映射

前面我们经过不懈的努力找到了旋转矩阵另外的表示方法, R = e x p ( ϕ ∧ ) R = exp(\boldsymbol\phi^{\wedge}) R=exp(ϕ),但是我们并不知道这个 e x p ( ϕ ∧ ) exp(\boldsymbol\phi^{\wedge}) exp(ϕ)应该怎么计算。下面我们就跟着作者的思路一起学习一下。
  
  我要再次跟你强调一下 ϕ \boldsymbol\phi ϕ是一个四元数,它实际上也是一个三维向量,这一点请你别忘记了!同时你也别忘记 ϕ ∧ \boldsymbol\phi^{\wedge} ϕ表示的是反对称矩阵,虽然前面已经说过了,但是再强调一下。
  首先我们对 e x p ( ϕ ∧ ) exp(\boldsymbol\phi^{\wedge}) exp(ϕ)写成泰勒级数的方式: e x p ( ϕ ∧ ) = ∑ n = 0 ∞ 1 n ! ( ϕ ∧ ) n (0) exp(\boldsymbol\phi^{\wedge})=\sum_{n=0}^{\infty} \frac 1 {n!}(\boldsymbol\phi^{\wedge})^n\tag 0 exp(ϕ)=n=0n!1(ϕ)n(0)因为 ϕ \boldsymbol\phi ϕ是一个向量,我们可以把它写成 ϕ = θ a ⃗ \boldsymbol\phi=\theta\vec a ϕ=θa a ⃗ \vec a a 是和 ϕ \boldsymbol\phi ϕ方向相同的单位向量, θ \theta θ ϕ \boldsymbol\phi ϕ的模长。
  书中说到,对于 a ⃗ \vec a a ,有两条性质, a ⃗ ∧ ∗ a ⃗ ∧ = a ⃗ ∗ a ⃗ T − I (1) \vec a^{\wedge}*\vec a^{\wedge} = \vec a * \vec a^T - I \tag1 a a =a a TI(1) a ⃗ ∧ ∗ a ⃗ ∧ ∗ a ⃗ ∧ = − a ⃗ ∧ (2) \vec a^{\wedge}*\vec a^{\wedge}*\vec a^{\wedge} = -\vec a^{\wedge} \tag2 a a a =a (2)然后我们就可以把(0)式进行展开了,并且应用上(1)(2)的性质 e x p ( ϕ ∧ ) = e x p ( θ a ⃗ ∧ ) = ∑ n = 0 ∞ 1 n ! ( θ a ⃗ ∧ ) n (3) exp(\boldsymbol\phi^{\wedge})=exp(\theta\vec a^{\wedge})=\sum_{n=0}^{\infty} \frac 1 {n!}(\theta\vec a^{\wedge})^n \tag3 exp(ϕ)=exp(θa )=n=0n!1(θa )n(3)上式(3)拆开之后进行化简(具体过程请看书本),可以得到如下式子: e x p ( ϕ ∧ ) = e x p ( θ a ⃗ ∧ ) = c o s θ I + ( 1 − c o s θ ) a ⃗ a ⃗ T + s i n θ a ⃗ ∧ (4) exp(\boldsymbol\phi^{\wedge})=exp(\theta\vec a^{\wedge})=cos\theta I+(1-cos\theta)\vec a\vec a^T+sin\theta\vec a^{\wedge}\tag4 exp(ϕ)=exp(θa )=cosθI+(1cosθ)a a T+sinθa (4)握草,(4)式不就是我们第三讲说的罗德里格斯公式吗!?怎么搞了一大圈又回到原点了!?
  
  我们上面的推导没有问题啊!那我们来仔细回味一下这些推导过程到底得到了什么结论。我们首先把旋转矩阵转换成了对应的李代数形式,即就是 R = e x p ( ϕ ∧ ) R = exp(\boldsymbol\phi^{\wedge}) R=exp(ϕ),然后求得了这个指数映射关系实际上就是罗德里格斯公式。我们上一讲运用罗德里格斯公式的时候,主要是用来把旋转向量转换成旋转矩阵。我们仔细观察(4)式, θ a ⃗ \theta\vec a θa 不就等于是旋转向量嘛!那是不是可以这样认为,旋转矩阵对应的李代数实际上就是旋转向量组成的空间?答案是:肯定的!
  
  上面的思维转换有一点难,我们不妨再不厌其烦的总结一下:我们一开始从 R = e x p ( ϕ ∧ ) R = exp(\boldsymbol\phi^{\wedge}) R=exp(ϕ)入手,等式左边的 R R R是李群,等式右边的 ϕ \boldsymbol\phi ϕ是它对应的李代数,然后去探索这个指数映射的解法。惊奇的发现这个指数映射其实就是通过罗德里格斯公式变换过去的。而罗德里格斯公式也是将旋转向量转换成旋转矩阵的公式。所以我们可以得出一个结论,旋转矩阵群对应的李代数,实际上就是旋转向量组成的集合。也就是说旋转矩阵的李代数就是旋转向量。哇,看来前面这么多内容只是将第三讲的内容升华到了更高的理论层上,实际上也并没有什么新的东西产生。于是乎,我们得到了一个结论,第四讲一大部分东西都是忽悠人的,现在看来确实是这样的,哈哈,开个玩笑。
  
  当我们明白了旋转矩阵的指数映射之后,理解变换矩阵 T T T的指数映射似乎也就顺理成章了,所以不再解读,大家看书即可!如果上面的内容你还觉得思维转不过来,请结合书本多看几遍。
  
  既然有旋转向量到旋转矩阵的指数映射,那也就有旋转矩阵到旋转向量的对数映射,书中直接给出了对数映射的公式,大家请参考课本《十四讲》!

BCH公式与近似形式

还记得我们一开始说的,为什么要引入李群和李代数吗?目的就是为了后面在优化过程中就行求导。
  
  我们说旋转矩阵不满足加法封闭,那我们通过指数映射 R = e x p ( ϕ ∧ ) R = exp(\boldsymbol\phi^{\wedge}) R=exp(ϕ)变换到李代数的形式,在李代数的形式下,我们是否可以求导呢?让我们来探讨一下:
  
  如果我们想要能求导,那就必须能够对加法运算封闭,如果我们旋转矩阵相乘对应到李代数是相加,那我们就可以通过李代数的方式进行求导。也就是说要下式(5)成立 e x p ( ϕ 1 ∧ ) e x p ( ϕ 2 ∧ ) = e x p ( ϕ 1 ∧ + ϕ 2 ∧ ) (5) exp(\boldsymbol\phi_1^{\wedge})exp(\boldsymbol\phi_2^{\wedge})=exp(\boldsymbol\phi_1^{\wedge}+\boldsymbol\phi_2^{\wedge})\tag5 exp(ϕ1)exp(ϕ2)=exp(ϕ1+ϕ2)(5) l n ( e x p ( ϕ 1 ∧ ) e x p ( ϕ 2 ∧ ) ) = ϕ 1 ∧ + ϕ 2 ∧ (6) ln(exp(\boldsymbol\phi_1^{\wedge})exp(\boldsymbol\phi_2^{\wedge}))=\boldsymbol\phi_1^{\wedge}+\boldsymbol\phi_2^{\wedge}\tag6 ln(exp(ϕ1)exp(ϕ2))=ϕ1+ϕ2(6)显然对于标量,(5)(6)式是成立的,但是对于矩阵(5)(6)式不成立。
  等式(6)在对矩阵进行运算的时候,是满足 BCH公式 l n ( e x p ( ϕ 1 ∧ ) e x p ( ϕ 2 ∧ ) ) = ϕ 1 ∧ + ϕ 2 ∧ + 1 2 [ ϕ 1 ∧ , [ ϕ 1 ∧ , ϕ 2 ∧ ] ] + . . . ln(exp(\boldsymbol\phi_1^{\wedge})exp(\boldsymbol\phi_2^{\wedge}))=\boldsymbol\phi_1^{\wedge}+\boldsymbol\phi_2^{\wedge}+\frac 1 2[\boldsymbol\phi_1^{\wedge},[\boldsymbol\phi_1^{\wedge},\boldsymbol\phi_2^{\wedge}]]+... ln(exp(ϕ1)exp(ϕ2))=ϕ1+ϕ2+21[ϕ1,[ϕ1,ϕ2]]+...,BCH告诉我们,在做矩阵运算时会产生余项。
  考虑到,SLAM是实际问题,所以我们可以做一些近似,我们把小量中二次以上的项都忽略掉。此时(6)式可以近似等于如下表达: l n ( e x p ( ϕ 1 ∧ ) e x p ( ϕ 2 ∧ ) ) ∨ ≈ { J l ( ϕ 2 ) − 1 ϕ 1 + ϕ 2   当 ϕ 1 为 小 量 J r ( ϕ 1 ) − 1 ϕ 2 + ϕ 1   当 ϕ 2 为 小 量 (7) ln(exp(\boldsymbol\phi_1^{\wedge})exp(\boldsymbol\phi_2^{\wedge}))^{\vee}\approx \begin{cases}J_l(\boldsymbol\phi_2)^{-1}\boldsymbol\phi_1+\boldsymbol\phi_2 当\boldsymbol\phi_1为小量\\J_r(\boldsymbol\phi_1)^{-1}\boldsymbol\phi_2+\boldsymbol\phi_1 当\boldsymbol\phi_2为小量\end{cases}\tag 7 ln(exp(ϕ1)exp(ϕ2)){Jl(ϕ2)1ϕ1+ϕ2 ϕ1Jr(ϕ1)1ϕ2+ϕ1 ϕ(7)通过(7)式我们就可以得到,李群乘法(旋转矩阵乘法)与李代数加法(旋转向量)的关系了。
  现在我们来考虑一个实际情况,某一个旋转 R R ,对应的李代数 ϕ \boldsymbol\phi ϕ,如果在它左边乘上一个微小的旋转 Δ R \Delta R ΔR Δ R \Delta R ΔR对应的李代数是 Δ ϕ \Delta\boldsymbol\phi Δϕ。根据(7)式中的第一个等式,可以得到: e x p ( Δ ϕ ) e x p ( ϕ ) = e x p ( ( ϕ + J l − 1 Δ ϕ ) ∧ ) (8) exp(\Delta\boldsymbol\phi)exp(\boldsymbol\phi)=exp((\boldsymbol\phi+J_l^{-1}\Delta\boldsymbol\phi)^{\wedge})\tag8 exp(Δϕ)exp(ϕ)=exp((ϕ+Jl1Δϕ))(8)上式(8)就告诉我们了,旋转向量加法和旋转矩阵乘法的关系。注意:我并没有介绍 J J J怎么计算,请看书中给出的公式。
  反过来,当我们做李代数的加法时,对应到李群上面是怎样的运算呢?可以由下式给出: e x p ( ( ϕ + Δ ϕ ) ∧ ) = e x p ( ( J l − 1 Δ ϕ ) ∧ ) e x p ( ϕ ∧ ) = e x p ( ϕ ∧ ) e x p ( ( J r − 1 Δ ϕ ) ∧ ) (9) exp((\boldsymbol\phi+\Delta\boldsymbol\phi)^{\wedge})=exp((J_l^{-1}\Delta\boldsymbol\phi)^{\wedge})exp(\boldsymbol\phi^{\wedge})=exp(\boldsymbol\phi^{\wedge})exp((J_r^{-1}\Delta\boldsymbol\phi)^{\wedge})\tag{9} exp((ϕ+Δϕ))=exp((Jl1Δϕ))exp(ϕ)=exp(ϕ)exp((Jr1Δϕ))(9)

对位姿有关函数的求导问题

对于旋转矩阵和变换矩阵,它们对加法都没有良好的定义,所以对姿态有关的函数求导,只能通过李代数进行。关于用李代数解决求导问题,有两种思路:

  • 用李代数表示姿态,然后根据李代数加法对李代数进行求导;
  • 对李群左乘或者右乘微小扰动,然后对该扰动求导。

我们分别来看这两种求导方法的区别:

李代数的求导

假设我们要对前后两个时刻的姿态求导数,因为旋转矩阵没有加法,所以我们就对旋转矩阵的李代数就行求导,如下式: ∂ ( e x p ( ϕ ∧ ) ) ∂ ϕ (10) \frac {\partial(exp(\boldsymbol\phi^{\wedge}))}{\partial\boldsymbol\phi}\tag{10} ϕ(exp(ϕ))(10)上式根据导数定义进行求导: ∂ ( e x p ( ϕ ∧ ) ) ∂ ϕ = lim ⁡ δ ϕ → 0 e x p ( ( ϕ + δ ϕ ) ∧ ) − e x p ( ϕ ∧ ) δ ϕ \frac{\partial(exp(\boldsymbol\phi^{\wedge}))}{\partial\boldsymbol\phi} = \lim_{\delta\boldsymbol\phi \to 0}\frac{exp((\boldsymbol\phi+\delta\boldsymbol\phi)^{\wedge})-exp(\boldsymbol\phi^{\wedge})}{\delta\boldsymbol\phi} ϕ(exp(ϕ))=δϕ0limδϕexp((ϕ+δϕ))exp(ϕ)对上式使用BCH线性近似,得到: = lim ⁡ δ ϕ → 0 e x p ( ( J l δ ϕ ) ∧ ) e x p ( ϕ ∧ ) − e x p ( ϕ ∧ ) δ ϕ =\lim_{\delta\boldsymbol\phi \to 0}\frac{exp((J_l\delta\boldsymbol\phi)^{\wedge})exp(\boldsymbol\phi^{\wedge})-exp(\boldsymbol\phi^{\wedge})}{\delta\boldsymbol\phi} =δϕ0limδϕexp((Jlδϕ))exp(ϕ)exp(ϕ)对上式的 e x p ( ( J l δ ϕ ) ∧ ) exp((J_l\delta\boldsymbol\phi)^{\wedge}) exp((Jlδϕ))进行泰勒展开取常数项和一次项,得到下式: ≈ lim ⁡ δ ϕ → 0 e x p ( I + ( J l δ ϕ ) ∧ ) e x p ( ϕ ∧ ) − e x p ( ϕ ∧ ) δ ϕ \approx\lim_{\delta\boldsymbol\phi \to 0}\frac{exp(I+(J_l\delta\boldsymbol\phi)^{\wedge})exp(\boldsymbol\phi^{\wedge})-exp(\boldsymbol\phi^{\wedge})}{\delta\boldsymbol\phi} δϕ0limδϕexp(I+(Jlδϕ))exp(ϕ)exp(ϕ) = lim ⁡ δ ϕ → 0 ( J l δ ϕ ) ∧ e x p ( ϕ ∧ ) δ ϕ =\lim_{\delta\boldsymbol\phi \to 0}\frac{(J_l\delta\boldsymbol\phi)^{\wedge}exp(\boldsymbol\phi^{\wedge})}{\delta\boldsymbol\phi} =δϕ0limδϕ(Jlδϕ)exp(ϕ)上式中,将反对称符号看做是叉积,交换两项的叉积顺序,然后变号: = lim ⁡ δ ϕ → 0 − ( e x p ( ϕ ∧ ) ) ∧ J l δ ϕ δ ϕ =\lim_{\delta\boldsymbol\phi \to 0}\frac{-(exp(\boldsymbol\phi^{\wedge}))^{\wedge}J_l\delta\boldsymbol\phi}{\delta\boldsymbol\phi} =δϕ0limδϕ(exp(ϕ))Jlδϕ = − ( R ) ∧ J l =-(R)^{\wedge}J_l =(R)Jl通过上面的过程我们得到了旋转矩阵相对于李代数的求导: ∂ R ∂ ϕ = ∂ ( e x p ( ϕ ∧ ) ) ∂ ϕ = − ( R ) ∧ J l \frac {\partial R}{\partial\boldsymbol\phi}=\frac {\partial(exp(\boldsymbol\phi^{\wedge}))}{\partial\boldsymbol\phi}=-(R)^{\wedge}J_l ϕR=ϕ(exp(ϕ))=(R)Jl书中说到 J l J_l Jl的计算很复杂,所以求导时候,并不采用这种方法,而是采用下面介绍的扰动模型的方法。

扰动模型(左乘)

以左乘为例,我们在对 R R R左乘一个微小量 Δ R \Delta R ΔR,就可以得到下一个姿态为 Δ R ∗ R \Delta R*R ΔRR,我们设这左扰动的李代数为 φ \boldsymbol\varphi φ,然后再次使用导数定义对 ∂ R ∂ φ \frac {\partial R}{\partial\boldsymbol\varphi} φR进行求导:
∂ R ∂ ϕ = lim ⁡ φ → 0 e x p ( φ ∧ ) ∗ e x p ( ϕ ∧ ) − e x p ( ϕ ∧ ) φ \frac {\partial R}{\partial\boldsymbol\phi} = \lim_{\boldsymbol\varphi \to 0} \frac {exp(\boldsymbol\varphi^{\wedge})*exp(\boldsymbol\phi^{\wedge}) - exp(\boldsymbol\phi^{\wedge})} {\boldsymbol\varphi} ϕR=φ0limφexp(φ)exp(ϕ)exp(ϕ)
与前面的思路一样,先对 e x p ( φ ∧ ) exp(\boldsymbol\varphi^{\wedge}) exp(φ)进行泰勒展开,然后保留低阶项,最终可以得到如下结论:
∂ R ∂ ϕ = − ( R ) ∧ (11) \frac {\partial R}{\partial\boldsymbol\phi} =-(R)^{\wedge} \tag{11} ϕR=(R)(11)
两种求导的方法,至于哪个精度更高,说实话还得就实际情况才能知道,但是扰动模型,显然计算量上要少非常多。
  
  同样的,变换矩阵的李代数求导,也可以类比获得,直接看书上的结论就可以了!
注意:不管是李代数求导还是扰动模型,都是旋转矩阵对李代数的求导,请你仔细观察一下!

实践

实践部分,请注意一定要使用作者Github上提供的Sophus库,不要使用Sophus官方的库,因为现在Sophus已经是模板类的方法编写的了,书中的例子已经不能直接使用最新版本的Sophus。

题外话:说实话这一讲,有一点儿难,特别是其中的证明特别多,而且概念之间的跳跃也很大,理解上来说是需要时间的,我已经尽量省去了很多不必要的内容,但是还是显得有点乱,你在学习的时候,如果实在不能理解证明过程,请先记住结论,但是在记住结论的同时,你要知道这个公式是用来干啥的。就像我们不知道电脑是怎么生产出来的,但是我们会用就行了。

人生在勤,不索何获 ——张衡

### 关于 SLAM李群代数的代码实现 在《视觉SLAM十四》中提到,为了处理旋转平移操作中的微分问题,引入了李群代数的概念。由于李群上的运算仅限于乘法而缺乏加法规则,这使得在其上定义导数变得困难[^3]。 针对这一挑战,在实际编程实践中通常会通过指数映射将李群转换至其对应的代数空间内进行计算,因为后者是一个线性的向量空间,允许执行诸如求导这样的操作。下面给出一段简单的 Python 实现例子用于展示如何利用 Sophus 库来进行 SE(3) 的基本操作: ```python import sophus as sp from scipy.spatial.transform import Rotation as R def se3_exp_map(w,u): """Compute the exponential map from Lie algebra to Lie group. Args: w (numpy.ndarray): A 3D vector representing angular velocity. u (numpy.ndarray): A 3D vector representing linear velocity. Returns: sophus.SE3: An element of SE(3). """ omega_hat = sp.so3.exp(sp.Vector3d(*w)) v = sp.Vector3d(*u) return sp.SE3(omega_hat, v) if __name__ == "__main__": # Example usage with random values for demonstration purposes only rotation_velocity = [0.1, 0.2, 0.3] translation_velocity = [0.4, 0.5, 0.6] transformation_matrix = se3_exp_map(rotation_velocity, translation_velocity) print(transformation_matrix.matrix()) ``` 上述代码片段展示了怎样创建一个 `sophus` 类型的对象并打印出相应的变换矩阵。这里使用的是 Sophus 这一专门设计用来高效表示 SO(3)/SE(3) 及其对应代数 so(3)/se(3) 的 C++/Python 库[^4]。 对于更复杂的场景比如轨迹绘制,则可能涉及到读取外部文件以及调用图形库如 Pangolin 来可视化结果。这部分工作往往依赖具体的应用需求个人偏好来决定具体的实施方案。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值