这周自己被安排进行优化软件 IMU 姿态解算项目,之前自己只简单了解四元数,对IMU数据处理从未接触,通过这一周的学习感觉收获颇丰,在今天光棍节之际,,,用大半天的时间对这一周的收获进行整理,内容难免有错误还请大佬们指正, 抱拳感谢!!下面是自己学习过程主要参考的内容:参考链接1 、参考链接2 、参考链接3、参考链接4
一、元件简介
1.1 陀螺仪
  陀螺仪,测量角速度,具有高动态特性,它是一个间接测量角度的器件。它测量的是角度的导数,即角速度,要将角速度对时间积分才能得到角度。
   陀螺仪内部有一个陀螺,它的轴由于陀螺效应始终与初始方向平行,这样就可以通过与初始方向的偏差计算出旋转方向和角度。传感器MPU6050实际上是一个结构非常精密的芯片,内部包含超微小的陀螺。
   如果这个世界是理想的美好的,从理论上讲只用陀螺仪是可以完成姿态导航的任务。只需要对3个轴的陀螺仪角速度进行积分,得到3个方向上的旋转角度,也就是姿态数据,即快速融合。不过现实是由于误差噪声等的存在,对陀螺仪积分并不能够得到完全准确的姿态,尤其是运转一段时间以后,积分误差的累加会让得到的姿态和实际的相差甚远。
   那么哪些原因会使陀螺仪得到的姿态结果不准确呢?下面列举出常见的几种:
 零点漂移
假设陀螺仪固定不动,理想角速度值是0dps(degree per second),但是存在零点漂移,例如有一个偏置0.1dps加在上面,于是测量出来是0.1dps,积分一秒之后,得到的角度是0.1度,1分钟之后是6度,还能忍受,一小时之后是360度,转了一圈,也就是说,陀螺仪在短时间内有很大的参考价值。
白噪声
电信号的测量中,一定会带有白噪声,陀螺仪数据的测量也不例外。所以获得的陀螺仪数据中也会带有白噪声,而且这种白噪声会随着积分而累加。
温度/加速度影响
陀螺仪是一个温度和加速度敏感的元器件。例如对于加速度,多轴机器人中的马达一般会带来较强烈的振动,一旦减震控制不好,就会在飞行过程中产生很大的加速度,必会带来陀螺输出的变化,引入误差。这就是在陀螺仪数据手册上常见的deg/sec/g指标。
积分误差
对陀螺仪角速度的积分是离散的,长时间的积分会出现漂移的情况。所以要考虑积分误差的问题。
 这是由于陀螺仪测量姿态存在这么多的误差,所以必须要使用其它传感器辅助校正,其中最重要的就是加速度传感器。
1.2 加速度计
  加速度计的低频特性好,可以测量低速的静态加速度。在机器人上即是对重力加速度g的测量和分析,其它瞬间加速度可以忽略。记住这一点对姿态解算融合理解非常重要。
   在使用加速度计进行测量时,关注的是重力加速度在三个轴上的分量值。加速度计在自由落体时,其输出为0。为什么会这样呢?这里涉及到加速度计的设计原理:加速度计测量加速度是通过比力来测量,而不是通过加速度 (比力即载体受到的除重力以外的外力) , 
     
      
       
       
         惯导比力方程: 
        
        
        
          f 
         
        
          = 
         
        
          a 
         
        
          − 
         
        
          g 
         
        
       
      
        惯导比力方程:\pmb{f=a-g} 
       
      
    惯导比力方程:f=a−g 。
   加速度计仅仅测量的是重力加速度,3轴加速度计输出重力加速度在加速度计所在机体坐标系3个轴上的分量大小。重力加速度的方向和大小是固定的。通过这种关系,可以得到加速度计所在平面与地面的角度关系.
   加速度计若是绕着重力加速度的轴转动,则测量值不会改变,也就是说加速度计无法感知这种水平旋转。
   有关陀螺仪和加速度计和关系,姿态解算融合的原理,再把下面这个比喻放到这里一遍。
1.3 MPU6050
  MPU-60x0是全球首例9轴运动处理传感器。它集成了3轴MEMS陀螺仪,3轴MEMS加速度计,以及一个可扩展的数字运动处理器DMP(Digital Motion Processor),可用I2C接口连接一个第三方的数字传感器,比如磁力计。扩展之后就可以通过其I2C或SPI接口输出一个9轴的信号(SPI接口仅在MPU-6000可用)。MPU-60x0也可以通过其I2C接口连接非惯性的数字传感器,比如压力传感器。
   MPU-60x0对陀螺仪和加速度计分别用了三个16位的ADC,将其测量的模拟量转化为可输出的数字量。为了精确跟踪快速和慢速的运动,传感器的测量范围都是用户可控的,陀螺仪可测范围为±250,±500,±1000,±2000°/秒(dps),加速度计可测范围为±2,±4,±8,±16g。一个片上1024字节的FIFO,有助于降低系统功耗。和所有设备寄存器之间的通信采用400kHz的I2C接口或1MHz 的SPI接口(SPI仅MPU-6000可用)。对于需要高速传输的应用,对寄存器的读取和中断可用20MHz的SPI。另外,片上还内嵌了一个温度传感器和在工作环境下仅有±1%变动的振荡器。
   MPU6050/HMC5883/MS5611传感器之间的连接如下图所示。
 
1.4 DMP硬件解算
  软件解算四元数,即从IIC总线上读到的MPU60x0的AD值,然后通过四元数解算姿态角这种实现方式。
 
   MPU6050的硬解四元数,即从IIC总线上读到的数据不再是MPU60x0的AD值,而是通过初始化对DMP引擎的配置,从IIC总线上读到的直接就是四元数的值,从而跳过了程序通过AD值计算四元数这个看起来繁琐的步骤。机身反应的确要比之前反应灵活,最关键的一点是,这样得出的偏航角(Yaw)很稳很稳,基本不会漂移或者说漂移小到了可以容忍的地步。
  最后,MPU60x0的强大之处不仅于此,它支持一个从IIC接口,可以外部接上一个磁力计,如HMC5883,这样一来,DMP引擎可以直接输出一个绝对的方向姿态,即能够输出一个带东西南北的姿态数据包。
 
接下来,需要讲清楚什么是姿态,怎么表示姿态,如何得到姿态。
二、姿态及其表示
2.1 什么是姿态
姿态就是指机器人运行过程中的俯仰/横滚/航向情况。机器人需要实时知道当前自己的姿态,才能够根据需要操控其接下来的动作,例如保持平稳,例如实现翻滚。
数学模型
  姿态是用来描述一个刚体的固连坐标系和参考坐标系之间的角位置关系,有一些数学表示方法。常见的如欧拉角,四元数,矩阵,轴角。
   地球坐标系又叫做地理坐标系、世界坐标系是固定不变的。正北,正东,正向上构成了这个坐标系的X,Y,Z轴,用坐标系n表示。机器人上固定着一个坐标系,一般称之为机体坐标系,用坐标系b表示。那么就可用欧拉角,四元数等来描述b和n的角位置关系。这就是姿态解算的数学模型和基础。

2.2 姿态表示方式
姿态有多种数学表示方式,常见的是四元数,欧拉角,矩阵和轴角。他们各自有其自身的优点,在不同的领域使用不同的表示方式。在机器人中使用到了四元数和欧拉角。
四元数
四元数是由爱尔兰数学家威廉·卢云·哈密顿在1843年发现的数学概念。从明确地角度而言,四元数是复数的不可交换延伸。如把四元数的集合考虑成多维实数空间的话,四元数就代表着一个四维空间,相对于复数为二维空间。
四元数大量用于电脑绘图(及相关的图像分析)上表示三维物件的旋转及方位。四元数亦见于控制论、信号处理、姿态控制、物理和轨道力学,都是用来表示旋转和方位。相对于另几种旋转表示法(矩阵,欧拉角,轴角),四元数具有某些方面的优势,如速度更快、提供平滑插值、有效避免万向锁问题、存储空间较小等等。
欧拉角
莱昂哈德·欧拉用欧拉角来描述刚体在三维欧几里得空间的取向。对于在三维空间里的一个参考系,任何坐标系的取向,都可以用三个欧拉角来表现。参考系又称为实验室参考系,是静止不动的。而坐标系则固定于刚体,随着刚体的旋转而旋转。

下面通过图例来看看欧拉角是如何产生的,并且分别对应哪个角度。

2.3 姿态解算
姿态解算需要解决的是机器人在地球坐标系中姿态。姿态解算的英文是attitude algorithm,也叫做姿态分析,姿态估计,姿态融合。姿态解算是指根据IMU数据(陀螺仪、加速度计、罗盘等)求解出机器人的姿态,所以也叫做IMU数据融合(IMU Data Fusing)。
角位置关系测量
如上所说,地球坐标系n是固定的。机器人上固定一个坐标系b,这个坐标系b在坐标系n中运动。那么如何知道坐标系b和坐标系n的角位置关系呢,也就是怎么知道机器人相对于地球这个固定坐标系R转动了一下航向,或者侧翻了一下机身。这就是传感器需要测量的数据,传感器包括陀螺仪,加速度计,磁力计。通过获得这些测量数据,得到坐标系b和坐标系n的角位置关系。
惯性测量模块:IMU(Inertial Measurement Unit),提供机器人姿态的传感器原始数据,一般由陀螺仪传感器/加速度传感器/磁力计提供机器人9DOF数据。
机器人根据陀螺仪的三轴角速度对时间积分得到的俯仰/横滚/航向角,这是快速解算。快速解算得到的姿态是存在误差的,而且误差会累加。如果再结合三轴地磁和三轴加速度数据进行校正,得到准确的姿态,这就是深度解算。
当然,快速解算的姿态一般是不能够用于控制机器人的,因为误差太大。所以,一般说的姿态解算是深度解算。
四元数和欧拉角在姿态解算中如何使用
姿态解算的核心在于旋转,一般旋转有4种表示方式:矩阵表示、欧拉角表示、轴角表示和四元数表示。矩阵表示适合变换向量,欧拉角最直观,轴角表示则适合几何推导,而在组合旋转方面,四元数表示最佳。因为姿态解算需要频繁组合旋转和用旋转变换向量,所以采用四元数保存机器人的姿态。
一般来说,使用四元数来保存机器人的姿态(即在地球坐标系中的俯仰/横滚/航向情况)。在需要控制的时候,会将四元数转化为欧拉角,然后输入到姿态控制算法中。
姿态控制算法的输入参数必须要是欧拉角。
下面就是常见机器人姿态解算到姿态控制的整个流程。AD值是指MPU6050的陀螺仪和加速度值,3个维度的陀螺仪值和3个维度的加速度值,每个值为16位精度。AD值通过姿态解算算法得到机器人当前的姿态(姿态使用四元数表示),然后将四元数转化为欧拉角,用于姿态控制算法(PID控制)中。

2.4 余弦矩阵
下面介绍由三轴陀螺仪和加速度计的值来使用软件算法解算姿态的方法。
先逐步认识如何用欧拉角描述一次平面旋转(坐标变换):
 
设坐标系绕旋转 ψ \psi ψ角后得到坐标系,在空间中有一个矢量在坐标系中的投影为,在内的投影为由于旋转绕进行,所以Z坐标未变,即有。
x ′ = O C + C D + D E = O A c o s ψ + A D s i n ψ + D G s i n ψ = O A c o s ψ + ( A D + D G ) s i n ψ = x c o s ψ + y s i n ψ x^{'}=OC+CD+DE =OAcos\psi+ADsin\psi+DGsin\psi \\=OAcos\psi+(AD+DG)sin\psi =xcos\psi+ysin\psi x′=OC+CD+DE=OAcosψ+ADsinψ+DGsinψ=OAcosψ+(AD+DG)sinψ=xcosψ+ysinψ
y ′ = A F − A C = A G c o s ψ − O A c o s ψ = y c o s ψ − x s i n ψ y^{'}=AF-AC=AGcos\psi-OAcos\psi \\ =ycos\psi-xsin\psi y′=AF−AC=AGcosψ−OAcosψ=ycosψ−xsinψ
转换成矩阵形式表示为:
  
      
       
        
         
         
           [ 
          
          
           
            
             
              
              
                x 
               
               
                
               
                 ′ 
                
               
              
             
            
           
           
            
             
              
              
                y 
               
               
                
               
                 ′ 
                
               
              
             
            
           
           
            
             
              
              
                z 
               
               
                
               
                 ′ 
                
               
              
             
            
           
          
         
           ] 
          
         
        
          = 
         
         
         
           [ 
          
          
           
            
             
              
              
                c 
               
              
                o 
               
              
                s 
               
              
                ψ 
               
              
             
            
            
             
              
             
            
            
             
              
              
                s 
               
              
                i 
               
              
                n 
               
              
                ψ 
               
              
             
            
            
             
              
             
            
            
             
             
               0 
              
             
            
           
           
            
             
              
              
                − 
               
              
                s 
               
              
                i 
               
              
                n 
               
              
                ψ 
               
              
             
            
            
             
              
             
            
            
             
              
              
                c 
               
              
                o 
               
              
                s 
               
              
                ψ 
               
              
             
            
            
             
              
             
            
            
             
             
               0 
              
             
            
           
           
            
             
             
               0 
              
             
            
            
             
              
             
            
            
             
             
               0 
              
             
            
            
             
              
             
            
            
             
             
               1 
              
             
            
           
          
         
           ] 
          
         
         
         
           [ 
          
          
           
            
             
             
               x 
              
             
            
           
           
            
             
             
               y 
              
             
            
           
           
            
             
             
               z 
              
             
            
           
          
         
           ] 
          
         
        
       
         \left[\begin{matrix} x^{'} \\ y^{'} \\ z^{'} \end{matrix} \right] =\left[ \begin{matrix} cos\psi && sin\psi && 0 \\ -sin\psi && cos\psi && 0\\ 0 && 0 && 1 \end{matrix} \right] \left[\begin{matrix} x \\ y \\ z \end{matrix} \right] 
        
       
      
              x′y′z′ 
              = 
              cosψ−sinψ0sinψcosψ0001 
               
              xyz 
              
上面仅仅是绕一根轴的旋转,如果三维空间中的欧拉角旋转要转三次:
  
      
       
        
         
          
           
            
            
              R 
             
            
              ( 
             
            
              ψ 
             
            
              ) 
             
            
           
          
          
           
            
             
            
              = 
             
             
             
               [ 
              
              
               
                
                 
                  
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ψ 
                   
                  
                 
                
                
                 
                  
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ψ 
                   
                  
                 
                
                
                 
                 
                   0 
                  
                 
                
               
               
                
                 
                  
                  
                    − 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ψ 
                   
                  
                 
                
                
                 
                  
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ψ 
                   
                  
                 
                
                
                 
                 
                   0 
                  
                 
                
               
               
                
                 
                 
                   0 
                  
                 
                
                
                 
                 
                   0 
                  
                 
                
                
                 
                 
                   1 
                  
                 
                
               
              
             
               ] 
              
             
            
           
          
         
         
          
           
            
            
              R 
             
            
              ( 
             
            
              θ 
             
            
              ) 
             
            
           
          
          
           
            
             
            
              = 
             
             
             
               [ 
              
              
               
                
                 
                  
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    θ 
                   
                  
                 
                
                
                 
                 
                   0 
                  
                 
                
                
                 
                  
                  
                    − 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    θ 
                   
                  
                 
                
               
               
                
                 
                 
                   0 
                  
                 
                
                
                 
                 
                   1 
                  
                 
                
                
                 
                 
                   0 
                  
                 
                
               
               
                
                 
                  
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    θ 
                   
                  
                 
                
                
                 
                 
                   0 
                  
                 
                
                
                 
                  
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    θ 
                   
                  
                 
                
               
              
             
               ] 
              
             
            
           
          
         
         
          
           
            
            
              R 
             
            
              ( 
             
            
              γ 
             
            
              ) 
             
            
           
          
          
           
            
             
            
              = 
             
             
             
               [ 
              
              
               
                
                 
                 
                   1 
                  
                 
                
                
                 
                 
                   0 
                  
                 
                
                
                 
                 
                   0 
                  
                 
                
               
               
                
                 
                 
                   0 
                  
                 
                
                
                 
                  
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    γ 
                   
                  
                 
                
                
                 
                  
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    γ 
                   
                  
                 
                
               
               
                
                 
                 
                   0 
                  
                 
                
                
                 
                  
                  
                    − 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    γ 
                   
                  
                 
                
                
                 
                  
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    γ 
                   
                  
                 
                
               
              
             
               ] 
              
             
            
           
          
         
        
       
         \begin{aligned} R(\psi)&=\begin{bmatrix}cos\psi&sin\psi&0\\-sin\psi&cos\psi&0\\0&0&1\end{bmatrix} \\ R(\theta)&=\begin{bmatrix}cos\theta&0&-sin\theta\\ 0&1&0\\sin\theta&0&cos\theta\end{bmatrix}\\ R(\gamma)&=\begin{bmatrix}1&0&0\\ 0&cos\gamma&sin\gamma\\0&-sin\gamma&cos\gamma\end{bmatrix}\\ \end{aligned} 
        
       
     R(ψ)R(θ)R(γ)= 
                      cosψ−sinψ0sinψcosψ0001 
                      = 
                      cosθ0sinθ010−sinθ0cosθ 
                      = 
                      1000cosγ−sinγ0sinγcosγ 
                      
由于矩阵乘法不满足交换律,所以旋转顺序不同,得到的姿态也不同,一般按照"ZYX"的顺序进行旋转。假设将世界坐标系下的向量 v n v^n vn 按照欧拉角 ϕ , θ , ψ \phi, \theta, \psi ϕ,θ,ψ旋转到机体坐标系得到 v b v^b vb 。
首先绕世界坐标系的Z轴旋转  
     
      
       
       
         ψ 
        
       
      
        \psi 
       
      
    ψ,得到  
     
      
       
        
        
          v 
         
         
         
           b 
          
         
           ′ 
          
         
        
       
      
        v^{b'} 
       
      
    vb′:
  
      
       
        
         
         
           v 
          
          
          
            b 
           
          
            ′ 
           
          
         
        
          = 
         
        
          R 
         
        
          ( 
         
        
          ψ 
         
        
          ) 
         
         
         
           v 
          
         
           n 
          
         
        
       
         v^{b'}=R(\psi)v^n 
        
       
     vb′=R(ψ)vn
 继续绕世界坐标系的Y轴旋转  
     
      
       
       
         θ 
        
       
      
        \theta 
       
      
    θ,得到  
     
      
       
        
        
          v 
         
         
         
           b 
          
          
          
            ′ 
           
          
            ′ 
           
          
         
        
       
      
        v^{b''} 
       
      
    vb′′ :
 
      
       
        
         
         
           v 
          
          
          
            b 
           
           
           
             ′ 
            
           
             ′ 
            
           
          
         
        
          = 
         
        
          R 
         
        
          ( 
         
        
          θ 
         
        
          ) 
         
         
         
           v 
          
          
          
            b 
           
          
            ′ 
           
          
         
        
          = 
         
        
          R 
         
        
          ( 
         
        
          θ 
         
        
          ) 
         
        
          R 
         
        
          ( 
         
        
          ψ 
         
        
          ) 
         
         
         
           v 
          
         
           n 
          
         
        
       
         v^{b''}=R(\theta)v^{b'}=R(\theta)R(\psi)v^n 
        
       
     vb′′=R(θ)vb′=R(θ)R(ψ)vn
 最后绕世界坐标系的X轴旋转  
     
      
       
       
         ϕ 
        
       
      
        \phi 
       
      
    ϕ,得到  
     
      
       
        
        
          v 
         
        
          b 
         
        
       
      
        v^b 
       
      
    vb :
 
      
       
        
         
         
           v 
          
         
           b 
          
         
        
          = 
         
        
          R 
         
        
          ( 
         
        
          ϕ 
         
        
          ) 
         
         
         
           v 
          
          
          
            b 
           
           
           
             ′ 
            
           
             ′ 
            
           
          
         
        
          = 
         
        
          R 
         
        
          ( 
         
        
          ϕ 
         
        
          ) 
         
        
          R 
         
        
          ( 
         
        
          θ 
         
        
          ) 
         
        
          R 
         
        
          ( 
         
        
          ψ 
         
        
          ) 
         
         
         
           v 
          
         
           n 
          
         
        
       
         v^b=R(\phi)v^{b''}=R(\phi)R(\theta)R(\psi)v^n 
        
       
     vb=R(ϕ)vb′′=R(ϕ)R(θ)R(ψ)vn
 所以从世界坐标系到机体坐标系的旋转矩阵为:
 
      
       
        
         
          
           
           
             R 
            
           
          
          
           
            
             
            
              = 
             
            
              R 
             
            
              ( 
             
            
              ϕ 
             
            
              ) 
             
            
              R 
             
            
              ( 
             
            
              θ 
             
            
              ) 
             
            
              R 
             
            
              ( 
             
            
              ψ 
             
            
              ) 
             
            
           
          
         
         
          
           
            
           
          
          
           
            
             
            
              = 
             
             
             
               [ 
              
              
               
                
                 
                  
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    θ 
                   
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    φ 
                   
                  
                 
                
                
                 
                  
                  
                    − 
                   
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ϕ 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ψ 
                   
                  
                    + 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ϕ 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    θ 
                   
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ψ 
                   
                  
                 
                
                
                 
                  
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ϕ 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ψ 
                   
                  
                    + 
                   
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ϕ 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    θ 
                   
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ψ 
                   
                  
                 
                
               
               
                
                 
                  
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    θ 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ψ 
                   
                  
                 
                
                
                 
                  
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ϕ 
                   
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ψ 
                   
                  
                    + 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ϕ 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    θ 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ψ 
                   
                  
                 
                
                
                 
                  
                  
                    − 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ϕ 
                   
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ψ 
                   
                  
                    + 
                   
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ϕ 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    θ 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ψ 
                   
                  
                 
                
               
               
                
                 
                  
                  
                    − 
                   
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    θ 
                   
                  
                 
                
                
                 
                  
                  
                    s 
                   
                  
                    i 
                   
                  
                    n 
                   
                  
                    ϕ 
                   
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    θ 
                   
                  
                 
                
                
                 
                  
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    ϕ 
                   
                  
                    c 
                   
                  
                    o 
                   
                  
                    s 
                   
                  
                    θ 
                   
                  
                 
                
               
              
             
               ] 
              
             
            
           
          
         
        
       
         \begin{aligned} R&=R(\phi)R(\theta)R(\psi)\\ &=\begin{bmatrix} cos\theta cos\varphi&-cos\phi sin\psi+sin\phi sin\theta cos\psi&sin\phi sin\psi +cos\phi sin\theta cos\psi\\ cos\theta sin\psi&cos\phi cos\psi+sin\phi sin\theta sin\psi&-sin\phi cos\psi+cos\phi sin\theta sin\psi\\ -sin\theta&sin\phi cos\theta &cos\phi cos\theta \end{bmatrix} \end{aligned} 
        
       
     R=R(ϕ)R(θ)R(ψ)= 
                      cosθcosφcosθsinψ−sinθ−cosϕsinψ+sinϕsinθcosψcosϕcosψ+sinϕsinθsinψsinϕcosθsinϕsinψ+cosϕsinθcosψ−sinϕcosψ+cosϕsinθsinψcosϕcosθ 
                      
 上面得到了一个表示旋转的方向余弦矩阵。
不过要想用欧拉角解算姿态,其实我们套用欧拉角微分方程就行了:

  上式中左侧,是本次更新后的欧拉角,对应row,pit,yaw。右侧,是上个周期测算出来的角度,三个角速度由直接安装在机器人的三轴陀螺仪在这个周期转动的角度,单位为弧度,计算间隔时T_陀螺角速度,比如0.02秒_ 0.01弧度/秒=0.0002弧度。因此求解这个微分方程就能解算出当前的欧拉角。
   前面介绍了什么是欧拉角,而且欧拉角微分方程解算姿态关系简单明了,概念直观容易理解,那么我们为什么不用欧拉角来表示旋转而要引入四元数呢?一方面是因为欧拉角微分方程中包含了大量的三角运算,这给实时解算带来了一定的困难。而且当俯仰角为90度时方程式会出现“GimbalLock”。所以欧拉角方法只适用于水平姿态变化不大的情况,而不适用于全姿态机器人的姿态确定,故一般采用四元数进行实时解算。
将欧拉角描述的方向余弦矩阵用四元数描述则为:
 
三、四元数微分方程
3.1 四元数三角化表达
某四元数为 Q = q 0 + q = q 0 + q 1 i + q 2 j + q 3 k \pmb{Q}=q_0+\pmb{q}=q_0+q_1\pmb{i}+q_2\pmb{j}+q_3\pmb{k} Q=q0+q=q0+q1i+q2j+q3k (式中, i , j , k \pmb{i,j,k} i,j,k是正交单位矢量)。
四元数的范数: ∣ ∣ Q ∣ ∣ = q 0 2 + q 1 2 + q 2 2 + q 3 2 ||Q||=q_0^2+q_1^2+q_2^2+q_3^2 ∣∣Q∣∣=q02+q12+q22+q32
四元数的模: ∣ Q ∣ = q 0 2 + q 1 2 + q 2 2 + q 3 2 = 1 |Q|=\sqrt{q_0^2+q_1^2+q_2^2+q_3^2}=1 ∣Q∣=q02+q12+q22+q32=1
按 Q \pmb{Q} Q 定向的单位向量 n = q 1 i + q 2 j + q 3 k q 1 2 + q 2 2 + q 3 2 \pmb{n}=\frac{q_1\pmb{i}+q_2\pmb{j}+q_3\pmb{k}}{\sqrt{q_1^2+q_2^2+q_3^2}} n=q12+q22+q32q1i+q2j+q3k
令, c o s θ 2 = q 0 ∣ Q ∣ cos\frac{\theta}{2}=\frac{q_0}{|Q|} cos2θ=∣Q∣q0 , s i n θ 2 = q 1 2 + q 2 2 + q 3 2 ∣ Q ∣ sin\frac{\theta}{2}=\frac{\sqrt{q_1^2+q_2^2+q_3^2}}{|Q|} sin2θ=∣Q∣q12+q22+q32 ,则
Q = ∣ Q ∣ ( q 0 ∣ Q ∣ + q 1 i + q 2 j + q 3 k q 1 2 + q 2 2 + q 3 2 q 1 2 + q 2 2 + q 3 2 ∣ Q ∣ ) = ∣ Q ∣ ( c o s θ 2 + n s i n θ 2 ) = c o s θ 2 + n s i n θ 2 = cos  θ 2 + n ^ sin  θ 2 \pmb{Q}=|Q|\left(\frac{q_0}{|Q|}+\frac{q_1\pmb{i}+q_2\pmb{j}+q_3\pmb{k}}{\sqrt{q_1^2+q_2^2+q_3^2}}\frac{\sqrt{q_1^2+q_2^2+q_3^2}}{|Q|}\right)=|Q|(cos\frac{\theta}{2}+\pmb{n}sin\frac{\theta}{2})=cos\frac{\theta}{2}+\pmb{n}sin\frac{\theta}{2}=\cos \frac{\theta}{2}+\hat{n} \sin \frac{\theta}{2} Q=∣Q∣(∣Q∣q0+q12+q22+q32q1i+q2j+q3k∣Q∣q12+q22+q32)=∣Q∣(cos2θ+nsin2θ)=cos2θ+nsin2θ=cos2θ+n^sin2θ
欧拉公式:
 e i θ = c o s θ + i s i n θ e^{\pmb{i}\theta}=cos\theta+\pmb{i}sin\theta eiθ=cosθ+isinθ
故,四元数指数式:
 Q = e n ^ θ 2 \pmb{Q}=e^{\hat{n}\frac{\theta}{2}} Q=en^2θ
PS:为什么四元数的三角式是 $\mathbf{Q} = \cos \frac{\theta}{2} + \hat{n} \sin \frac{\theta}{2} $ , 不是$\mathbf{Q} = cos\theta+ \hat{n} sin\theta $ ?
答:关于四元数的三角形式是 $\mathbf{Q} = \cos \frac{\theta}{2} + \hat{n} \sin \frac{\theta}{2} $ ,而不是 $ \mathbf{Q} = cos \theta + \hat{n} sin \theta$ ,是因为四元数可以用来表示三维空间中的旋转。前者描述了四元数旋转的性质,而后者则没有适当地捕捉到这种旋转特性,(在这里, θ \theta θ 是旋转的角度,而 $\hat{n} $ 是一个单位向量,表示旋转轴的方向)。
考虑一个四元数的旋转操作,如果我们将 θ \theta θ 乘以2,即 θ → 2 θ \theta \rightarrow 2\theta θ→2θ ,那么 c o s θ 2 cos \frac{\theta}{2} cos2θ 会变成 cos  θ \cos \theta cosθ ,而 s i n θ 2 sin \frac{\theta}{2} sin2θ 会变成 $sin \theta $。这样,你会得到 $\mathbf{Q} = cos \theta + \hat{n} sin \theta $。但这实际上表示的是一个两倍角度的旋转,而不是原来的旋转。
为了保持旋转的性质,我们使用 $cos \frac{\theta}{2} $ 和 $sin \frac{\theta}{2} $。这种形式的好处是,当我们对一个四元数连续进行旋转时,它们会累积旋转效果而不是叠加角度。这种表达方式更加适合描述旋转运算。
3.2 四元数微分
已知,从  
     
      
       
       
         n 
        
       
      
        n 
       
      
    n 系到  
     
      
       
       
         b 
        
       
      
        b 
       
      
    b 系的旋转四元数可以表示为:
  
      
       
        
         
         
           Q 
          
         
        
          = 
         
        
          cos 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
        
          + 
         
         
         
           n 
          
         
           ^ 
          
         
        
          sin 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
         
        
       
         \pmb{Q}=\cos \frac{\theta}{2}+\hat{n} \sin \frac{\theta}{2} \\ 
        
       
     Q=cos2θ+n^sin2θ
上式 $\hat{n} $ 中为旋转轴,  
     
      
       
       
         θ 
        
       
      
        θ 
       
      
    θ为旋转角,对两边求导可得:
  
      
       
        
         
          
          
            d 
           
           
           
             Q 
            
           
          
          
          
            d 
           
          
            t 
           
          
         
        
          = 
         
        
          − 
         
         
          
          
            θ 
           
          
            ˙ 
           
          
         
           2 
          
         
        
          sin 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
        
          + 
         
         
         
           n 
          
         
           ^ 
          
         
         
          
          
            θ 
           
          
            ˙ 
           
          
         
           2 
          
         
        
          cos 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
        
          + 
         
        
          sin 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
         
          
          
            d 
           
           
           
             n 
            
           
             ^ 
            
           
          
          
          
            d 
           
          
            t 
           
          
         
         
        
       
         \frac{d \pmb{Q}}{d t}=-\frac{\dot{\theta}}{2} \sin \frac{\theta}{2}+\hat{n} \frac{\dot{\theta}}{2} \cos \frac{\theta}{2}+\sin \frac{\theta}{2} \frac{d \hat{n}}{d t} \\ 
        
       
     dtdQ=−2θ˙sin2θ+n^2θ˙cos2θ+sin2θdtdn^
根据哥氏定理可得:
d n ^ d t = C b n d n b d t + ω n b n × n ^ \frac{d \hat{n}}{d t}=C_{b}^{n} \frac{d n^{b}}{d t}+\omega_{n b}^{n} \times \hat{n} \\ dtdn^=Cbndtdnb+ωnbn×n^
由于刚体绕轴旋转,与刚体固联的 b b b 坐标系的各个轴在旋转的过程中分别位于三个不同的圆锥面上,三个圆锥面的定点即为 b b b 系的原点,为其共同的对称轴,这块大家可以想象一下,还是挺容易想象的,这样到 b b b 坐标系三个轴上的投影不变,长度为各自圆锥底面半径,所以有:
d n b d t = 0 \frac{d n^{b}}{d t}=0 dtdnb=0
又有:
ω n b n = θ ˙ n ^ \omega_{n b}^{n}=\dot{\theta} \hat{n} \\ ωnbn=θ˙n^
上式中的意思是: n n n 系到 b b b 系的角速度在 n n n 系上的投影。所以:
d n ^ d t = θ ˙ n ^ × n ^ = 0 \frac{d \hat{n}}{d t}=\dot{\theta} \hat{n} \times \hat{n}=0 \\ dtdn^=θ˙n^×n^=0
或者,也可以直接理解为:因为旋转轴 n ^ \hat{n} n^ 始终未变,所以 d n ^ d t = 0 \frac{d \hat{n}}{d t}=0 dtdn^=0 。
因此
  
      
       
        
         
          
          
            d 
           
           
           
             Q 
            
           
          
          
          
            d 
           
          
            t 
           
          
         
        
          = 
         
        
          − 
         
         
          
          
            θ 
           
          
            ˙ 
           
          
         
           2 
          
         
        
          sin 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
        
          + 
         
         
         
           n 
          
         
           ^ 
          
         
         
          
          
            θ 
           
          
            ˙ 
           
          
         
           2 
          
         
        
          cos 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
        
       
         \frac{d \pmb{Q}}{d t}=-\frac{\dot{\theta}}{2} \sin \frac{\theta}{2}+\hat{n} \frac{\dot{\theta}}{2} \cos \frac{\theta}{2} 
        
       
     dtdQ=−2θ˙sin2θ+n^2θ˙cos2θ
设 , $\hat{n} \otimes \hat{n} $ 表示纯单位四元数相乘,根据四元数乘法法则容易推出 $\hat{n} \otimes \hat{n}=-1 $,详细证明可见附录,所以
  
      
       
        
         
          
          
            d 
           
           
           
             Q 
            
           
          
          
          
            d 
           
          
            t 
           
          
         
        
          = 
         
        
          − 
         
         
          
          
            θ 
           
          
            ˙ 
           
          
         
           2 
          
         
        
          sin 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
        
          + 
         
         
         
           n 
          
         
           ^ 
          
         
         
          
          
            θ 
           
          
            ˙ 
           
          
         
           2 
          
         
        
          cos 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
        
          = 
         
         
          
          
            θ 
           
          
            ˙ 
           
          
         
           2 
          
         
        
          cos 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
         
         
           n 
          
         
           ^ 
          
         
        
          + 
         
         
         
           n 
          
         
           ^ 
          
         
        
          ⊗ 
         
         
         
           n 
          
         
           ^ 
          
         
         
          
          
            θ 
           
          
            ˙ 
           
          
         
           2 
          
         
        
          sin 
         
        
           
         
         
         
           θ 
          
         
           2 
          
         
         
        
          = 
         
         
          
          
            θ 
           
          
            ˙ 
           
          
         
           2 
          
         
         
         
           n 
          
         
           ^ 
          
         
        
          ⊗ 
         
         
         
           ( 
          
         
           cos 
          
         
            
          
          
          
            θ 
           
          
            2 
           
          
         
           + 
          
          
          
            n 
           
          
            ^ 
           
          
         
           sin 
          
         
            
          
          
          
            θ 
           
          
            2 
           
          
         
           ) 
          
         
        
          = 
         
         
          
          
            θ 
           
          
            ˙ 
           
          
         
           2 
          
         
         
         
           n 
          
         
           ^ 
          
         
        
          ⊗ 
         
        
          Q 
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
         
         
           ω 
          
          
          
            n 
           
          
            b 
           
          
         
           n 
          
         
        
          ⊗ 
         
         
         
           Q 
          
         
        
       
         \frac{d \pmb{Q}}{d t}=-\frac{\dot{\theta}}{2} \sin \frac{\theta}{2}+\hat{n} \frac{\dot{\theta}}{2} \cos \frac{\theta}{2}=\frac{\dot{\theta}}{2} \cos \frac{\theta}{2} \hat{n}+\hat{n} \otimes \hat{n} \frac{\dot{\theta}}{2} \sin \frac{\theta}{2} \\ = \frac{\dot{\theta}}{2} \hat{n} \otimes\left(\cos \frac{\theta}{2}+\hat{n} \sin \frac{\theta}{2}\right)=\frac{\dot{\theta}}{2} \hat{n} \otimes Q=\frac{1}{2} \omega_{n b}^{n} \otimes \pmb{Q} 
        
       
     dtdQ=−2θ˙sin2θ+n^2θ˙cos2θ=2θ˙cos2θn^+n^⊗n^2θ˙sin2θ=2θ˙n^⊗(cos2θ+n^sin2θ)=2θ˙n^⊗Q=21ωnbn⊗Q
 上面公式中的 $\omega_{n b}^{n} $ 是在世界坐标系下的角速度,而IMU中的陀螺仪测量得到的角速度是在机体坐标系的,所以还需要一个转换关系,根据坐标变换的四元数乘法表示法:
 
      
       
        
         
         
           r 
          
         
           n 
          
         
        
          = 
         
         
         
           Q 
          
         
        
          ⊗ 
         
         
         
           r 
          
         
           b 
          
         
        
          ⊗ 
         
         
          
          
            Q 
           
          
         
           ∗ 
          
         
         
        
       
         r^{n}=\pmb{Q} \otimes r^{b} \otimes \pmb{Q}^{*} \\ 
        
       
     rn=Q⊗rb⊗Q∗
 上式中 $Q^{*} $为  
     
      
       
       
         Q 
        
       
      
        Q 
       
      
    Q 的共轭四元数,需要注意上公式中的  
     
      
       
       
         Q 
        
       
      
        Q 
       
      
    Q 依然是从  
     
      
       
       
         n 
        
       
      
        n 
       
      
    n 系到  
     
      
       
       
         b 
        
       
      
        b 
       
      
    b 系转换的四元数,  
     
      
       
        
        
          r 
         
        
          b 
         
        
       
      
        r^{b} 
       
      
    rb 和  
     
      
       
        
        
          r 
         
        
          n 
         
        
       
      
        r^{n} 
       
      
    rn是实部为0的四元数。
所以
  
      
       
        
         
         
           ω 
          
          
          
            n 
           
          
            b 
           
          
         
           n 
          
         
        
          = 
         
         
         
           Q 
          
         
        
          ⊗ 
         
         
         
           ω 
          
          
          
            n 
           
          
            b 
           
          
         
           b 
          
         
        
          ⊗ 
         
         
          
          
            Q 
           
          
         
           ∗ 
          
         
         
        
       
         \omega_{n b}^{n}=\pmb{Q} \otimes \omega_{n b}^{b} \otimes \pmb{Q}^{*} \\ 
        
       
     ωnbn=Q⊗ωnbb⊗Q∗
 带入 $\frac{d \pmb{Q}}{d t} $的公式得:
  
      
       
        
         
          
          
            d 
           
           
           
             Q 
            
           
          
          
          
            d 
           
          
            t 
           
          
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
         
         
           ω 
          
          
          
            n 
           
          
            b 
           
          
         
           n 
          
         
        
          ⊗ 
         
         
         
           Q 
          
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
         
         
           Q 
          
         
        
          ⊗ 
         
         
         
           ω 
          
          
          
            n 
           
          
            b 
           
          
         
           b 
          
         
        
          ⊗ 
         
         
          
          
            Q 
           
          
         
           ∗ 
          
         
        
          ⊗ 
         
         
         
           Q 
          
         
         
        
       
         \frac{d \pmb{Q}}{d t}=\frac{1}{2} \omega_{n b}^{n} \otimes \pmb{Q}=\frac{1}{2} \pmb{Q} \otimes \omega_{n b}^{b} \otimes \pmb{Q}^{*} \otimes \pmb{Q} \\ 
        
       
     dtdQ=21ωnbn⊗Q=21Q⊗ωnbb⊗Q∗⊗Q
 由于  
     
      
       
        
        
          Q 
         
        
       
      
        \pmb{Q} 
       
      
    Q 为单位四元数, 
     
      
       
        
         
         
           Q 
          
         
        
          ∗ 
         
        
       
      
        \pmb{Q}^{*} 
       
      
    Q∗ 为单位四元数的逆,所以 $\pmb{Q}^{*} \otimes \pmb{Q}=1 $ 。
 
      
       
        
         
          
          
            d 
           
           
           
             Q 
            
           
          
          
          
            d 
           
          
            t 
           
          
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
         
         
           Q 
          
         
        
          ⊗ 
         
         
         
           ω 
          
          
          
            n 
           
          
            b 
           
          
         
           b 
          
         
        
       
         \frac{d \pmb{Q}}{d t}=\frac{1}{2} \pmb{Q} \otimes \omega_{n b}^{b} 
        
       
     dtdQ=21Q⊗ωnbb
 $\omega_{n b}^{b} $为陀螺仪的测量值,记
  
      
       
        
         
         
           [ 
          
          
           
            
             
             
               0 
              
             
            
           
           
            
             
              
              
                ω 
               
              
                x 
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                y 
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                z 
               
              
             
            
           
          
         
           ] 
          
         
         
        
       
         \left[\begin{array}{c} {0} \\ {\omega_{x}} \\ {\omega_{y}} \\ {\omega_{z}} \end{array}\right] \\ 
        
       
      
              0ωxωyωz 
              
 根据四元数的乘法定义, $\frac{d \pmb{Q}}{d t} $有两种表示形式,第一种 如下所示:
  
      
       
        
         
          
          
            d 
           
           
           
             Q 
            
           
          
          
          
            d 
           
          
            t 
           
          
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
         
         
           M 
          
         
           ′ 
          
         
         
         
           ( 
          
          
          
            ω 
           
           
           
             n 
            
           
             b 
            
           
          
            b 
           
          
         
           ) 
          
         
         
         
           Q 
          
         
         
        
       
         \frac{d \pmb{Q}}{d t}=\frac{1}{2} M^{\prime}\left(\omega_{n b}^{b}\right) \pmb{Q} \\ 
        
       
     dtdQ=21M′(ωnbb)Q
 即
  
      
       
        
         
         
           [ 
          
          
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                0 
               
              
             
            
           
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                1 
               
              
             
            
           
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                2 
               
              
             
            
           
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                3 
               
              
             
            
           
          
         
           ] 
          
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
         
         
           [ 
          
          
           
            
             
             
               0 
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 x 
                
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 y 
                
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 z 
                
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                x 
               
              
             
            
            
             
             
               0 
              
             
            
            
             
              
              
                ω 
               
              
                z 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 y 
                
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                y 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 z 
                
               
              
             
            
            
             
             
               0 
              
             
            
            
             
              
              
                ω 
               
              
                x 
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                z 
               
              
             
            
            
             
              
              
                ω 
               
              
                y 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 x 
                
               
              
             
            
            
             
             
               0 
              
             
            
           
          
         
           ] 
          
         
         
         
           [ 
          
          
           
            
             
              
              
                q 
               
              
                0 
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                1 
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                2 
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                3 
               
              
             
            
           
          
         
           ] 
          
         
         
        
       
         \left[\begin{array}{c} {\dot{q}_{0}} \\ {\dot{q}_{1}} \\ {\dot{q}_{2}} \\ {\dot{q}_{3}} \end{array}\right]=\frac{1}{2}\left[\begin{array}{cccc} {0} & {-\omega_{x}} & {-\omega_{y}} & {-\omega_{z}} \\ {\omega_{x}} & {0} & {\omega_{z}} & {-\omega_{y}} \\ {\omega_{y}} & {-\omega_{z}} & {0} & {\omega_{x}} \\ {\omega_{z}} & {\omega_{y}} & {-\omega_{x}} & {0} \end{array}\right]\left[\begin{array}{l} {q_{0}} \\ {q_{1}} \\ {q_{2}} \\ {q_{3}} \end{array}\right] \\ 
        
       
      
              q˙0q˙1q˙2q˙3 
              =21 
              0ωxωyωz−ωx0−ωzωy−ωyωz0−ωx−ωz−ωyωx0 
               
              q0q1q2q3 
              
 或者也可以写成如下形式:
  
      
       
        
         
          
          
            d 
           
           
           
             Q 
            
           
          
          
          
            d 
           
          
            t 
           
          
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
        
          M 
         
        
          ( 
         
         
         
           Q 
          
         
        
          ) 
         
         
         
           ω 
          
          
          
            n 
           
          
            b 
           
          
         
           b 
          
         
         
        
       
         \frac{d \pmb{Q}}{d t}=\frac{1}{2} M(\pmb{Q}) \omega_{n b}^{b} \\ 
        
       
     dtdQ=21M(Q)ωnbb
 即为:
  
      
       
        
         
         
           [ 
          
          
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                0 
               
              
             
            
           
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                1 
               
              
             
            
           
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                2 
               
              
             
            
           
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                3 
               
              
             
            
           
          
         
           ] 
          
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
         
         
           [ 
          
          
           
            
             
              
              
                q 
               
              
                0 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 q 
                
               
                 1 
                
               
              
             
            
            
             
              
              
                − 
               
               
               
                 q 
                
               
                 2 
                
               
              
             
            
            
             
              
              
                − 
               
               
               
                 q 
                
               
                 3 
                
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                1 
               
              
             
            
            
             
              
              
                q 
               
              
                0 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 q 
                
               
                 3 
                
               
              
             
            
            
             
              
              
                q 
               
              
                2 
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                2 
               
              
             
            
            
             
              
              
                q 
               
              
                3 
               
              
             
            
            
             
              
              
                q 
               
              
                0 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 q 
                
               
                 1 
                
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                3 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 q 
                
               
                 2 
                
               
              
             
            
            
             
              
              
                q 
               
              
                1 
               
              
             
            
            
             
              
              
                q 
               
              
                0 
               
              
             
            
           
          
         
           ] 
          
         
         
         
           [ 
          
          
           
            
             
             
               0 
              
             
            
           
           
            
             
              
              
                ω 
               
              
                x 
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                y 
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                z 
               
              
             
            
           
          
         
           ] 
          
         
         
        
       
         \left[\begin{array}{l} {\dot{q}_{0}} \\ {\dot{q}_{1}} \\ {\dot{q}_{2}} \\ {\dot{q}_{3}} \end{array}\right]=\frac{1}{2}\left[\begin{array}{cccc} {q_{0}} & {-q_{1}} & {-q_{2}} & {-q_{3}} \\ {q_{1}} & {q_{0}} & {-q_{3}} & {q_{2}} \\ {q_{2}} & {q_{3}} & {q_{0}} & {-q_{1}} \\ {q_{3}} & {-q_{2}} & {q_{1}} & {q_{0}} \end{array}\right]\left[\begin{array}{c} {0} \\ {\omega_{x}} \\ {\omega_{y}} \\ {\omega_{z}} \end{array}\right] \\ 
        
       
      
              q˙0q˙1q˙2q˙3 
              =21 
              q0q1q2q3−q1q0q3−q2−q2−q3q0q1−q3q2−q1q0 
               
              0ωxωyωz 
              
 此处,我们采用第一种表达方式: $\frac{d \pmb{Q}}{d t}=\frac{1}{2} M^{\prime}\left(\omega_{n b}^{b}\right) \pmb{Q} \$
注意:四元数乘法不满足交换律
P ⊗ Q = M ( P ) Q = M ′ ( Q ) P \pmb{P} \otimes \pmb{Q}=\pmb{M(P)Q}=\pmb{M^{'}(Q)P} P⊗Q=M(P)Q=M′(Q)P
P ⊗ Q = M ( P ) Q ≠ M ′ ( P ) Q = Q ⊗ P \pmb{P} \otimes \pmb{Q}=\pmb{M(P)Q}\neq\pmb{M^{'}(P)Q}=\pmb{Q} \otimes \pmb{P} P⊗Q=M(P)Q=M′(P)Q=Q⊗P
四元数乘法满足分配律与结合律:
P ⊗ ( Q + R ) = P ⊗ Q + P ⊗ R \pmb{P} \otimes (\pmb{Q}+\pmb{R})=\pmb{P} \otimes \pmb{Q}+\pmb{P} \otimes\pmb{R} P⊗(Q+R)=P⊗Q+P⊗R
P ⊗ Q ⊗ R = ( P ⊗ Q ) ⊗ R = P ⊗ ( Q ⊗ R ) \pmb{P} \otimes \pmb{Q}\otimes\pmb{R}=(\pmb{P} \otimes \pmb{Q})\otimes\pmb{R}=\pmb{P} \otimes (\pmb{Q}\otimes\pmb{R}) P⊗Q⊗R=(P⊗Q)⊗R=P⊗(Q⊗R)
3.3 龙格-库塔法求解微分方程
由 上一节 3.2可知 $\frac{d \pmb{Q}}{d t} $如下所示:
  
      
       
        
         
          
          
            d 
           
           
           
             Q 
            
           
          
          
          
            d 
           
          
            t 
           
          
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
         
         
           M 
          
         
           ′ 
          
         
         
         
           ( 
          
          
          
            ω 
           
           
           
             n 
            
           
             b 
            
           
          
            b 
           
          
         
           ) 
          
         
         
         
           Q 
          
         
         
        
       
         \frac{d \pmb{Q}}{d t}=\frac{1}{2} M^{\prime}\left(\omega_{n b}^{b}\right) \pmb{Q} \\ 
        
       
     dtdQ=21M′(ωnbb)Q
 即
  
      
       
        
         
         
           [ 
          
          
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                0 
               
              
             
            
           
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                1 
               
              
             
            
           
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                2 
               
              
             
            
           
           
            
             
              
               
               
                 q 
                
               
                 ˙ 
                
               
              
                3 
               
              
             
            
           
          
         
           ] 
          
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
         
         
           [ 
          
          
           
            
             
             
               0 
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 x 
                
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 y 
                
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 z 
                
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                x 
               
              
             
            
            
             
             
               0 
              
             
            
            
             
              
              
                ω 
               
              
                z 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 y 
                
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                y 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 z 
                
               
              
             
            
            
             
             
               0 
              
             
            
            
             
              
              
                ω 
               
              
                x 
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                z 
               
              
             
            
            
             
              
              
                ω 
               
              
                y 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 x 
                
               
              
             
            
            
             
             
               0 
              
             
            
           
          
         
           ] 
          
         
         
         
           [ 
          
          
           
            
             
              
              
                q 
               
              
                0 
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                1 
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                2 
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                3 
               
              
             
            
           
          
         
           ] 
          
         
         
        
       
         \left[\begin{array}{c} {\dot{q}_{0}} \\ {\dot{q}_{1}} \\ {\dot{q}_{2}} \\ {\dot{q}_{3}} \end{array}\right]=\frac{1}{2}\left[\begin{array}{cccc} {0} & {-\omega_{x}} & {-\omega_{y}} & {-\omega_{z}} \\ {\omega_{x}} & {0} & {\omega_{z}} & {-\omega_{y}} \\ {\omega_{y}} & {-\omega_{z}} & {0} & {\omega_{x}} \\ {\omega_{z}} & {\omega_{y}} & {-\omega_{x}} & {0} \end{array}\right]\left[\begin{array}{l} {q_{0}} \\ {q_{1}} \\ {q_{2}} \\ {q_{3}} \end{array}\right] \\ 
        
       
      
              q˙0q˙1q˙2q˙3 
              =21 
              0ωxωyωz−ωx0−ωzωy−ωyωz0−ωx−ωz−ωyωx0 
               
              q0q1q2q3 
              
 龙格库塔法(Runge-Kutta,简称RK法)是一组常微分方程求解器,它可以根据要求调整阶数,输出误差级别不一样的结果。龙格库塔法的基本思想囊括了欧拉法、显式梯形法、中点法和泰勒法,是一种使用广泛的求解方法(具体可参考参考链接)。
 龙格库塔法的一般形式
 龙格库塔法通过在区间内取多个点的斜率,然后进行线性组合,从而得到不用计算高阶导数的n阶方法。它的一般形式如下:
  
      
       
        
        
          { 
         
         
          
           
            
             
              
              
                ω 
               
              
                0 
               
              
             
               = 
              
              
              
                y 
               
              
                0 
               
              
             
            
           
          
          
           
            
             
              
              
                w 
               
               
               
                 i 
                
               
                 + 
                
               
                 1 
                
               
              
             
               = 
              
              
              
                w 
               
              
                i 
               
              
             
               + 
              
             
               h 
              
              
              
                ∑ 
               
               
               
                 i 
                
               
                 = 
                
               
                 1 
                
               
              
                L 
               
              
              
              
                λ 
               
              
                i 
               
              
              
              
                K 
               
              
                i 
               
              
             
            
           
          
          
           
            
             
              
              
                K 
               
              
                1 
               
              
             
               = 
              
             
               f 
              
             
               ( 
              
              
              
                x 
               
              
                i 
               
              
             
               , 
              
              
              
                w 
               
              
                i 
               
              
             
               ) 
              
             
            
           
          
          
           
            
             
              
              
                K 
               
              
                i 
               
              
             
               = 
              
             
               f 
              
             
               ( 
              
              
              
                x 
               
              
                n 
               
              
             
               + 
              
              
              
                c 
               
              
                i 
               
              
             
               h 
              
             
               , 
              
              
              
                w 
               
              
                i 
               
              
             
               + 
              
              
              
                c 
               
              
                i 
               
              
             
               h 
              
              
              
                ∑ 
               
               
               
                 j 
                
               
                 = 
                
               
                 1 
                
               
               
               
                 i 
                
               
                 − 
                
               
                 1 
                
               
              
              
              
                a 
               
               
               
                 i 
                
               
                 j 
                
               
              
              
              
                K 
               
              
                i 
               
              
             
               ) 
              
             
            
           
           
            
             
             
               , 
              
             
               i 
              
             
               = 
              
             
               2 
              
             
               , 
              
             
               3 
              
             
               , 
              
             
               … 
              
             
               , 
              
             
               L 
              
             
            
           
          
         
        
       
         \begin{cases} ω_0 = y_0 \\ w_{i+1} = w_i+h\sum^L_{i=1}\lambda_iK_i \\ K_1=f(x_i, w_i) \\ K_i = f(x_n+c_ih,w_i+c_ih\sum^{i-1}_{j=1}a_{ij}K_i) & ,i=2,3,\dots,L \end{cases} 
        
       
     ⎩ 
              ⎨ 
              ⎧ω0=y0wi+1=wi+h∑i=1LλiKiK1=f(xi,wi)Ki=f(xn+cih,wi+cih∑j=1i−1aijKi),i=2,3,…,L
其中, c i ≤ 1 , ∑ i = 1 L λ i = 1 , ∑ j = 1 i − 1 a i j = 1 c_i\le1, \sum^L_{i=1}\lambda_i=1, \sum_{j=1}^{i-1}a_{ij}=1 ci≤1,∑i=1Lλi=1,∑j=1i−1aij=1 。
可知,此处使用一阶龙格-库塔法,则 
     
      
       
       
         L 
        
       
         = 
        
       
         1 
        
       
         , 
        
       
         h 
        
       
         = 
        
       
         d 
        
       
         t 
        
       
      
        L=1, h=dt 
       
      
    L=1,h=dt
  
      
       
        
         
         
           K 
          
         
           1 
          
         
        
          = 
         
        
          f 
         
        
          ( 
         
         
         
           x 
          
         
           i 
          
         
        
          , 
         
         
         
           w 
          
         
           i 
          
         
        
          ) 
         
        
          = 
         
         
         
           1 
          
         
           2 
          
         
         
         
           [ 
          
          
           
            
             
             
               0 
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 x 
                
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 y 
                
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 z 
                
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                x 
               
              
             
            
            
             
             
               0 
              
             
            
            
             
              
              
                ω 
               
              
                z 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 y 
                
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                y 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 z 
                
               
              
             
            
            
             
             
               0 
              
             
            
            
             
              
              
                ω 
               
              
                x 
               
              
             
            
           
           
            
             
              
              
                ω 
               
              
                z 
               
              
             
            
            
             
              
              
                ω 
               
              
                y 
               
              
             
            
            
             
              
              
                − 
               
               
               
                 ω 
                
               
                 x 
                
               
              
             
            
            
             
             
               0 
              
             
            
           
          
         
           ] 
          
         
         
         
           [ 
          
          
           
            
             
              
              
                q 
               
              
                0 
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                1 
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                2 
               
              
             
            
           
           
            
             
              
              
                q 
               
              
                3 
               
              
             
            
           
          
         
           ] 
          
         
        
       
         K_1=f(x_i, w_i)=\frac{1}{2}\left[\begin{array}{cccc} {0} & {-\omega_{x}} & {-\omega_{y}} & {-\omega_{z}} \\ {\omega_{x}} & {0} & {\omega_{z}} & {-\omega_{y}} \\ {\omega_{y}} & {-\omega_{z}} & {0} & {\omega_{x}} \\ {\omega_{z}} & {\omega_{y}} & {-\omega_{x}} & {0} \end{array}\right]\left[\begin{array}{l} {q_{0}} \\ {q_{1}} \\ {q_{2}} \\ {q_{3}} \end{array}\right] 
        
       
     K1=f(xi,wi)=21 
              0ωxωyωz−ωx0−ωzωy−ωyωz0−ωx−ωz−ωyωx0 
               
              q0q1q2q3 
              
Q i + 1 = Q i + d t K i = Q i + 1 2 [ 0 − ω x − ω y − ω z ω x 0 ω z − ω y ω y − ω z 0 ω x ω z ω y − ω x 0 ] [ q 0 q 1 q 2 q 3 ] d t \pmb{Q}_{i+1} = \pmb{Q}_{i}+dtK_i=\pmb{Q}_{i}+\frac{1}{2}\left[\begin{array}{cccc} {0} & {-\omega_{x}} & {-\omega_{y}} & {-\omega_{z}} \\ {\omega_{x}} & {0} & {\omega_{z}} & {-\omega_{y}} \\ {\omega_{y}} & {-\omega_{z}} & {0} & {\omega_{x}} \\ {\omega_{z}} & {\omega_{y}} & {-\omega_{x}} & {0} \end{array}\right]\left[\begin{array}{l} {q_{0}} \\ {q_{1}} \\ {q_{2}} \\ {q_{3}} \end{array}\right]dt Qi+1=Qi+dtKi=Qi+21 0ωxωyωz−ωx0−ωzωy−ωyωz0−ωx−ωz−ωyωx0  q0q1q2q3 dt
四、Mahony 互补滤波
在进行软件姿态解算中,传入数据参数是陀螺仪x,y,z值、加速度计x,y,z值,磁力计x,y,z值及两帧数据时间差dt,首先把加速度计采集到的值(三维向量)转化为单位向量,即向量除以模:
void NonlinearSO3AHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz, float twoKp, float twoKi, float dt)
   
//归一化,得到单位加速度
recipNorm = invSqrt(ax * ax + ay * ay + az * az);  // 求平方根的倒数
ax *= recipNorm;
ay *= recipNorm;
az *= recipNorm;
 
  把机器人上次计算得到的姿态(四元数)换算成“方向余弦矩阵”中的第三行的三个元素。根据余弦矩阵和欧拉角的定义,将世界坐标系的重力向量转到机体坐标系,正好是这三个元素。所以这里的halfvx、halfvy、halfvz,其实是用上一次机器人机体姿态(四元数)换算出来的在当前的机体坐标系上的重力单位向量。注意,代码中取了其中的一半1/2,下面的误差同理。
// 根据余弦矩阵和欧拉角将地理坐标系转至机体坐标系(用上一时刻goat的姿态四元数换算到当前机体坐标系的重力单位向量)
// 即 陀螺仪积分后推算的重力分量
halfvx = q1q3 - q0q2;  // 使用 halfvx 而非 vx 是为了减小乘法运算量
halfvy = q0q1 + q2q3;
halfvz = q0q0 - 0.5f + q3q3;  // ! 为什么直接是0.5f: q0q0 - q1q1 - q2q2 + q3q3 = q0q0 - q1q1 - q2q2 + q3q3 + 1 - 1
 
axyz是机体坐标参照系上,加速度计测出来的重力向量,也就是实际测出来的重力向量。axyz是测量得到的重力向量,halfvxyz是陀螺积分后的姿态来推算出的重力向量,它们都是机体坐标参照系上的重力向量。那它们之间的误差向量,就是陀螺积分后的姿态和加计测出来的姿态之间的误差。向量间的误差,可以用向量叉积(也叫向量外积、叉乘)来表示,halfexyz就是两个重力向量的叉积。这个叉积向量仍旧是位于机体坐标系上的,而陀螺积分误差也是在机体坐标系,而且叉积的大小与陀螺积分误差成正比,正好拿来纠正陀螺仪。(你可以自己拿东西想象一下)由于陀螺是对机体直接积分,所以对陀螺的纠正量会直接体现在对机体坐标系的纠正。
// 获得叉积误差,叉积的大小与陀螺仪积分误差成正比
// Err = 单位加速度a X(叉乘) 积分重力分量v
halfex += ay * halfvz - az * halfvy;
halfey += az * halfvx - ax * halfvz;
halfez += ax * halfvy - ay * halfvx;
 
下面一段代码,用叉乘误差来做 K p K_p Kp、$ K_i$修正陀螺零偏,通过调节twoKp,twoKi两个参数,可以控制加速度计修正陀螺仪积分姿态的速度。
    // 叉积误差判断
    if(halfex != 0.0f && halfey != 0.0f && halfez != 0.0f) {
        // 用叉积误差进行积分
        // 通过 twoKp 、twoKi 比例、积分参数控制加速计修正陀螺仪积分姿态的速度
        // w_bias = Kp*Err + Ki*\sumErr
        if(twoKi > 0.0f) 
        {
            gyro_bias[0] += twoKi * halfex * dt;	// 误差积分
            gyro_bias[1] += twoKi * halfey * dt;
            gyro_bias[2] += twoKi * halfez * dt;
            // 积分反馈
            gx += gyro_bias[0];
            gy += gyro_bias[1];
            gz += gyro_bias[2];
        }
        else {
            gyro_bias[0] = 0.0f;  // 防止积分饱和
            gyro_bias[1] = 0.0f;
            gyro_bias[2] = 0.0f;
        }
      // 比例反馈
        gx += twoKp * halfex;   
        gy += twoKp * halfey;
        gz += twoKp * halfez;
    }
 
到此,使用加速度计数据对陀螺仪数据的修正已经完成,这就是姿态解算中的深度融合。
接着,将修正后的陀螺仪数据通过四元数微分方程更新至当前姿态角中。
    // 四元数微分方程(一阶龙格-库塔法).
    //      |dq0|       | 0  -gx -gy -gz||q0|
    //      |dq1|       | gx  0   gz -gy||q1|
    // s1 = |dq2| = 0.5*| gy -gz  0   gx||q2| 
    //      |dq3|       | gz  gy -gx  0 ||q3|
    dq0 = 0.5f*(-q1 * gx - q2 * gy - q3 * gz);
    dq1 = 0.5f*(q0 * gx + q2 * gz - q3 * gy);   
    dq2 = 0.5f*(q0 * gy - q1 * gz + q3 * gx);
    dq3 = 0.5f*(q0 * gz + q1 * gy - q2 * gx);
    // q_i+1 = q_i + s1*dt
    q0 += dt*dq0;
    q1 += dt*dq1;
    q2 += dt*dq2;
    q3 += dt*dq3;
 
附录
四元数乘法法则容易推出 $\hat{n} \otimes \hat{n}=-1 $
  
      
       
        
        
          p 
         
        
          ⊗ 
         
        
          q 
         
        
          = 
         
         
         
           [ 
          
          
           
            
             
              
               
               
                 p 
                
               
                 w 
                
               
               
               
                 q 
                
               
                 w 
                
               
              
                − 
               
               
               
                 p 
                
               
                 v 
                
               
                 T 
                
               
               
               
                 q 
                
               
                 v 
                
               
              
             
            
           
           
            
             
              
               
               
                 p 
                
               
                 w 
                
               
               
               
                 q 
                
               
                 v 
                
               
              
                + 
               
               
               
                 q 
                
               
                 w 
                
               
               
               
                 p 
                
               
                 v 
                
               
              
                + 
               
               
               
                 p 
                
               
                 v 
                
               
              
                × 
               
               
               
                 q 
                
               
                 v 
                
               
              
             
            
           
          
         
           ] 
          
         
         
        
       
         \mathrm{p} \otimes \mathrm{q}=\left[\begin{array}{c} {p_{w} q_{w}-p_{v}^{T} q_{v}} \\ {p_{w} q_{v}+q_{w} p_{v}+p_{v} \times q_{v}} \end{array}\right] \\ 
        
       
     p⊗q=[pwqw−pvTqvpwqv+qwpv+pv×qv]
 其中  
     
      
       
       
         w 
        
       
      
        w 
       
      
    w 代表实部,  
     
      
       
       
         υ 
        
       
      
        υ 
       
      
    υ 代表虚部, $p_{v}^{T} $为 $p_{v} $的转置,当  
     
      
       
       
         p 
        
       
      
        p 
       
      
    p 和  
     
      
       
       
         q 
        
       
      
        q 
       
      
    q 为纯四元数时,
  
      
       
        
        
          p 
         
        
          ⊗ 
         
        
          q 
         
        
          = 
         
         
         
           [ 
          
          
           
            
             
              
              
                − 
               
               
               
                 p 
                
               
                 v 
                
               
                 T 
                
               
               
               
                 q 
                
               
                 v 
                
               
              
             
            
           
           
            
             
              
               
               
                 p 
                
               
                 v 
                
               
              
                × 
               
               
               
                 q 
                
               
                 v 
                
               
              
             
            
           
          
         
           ] 
          
         
         
        
       
         \mathrm{p} \otimes \mathrm{q}=\left[\begin{array}{l} {-p_{v}^{T} q_{v}} \\ {p_{v} \times q_{v}} \end{array}\right] \\ 
        
       
     p⊗q=[−pvTqvpv×qv]
p ⊗ p = − p v T p v = − ∥ p v ∥ 2 = − 1 \mathrm{p} \otimes \mathrm{p}=-p_{v}^{T} p_{v}=-\left\|p_{v}\right\|^{2}=-1 \\ p⊗p=−pvTpv=−∥pv∥2=−1
相关完整代码如下:
// 描述:姿态解算器初始化
static void NonlinearSO3AHRSinit(float ax, float ay, float az, float mx, float my, float mz)
{
    float initialRoll, initialPitch;
    float cosRoll, sinRoll, cosPitch, sinPitch;
    float magX, magY;
    float initialHdg, cosHeading, sinHeading;
    initialRoll = atan2(-ay, -az);
    initialPitch = atan2(ax, -az);
    cosRoll = cosf(initialRoll);
    sinRoll = sinf(initialRoll);
    cosPitch = cosf(initialPitch);
    sinPitch = sinf(initialPitch);
    magX = mx * cosPitch + my * sinRoll * sinPitch + mz * cosRoll * sinPitch;
    magY = my * cosRoll - mz * sinRoll;
    initialHdg = atan2f(-magY, magX);
    cosRoll = cosf(initialRoll * 0.5f);
    sinRoll = sinf(initialRoll * 0.5f);
    cosPitch = cosf(initialPitch * 0.5f);
    sinPitch = sinf(initialPitch * 0.5f);
    cosHeading = cosf(initialHdg * 0.5f);
    sinHeading = sinf(initialHdg * 0.5f);
    q0 = cosRoll * cosPitch * cosHeading + sinRoll * sinPitch * sinHeading;
    q1 = sinRoll * cosPitch * cosHeading - cosRoll * sinPitch * sinHeading;
    q2 = cosRoll * sinPitch * cosHeading + sinRoll * cosPitch * sinHeading;
    q3 = cosRoll * cosPitch * sinHeading - sinRoll * sinPitch * cosHeading;
// 辅助变量,避免重复操作
    q0q0 = q0 * q0;
    q0q1 = q0 * q1;
    q0q2 = q0 * q2;
    q0q3 = q0 * q3;
    q1q1 = q1 * q1;
    q1q2 = q1 * q2;
    q1q3 = q1 * q3;
    q2q2 = q2 * q2;
    q2q3 = q2 * q3;
    q3q3 = q3 * q3;
}
// 函数名:NonlinearSO3AHRSupdate()
// 描述:姿态解算融合, Mahony互补滤波算法
// 说明:陀螺仪具有良好高频特性,但会随着时间漂移; 加速计具有良好低频特性,不会随着时间漂移,但goat剧烈运动,不易解算真实姿态
// static void NonlinearSO3AHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz, float twoKp, float twoKi, float dt)
void NonlinearSO3AHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz, float twoKp, float twoKi, float dt)
{
    float recipNorm;
    float halfex = 0.0f, halfey = 0.0f, halfez = 0.0f;
    // 初始化条件,静置初始化 (注意,避免抱起机器在空中进行重启)
    if(bFilterInit == 0) {
        NonlinearSO3AHRSinit(ax,ay,az,mx,my,mz);
        bFilterInit = 1;
    }
    // 若存在磁力计数据,则使用磁力计数据
    if(!((mx == 0.0f) && (my == 0.0f) && (mz == 0.0f))) {
        float hx, hy, hz, bx, bz;
        float halfwx, halfwy, halfwz;
        recipNorm = invSqrt(mx * mx + my * my + mz * mz);   // 求平方根的倒数
        mx *= recipNorm;
        my *= recipNorm;
        mz *= recipNorm;
        hx = 2.0f * (mx * (0.5f - q2q2 - q3q3) + my * (q1q2 - q0q3) + mz * (q1q3 + q0q2));
        hy = 2.0f * (mx * (q1q2 + q0q3) + my * (0.5f - q1q1 - q3q3) + mz * (q2q3 - q0q1));
        hz = 2.0f * mx * (q1q3 - q0q2) + 2.0f * my * (q2q3 + q0q1) + 2.0f * mz * (0.5f - q1q1 - q2q2);
        bx = sqrt(hx * hx + hy * hy);
        bz = hz;
        halfwx = bx * (0.5f - q2q2 - q3q3) + bz * (q1q3 - q0q2);
        halfwy = bx * (q1q2 - q0q3) + bz * (q0q1 + q2q3);
        halfwz = bx * (q0q2 + q1q3) + bz * (0.5f - q1q1 - q2q2);
        halfex += (my * halfwz - mz * halfwy);
        halfey += (mz * halfwx - mx * halfwz);
        halfez += (mx * halfwy - my * halfwx);
    }
    if(!((ax == 0.0f) && (ay == 0.0f) && (az == 0.0f)))
    {
        float halfvx, halfvy, halfvz;
        //归一化,得到单位加速度
        recipNorm = invSqrt(ax * ax + ay * ay + az * az);  // 求平方根的倒数
        ax *= recipNorm;
        ay *= recipNorm;
        az *= recipNorm;
        // 根据余弦矩阵和欧拉角将地理坐标系转至机体坐标系(用上一时刻goat的姿态四元数换算到当前机体坐标系的重力单位向量)
        // 即 陀螺仪积分后推算的重力分量
        halfvx = q1q3 - q0q2;  // 使用 halfvx 而非 vx 是为了减小乘法运算量
        halfvy = q0q1 + q2q3;
        halfvz = q0q0 - 0.5f + q3q3;  // ! 为什么直接是0.5f: q0q0 - q1q1 - q2q2 + q3q3 = q0q0 - q1q1 - q2q2 + q3q3 + 1 - 1
        // 获得叉积误差,叉积的大小与陀螺仪积分误差成正比
        // Err = 单位加速度a X(叉乘) 积分重力分量v
        halfex += ay * halfvz - az * halfvy;
        halfey += az * halfvx - ax * halfvz;
        halfez += ax * halfvy - ay * halfvx;
    }
    // 叉积误差判断
    if(halfex != 0.0f && halfey != 0.0f && halfez != 0.0f) {
        // 用叉积误差进行积分
        // 通过 twoKp 、twoKi 比例、积分参数控制加速计修正陀螺仪积分姿态的速度
        // w_bias = Kp*Err + Ki*\sumErr
        if(twoKi > 0.0f) 
        {
            gyro_bias[0] += twoKi * halfex * dt;	// 误差积分
            gyro_bias[1] += twoKi * halfey * dt;
            gyro_bias[2] += twoKi * halfez * dt;
            // 积分反馈
            gx += gyro_bias[0];
            gy += gyro_bias[1];
            gz += gyro_bias[2];
        }
        else {
            gyro_bias[0] = 0.0f;  // 防止积分饱和
            gyro_bias[1] = 0.0f;
            gyro_bias[2] = 0.0f;
        }
      // 比例反馈
        gx += twoKp * halfex;   
        gy += twoKp * halfey;
        gz += twoKp * halfez;
    }
    // 四元数微分方程(一阶龙格-库塔法).
    //! \dot{q} = 0.5*q \otimes P(\omega)
    //      |dq0|       | 0  -gx -gy -gz||q0|
    //      |dq1|       | gx  0   gz -gy||q1|
    // s1 = |dq2| = 0.5*| gy -gz  0   gx||q2| 
    //      |dq3|       | gz  gy -gx  0 ||q3|
    dq0 = 0.5f*(-q1 * gx - q2 * gy - q3 * gz);
    dq1 = 0.5f*(q0 * gx + q2 * gz - q3 * gy);   
    dq2 = 0.5f*(q0 * gy - q1 * gz + q3 * gx);
    dq3 = 0.5f*(q0 * gz + q1 * gy - q2 * gx);
    // q_i+1 = q_i + s1*dt
    q0 += dt*dq0;
    q1 += dt*dq1;
    q2 += dt*dq2;
    q3 += dt*dq3;
    // 四元数归一化
    recipNorm = invSqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);  // 求平方根的倒数
    if(recipNorm!=0)
    {
      q0 *= recipNorm;
      q1 *= recipNorm;
      q2 *= recipNorm;
      q3 *= recipNorm;
      Quaternion.Q[0] = q0;
      Quaternion.Q[1] = q1;
      Quaternion.Q[2] = q2;
      Quaternion.Q[3] = q3;
      // 辅助变量,避免重复计算
      q0q0 = q0 * q0;
      q0q1 = q0 * q1;
      q0q2 = q0 * q2;
      q0q3 = q0 * q3;
      q1q1 = q1 * q1;
      q1q2 = q1 * q2;
      q1q3 = q1 * q3;
      q2q2 = q2 * q2;
      q2q3 = q2 * q3;
      q3q3 = q3 * q3;
    }
}
                

















