SLAM 中关于姿态导数的计算
SLAM 中关于姿态导数的计算
在学习SLAM的过程中,不可避免地会遇到需要对姿态求导的场景。姿态分别有:旋转向量、旋转矩阵、欧拉角、四元数四种表示方法。旋转矩阵适合对坐标进行坐标变换,即将某一个坐标系下的坐标转换至另一个坐标系;欧拉角适合直观的描述载体当前的姿态,便于人们感受姿态;四元数适合更新姿态,只要我们记着及时将四元数归一化;而旋转向量更适合在求导中使用,下面我将试图说清楚旋转向量在求导中的使用。讲清楚此部分内容可能需要较多角标符号,所以请大家仔细分辨这些符号,可能我自己都分辨不清楚。由于本人能力有限,难免会有出错,请大家多多指正。
符号约定
为避免符号约定的歧义,在此说明,在本文中:
对于旋转矩阵 RbwR_{b}^{w}Rbw,其表示将坐标系b中的坐标旋转至坐标系 w 中的坐标变换矩阵,即若存在一个 b 系下的坐标 pb=[xb yb zb]Tp^{b}=\left[x^{b}\ y^{b}\ z^{b}\right]^{T}pb=[xb yb zb]T,那么有 pw=Rbwpbp^{w}=R_{b}^{w}p^{b}pw=Rbwpb。这里的 b 系,我们通常认为是载体系,w 系通常认为是世界系。
四元数 qwbq_{w}^{b}qwb 在表示坐标变换时,与 RbwR_{b}^{w}Rbw 表达的含义相反,但与 RwbR_{w}^{b}Rwb 的含义相同,四元数具体的坐标转换方式见SLAM14 讲第二版3.4.3 节。我习惯称 qwb/Rwbq_{w}^{b}/R_{w}^{b}qwb/Rwb 形式的姿态为 w 系在 b 系下的姿态。
旋转向量 ϕbwb\phi_{bw}^{b}ϕbwb,令其为 ϕbwb=θab\phi_{bw}^{b}=\theta a^{b}ϕbwb=θab,θ 为标量表示旋转向量转过的角度,aba^{b}ab 是 3 维单位向量,位于 b 系。那么 ϕbwb\phi_{bw}^{b}ϕbwb 的完整含义为:按右手定则,让 b 系绕 aba^{b}ab 轴转动 θ 角度,即可让 b 系三轴与 w 系三轴重合,这里说的重合,是指 b 系的 x、y、z 轴依次与 w 系的 x、y、z 轴重合。
各姿态表示之间的一些必要转换
首先对于旋转向量有:
−ϕbwb=ϕwbw-\phi_{bw}^{b}=\phi_{wb}^{w}−ϕbwb=ϕwbw
如果 R3×3(ϕ)R_{3\times3}(\phi)R3×3(ϕ) 表示用罗德里格斯公式将旋转向量转化为旋转矩阵,那么有下式:
R3×3(ϕbwb)=cos(θ)I+(1−cos(θ))ab(ab)T+sinθ(ab×)R_{3\times 3}\left(\phi_{bw}^{b}\right)=\cos(\theta)I+\left(1-\cos(\theta)\right)a^{b}\left(a^{b}\right)^{T}+\sin\theta\left(a^{b}\times\right)R3×3(ϕbwb)=cos(θ)I+(1−cos(θ))ab(ab)T+sinθ(ab×)
R3×3(ϕbwb)R_{3\times 3}(\phi_{bw}^{b})R3×3(ϕbwb) 表示的其实是RwbR_{w}^{b}Rwb,R3×3(−ϕbwb)R_{3\times3}(-\phi_{bw}^{b})R3×3(−ϕbwb) 表示 RbwR_{b}^{w}Rbw。当 θ 为小量时:
Rwb≈I−ϕwbw×=I+ϕbwb×R_{w}^{b}\approx I-\phi_{wb}^{w}\times =I+\phi_{bw}^{b}\timesRwb≈I−ϕwbw×=I+ϕbwb×
Rbw≈I+ϕwbw×=I−ϕbwb×R_{b}^{w}\approx I+\phi_{wb}^{w}\times =I-\phi_{bw}^{b}\timesRbw≈I+ϕwbw×=I−ϕbwb×
“×”符号在这里表示取左侧向量的反对称阵。
对于 qwbq_{w}^{b}qwb 与 ϕbwb\phi_{bw}^{b}ϕbwb,我们有如下转化关系:
qwb=[cos(∣ϕbwb∣2)ϕbwb∣ϕbwb∣sin(∣ϕbwb∣2)]=[cos(∣−ϕwbw∣2)−ϕwbw∣−ϕwbw∣sin(∣−ϕwbw∣2)]q_{w}^{b}=\left[\begin{array}{c}\cos\left(\frac{\left|\phi_{bw}^{b}\right|}{2}\right)\\ \frac{\phi_{bw}^{b}}{\left|\phi_{bw}^{b}\right|}\sin\left(\frac{\left|\phi_{bw}^{b}\right|}{2}\right)\end{array}\right]=\left[\begin{array}{c}\cos\left(\frac{\left|-\phi_{wb}^{w}\right|}{2}\right)\\ \frac{-\phi_{wb}^{w}}{\left|-\phi_{wb}^{w}\right|}\sin\left(\frac{\left|-\phi_{wb}^{w}\right|}{2}\right)\end{array}\right]qwb=cos(2∣ϕbwb∣)∣ϕbwb∣ϕbwbsin(2∣ϕbwb∣)=cos(2∣−ϕwbw∣)∣−ϕwbw∣−ϕwbwsin(2∣−ϕwbw∣)
当 θ 为小量时,有:
qwb≈[1ϕbwb2]=[1−ϕwbw2]q_{w}^{b}\approx\left[\begin{array}{c}1\\ \frac{\phi_{bw}^{b}}{2}\end{array}\right]=\left[\begin{array}{c}1\\ \frac{-\phi_{wb}^{w}}{2}\end{array}\right]qwb≈[12ϕbwb]=[12−ϕwbw]
我习惯称 ϕbwb\phi_{bw}^{b}ϕbwb 对应的旋转向量和四元数为:RwbR_{w}^{b}Rwb 和 qwbq_{w}^{b}qwb,那么 ϕwbw\phi_{wb}^{w}ϕwbw 就与 RbwR_{b}^{w}Rbw 和 qbwq_{b}^{w}qbw 对应。
姿态如何累积
各种姿态的表示方法都不满足普通的加法,我们需要使用以下方法将姿态累积起来:
Rbw=Rw1wRbw1R_{b}^{w}=R_{w1}^{w}R_{b}^{w1}Rbw=Rw1wRbw1
qbw=qw1w⊗qbw1q_{b}^{w}=q_{w1}^{w}\otimes q_{b}^{w1}qbw=qw1w⊗qbw1
如上,分别以旋转矩阵和四元数的形式将 b 系在 w1w1w1 系的姿态与 w1w1w1 系在 w 系的姿态叠加起来。按照之前的习惯,Rw1wR_{w1}^{w}Rw1w 对应的旋转向量为:ϕww1w\phi_{ww1}^{w}ϕww1w。如果 ϕww1w\phi_{ww1}^{w}ϕww1w 的模值是小量,那么此时就有:
Rw1w≈I+ϕww1w×R_{w1}^{w}\approx I+\phi_{ww1}^{w}\timesRw1w≈I+ϕww1w×
姿态的导数
我们设定一个关于姿态的函数:
g(ϕw1bw1)=Rbw1pb−pwg\left(\phi_{w1b}^{w1}\right)=R_{b}^{w1}p^{b}-p^{w}g(ϕw1bw1)=Rbw1pb−pw
该函数表示将坐标 pbp^{b}pb 旋转至 w1w1w1 系,然后与坐标 pwp^{w}pw 相减,pwp^{w}pw 表示点 p 在世界系下的真实坐标。我们选择将 ϕw1bw1\phi_{w1b}^{w1}ϕw1bw1 作为函数的自变量,这是因为我们后面要对旋转向量求导。那么世界系 w 为什么要添加符号1 呢?这是因为在估计问题中,我们拿到的状态并不准确,RbwR_{b}^{w}Rbw 表示真值,但是我们只能获取到有误差的姿态,这个误差如何体现出来呢?RbwR_{b}^{w}Rbw 表示将坐标系 b 中的坐标旋转至坐标系 w 中,但是如果有误差了,那么我们拿到的姿态可能就表示将坐标系b 中的坐标旋转至坐标系 w1w1w1 中,于是就有了 Rbw1R_{b}^{w1}Rbw1,所以符号1 表达了我们对当前所获得世界系的不信任,也就是误差。关于这个1 为何加在 w 上,不是b 上,我们后面解释。
下面解释为什么要对 g(ϕw1bw1)g(\phi_{w1b}^{w1})g(ϕw1bw1) 求导,我们注意到 g(ϕw1bw1)g(\phi_{w1b}^{w1})g(ϕw1bw1) 实质为两个坐标的相减,但因为 Rbw1R_{b}^{w1}Rbw1 不是 RbwR_{b}^{w}Rbw,所以 Rbw1pbR_{b}^{w1}p^{b}Rbw1pb 与 pwp^{w}pw 相减后得到的很可能是非零向量。如果有一种方法能让我们调整 Rbw1R_{b}^{w1}Rbw1 中的 w1w1w1 系,使其不断靠近 w 系,那我们就逐渐估计出了 RbwR_{b}^{w}Rbw。一种可行的、估计 RbwR_{b}^{w}Rbw 的方法就是高斯牛顿法(具体介绍见SLAM 十四讲6.2.2 节)。在我们这个问题中,高斯牛顿法是在做这样一件事:在 ϕw1bw1\phi_{w1b}^{w1}ϕw1bw1 的基础上叠加一个微弱转动,叠加微弱转动后的旋转向量所对应的旋转矩阵可以让 g(⋅)g(\cdot)g(⋅) 函数更接近0向量。因为每次添加微弱转动都可以让 g(⋅)g(\cdot)g(⋅) 函数更靠近0向量,所以不断重复上述过程,那么就会估计出较为理想的旋转向量,当然,对应的旋转矩阵也会得到。
下面介绍如何在 ϕw1bw1\phi_{w1b}^{w1}ϕw1bw1 上叠加微弱转动以及 g(ϕw1bw1)g(\phi_{w1b}^{w1})g(ϕw1bw1) 的导数如何计算。
对于函数 f(x)f(x)f(x),其在 x 处的导数为:
f′(x)=limδx→0f(x⊕δx)−f(x)δxf'(x)=\lim_{\delta x\to 0}\frac{f(x\oplus\delta x)-f(x)}{\delta x}f′(x)=δx→0limδxf(x⊕δx)−f(x)
“⊕”表示广义的加法,因为姿态不满足普通加法,所以我们这里用它泛指一种叠加行为。δx\delta xδx 表示在 x 基础上的一个轻微扰动,那么ϕw1bw1\phi_{w1b}^{w1}ϕw1bw1 的轻微扰动是什么?我们知道 ϕw1bw1\phi_{w1b}^{w1}ϕw1bw1 的含义是:让 w1w1w1 系绕某个轴转动某个角度,使得 w1w1w1 系三轴与 b 系三轴重合。那么这个小扰动就可以是先让 w2w2w2 系绕某个轴转动某个很小的角度,使得 w2w2w2 系三轴与 w1w1w1 系三轴重合,这个小扰动对应的符号就是 ϕw2w1w2\phi_{w2w1}^{w2}ϕw2w1w2。而 ϕw2w1w2\phi_{w2w1}^{w2}ϕw2w1w2 对应的旋转矩阵为 Rw1w2R_{w1}^{w2}Rw1w2。于是
∂g(ϕw1bw1)∂ϕw1bw1=limϕw2w1w2→0g(ϕw1bw1⊕ϕw2w1w2)−g(ϕw1bw1)ϕw2w1w2\frac{\partial g\left(\phi_{w1b}^{w1}\right)}{\partial\phi_{w1b}^{w1}}=\lim_{\phi_{w2w1}^{w2}\to 0}\frac{g\left(\phi_{w1b}^{w1}\oplus\phi_{w2w1}^{w2}\right)-g\left(\phi_{w1b}^{w1}\right)}{\phi_{w2w1}^{w2}}∂ϕw1bw1∂g(ϕw1bw1)=ϕw2w1w2→0limϕw2w1w2g(ϕw1bw1⊕ϕw2w1w2)−g(ϕw1bw1)
那么 g(ϕw1bw1⊕ϕw2w1w2)g(\phi_{w1b}^{w1}\oplus\phi_{w2w1}^{w2})g(ϕw1bw1⊕ϕw2w1w2) 等于什么呢?ϕw1bw1⊕ϕw2w1w2\phi_{w1b}^{w1}\oplus\phi_{w2w1}^{w2}ϕw1bw1⊕ϕw2w1w2 从物理含义上来说是:让 w2w2w2 系绕某个轴转动某个角度,使得 w2w2w2 系三轴与 b 系三轴重合,即旋转向量 ϕw2bw2\phi_{w2b}^{w2}ϕw2bw2,而 ϕw2bw2\phi_{w2b}^{w2}ϕw2bw2 对应的旋转矩阵是 Rbw2R_{b}^{w2}Rbw2,又因为有 Rbw2=Rw1w2Rbw1R_{b}^{w2}=R_{w1}^{w2}R_{b}^{w1}Rbw2=Rw1w2Rbw1,所以有:
g(ϕw1bw1⊕ϕw2w1w2)=g(ϕw2bw2)=Rbw2pb−pw=Rw1w2Rbw1pb−pw=[I+ϕw2w1w2×]Rbw1pb−pwg\left(\phi_{w1b}^{w1}\oplus\phi_{w2w1}^{w2}\right)=g\left(\phi_{w2b}^{w2}\right)=R_{b}^{w2}p^{b}-p^{w}=R_{w1}^{w2}R_{b}^{w1}p^{b}-p^{w}=\left[I+\phi_{w2w1}^{w2}\times\right]R_{b}^{w1}p^{b}-p^{w}g(ϕw1bw1⊕ϕw2w1w2)=g(ϕw2bw2)=Rbw2pb−pw=Rw1w2Rbw1pb−pw=[I+ϕw2w1w2×]Rbw1pb−pw
于是有:
∂g(ϕw1bw1)∂ϕw1bw1=limϕw2w1w2→0[I+ϕw2w1w2×]Rbw1pb−Rbw1pbϕw2w1w2\frac{\partial g\left(\phi_{w1b}^{w1}\right)}{\partial\phi_{w1b}^{w1}}=\lim_{\phi_{w2w1}^{w2}\to 0}\frac{\left[I+\phi_{w2w1}^{w2}\times\right]R_{b}^{w1}p^{b}-R_{b}^{w1}p^{b}}{\phi_{w2w1}^{w2}}∂ϕw1bw1∂g(ϕw1bw1)=ϕw2w1w2→0limϕw2w1w2[I+ϕw2w1w2×]Rbw1pb−Rbw1pb
=limϕw2w1w2→0[ϕw2w1w2×]Rbw1pbϕw2w1w2=limϕw2w1w2→0−[(Rbw1pb)×]ϕw2w1w2ϕw2w1w2=−(Rbw1pb)×=\lim_{\phi_{w2w1}^{w2}\to 0}\frac{\left[\phi_{w2w1}^{w2}\times\right]R_{b}^{w1}p^{b}}{\phi_{w2w1}^{w2}}=\lim_{\phi_{w2w1}^{w2}\to 0}-\frac{\left[\left(R_{b}^{w1}p^{b}\right)\times\right]\phi_{w2w1}^{w2}}{\phi_{w2w1}^{w2}}=-\left(R_{b}^{w1}p^{b}\right)\times=ϕw2w1w2→0limϕw2w1w2[ϕw2w1w2×]Rbw1pb=ϕw2w1w2→0lim−ϕw2w1w2[(Rbw1pb)×]ϕw2w1w2=−(Rbw1pb)×
请注意,上面在 ϕw1bw1\phi_{w1b}^{w1}ϕw1bw1 上添加扰动ϕw2w1w2\phi_{w2w1}^{w2}ϕw2w1w2是为了按照导数的定义计算 ∂g(ϕw1bw1)∂ϕw1bw1\frac{\partial g(\phi_{w1b}^{w1})}{\partial\phi_{w1b}^{w1}}∂ϕw1bw1∂g(ϕw1bw1),扰动 ϕw2w1w2\phi_{w2w1}^{w2}ϕw2w1w2 并不是高斯牛顿法中待求的扰动,且ϕw2w1w2\phi_{w2w1}^{w2}ϕw2w1w2 在此处是一个趋于无穷小的量,这些注意事项我们最好都留意一下。上述内容解释了扰动如何加在姿态上,下面我将提到高斯牛顿法中的“扰动”。
我们假设在使用高斯牛顿法时,在 ϕw1bw1\phi_{w1b}^{w1}ϕw1bw1 基础上添加的“扰动”(扰动这个词不太好,此处更准确的说法应该是调整量)为 ϕw3w1w3\phi_{w3w1}^{w3}ϕw3w1w3,ϕw3w1w3\phi_{w3w1}^{w3}ϕw3w1w3 是一个有限小的量,这是与 ϕw2w1w2\phi_{w2w1}^{w2}ϕw2w1w2 的区别,但是他们表达的都是从其他系向 w1w1w1 系转动的旋转向量。则有:
g(ϕw1bw1⊕ϕw3w1w3)≈g(ϕw1bw1)+∂g(ϕw1bw1)∂ϕw1bw1ϕw3w1w3g\left(\phi_{w1b}^{w1}\oplus\phi_{w3w1}^{w3}\right)\approx g\left(\phi_{w1b}^{w1}\right)+\frac{\partial g\left(\phi_{w1b}^{w1}\right)}{\partial\phi_{w1b}^{w1}}\phi_{w3w1}^{w3}g(ϕw1bw1⊕ϕw3w1w3)≈g(ϕw1bw1)+∂ϕw1bw1∂g(ϕw1bw1)ϕw3w1w3
参考14 讲,ϕw3w1w3\phi_{w3w1}^{w3}ϕw3w1w3 便可求解出来。那么 ϕw3w1w3\phi_{w3w1}^{w3}ϕw3w1w3 如何更新在 ϕw1bw1\phi_{w1b}^{w1}ϕw1bw1 上呢?直接令 ϕw1bw1=ϕw1bw1⊕ϕw3w1w3\phi_{w1b}^{w1}=\phi_{w1b}^{w1}\oplus\phi_{w3w1}^{w3}ϕw1bw1=ϕw1bw1⊕ϕw3w1w3 就可以,两个旋转向量可以直接合并(我实际中很少见两个旋转向量直接合并),实际中可能更多是用以下方法更新姿态, ϕw1bw1\phi_{w1b}^{w1}ϕw1bw1 对应的四元数为qbw1q_{b}^{w1}qbw1,ϕw3w1w3\phi_{w3w1}^{w3}ϕw3w1w3 对应的四元数为 qw1w3q_{w1}^{w3}qw1w3,所以利用 qbw3=qw1w3⊗qbw1q_{b}^{w3}=q_{w1}^{w3}\otimes q_{b}^{w1}qbw3=qw1w3⊗qbw1 更新姿态也是可以的。
备注
(1)为什么使用 ϕw2w1w2\phi_{w2w1}^{w2}ϕw2w1w2、ϕw3w1w3\phi_{w3w1}^{w3}ϕw3w1w3?使用 ϕw1w2w1\phi_{w1w2}^{w1}ϕw1w2w1、ϕw1w3w1\phi_{w1w3}^{w1}ϕw1w3w1 可以吗?当然可以,只不过需要注意两件事:
①
Rw1w2≈I−ϕw1w2w1×R_{w1}^{w2}\approx I-\phi_{w1w2}^{w1}\timesRw1w2≈I−ϕw1w2w1×
Rw1w3≈I−ϕw1w3w1×R_{w1}^{w3}\approx I-\phi_{w1w3}^{w1}\timesRw1w3≈I−ϕw1w3w1×
②
ϕw2w1w2\phi_{w2w1}^{w2}ϕw2w1w2、ϕw3w1w3\phi_{w3w1}^{w3}ϕw3w1w3 是同一组的,ϕw1w2w1\phi_{w1w2}^{w1}ϕw1w2w1、ϕw1w3w1\phi_{w1w3}^{w1}ϕw1w3w1 是同一组的,不要混搭,例如:ϕw2w1w2\phi_{w2w1}^{w2}ϕw2w1w2,ϕw1w3w1\phi_{w1w3}^{w1}ϕw1w3w1 是不建议的。
(2)1 为何加在 w 上,不是 b 上?因为我们是在对当前的世界系调整,使其靠近真正的世界系,如果我们设定拿到的旋转矩阵是 Rb1wR_{b1}^{w}Rb1w,就代表我们认为 b 系是不准的,需要不断调整 b 系,那么此时的旋转矩阵的调整量就应该表示为 Rb3b1R_{b3}^{b1}Rb3b1,计算导数和利用高斯牛顿法时,对 Rb1wR_{b1}^{w}Rb1w 施加扰动(调整)的方式就变为:Rb2w=Rb1wRb2b1R_{b2}^{w}=R_{b1}^{w}R_{b2}^{b1}Rb2w=Rb1wRb2b1,Rb3w=Rb1wRb3b1R_{b3}^{w}=R_{b1}^{w}R_{b3}^{b1}Rb3w=Rb1wRb3b1,对应的旋转向量也将变为:ϕb2b1b2\phi_{b2b1}^{b2}ϕb2b1b2、ϕb3b1b3\phi_{b3b1}^{b3}ϕb3b1b3 或 ϕb1b2b1\phi_{b1b2}^{b1}ϕb1b2b1、ϕb1b3b1\phi_{b1b3}^{b1}ϕb1b3b1。
(3)为什么选择 Rbw1R_{b}^{w1}Rbw1,不选择 Rb1wR_{b1}^{w}Rb1w,这是我随意假设的。看源码时,往往是作者怎么假设我就怎么看。
(4)g(ϕw1bw1)g(\phi_{w1b}^{w1})g(ϕw1bw1) 这个残差函数很明显是无法约束住姿态的,即无法有效优化 Rbw1R_{b}^{w1}Rbw1,但我们的目的是讲解姿态的导数如何计算。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)