文章目录

  • 写在前面
  • Reference
  • 缘起——旋转的主动性(Active)和被动性(Passive)
    • 旋转方向的定义
    • 被动旋转
    • 主动旋转
    • 结论
  • 乱入——四元数对于旋转的表示
    • Hamilton四元数表示法
    • Hamilton四元数表示法的缺陷
    • Shuster四元数表示法
    • Shuster表示法是如何解决Hamilton的缺陷的
  • 统一——如何使用两种四元数
    • 旋转的主动性与被动性上
    • 旋转的方向上
  • 总结

写在前面

最近看MSCKF方法,发现里面的旋转表示与笔者先前理解的非常不同,也让笔者重新审视了一下自己对于旋转向量、旋转矩阵与四元数的关系,通过查找一些资料,也算是把这些关系理得比较清楚,该文章就是对自己理解过程的一次总结,希望能帮助更多的小伙伴。


Reference

  1. Active versus Passive Rotations. 该论文比较清晰的解释了“主动旋转”和“被动旋转”;
  2. Why and How to Avoid the Flipped Quaternion Multiplication. 该论文比较系统的总结了Hamilton和Shuster两种四元数的运用,然后作者提出了一种四元数到旋转矩阵的映射,可以保持使用Hamilton四元数的同时,保持乘法的Homogeneous;
  3. Quaternion kinematics for the error-state Kalman filter. ESKF中的前4章也都是在讲四元数和旋转的事情,该篇文章主要使用Hamilton表示法的四元数;
  4. Indirect Kalman Filter for 3D Attitude Estimation. MARS LAB关于四元数表示旋转的一篇文章,里面详细推导了JPL表示下的四元数的公式;
  5. 还有一篇邱博的笔记,但是实在找不到链接;

特别希望的是,在本文之前,大家对于四元数和旋转矩阵相信都有自己的理解,但是希望读者暂时忘记之前的理解,因为很可能这些理解会导致你很不理解本文的变换关系,就像参考2中提醒读者的一样:If a reader is unaware of the split, the discovery that two different quaternion multiplications are in use, and that in fact “the other” was employed, might be made only after several failures, during which the confusion may even have spread to third parties.


缘起——旋转的主动性(Active)和被动性(Passive)

旋转的主动性与被动性绝对是相对关系的一个很好的体现,特别是在SLAM中,算法其实一直都在用两者,但是却总是不对两者进行区分,导致笔者之前觉得:旋转嘛,就用四元数或者旋转矩阵表示就可以了。但是实际上两个的自然含义确实是千差万别。

举个简单的例子——重投影误差。这里仅仅考虑旋转,通常有公式如下:
PC=RWCPW(1)\mathrm{P^C} = \mathrm{R_{W}^{C}}\mathrm{P^W} \tag{1} PC=RWC​PW(1)
对于上述公式,我们可以从两个角度去解释:

  1. 世界坐标系下的一个点经过旋转,转到了相机坐标系下,我们称之为主动旋转,也就是旋转前后,坐标系没有发生变化,而是其中的点被旋转到了一个新位置上;
  2. 世界坐标系整个旋转成为相机坐标系,此时再去观察同样的点,具有了不一样的值,我们称之为被动旋转,也就是旋转前后,空间中的点的绝对位置没有变化,变化的仅仅是观察者的坐标系;

显然,机器人运动中更应该偏向被动旋转

旋转方向的定义

绕一个轴的旋转其实有两种,顺时针(左手法则)和逆时针(右手法则),所以这里先规定旋转的方向,再说明其他的部分:通常定义逆时针为正旋转,如果有变动会在那个地方说明。

被动旋转

这里先说被动旋转,原因是因为被动旋转的表示其实是最早被提出来的,像之前所说的,被动旋转表示把一个坐标系{R}转成了另一个坐标系{b},如下图的例子所述:

{xyz}坐标系绕着其中中的z轴,正向旋转45°,那么其中在{xyz}坐标系下的点A如何变化。

根据图能很容易的看出,该种情形下的旋转公式如下:
[200]=Rv=[cos(θ)sin(θ)0−sin(θ)cos(θ)0001][110](1)\begin{bmatrix}\sqrt{2} \\ 0 \\ 0 \end{bmatrix} = \mathbf{R} \mathrm{v} =\begin{bmatrix}cos(\theta) & sin(\theta) & 0 \\ -sin(\theta) & cos(\theta) & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 \\ 1\\ 0 \end{bmatrix} \tag{1} ⎣⎡​2​00​⎦⎤​=Rv=⎣⎡​cos(θ)−sin(θ)0​sin(θ)cos(θ)0​001​⎦⎤​⎣⎡​110​⎦⎤​(1)
但是,如果我们把目光放在基底的变化上,就会发现事情没有那么简单。从图中不难看出,如果我们在这个过程中把整个{xyz}的基底进行旋转,则旋转的过程如下:
[e1′e2′e3′]=[12−12012120001]=[cos(θ)−sin(θ)0sin(θ)cos(θ)0001][e1e2e3]=GbC[e1e2e3](2)\begin{bmatrix}e_1^{\prime} & e_2^{\prime} & e_3^{\prime}\end{bmatrix} = \begin{bmatrix} \frac{1}{\sqrt{2}} & -\frac{1}{\sqrt{2}} & 0 \\ \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} & 0 \\ 0 & 0 & 1 \end{bmatrix}=\begin{bmatrix}cos(\theta) & -sin(\theta) & 0 \\ sin(\theta) & cos(\theta) & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} e_1 & e_2 & e_3\end{bmatrix} = \mathbf{^{b}_{G}C}\begin{bmatrix} e_1 & e_2 & e_3\end{bmatrix} \tag{2} [e1′​​e2′​​e3′​​]=⎣⎡​2​1​2​1​0​−2​1​2​1​0​001​⎦⎤​=⎣⎡​cos(θ)sin(θ)0​−sin(θ)cos(θ)0​001​⎦⎤​[e1​​e2​​e3​​]=Gb​C[e1​​e2​​e3​​](2)
于是我们得到如下的结论:在被动旋转的表示方法下,整个坐标系绕着一个旋转轴正向旋转(也就是逆时针)等于把其中的向量绕着相同的旋转轴逆向旋转(也就是顺时针),有公式:
R=Rz(−θ)=GbCT=Rz(θ)(3)\mathbf{R}=\mathbf{R_z(-\theta)}=\mathbf{^{b}_{G}C}^T=\mathbf{R_z(\theta)} \tag{3} R=Rz​(−θ)=Gb​CT=Rz​(θ)(3)
这里把旋转矩阵R的方向定为{b}系到{G}系,就好像原先在{b}系中的向量经过了旋转矩阵旋转到了{G}系一样;

主动旋转

如果旋转轴依旧是{xyz}中的z轴,而旋转角度也还是45°,但是这次直接旋转A点的话,A点如何变化呢?

根据图能很容易的看出,该种情形下的旋转公式如下:
[020]=Rv=[cos(θ)−sin(θ)0sin(θ)cos(θ)0001][110](4)\begin{bmatrix}0 \\ \sqrt{2} \\ 0 \end{bmatrix} = \mathbf{R} \mathrm{v} =\begin{bmatrix}cos(\theta) & -sin(\theta) & 0 \\ sin(\theta) & cos(\theta) & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 \\ 1\\ 0 \end{bmatrix} \tag{4} ⎣⎡​02​0​⎦⎤​=Rv=⎣⎡​cos(θ)sin(θ)0​−sin(θ)cos(θ)0​001​⎦⎤​⎣⎡​110​⎦⎤​(4)
同样,如果我们把目光放在基底的变化上,就会发现事情没有那么简单。从图中不难看出,如果我们在这个过程中把整个{xyz}的基底进行旋转,则旋转的过程如下:
[e1′e2′e3′]=[12120−12120001]=[cos(θ)sin(θ)0−sin(θ)cos(θ)0001][e1e2e3]=GbC[e1e2e3](5)\begin{bmatrix}e_1^{\prime} & e_2^{\prime} & e_3^{\prime}\end{bmatrix} = \begin{bmatrix} \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} & 0 \\ -\frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} & 0 \\ 0 & 0 & 1 \end{bmatrix}=\begin{bmatrix}cos(\theta) & sin(\theta) & 0 \\ -sin(\theta) & cos(\theta) & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} e_1 & e_2 & e_3\end{bmatrix} = \mathbf{^{b}_{G}C}\begin{bmatrix} e_1 & e_2 & e_3\end{bmatrix} \tag{5} [e1′​​e2′​​e3′​​]=⎣⎡​2​1​−2​1​0​2​1​2​1​0​001​⎦⎤​=⎣⎡​cos(θ)−sin(θ)0​sin(θ)cos(θ)0​001​⎦⎤​[e1​​e2​​e3​​]=Gb​C[e1​​e2​​e3​​](5)
于是我们得到如下的结论:在主动旋转的表示方法下,坐标系中的一个点绕着一个旋转轴正向旋转(也就是逆时针)等于把整个坐标系绕着相同的旋转轴逆向旋转(也就是顺时针),有公式:
R=Rz(θ)=GbCT=Rz(−θ)(6)\mathbf{R}=\mathbf{R_z(\theta)}=\mathbf{^{b}_{G}C}^T=\mathbf{R_z(-\theta)} \tag{6} R=Rz​(θ)=Gb​CT=Rz​(−θ)(6)

结论

可以看到,同样的一个旋转动作(绕着Z轴旋转45°),被动旋转和主动旋转给出的结论完全不同,其本质原因在于被动旋转在主动的转坐标系,那么对于坐标系中的所有点来说就是逆向的旋转了。

于是容易得到下面的结论:如果使用一个被动旋转去旋转一个点或者是向量,则坐标系的变换是正向的,但是表示主动旋转的旋转矩阵确实逆向的;主动旋转则是相反的结论。


乱入——四元数对于旋转的表示

这一小节我们具体来看一下Hamilton和Shuster表示法的“爱恨情仇”。

Hamilton四元数表示法

四元数与旋转向量之间的关系如下:
q=sin(θ2)+cos(θ2)uR=[sin(θ2),cos(θ2)uR](7)\mathbf{q}=\mathrm{sin}(\frac{\theta}{2})+\mathrm{cos}(\frac{\theta}{2})\mathbf{u_R}=[\mathrm{sin}(\frac{\theta}{2}), \mathrm{cos}(\frac{\theta}{2})\mathbf{u_R}] \tag{7} q=sin(2θ​)+cos(2θ​)uR​=[sin(2θ​),cos(2θ​)uR​](7)
其中旋转轴是在参考系上的。

随后定义虚部的乘法运算法则:
{i2=j2=k2=ijk=1ij=−ji=kjk=−kj=iki=−ik=j(8)\begin{cases} i^2=j^2=k^2=ijk=1 \\ i j=-j i=k \\ j k=-k j=i \\ k i=-i k=j \end{cases} \tag{8} ⎩⎪⎪⎪⎨⎪⎪⎪⎧​i2=j2=k2=ijk=1ij=−ji=kjk=−kj=iki=−ik=j​(8)
这里对四元数的其他的数学性质就不做过多赘述,感兴趣的可以到参考3和参考4中看。

对于两个四元数的相乘,应用虚部乘法法则之后有:
qˉ⊙pˉ=[qw−qx−qy−qzqxqw−qzqyqyqzqw−qxqz−qyqxqw][pxpypzpw]=[qw−qTqqwI3×3+⌊q×⌋][ppw]=L(q‾)p‾qˉ⊙pˉ=[pw−px−py−pzpxpwpz−pypy−pzpwpxpzpy−pxpw][qxqyqzqw]=[pw−pTppwI3×3+⌊p×⌋][qqw]=R(p‾)q‾(9)\begin{aligned} \begin{array}{l} \bar{q} \odot \bar{p}&=\left[\begin{array}{cccc} q_{w} & -q_{x} & -q_{y} & -q_{z} \\ q_{x} & q_{w} & -q_{z} & q_{y} \\ q_{y} & q_{z} & q_{w} & -q_{x} \\ q_{z} & -q_{y} & q_{x} & q_{w} \end{array}\right]\left[\begin{array}{c} p_{x} \\ p_{y} \\ p_{z} \\ p_{w} \end{array}\right] \\ &=\left[\begin{array}{cc} \mathrm{q_w} & -\mathbf{q}^T \\ \mathbf{q} & q_{w} \mathbf{I}_{3 \times 3}+\lfloor\mathbf{q} \times\rfloor \end{array}\right]\left[\begin{array}{c} \mathbf{p} \\ p_{w} \end{array}\right] \\ &=\mathcal{L}(\overline{q})\overline{p} \end{array} \\ \begin{array}{l} \bar{q} \odot \bar{p}&=\left[\begin{array}{cccc} p_{w} & -p_{x} & -p_{y} & -p_{z} \\ p_{x} & p_{w} & p_{z} & -p_{y} \\ p_{y} & -p_{z} & p_{w} & p_{x} \\ p_{z} & p_{y} & -p_{x} & p_{w} \end{array}\right]\left[\begin{array}{c} q_{x} \\ q_{y} \\ q_{z} \\ q_{w} \end{array}\right] \\ &=\left[\begin{array}{cc} \mathrm{p_w} & -\mathbf{p}^T \\ \mathbf{p} & p_{w} \mathbf{I}_{3 \times 3}+\lfloor\mathbf{p} \times\rfloor \end{array}\right]\left[\begin{array}{c} \mathbf{q} \\ q_{w} \end{array}\right] \\ &=\mathcal{R}(\overline{p})\overline{q} \end{array} \end{aligned} \tag{9} qˉ​⊙pˉ​​=⎣⎢⎢⎡​qw​qx​qy​qz​​−qx​qw​qz​−qy​​−qy​−qz​qw​qx​​−qz​qy​−qx​qw​​⎦⎥⎥⎤​⎣⎢⎢⎡​px​py​pz​pw​​⎦⎥⎥⎤​=[qw​q​−qTqw​I3×3​+⌊q×⌋​][ppw​​]=L(q​)p​​qˉ​⊙pˉ​​=⎣⎢⎢⎡​pw​px​py​pz​​−px​pw​−pz​py​​−py​pz​pw​−px​​−pz​−py​px​pw​​⎦⎥⎥⎤​⎣⎢⎢⎡​qx​qy​qz​qw​​⎦⎥⎥⎤​=[pw​p​−pTpw​I3×3​+⌊p×⌋​][qqw​​]=R(p​)q​​​(9)

Hamilton提出四元数其实是铁站边被动旋转的,也就是说四元数其实表示的是对于坐标系的旋转。有如下的公式:
XB=q⊙XA⊙q−1(10)\mathcal{X}_{B}=\mathbf{q}\odot \mathcal{X}_{A} \odot \mathbf{q^{-1}} \tag{10} XB​=q⊙XA​⊙q−1(10)
其中XA\mathcal{X}_{A}XA​和XB\mathcal{X}_{B}XB​表示坐标系{A}和坐标系{B}。

根据Hamilton规定的虚部乘法运算法则:,有:
XB=ABq⊙XA⊙ABq−1=[q−1]R[q]LXA=((2qw2−1)I3×3+2qw⌊q×⌋+2qqT)XA=[qw2+qx2−qy2−qz22(qxqy−qwqz)2(qxqz+qwqy)2(qxqy+qwqz)qw2−qx2+qy2−qz22(qyqz−qwqx)2(qxqz−qwqy)2(qyqz+qwqx)qw2−qx2−qy2+qz2]XA=ABRXA(11)\begin{aligned} \mathcal{X}_{B} &= \mathbf{_{A}^{B}q}\odot \mathcal{X}_{A} \odot \mathbf{_{A}^{B}q^{-1}} \\ &=[\mathbf{q^{-1}}]_{R}[\mathbf{q}]_{L} \mathcal{X}_{A} \\ &=(\left(2 q_{w}^{2}-1\right) \mathbf{I}_{3 \times 3}+2 q_{w}\lfloor\mathbf{q} \times\rfloor+2 \mathbf{q} \mathbf{q}^{\mathrm{T}})\mathcal{X}_A \\ &=\left[\begin{array}{ccc} q_{w}^{2}+q_{x}^{2}-q_{y}^{2}-q_{z}^{2} & 2\left(q_{x} q_{y}-q_{w} q_{z}\right) & 2\left(q_{x} q_{z}+q_{w} q_{y}\right) \\ 2\left(q_{x} q_{y}+q_{w} q_{z}\right) & q_{w}^{2}-q_{x}^{2}+q_{y}^{2}-q_{z}^{2} & 2\left(q_{y} q_{z}-q_{w} q_{x}\right) \\ 2\left(q_{x} q_{z}-q_{w} q_{y}\right) & 2\left(q_{y} q_{z}+q_{w} q_{x}\right) & q_{w}^{2}-q_{x}^{2}-q_{y}^{2}+q_{z}^{2} \end{array}\right]\mathcal{X}_{A} \\ &=\mathbf{_{A}^{B}R}\mathcal{X}_{A} \end{aligned} \tag{11} XB​​=AB​q⊙XA​⊙AB​q−1=[q−1]R​[q]L​XA​=((2qw2​−1)I3×3​+2qw​⌊q×⌋+2qqT)XA​=⎣⎡​qw2​+qx2​−qy2​−qz2​2(qx​qy​+qw​qz​)2(qx​qz​−qw​qy​)​2(qx​qy​−qw​qz​)qw2​−qx2​+qy2​−qz2​2(qy​qz​+qw​qx​)​2(qx​qz​+qw​qy​)2(qy​qz​−qw​qx​)qw2​−qx2​−qy2​+qz2​​⎦⎤​XA​=AB​RXA​​(11)
这里可以把上面关于旋转的例子带入进来,即旋转轴在{R}系,旋转角为45°,对应四元数为[cos(θ2),0,0,sin(θ2)][\mathrm{cos}(\frac{\theta}{2}), 0, 0, \mathrm{sin}(\frac{\theta}{2})][cos(2θ​),0,0,sin(2θ​)],则公式(11)描述的旋转刚好就是对于坐标系的旋转(也就是公式(2))。

于是对于Hamilton四元数而言,与旋转向量的映射关系如下:
Cs(Gbq)∼GbR(RGb)(12)\mathbf{C_s}(_{G}^{b}\mathbf{q}) \sim {}_{G}^{b}\mathbf{R}(\mathbf{R}_{G}^{b}) \tag{12} Cs​(Gb​q)∼Gb​R(RGb​)(12)

Attention:

  1. 上式的旋转关系按最初的用意来说只能用于坐标系的旋转,所以笔者把GbR{}_{G}^{b}\mathbf{R}Gb​R写在前面;
  2. 但是如果要旋转的变量并不是坐标系,而是一个向量的话,那么用四元数的乘法则相当于乘了RGb\mathbf{R}_{G}^{b}RGb​矩阵;

Hamilton四元数表示法的缺陷

Hamilton表示法对于天生就是运用于位姿表示的表示法,但是对于旋转一个向量或者点的话却极其不友好(但是并不是不对!),具体而言:对于一个在{b}系的向量,如果希望把它用四元数转到{G}系的话,则需要使用Gbq\mathbf{_{G}^{b}q}Gb​q表示的被动旋转来旋转,这样的自然意义是想把这个向量由{b}转到{G}的方向旋转的,有:
vG=Gbq⊙vb⊙Gbq−1=GbRvb≅RbGvb(13)\mathbf{v^G}=\mathbf{_{G}^{b}q} \odot \mathbf{v^b} \odot \mathbf{_{G}^{b}q^{-1}} = \mathbf{_{G}^{b}R}\mathbf{v^b} \cong \mathbf{R}_{b}^{G}\mathbf{v^b} \tag{13} vG=Gb​q⊙vb⊙Gb​q−1=Gb​Rvb≅RbG​vb(13)
这里的≅\cong≅表示期望相等。因为本质上四元数表示的旋转是对于坐标系的旋转,如果应用于向量,则旋转矩阵应该是GbR{}_{G}^{b}\mathbf{R}Gb​R的逆才对!如果硬生生的用四元数表示对于向量的主动旋转,那么相同的旋转向量则会像上述的主动旋转中的公式(4)一样,与被动旋转对应的主动旋转公式(1)意义和数值上都会相差甚远。

所以如果直接用表示被动旋转的四元数乘法作用于一个向量的话,那么得到的结果不管是用意上还是数值上,其实都是不对的。

同时,如果表示连续的坐标旋转的话,Hamilton表示法的四元数还会出现anti-homomorphy的情况,具体而言:假设另有坐标系{I},如果希望把{G}系的向量用四元数转到{I}系的话,则需要用四元数IGq\mathbf{_{I}^{G}q}IG​q对{G}系下的向量进行旋转,则有:
vI=IGq⊙vG⊙IGq−1=IGRvG≅RGIvG(14)\mathbf{v^I}=\mathbf{_{I}^{G}q} \odot \mathbf{v^G} \odot \mathbf{_{I}^{G}q^{-1}} = {}_{I}^{G}\mathbf{R}\mathbf{v^G} \cong \mathbf{R}_{G}^{I}\mathbf{v^G} \tag{14} vI=IG​q⊙vG⊙IG​q−1=IG​RvG≅RGI​vG(14)
联合公式(13)和(14),四元数想表示的旋转规则如下:
vI=IGq⊙Gbq⊙vb⊙Gbq−1⊙IGq−1=(IGq⊙Gbq)⊙vb⊙(IGq⊙Gbq)−1=Ibq⊙vb⊙Ibq−1(15A)\begin{aligned} \mathbf{v^I}&=\mathbf{_{I}^{G}q} \odot \mathbf{_{G}^{b}q} \odot \mathbf{v^b} \odot \mathbf{_{G}^{b}q^{-1}} \odot \mathbf{_{I}^{G}q^{-1}} \\ &=(\mathbf{_{I}^{G}q} \odot \mathbf{_{G}^{b}q}) \odot \mathbf{v^{b}} \odot (\mathbf{_{I}^{G}q} \odot \mathbf{_{G}^{b}q})^{-1} \\ &=\mathbf{_{I}^{b}q} \odot \mathbf{v^{b}} \odot \mathbf{_{I}^{b}q}^{-1} \end{aligned} \tag{15A} vI​=IG​q⊙Gb​q⊙vb⊙Gb​q−1⊙IG​q−1=(IG​q⊙Gb​q)⊙vb⊙(IG​q⊙Gb​q)−1=Ib​q⊙vb⊙Ib​q−1​(15A)

然而,如果使用四元数与旋转矩阵映射关系公式(12)的话,那么公式(14)的连续旋转则变作:
Cs(IGq⊙Gbq)=Cs(IGq)Cs(Gbq)=RIGRGb≢RbI(15B)\mathbf{C_s}(\mathbf{_{I}^{G}q} \odot \mathbf{_{G}^{b}q})=\mathbf{C_s}(\mathbf{_{I}^{G}q})\mathbf{C_s}(\mathbf{_{G}^{b}q})=\mathbf{R}_{I}^{G}\mathbf{R}_{G}^{b} \not\equiv \mathbf{R}_{b}^{I} \tag{15B} Cs​(IG​q⊙Gb​q)=Cs​(IG​q)Cs​(Gb​q)=RIG​RGb​​≡RbI​(15B)

所以看到,Hamilton在旋转向量的时候,一共有两个缺点:

  1. 在对向量进行旋转的时候,数值意义上与自然意义上完全不相同;
  2. 在连续旋转时,无法保持homomorphy;

其实以上问题,如果在用四元数的时候一直记得它是被动旋转,所以映射到旋转矩阵时映射为转置,那么一切都是对的,即参考2中提倡的映射方式:
CH(Gbq)∼RbG(16)\mathbf{C_H}(_{G}^{b}\mathbf{q}) \sim \mathbf{R}_{b}^{G} \tag{16} CH​(Gb​q)∼RbG​(16)
注意这里就不表示对于坐标系的旋转了,所以直接把字母放在了旋转矩阵R后面;

Shuster四元数表示法

Shuster四元数的表示法为了解决上述意义与数值不同的缺点用的方法比较巧妙,通过改变四元数的虚数运算法则达到了数学上的一致性:
{i2=j2=k2=−1−ij=ji=k−jk=kj=i−ki=ik=j(17)\begin{cases} i^2=j^2=k^2=-1 \\ -i j=j i=k \\ -j k=k j=i \\ -k i=i k=j \end{cases} \tag{17} ⎩⎪⎪⎪⎨⎪⎪⎪⎧​i2=j2=k2=−1−ij=ji=k−jk=kj=i−ki=ik=j​(17)
同时为了与Hamilton四元数区分开,Shuster将四元数的运算做了如下改变:

  1. 将四元数的组织方式也变化了一下:

q=[qv,qw](18)\mathbf{q}=[\mathbf{q_v}, \mathrm{q_w}] \tag{18} q=[qv​,qw​](18)

  1. 表示四元数乘法的符号从原先的⊙\odot⊙变作了⊗\otimes⊗;

如果用公式(17)定义的虚部乘法法则来计算四元数的乘法的话,则有:
qˉ⊗pˉ=[qwqz−qyqx−qzqwqxqyqy−qxqwqz−qx−qy−qzqw][pxpypzpw]=[qwI3×3−⌊q×⌋q−qTqw][ppw]=L(q‾)p‾qˉ⊗pˉ=[pw−pzpypxpzpw−pxpy−pypxpwpz−px−py−pzpw][qxqyqzqw]=[pwI3×3+⌊p×⌋p−pTpw][qqw]=R(p‾)q‾(19)\begin{aligned} \begin{array}{l} \bar{q} \otimes \bar{p}&=\left[\begin{array}{cccc} q_{w} & q_{z} & -q_{y} & q_{x} \\ -q_{z} & q_{w} & q_{x} & q_{y} \\ q_{y} & -q_{x} & q_{w} & q_{z} \\ -q_{x} & -q_{y} & -q_{z} & q_{w} \end{array}\right]\left[\begin{array}{c} p_{x} \\ p_{y} \\ p_{z} \\ p_{w} \end{array}\right] \\ &=\left[\begin{array}{cc} q_{w} \mathbf{I}_{3 \times 3}-\lfloor\mathbf{q} \times\rfloor & \mathbf{q} \\ -\mathbf{q}^{\mathrm{T}} & q_{w} \end{array}\right]\left[\begin{array}{c} \mathbf{p} \\ p_{w} \end{array}\right] \\ &=\mathcal{L}(\overline{q})\overline{p} \end{array} \\ \begin{array}{l} \bar{q} \otimes \bar{p}&=\left[\begin{array}{cccc} p_{w} & -p_{z} & p_{y} & p_{x} \\ p_{z} & p_{w} & -p_{x} & p_{y} \\ -p_{y} & p_{x} & p_{w} & p_{z} \\ -p_{x} & -p_{y} & -p_{z} & p_{w} \end{array}\right]\left[\begin{array}{c} q_{x} \\ q_{y} \\ q_{z} \\ q_{w} \end{array}\right] \\ &=\left[\begin{array}{cc} p_{w} \mathbf{I}_{3 \times 3}+\lfloor\mathbf{p} \times\rfloor & \mathbf{p} \\ -\mathbf{p}^{\mathrm{T}} & p_{w} \end{array}\right]\left[\begin{array}{c} \mathbf{q} \\ q_{w} \end{array}\right] \\ &=\mathcal{R}(\overline{p})\overline{q} \end{array} \end{aligned} \tag{19} qˉ​⊗pˉ​​=⎣⎢⎢⎡​qw​−qz​qy​−qx​​qz​qw​−qx​−qy​​−qy​qx​qw​−qz​​qx​qy​qz​qw​​⎦⎥⎥⎤​⎣⎢⎢⎡​px​py​pz​pw​​⎦⎥⎥⎤​=[qw​I3×3​−⌊q×⌋−qT​qqw​​][ppw​​]=L(q​)p​​qˉ​⊗pˉ​​=⎣⎢⎢⎡​pw​pz​−py​−px​​−pz​pw​px​−py​​py​−px​pw​−pz​​px​py​pz​pw​​⎦⎥⎥⎤​⎣⎢⎢⎡​qx​qy​qz​qw​​⎦⎥⎥⎤​=[pw​I3×3​+⌊p×⌋−pT​ppw​​][qqw​​]=R(p​)q​​​(19)

对比公式(9)和公式(19),可以发现一个有趣的事情:
qˉ⊙pˉ=LHN(q‾)p‾=RSH(q‾)p‾=pˉ⊗qˉ(20)\bar{q} \odot \bar{p} = \mathcal{L_{HN}}(\overline{q})\overline{p}=\mathcal{R_{SH}}(\overline{q})\overline{p}=\bar{p} \otimes \bar{q} \tag{20} qˉ​⊙pˉ​=LHN​(q​)p​=RSH​(q​)p​=pˉ​⊗qˉ​(20)
于是我们看到,调整了虚部乘法之后,四元数的乘法被flip了!

同时我们再来看看经过虚数乘法变化之后,四元数对向量的旋转公式变成了什么样:
XB=BAq⊗XA⊗BAq−1=[q−1]R[q]LXA=((2qw2−1)I3×3−2qw⌊q×⌋+2qqT)XA=[qw2+qx2−qy2−qz22(qxqy+qwqz)2(qxqz−qwqy)2(qxqy−qwqz)qw2−qx2+qy2−qz22(qyqz+qwqx)2(qxqz+qwqy)2(qyqz−qwqx)qw2−qx2−qy2+qz2]XA=RABXA(21)\begin{aligned} \mathbf{X}_{B} &= \mathbf{_{B}^{A}q}\otimes \mathbf{X}_{A} \otimes \mathbf{_{B}^{A}q^{-1}} \\ &=[\mathbf{q^{-1}}]_{R}[\mathbf{q}]_{L} \mathbf{X}_{A} \\ &=(\left(2 q_{w}^{2}-1\right) \mathbf{I}_{3 \times 3}-2 q_{w}\lfloor\mathbf{q} \times\rfloor+2 \mathbf{q} \mathbf{q}^{\mathrm{T}})\mathbf{X}_A \\ &=\left[\begin{array}{ccc} q_{w}^{2}+q_{x}^{2}-q_{y}^{2}-q_{z}^{2} & 2\left(q_{x} q_{y}+q_{w} q_{z}\right) & 2\left(q_{x} q_{z}-q_{w} q_{y}\right) \\ 2\left(q_{x} q_{y}-q_{w} q_{z}\right) & q_{w}^{2}-q_{x}^{2}+q_{y}^{2}-q_{z}^{2} & 2\left(q_{y} q_{z}+q_{w} q_{x}\right) \\ 2\left(q_{x} q_{z}+q_{w} q_{y}\right) & 2\left(q_{y} q_{z}-q_{w} q_{x}\right) & q_{w}^{2}-q_{x}^{2}-q_{y}^{2}+q_{z}^{2} \end{array}\right]\mathbf{X}_{A} \\ &=\mathbf{R_{A}^{B}}\mathbf{X}_{A} \end{aligned} \tag{21} XB​​=BA​q⊗XA​⊗BA​q−1=[q−1]R​[q]L​XA​=((2qw2​−1)I3×3​−2qw​⌊q×⌋+2qqT)XA​=⎣⎡​qw2​+qx2​−qy2​−qz2​2(qx​qy​−qw​qz​)2(qx​qz​+qw​qy​)​2(qx​qy​+qw​qz​)qw2​−qx2​+qy2​−qz2​2(qy​qz​−qw​qx​)​2(qx​qz​−qw​qy​)2(qy​qz​+qw​qx​)qw2​−qx2​−qy2​+qz2​​⎦⎤​XA​=RAB​XA​​(21)
对比公式(21)和公式(11):

  1. 两个四元数均表示被动旋转意义,不过一个是对坐标系的主动旋转,一个是对向量的主动旋转;
  2. 在公式(11)中,向量均为坐标系的基底,用花体表示;而在公式(21)中,向量都是坐标系中的一个向量,用大写粗体表示;
  3. 在公式(11)中和公式(21)中,他们的旋转矩阵刚好互为转置,也就是说在Shuster的表示方法中,一个表示被动旋转的四元数通过乘法运算法则得到的是在被动旋转意义下的旋转矩阵;

Shuster表示法是如何解决Hamilton的缺陷的

公式(21)其实解决了公式(14)的问题,即在数学运算意义下,整个数值推导与期望表示的意义等价;

而对于连续主动旋转一个向量的antihomography的解决(公式(15A)和(15B)),其实一个方案给出了两个不同角度的解决思路;

  1. 因为公式(20)的存在,导致四元数乘法的flip操作,有:
    Cs(Ibq)=Cs(IGq⊗Gbq)⏟JPL−conversion=Cs(Gbq⊙IGq)=Cs(Gbq)Cs(IGq)=RGbRIG≡RIb⏟HN−conversion(22)\mathbf{C_s}(\mathbf{{}_{I}^{b}q})=\underbrace{\mathbf{C_s}(\mathbf{_{I}^{G}q} \otimes \mathbf{_{G}^{b}q})}_{JPL-conversion}=\underbrace{\mathbf{C_s}(\mathbf{_{G}^{b}q} \odot \mathbf{_{I}^{G}q})=\mathbf{C_s}(\mathbf{_{G}^{b}q})\mathbf{C_s}(\mathbf{_{I}^{G}q})=\mathbf{R}_{G}^{b}\mathbf{R}_{I}^{G} \equiv \mathbf{R}_{I}^{b}}_{HN-conversion} \tag{22} Cs​(Ib​q)=JPL−conversionCs​(IG​q⊗Gb​q)​​=HN−conversionCs​(Gb​q⊙IG​q)=Cs​(Gb​q)Cs​(IG​q)=RGb​RIG​≡RIb​​​(22)
    笔者把在什么部分用什么conversion表明了出来;

  2. 因为公式(21)的存在,导致四元数到旋转矩阵的映射发生了变化,有:

    CsS(Ibq)=CsS(IGq⊗Gbq)=CsS(IGq)CsS(Gbq)=RGIRbG=RbI⏟JPL−conversion(23)\mathbf{C_s^S}(\mathbf{{}_{I}^{b}q})=\underbrace{\mathbf{C_s^S}(\mathbf{_{I}^{G}q} \otimes \mathbf{_{G}^{b}q})=\mathbf{C_s^S(_{I}^{G}q)} \mathbf{C_s^S(_{G}^{b}q)}=\mathbf{R_{G}^{I}}\mathbf{R_{b}^{G}} = \mathbf{R_{b}^{I}}}_{JPL-conversion} \tag{23} CsS​(Ib​q)=JPL−conversionCsS​(IG​q⊗Gb​q)=CsS​(IG​q)CsS​(Gb​q)=RGI​RbG​=RbI​​​(23)
    这里特意把映射矩阵写作CsS\mathbf{C_{s}^{S}}CsS​表示该映射是Shuster-conversion的。

可以看到,Shuster的方法确实十分巧妙的把四元数旋转一个向量这个公式从数值意义和自然意义下进行了统一。


统一——如何使用两种四元数

经过上面的分析之后,其实稍微透露出了一个信息就是:**虽然被动旋转表示的旋转更贴合实际,但是其实我们在使用和考虑更多的还是主动旋转。**否则就不会出现Shuster想把这两个意义统一起来的想法。

那在我们使用的时候,两个四元数到底差在什么地方呢?

旋转的主动性与被动性上

从四元数表示一个旋转行为上来看:

  1. 如果仅仅看四元数的话,其实两个四元数是一模一样的,均表示绕着{R}系中的一个旋转轴旋转了θ\mathbf{\theta}θ度。

  2. 但是如果看与向量乘积的最后结果,则用Hamilton的四元数更像是公式(4)描述的主动旋转;而Shuster的四元数是公式(1)描述的被动旋转。

于是在实际使用的时候,Hamilton四元数其实更多的描述了主动旋转了,而Shuster四元数则是更好的保留了作为本意的被动旋转的意义。

在参考[2]中,作者给出了如下的对照表:

旋转的方向上

根据参考2中第II节的介绍,主动旋转的方向与PBTW(body-to-world)相同,而被动旋转的方向则与之相反,为PWTB(world-to-body)。对比现有的一些文章(例如参考3和参考4)中的方向也能发现:

  1. 对于Hamilton的表示方法,其四元数一般表示为将{b}系的向量转到{G}系下;
  2. 对于JPL的表示方法,其四元数表示为将{G}系的向量转到{b}系下;

但是这里我们需要明确的是,上述两种四元数的数值都是一样的(即旋转轴和旋转角度都是一致的),只不过因为虚部乘法法则不一样导致数值运算上刚好是互为转置。


总结

本文较为详细的分析了两种四元数的产生以及最终的演化,对于工程上来讲,通常使用更多的是Hamilton的表示方法,因为相当多的开源库(例如Eigen,ROS,Ceres等)都遵从这种表示方法。

但是对于MSCKF而言,其主要使用的是JPL的表示方法。但是我们说对于两种四元数来讲,他们所表示的旋转都是一个,不过是方向不同。

MSCKF(一)——四元数的两种表示相关推荐

  1. 右手系转左手系、旋转矩阵转四元数、四元数的两种表达(Hamilton/JPL)

    右手系转左手系.旋转矩阵转四元数.四元数的两种表达:Hamilton/JPL 右手系转左手系 旋转矩阵转四元数 四元数的两种表达:Hamilton/JPL 两种转换代码 最近一个项目需要使用unity ...

  2. 学习MSCKF笔记——四元数基础

    学习MSCKF笔记--四元数基础 学习MSCKF笔记--四元数基础 1. 四元数基本性质 1.1 加法 1.2 乘法 1.3 共轭 1.4 模 1.5 逆 1.6 单位四元数 1.7 指数 1.8 对 ...

  3. 旋转矩阵转化成四元数的三种算法

    本文为博主"声时刻"原创文章,未经博主允许不得转载. 联系方式:shenshikexmu@163.com 旋转矩阵的两种表示 看到旋转矩阵有两种表现方式,左乘矩阵.右乘矩阵(两矩阵 ...

  4. 继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错? springboot 两种方式稳定解决跨域问题

    继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错???springboot 两种方式稳定解决跨域问题! 之前我写了一篇文章,来解决CORS报错 ...

  5. tornado 异步两种实现形式 通过回调可以利用

    两种实现异步的方式 通过回调可以返回自己的数据

  6. Pytorch两种模型保存方式

    以字典方式保存,更容易解析和可视化 Pytorch两种模型保存方式 大黑_7e1b关注 2019.02.12 17:49:35字数 13阅读 5,907 只保存模型参数 # 保存 torch.save ...

  7. 2021年大数据Spark(九):Spark On Yarn两种模式总结

    目录 Spark On Yarn两种模式 引入 一.当一个MR应用提交运行到Hadoop YARN上时 二.当一个Spark应用提交运行在集群上时 注意 client 模式 cluster 模式 总结 ...

  8. 周一02.3运行python程序的两种方式

    一.运行python程序的两种方式 方法一:交互式:                      优点:输入一行代码立刻返回结果                       缺点:无法永久保存代码 方法 ...

  9. 单例模式的两种实现方式对比:DCL (double check idiom)双重检查 和 lazy initialization holder class(静态内部类)...

    首先这两种方式都是延迟初始化机制,就是当要用到的时候再去初始化. 但是Effective Java书中说过:除非绝对必要,否则就不要这么做. 1. DCL (double checked lockin ...

最新文章

  1. 树形dp --- 2020 icpc 南京 M Monster Hunter
  2. ipvs -r02–restore02恢复虚拟服务器规则,ipvs 介绍
  3. Mysql 乱码的解决
  4. Matlab实用程序--图形应用-图形的隐藏属性
  5. 第17讲:aiohttp 异步爬虫实战
  6. 吹气球问题的C语言编程,C语言怎样给一个数组中的数从大到小排序
  7. PHP中对hmac_sha1签名算法的实现方法
  8. python 进程 线程 协程
  9. 中国科学院计算机报录比,中科院报录比详情 几条择校建议 - 考研 - 小木虫 - 学术 科研 互动社区...
  10. 从零打造Android计算器(安卓开发初体验)
  11. android sd卡 f2fs,F2FS保你18个月不卡?手机文件系统相关科普
  12. 【OpenCV学习笔记】之离散傅里叶变换(DFT)
  13. 云主机磁盘I/O %util飙高排查
  14. 解决报错Connection terminated as request was larger than 10485760
  15. Java实现QQ邮箱登录,实现邮箱验证码三分钟失效,代码实现发送验证码和登录全过程思路。内附完整项目。
  16. 流媒体技术笔记(视频编码相关)
  17. windowsmobile 综合 注册表修改 CSDN 推荐tag:mp3 storage gprs 注册表 文件
  18. C语言实现学生成绩管理系统(EasyX图形界面)
  19. python怎么导入sql数据库,##使用python将excel表中数据导入sql server数据库
  20. 【22】Unet网络的复现和理解

热门文章

  1. vue 解决路由重复点击报错
  2. 5G的NSA和SA,到底啥意思?
  3. 横扫阿里、滴滴、美团后,3年经验的Java后端妹子整理出这份厚厚的面经!
  4. 条件生成对抗神经网络,生成对抗网络gan原理
  5. 北航2020计算机学院招生,北航网络空间安全学院接收2020推免研究生复试成绩公示及相关说明...
  6. 脂多糖(LPS) 来源于肠炎沙门氏菌, S-型解决方案
  7. 追爱系列电影电视剧书籍
  8. python第二周day5
  9. java毕业生设计星星电影购票网站计算机源码+系统+mysql+调试部署+lw
  10. ES版cpu如何购买和判断?