查看: 3156|回复: 0

【飞思卡尔博客】表示定位:第二部分

[复制链接]
  • TA的每日心情
    难过
    2021-12-15 16:01
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    305

    主题

    4701

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    377
    最后登录
    2023-8-16
    发表于 2013-4-2 09:38:01 | 显示全部楼层 |阅读模式
    表示定位:第二部分

    作者 Michael E Stanley

    在表示定位第一部分中,我们探讨了关于旋转矩阵和欧拉角的用途。在上次博客的结尾,我提到了一个事实——或许存在更加高效地描述旋转的方式方法。让我们随着下图1中所画的一个简单刚性物体(这种情况下一般表示的是汽缸)的旋转来研究。如图,汽缸表面的A点作为初始位置经旋转到空间上的B点。

    图1:刚性体从空间A坐标点旋转移动到B坐标点。

    在这一简单的情况下,我保持旋转的轴线沿着如图2所示汽缸垂直轴线的方向。但是这并非是对基础数学工作的一个要求。只要我们有一个刚性体,我们就可以一直按照如下的方式进行描述。


    图2:图1所示系统的直角坐标系轮廓。

    图3处理了相同的旋转,但重点是,我们有一个垂直于旋转轴线的旋转平面。汽缸的运动是围绕旋转轴线旋转了角度α,其中所述的点之间的关系被约束在旋转平面内。


    图3:只看旋转平面和旋转轴如上所示。

    旋转可以由在统一旋转轴内的三个分量和旋转角度共同描述,是弧度还是角度,这取决于系统中是如何使用。举个例子,我最近做了一些OpenGL ES图形编程。这个系统在便携设备上非常流行。我使用它来编写Android版本的演示程序,然后再移植到IOS系统上。在OpenGL ES中,你按照角度的集合构造了三维物体,这些角度可以偏移和/或旋转来改变视角。作为一个例子,我们的汽缸也可被粗略的绘制成图4中所示。


    图4:OpenGL ES绘制汽缸的过程

    在这一示例中,汽缸的底部和顶部各用六个三角形来建模。另外的柱面建模使用了设定在一条带状图形的16个三角形。OpenGL ES可以对画出的图形结构进行有效的优化,并且可以对绘制出的表面纹理进行渲染。一旦画出来,图形非常整洁,我们可以使用一条简单的OpenGL ES 指令,得出图1中的汽缸围绕Z轴简单旋转30度的合理估算。这一指令是:

    gl.glRotatef(-30.0f, 0.0f, 0.0f, 1.0f);

    就这一点,你可能会想到:“是啊,有道理,但是,在数学层面上它是如何工作的呢?”这就需要笔者向各位介绍一下四元数的概念。从概念上讲,一个四元数的编码等同于上述的轴线和角度。但是,基于数学的原因,它处理旋转角度的半角如下所示:


    图5:图4系统中相关的四元数

    在基础数学把你搞得晕头转向之前,你应该知道,没有必要计划自己构建实施四元数的应用程序库,你只需要知道几个要点:

         

    •     这需要4个数字来完全描述一个四元数(通常是q0至q3)。   
    • 并非所有的四元数都是旋转四元数,有单位长度的才是旋转四元数(q02 + q12 + q22 + q32 = 1)。我们会在后续文章中对旋转四元数进行严格的讨论。   
    • 根据前文提到的讨论结果,这些相同的旋转可以使用欧拉角、旋转矩阵等来描述。形式之间的转换和使用多种形式比较普遍。旋转矩阵的特性就是始终唯一。欧拉角受限于万向节锁定,并且不应该用于内部计算(唯一的输入/输出的结果)。   
    • 你可以使用1个四元数q和方程式W = qVq*,来旋转1个向量V(四元产品和复共轭将稍后定义)。   
    • 一个旋转的序列可以通过四元数q1后跟q2来表示,通过计算旋转产品q=q2q1,然后应用旋转操作,可以将序列叠成单一的旋转。
    我将提出的数学定义,并没有证明。如果你真的想知道基本理论,我建议你去看杰克•柯伊伯所著的一篇出色文章:四元数和旋转序列。这似乎是到目前为止对此话题最广泛通用的处理方式,即使是剩余部分也极具可读性。

    请注意,旋转四元数处理α/2,并非α。我们可以定义一个旋转四元数的“q”的几个等价方程。

    q = (q0, q1, q2, q3)(等式1)
    q = q0 + q, 其中 q = iq1 + jq2 + kq3(等式2)
    q = cos(α/2) + u sin(α/2), 其中u是旋转的矢量轴(等式3)

    我使用的四元数形式如:q0 = cos(α/2)。一些文本会重新排序四元数,结果是向量分量q包含于q0-2 和 q3 = cos(α/2)中。请确保您了解您的文字/软件库支持的形式。

    四元数是一个超复数形式,而非一个简单实际的虚构成分,我们有一个真实和3个虚构的部分(I,J和K)。这些想象中的成分规则如下:

    i2 = j2 = k2 = ijk = -1(等式4)
    ij = k = -ji(等式5)
    jk = i = -kj(等式6)
    ki = j = -ik(等式7)

    2个四元数p和q,只有当其各个独立的组成部分相等,彼此才相等。您需要将独立的组成部分加起来才能完成2个四元数的相加。如果

    p = p0 + ip1 + jp2 + kp3; 和(等式8)
    q = q0 + iq1 + jq2 + kq3(等式9)

    那么

    p + q = (p0 + q0) + i(p1+q1) + j(p2+q2) + k(p3+q3)(等式10)

    加法操作符合交换性原理。也就是说p+q = q+p。通过实数的标量相乘来实现四元数的乘法是无价值的,仅当四元数每个组成成分的标量相互相乘来实现。两个四元数相乘也并非如此微末。

    pq = p0q0 - p.q + p0q + q0p + p x q(等式11)
    一个四元数乘以另一个四元数结果会是第三个四元数。注意,第一个两部分(p0q0 - p.q)构成了结果的标量部分,最后3个组成部分(p0q + q0p + p x q)构成了向量部分。四元数产品的操作不可交换pq≠qp,顺序很重要。两个四元数的相乘包括标量、叉积和dot product术语。除非你正在写你自己专有的四元数库,否则你可能永远也不会使用如上的表达式。相反,你可以使用一个四元数乘法的函数来实现四元数的相乘。

    复共轭如下:

    q = q0 + iq1 + jq2 + kq3 is q* = q0 - iq1 - jq2 - kq3(等式12)
    与此相关的公式有:

    (pq)* = q*p*(等式13)
    q+q* = 2q0(等式14)
    q-1 = q* 适用于任何单位四元数(等式15)
    等式15很有趣。如果你认为一个四元数作为旋转的操作者的话,据说你可以通过反转旋转坐标轴来实现反转旋转操作。由于我们使用右手法则来描述极性旋转,所以这会显得非常有意义。反转坐标轴的方向就等同于旋转方向的反转。

    上述旋转的另一个有趣的地方是四元数并不是唯一的:

    q = -q(等式16)
    任何旋转的四元数都可以乘以-1,并且仍然产生相同的旋转!这是因为我们同时扭转了角度和旋转轴线的缘故(然后互相抵消)。因此,如果一个旋转四元数的标量部分是负数的话,通过对它求反来消除不确定性是常规使用的方式。

    在这一点上,你一定想知道,你究竟要选择或不选择使用四元数,而不使用旋转矩阵的原因。这里有一个优点和缺点的简要总结:


                主题            四元数            旋转矩阵                                    存储空间            需要16字节的存储空间,在单精度浮点数(每4字节存储4个元素)            需要36字节的存储空间(每4个字节存储9个元素)                            计算(2个连续旋转            4个元素,每一个都需要4次乘法和3次加法,共计28次操作            9个元素,每一个都需要3次乘法和2次加法,共计45次操作                            向量旋转            通过四元数前乘、后乘来旋转一个向量需要52次操作            通过旋转矩阵旋转一个向量需要15次操作(每3个元素需要3次乘法和2次加法)                            不连续性            一般来说,我们强制四元数标量的部分是正数,这可能会导致在旋转轴(翻转)的不连续性。            无                            易理解性            通常需要大量研究来了解详细情况            大多数工程师可以轻松理解                            转变            从旋转矩阵 =            m11                        m12                        m13                                                                m21                        m22                        m23                                                                m31                        m32                        m33                                我们有:
                q0 = 0.5 sqrt(m11 + m22 + m33 + 1)
                q1 = (m32 - m23) / (4q0)
                q2 = (m13 - m31) / (4q0)
                q3 = (m21 - m12) / (4q0) (等式17)
                            RM =            
    2q02- 1 + 2q122q1q2 - 2q0q32q1q3 +2q0q2
    2q1q2 + 2q0q3 2q2q3 - 2q0q1
    2q1q3 - 2q0q22q2q3 + 2q0q12q02-1 + 2q32
                 
                (等式18)
                        

    至于旋转方向,等式17和等式18是一致的。如果不是在一个固定的参数框架中旋转向量,你可以旋转参照系自身。你会使用到旋转方程等式18,在等式17中反转q1, q2 和 q3。

    回到四元数旋转操作算子W = qVq*上。注意V需要按照形如[0,VX,VY,Vz]四元数的形式来表示,在等式11中定义了乘法是四元数的相乘。q*是等式12中定义的复共轭。

    如果你做了大量的图形或传感器融合工作,你可能会发现自己不断地在我们已经提到过的变量表达式之间切换。你会发现记住几个高中几何课程中的定义对此很有用。



    Dot 产品u . v = | u | | v | cos α (等式19)
                如果u和v都是单位向量,那么:u . v = cos α (等式20)


    Cross 产品u x v = | u | | v | sin α n (等式21)
                
    在这里,n是一个单位向量,
                            垂直于包含u和v的平面(n的极性遵守右手法则)如果u和v都是单位向量,那么:n = u x v / (sin α) (等式22)
                
    如果你一直关注的话,你会发现α是u到v是围绕由u x v定义的坐标轴旋转而成。很简单!就是坐标轴和角度两部分。

                参考丛书:

                
                     
    • 四元数和旋转序列, Jack B. Kuipers著, 普林斯顿大学出版社,1999。               
    • 欧拉角Wolfram Demonstrations Project,Frederick W. Strauch著。               
    • 在使用加速度计和磁强计测量的欧拉角中的多元化冗余,Chirag Jagadish 与 Bor-Chin Chang著,第46届IEEE控制与决策会议论文集,2007年12月               
    • “欧拉角”,维基百科网页               
    • 方向表示:第1部分, 2012年10月迈克尔•斯坦利发表于Embedded Beat。            
                
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-5 19:04 , Processed in 0.080222 second(s), 19 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表