IMU&GPS融合定位::IMU姿態解算

姿態解算

1. 背景

姿態解算是飛控的一個基礎、重要部分,估計出來的姿態會發布給姿態控制器,控制飛行平穩,是飛行穩定的最重要保障。另外,姿態解算不僅僅用於無人機領域,無人車領域也需要進行姿態解算,用以進行GNSS和IMU、激光點雲的融合定位。


2. 主要內容

  • 傳感器基本原理
  • 座標系描述
  • 姿態的幾種表示方式
  • 姿態解算的基本算法

3. 傳感器基本原理

不展開,推薦以下參考:


4. 座標系描述

運載體在三位空間中運動包含六個自由度,既有角運動又有線運動。在地球表面附近,運載體的角運動又有線運動。運載體上的慣性傳感器(imu)是相對於慣性空間進行測量的,另外,地球繞其自轉軸相對於慣性空間以常值角速度旋轉,運載體在地球表面上的位置變化會引起其相對於地心的角速度變化。

4.1 地心慣性座標系(i系,inertial frame)

地心慣性座標系用oixiyizi表示,原點爲地球中心,x軸指向春分點(赤道面與黃道面的交線再與天球相交的交點之一),春分點是天文測量中確定恆星時的起點,z軸爲地球自轉軸,指向北極,慣性傳感器的輸出就是基於該座標系爲參考座標系的。

4.2 地球座標系(e系,earth frame)

地球座標系用oexeyeze表示,x軸指向本初子午線與赤道面的交點,z軸爲地球自轉軸,指向北極。e系與地球固連,也稱 地心地固座標系 (Earth-Centered Earth-Fixed,ECEF),地球座標系相對於慣性座標系的角速度大小爲地球自傳角速度,
wie=7.2921151467105rad/sw_{ie}=7.2921151467*10^{-5} rad/s

4.3 地理座標系(g系,geographic frame)

WGS-84

4.4 當地導航座標系(e系,earth frame)

導航座標系用oexeyeze,它是慣性導航系統在求解導航參數時採用的參考座標系。純慣導系統的高度通道在原理上是發散的,因而慣導系統多采用當地水平座標系作爲參考座標系,以實現水平和高度通道的解偶,即利用慣導長時間導航定位時只進行水平定位結算,簡單地將高度值設爲固定。
常用的導航座標系爲東-北-天(ENU)導航座標系

  • X軸:指東
  • Y軸:指北
  • Z軸:指天
    在這裏插入圖片描述

4.5 載體座標系(b系,body frame)

載體座標系用obxbybzb表示,原點爲載體重心,右-前-上座標系描述:x軸沿載體橫軸向右,y軸沿載體縱軸向前(即載體前進方向),z軸沿載體立軸向上。b系與載體固連,載體座標系b系與導航座標系n系的關係可用一組歐拉角表示。

4.6 常用相連座標系(特指載體座標系和導航座標系))

4.6.1 東北天(ENU)——右前上

(1)東北天——當地導航座標系

  • X軸:指東;
  • Y軸:指北;
  • Z軸:指天。

    畫成平面,如下圖:
    在這裏插入圖片描述

(2)右前上——當地導航座標系

  • X軸:指向載體右側;
  • Y軸:指向載體前進方向;
  • Z軸:指天。
    在這裏插入圖片描述
    在這裏插入圖片描述

5. 姿態的描述

5.1 歐拉角

歐拉角用來直觀表示載體的姿態,如下圖
在這裏插入圖片描述

  • 偏航角Yaw $ (\psi) $
    在這裏插入圖片描述
  • 俯仰角Pitch $ (\theta)$
    在這裏插入圖片描述
  • 翻滾角Roll (ϕ)(\phi)
    在這裏插入圖片描述
  • Proper Euler angles (z-x-z, x-y-x, y-z-y, z-y-z, x-z-x, y-x-y)
    指第一次旋轉和第三次旋轉中使用相同的軸(313),比較少用
  • 泰特-布萊恩角
    泰特布萊恩角表示圍繞三個不同軸的旋轉,如Z-X’-Y’’
    在這裏插入圖片描述
    上圖描述了一組歐拉角,主要看右圖就好了
  • (1)原座標系1如藍色的x-y-z
  • (2)座標系1沿z軸,逆時針旋轉ψ(ψ>0)\psi (\psi >0),認爲沿z軸逆時針旋轉爲正方向,ψ=Yaw\psi=Yaw;然後得到了黃色的座標系2x’-y’-z’
  • (3)將座標系2沿x(N)軸逆時針旋轉θ(θ>0)\theta(\theta >0),得到了紅色的座標系N-Y-Z
  • (4)將紅色座標系沿Y軸順時針旋轉(ϕ)(\phi),得到了目的座標系:紅色的X-Y-Z座標系

5.2 旋轉矩陣(方向餘弦矩陣)

由於使用歐拉角描述姿態存在萬向節死鎖的問題,具體參見:萬向節死鎖 gimbal lock
因此引入方向餘弦矩陣

5.2.1 方向餘弦矩陣的基本形式

一個向量的方向(姿態)我們可以用他在參考座標系(地理座標系)各個軸向的夾角的餘弦來表示(及在各個軸的投影)。
類似的 一個座標系 可以看成是3個向量組成,所以三個向量分別在座標軸上的投影可以用來表示一個座標系與參考座標系的關係。這總共9個方向餘弦組成了一個三階矩陣,其對應方式如下圖。
Cbn=[c11c12c13c21c22c23c11c12c13] \quad C_b^n= \begin{bmatrix} c_{11} & c_{12} &c_{13} \\ c_{21} & c_{22} &c_{23} \\ c_{11} & c_{12} &c_{13} \end{bmatrix} \quad
其中,第 i 行、 j 列的元素表示參考座標系 i 軸和姿態座標系 j 軸夾角的餘弦。事實上方向餘弦和歐拉角沒有本質區別,因爲方向餘弦實際上就是用歐拉角表示的。

5.2.2 方向餘弦矩陣的舉例推導

一個二維的座標變換如下:

點F爲固定點,在座標系1下的表示爲F(rx1,ry1)F(r_{x1},r_{y1}),在座標系2下爲F2(rx2,ry2)F_{2}(r_{x2},r_{y2})
由圖可知
rx2=rx1cosα+ry1sinαry2=rx1(sinα)+ry1cosα \begin{aligned} r_{x2}&=r_{x1}*\cos \alpha+ r_{y1}*\sin \alpha \\ r_{y2}&=r_{x1}*(-\sin \alpha)+r_{y1}*\cos \alpha \end{aligned}
推廣到三維的情況下,可看作是繞Z軸逆時針旋轉,並寫成矩陣形式:
[rx2ry2rz2]=[cosαsinα0sinαcosα0001][rx1ry1rz1] \quad \begin{bmatrix} r_{x2} \\ r_{y2} \\ r_{z2} \end{bmatrix}= \begin{bmatrix} \cos \alpha & \sin \alpha &0 \\ -\sin \alpha & \cos \alpha &0 \\ 0 & 0 &1 \end{bmatrix} \begin{bmatrix} r_{x1} \\ r_{y1} \\ r_{z1} \end{bmatrix} \quad
由上面的例子,可推理餘弦矩陣各個元素的意義
在這裏插入圖片描述

  • 第1行表示旋轉之後的X2軸在原座標系(X1,Y1,Z1)軸下的投影
  • 第2行表示旋轉之後的Y2軸在原座標系(X1,Y1,Z1)軸下的投影
  • 第3行表示旋轉之後的Z2軸在原座標系(X1,Y1,Z1)軸下的投影

5.2.2 東北天ENU---->右前上的餘弦矩陣CnbC_{n}^{b}推導

假設我們現在有一個東北天座標系和一個載體座標系,現需要將東北天座標系經過3次旋轉,使得最終得到的座標系與載體座標系重合。

在此之前,需要做出一些規定

  • 旋轉的正方向爲:從旋轉軸看的逆時針方向
  • 旋轉的順序爲:Z-X-Y
  • 對應的歐拉角:Yaw-Pitch-Roll
1. 繞Z軸逆時針旋轉ψ\psi——Yaw

在這裏插入圖片描述
得到旋轉矩陣Cn1C_{n}^{1}
Cn1=[cosψsinψ0sinψcosψ0001] \quad C_{n}^{1}= \begin{bmatrix} \cos \psi & \sin \psi &0 \\ -\sin \psi & \cos \psi &0 \\ 0 & 0 &1 \end{bmatrix} \quad

2. 繞X’軸逆時針旋轉θ\theta——Pitch

在這裏插入圖片描述
得到旋轉矩陣C12C_{1}^{2}
C12=[1000cosθsinθ0sinθcosθ] \quad C_{1}^{2}= \begin{bmatrix} 1 & 0 &0 \\ 0 &\cos \theta & \sin \theta \\ 0 &-\sin \theta & \cos \theta \end{bmatrix} \quad

3. 繞Y’'軸逆時針旋轉ϕ\phi——Roll

在這裏插入圖片描述
得到旋轉矩陣C23C_{2}^{3}
C23=[cosϕ0sinϕ010sinϕ0cosϕ] \quad C_{2}^{3}= \begin{bmatrix} \cos \phi & 0 &-\sin \phi \\ 0 & 1& 0 \\ \sin \phi & 0& \cos \phi \end{bmatrix} \quad

4. 得到ENU導航座標系到右前上載體座標系的方向餘弦矩陣CnbC_{n}^{b}

Cnb=C23C12Cn1=[cosϕ0sinϕ010sinϕ0cosϕ][1000cosθsinθ0sinθcosθ][cosψsinψ0sinψcosψ0001]=[cosψcosϕsinψsinθsinϕsinψcosϕ+cosψsinθsinϕcosθsinϕsinψcosθcosψcosθsinθcosψsinϕ+sinψsinθcosϕsinψsinϕcosψsinθcosϕcosθcosϕ]=[c11c12c13c21c22c23c11c12c13] \begin{aligned} C_{n}^{b}=&C_{2}^{3}C_{1}^{2}C_{n}^{1} \\ =& \begin{bmatrix} \cos \phi & 0 &-\sin \phi \\ 0 & 1& 0 \\ \sin \phi & 0& \cos \phi \end{bmatrix} \begin{bmatrix} 1 & 0 &0 \\ 0 &\cos \theta & \sin \theta \\ 0 &-\sin \theta & \cos \theta \end{bmatrix} \begin{bmatrix} \cos \psi & \sin \psi &0 \\ -\sin \psi & \cos \psi &0 \\ 0 & 0 &1 \end{bmatrix} \\ =& \begin{bmatrix} \cos \psi \cos \phi -\sin \psi \sin \theta \sin \phi & \sin \psi \cos \phi+\cos \psi \sin \theta \sin \phi & -\cos \theta \sin \phi \\ -\sin \psi \cos \theta & \cos \psi \cos \theta & \sin \theta \\ \cos \psi \sin \phi+ \sin \psi \sin \theta \cos \phi & \sin \psi \sin \phi- \cos \psi \sin \theta \cos \phi & \cos \theta \cos \phi \end{bmatrix} \\ = & \begin{bmatrix} c_{11} & c_{12} &c_{13} \\ c_{21} & c_{22} &c_{23} \\ c_{11} & c_{12} &c_{13} \end{bmatrix} \end{aligned}

5.3 四元數

用歐拉角表示姿態需要指定順序和方向,用餘弦矩陣表示姿態則參數較多,四元數出現了。
四元數(Quaternions)是由愛爾蘭數學家哈密頓(William Rowan Hamilton)在1843年提出。

三維空間的任意旋轉,都可以用繞三維空間的某個軸旋轉過某個角度來表示,即所謂的Axis-Angle表示方法。這種表示方法裏,Axis可用一個三維向量(x,y,z)來表示,θ可以用一個角度值來表示,直觀來講,一個四維向量(θ,x,y,z)就可以表示出三維空間任意的旋轉。注意,這裏的三維向量(x,y,z)只是用來表示axis的方向朝向,因此更緊湊的表示方式是用一個單位向量來表示方向axis,而用該三維向量的長度來表示角度值θ。

簡單來說,四元數的思想就是把方向餘弦矩陣的三次旋轉表示爲只繞一個旋轉軸旋轉一次完成,因此可以用4個數來表示這個過程,其中包括旋轉軸向量的長度(θ)和旋轉軸單位向量(x,y,z)

5.3.1 四元數的表示

[q0q1q2q3]=[cosθ2xsinθ2ysinθ2zsinθ2] \begin{aligned} \begin{bmatrix} q_0 \\ q_1 \\ q_2 \\ q_3 \end{bmatrix} = \begin{bmatrix} \cos \frac{\theta}{2} \\ x*\sin \frac{\theta}{2} \\ y*\sin \frac{\theta}{2} \\ z*\sin \frac{\theta}{2} \\ \end{bmatrix} \end{aligned}

5.3.2 四元數的複數定義

q=q0+q1i+q2j+q3k=[s,v]
其中 q0,q1,q2,q3均爲實數, s=q0,v=[q1,q2,q3],i2=j2=k2=−1
對於 i,j,k 本身的幾何意義可以理解爲一種旋轉,其中 i 代表 x 軸與 y 軸相交平面中 x 軸正向向 y 軸正向的旋轉, j 旋轉代表 z 軸與 x 軸相交平面中 z 軸正向向 x 軸正向的旋轉,k 旋轉代表 y 軸與 z 軸相交平面中 y 軸正向向 z 軸正向的旋轉, −i,−j,−k 分別代表 i,j,k 的反向旋轉。

5.3.3 四元數的模

q=q02+q12+q22+q32 \begin{aligned} |q|=\sqrt{q_{0}^{2}+q_{1}^{2}+q_{2}^{2}+q_{3}^{2}} \end{aligned}

5.3.4 四元數的運算
  • 主要運算
    在這裏插入圖片描述
  • 四元數乘法
    在這裏插入圖片描述

乘法性質

  1. 滿足結合律
  2. 不滿足交換律
  3. 乘積的模等於模的乘積
  4. 乘積的逆等於各個四元數的逆以相反的順序相乘
  • 其他運算
    在這裏插入圖片描述
    在這裏插入圖片描述

*四元數部分參考:旋轉矩陣、歐拉角、四元數理論及其轉換關係


6. 姿態解算

6.1 傳感器座標系準備

在進行解算之前,需要完成十分重要的一步(但是很多資料都沒展開描述),將加速度計、陀螺儀、磁力計對其到右前上座標系。原因是一些集成的imu中三者座標系並不一致。

6.1.1 加速度計
  • 車頭朝前
  • 向前加速,y軸加速度輸出爲+
  • 向右加速,x軸加速度輸出爲+
  • 向上加速,z軸加速度輸出爲+
6.1.2 陀螺儀
  • 車頭朝前
  • 從Z+看向Z-(即從上往下看),逆時針旋轉,Z軸角速度輸出爲+
  • 從X+看向X-(即從車右側看),逆時針旋轉(車頭上翹),X軸角速度輸出爲+
  • 從Y+看向Y-(即從車頭看),逆時針旋轉,Y軸角速度輸出爲+
6.1.3 磁力計
  • 車頭朝北,即Y軸指北
  • 磁力計應該輸出形如
    Magb=[0MNMD] \begin{aligned} Mag_b= \begin{bmatrix} 0 \\ M_N \\ M_D \end{bmatrix} \end{aligned}
    其中,
    MD<0MD>0 \begin{aligned} M_D <0 ,北半球 \\ M_D >0 ,北半球 \end{aligned}
  • 將車頭稍微向西偏
  • 檢查此時輸出,正確的輸出形如(主要看之前爲0的那一項的變化):
    Magb=[>0aMNbMD] \begin{aligned} Mag_b= \begin{bmatrix} >0 \\ a*M_N \\ b*M_D \end{bmatrix} \end{aligned}
  • 如果反向了,則需要添加‘-’號

6.2 初始姿態計算

在進行姿態解算前,需要確定初始的姿態,

  • 使用加速度計確定俯仰和翻滾,pitch 和 roll
  • 使用磁力計確定偏航角 yaw

6.2.1 確定俯仰和翻滾

  • 對載體座標系下的加速度(加速度計的輸出)進行歸一化
    Acc=Norm(Acc) \begin{aligned} Acc=Norm(Acc) \end{aligned}
  • 計算俯仰pitch
    由於我們是以右前上作爲載體座標系,Y軸爲車頭方向,與網上很多飛控採用的前右下座標系不一樣,因此pitch與y軸方向加速度相關
    pitch=atan2(accy,accx2+accz2) \begin{aligned} pitch=atan2(acc_y,\sqrt{acc_x^{2}+acc_z^{2}}) \end{aligned}
  • 計算翻滾roll
    roll=atan2(accx,accz) \begin{aligned} roll=-atan2(acc_x,acc_z) \end{aligned}

實現代碼C++

Vector3d getPoseFrom_Acc(Vector3d _acc){
    Vector3d acc=_acc;
    acc.normalize();
    double norm=sqrt(acc[0]*acc[0]+acc[1]*acc[1]+acc[2]*acc[2]);
    Vector3d result;
    result<<0,atan2(acc[1],sqrt(acc[0]*acc[0]+acc[2]*acc[2])),-atan2(acc[0],acc[2]);
    return result;
}

6.2.2 確定偏航角

確定偏航角需要使用磁力計,使用磁力計之前請先按照官方給定校正說明對磁力計進行校正(另外還需要時不時校正,這個東西太弱了))

我們使用ENU和右前上座標系,因此,當載體座標系b系與導航座標系n系重合時,即車頭朝北時,正常輸出如下:
Magb=Magn=[0MNMD] \begin{aligned} Mag_b=Mag_n= \begin{bmatrix} 0 \\ M_N \\ M_D \end{bmatrix} \end{aligned}

兩座標系不重合時,磁力計輸出如下:
Magb1=[magxbmagybmagzb] \begin{aligned} Mag_{b1}= \begin{bmatrix} mag_x^{b} \\ mag_y^{b} \\ mag_z^{b} \end{bmatrix} \end{aligned}

假定有從導航座標系n繫到載體座標系b系的方向餘弦矩陣Cnb,那麼將此時磁力計輸出變換到導航座標系下,得到:
Magb1=CnbMagn=Cnb[0MNMD]=[magxbmagybmagzb]=[MN(sinψcosϕ+cosψsinθsinϕ)MDcosθsinϕMNcosψcosθ+MDsinθMN(sinψsinϕcosψcosϕsinθ)+MDcosθcosϕ] \begin{aligned} Mag_{b1}=C_n^{b}Mag_n=C_n^{b} \begin{bmatrix} 0 \\ M_N \\ M_D \end{bmatrix}= \begin{bmatrix} mag_x^{b} \\ mag_y^{b} \\ mag_z^{b} \end{bmatrix} =& \begin{bmatrix} M_N (\sin \psi \cos \phi + \cos \psi \sin \theta \sin \phi)-M_D \cos \theta \sin \phi \\ M_N \cos \psi \cos \theta +M_D \sin \theta \\ M_N (\sin \psi \sin \phi- \cos \psi \cos \phi \sin \theta)+M_D \cos \theta \cos \phi \end{bmatrix} \end{aligned}
對上式進行變換:
my=MNsinψ=magxbcosϕ+magzbsinϕmx=MNcosψ=magxbsinϕsinθ+magybcosθmagzbcosϕsinθ \begin{aligned} my=M_N\sin \psi=&mag_x^{b}\cos \phi+ mag_z^{b}\sin \phi \\ mx=M_N\cos \psi=&mag_x^{b}\sin \phi \sin \theta+ mag_y^{b}\cos \theta -mag_z^{b}\cos \phi \sin \theta \end{aligned}
綜上,可得偏航角Yaw
Yaw=ψ=atan2(my,mx) \begin{aligned} Yaw=\psi=atan2(my,mx) \end{aligned}

6.3 基於Mahony算法的姿態解算

在這裏插入圖片描述

數據準備

  • 取初始姿態Yaw,pitch,roll
  • 利用euler_312_To_quaternion()函數,得到初始姿態對應的四元數q
  • 利用C_nb_312_from_qnb()函數,得到初始姿態對應的旋轉矩陣Cnb

利用磁力計校正Yaw偏差計算

  • 取當前b系下磁力計輸出,並歸一化
    Mag=Norm(Mag)Mag=Norm(Mag)
  • 將b系的磁力向量轉換到n系下
    MagRef=(Cnb)TMag MagRef=(C_{n}^{b})^TMag
  • 構建基於b系磁力分量和姿態矩陣的理想磁力計輸出
    MagRef_=[0MagRef[0]2+MagRef[1]2MagRef[2]]MagDir_hat=12CnbMagRef_ \begin{aligned} MagRef\_= & \begin{bmatrix} 0 \\ \sqrt{MagRef[0]^2+MagRef[1]^2} \\ MagRef[2] \end{bmatrix} \\ MagDir\_hat=& \frac{1}{2}C_{n}^{b}MagRef\_ \end{aligned}
  • 利用叉乘計算實際與理想的偏差
    Mag_err=Mag×MagDir_hat Mag\_err=Mag \times MagDir\_hat
  • 設置磁力分量偏差的Kp和Ki值
  • 計算磁力分量誤差
    errp=kpyawMag_errerri=kiyawΔTMag_err \begin{aligned} err_p=&kp_{yaw}*Mag\_err \\ err_i=&ki_{yaw}*\Delta T*Mag\_err \end{aligned}

利用加速度計校正pitch、roll偏差計算

  • 取當前b系下加速度計輸出,並歸一化
    Acc=Norm(Acc)Acc=Norm(Acc)
  • 由於標準n系下的加速度計輸出應該只有重力分量,即歸一化後的理想n系加速度爲:
    Accn=[001]Acc_hat=CnbAccn \begin{aligned} Acc_n= \begin{bmatrix} 0 \\ 0 \\ 1 \end{bmatrix} \\ Acc\_hat=C_{n}^{b}Acc_n \end{aligned}
  • 利用叉乘計算實際與理想的偏差
    Acc_err=Acc×Acc_hat Acc\_err=Acc \times Acc\_hat
  • 設置pitch\roll偏差的Kp和Ki值
  • 計算pitch\roll偏差
    errp=errp+kprollpitchAcc_errerri=erri+kirollpitchΔTAcc_err \begin{aligned} err_p=&err_p+kp_{rollpitch}*Acc\_err \\ err_i=&err_i+ki_{rollpitch}*\Delta T*Acc\_err \end{aligned}

對陀螺儀輸出角速度進行偏差修正
w=gyro=[gyroxgyroygyroz]+[errp[0]errp[1]errp[2]]+[erri[0]erri[1]erri[2]] \begin{aligned} w=gyro= \begin{bmatrix} gyro_x \\ gyro_y \\ gyro_z \end{bmatrix} + \begin{bmatrix} err_p[0] \\ err_p[1] \\ err_p[2] \end{bmatrix} + \begin{bmatrix} err_i[0] \\ err_i[1] \\ err_i[2] \end{bmatrix} \end{aligned}

角速度積分,得到角度較小變化量w
Δθ=gyroΔT \Delta \theta=gyro*\Delta T

解四元數微分方程

  • 四元數微分方程如下:
    Q˙(t)=12Mw(t)Q(t) \begin{aligned} \dot{Q}(t)=\frac{1}{2}M'_{w(t)}Q(t) \end{aligned}

  • 閉合解爲:
    Q(t+1)=e12ΔΘQ(t) \begin{aligned} Q(t+1)=e^{\frac{1}{2}\Delta\Theta }Q(t) \end{aligned}
    其中,
    ΔΘ=tktk+1[0wxwywzwx0wzwywywz0wxwzwywx0]dt[0ΔθxΔθyΔθzΔθx0ΔθzΔθyΔθyΔθz0ΔθxΔθzΔθyΔθx0] \begin{aligned} \Delta\Theta=\int_{t_k}^{t_k+1} \begin{bmatrix} 0 &-w_x &-w_y &-w_z \\ w_x &0 &w_z &-w_{y} \\ w_y &-w_z &0 &w_x \\ w_z &w_y &-w_x &0 \\ \end{bmatrix} dt \approx \begin{bmatrix} 0 &-\Delta\theta_x &-\Delta\theta_y &-\Delta\theta_z \\ \Delta\theta_x &0 &\Delta\theta_z &-\Delta\theta_{y} \\ \Delta\theta_y &-\Delta\theta_z &0 &\Delta\theta_x \\ \Delta\theta_z &\Delta\theta_y &-\Delta\theta_x &0 \\ \end{bmatrix} \end{aligned}

  • 爲了減少運算量,通常採用近似解

  • 畢卡近似解如下:
    在這裏插入圖片描述
    其中,
    Δθ2=Δθx2+Δθy2+Δθz2 \Delta \theta^2=\Delta \theta_x^{2}+\Delta \theta_y^{2}+\Delta \theta_z^{2}

代碼如下

void mahony(double currT){
    //初始化
    static double deltaT_prev=0;
    static bool init=false;
    if(!init){
        deltaT_prev=currT;
        init=true;
        return ;
    }
    //**數據準備**
    Quaterniond q=curr_pose;//euler2quaternion(align_pose);
    Matrix3d Cnb=C_nb_312_from_qnb(q);
    Cnb.normalize();

    //**對陀螺儀輸出角速度進行偏差修正**
    Vector3d mag=mag_dev.mag;
    mag.normalize();
    Vector3d magRef=Cnb.transpose()*mag;  //得到n系下的磁力計分量

    Vector3d magRef_(0,sqrt(magRef[0]*magRef[0]+magRef[1]*magRef[1]),magRef[2]);

    //估計磁場方向
    Vector3d magDir_hat=0.5*Cnb*magRef_;

    //mag 與 方向進行叉積
    Vector3d mag_cross_magDir=mag.cross(magDir_hat);

    //計算偏差
    Vector3d err_p(0,0,0);
    Vector3d err_i(0,0,0);

    double kp_yaw=1.2;
    double ki_yaw=0.0002;
    err_p=err_p+kp_yaw*mag_cross_magDir;
    err_i=err_i+ki_yaw*(currT-deltaT_prev)*mag_cross_magDir;

    //**利用加速度計校正pitch、roll偏差計算**
    Vector3d acc;
    acc=imu_dev.acc;
    acc.normalize();

    Vector3d vv=Cnb*Vector3d(0,0,1);
    Vector3d acc_cross_vv=acc.cross(vv);

    double kp_rollpitch=1.2;
    double ki_rollpitch=0.0002;
    err_p=err_p+kp_rollpitch*acc_cross_vv;
    err_i=err_i+ki_rollpitch*(currT-deltaT_prev)*acc_cross_vv;

    //**對陀螺儀輸出角速度進行偏差修正**
    Vector3d gyro=imu_dev.gyro;

    gyro=gyro+err_p+err_i;

    //**角速度積分,得到角度較小變化**
    if((currT-deltaT_prev)>0){
        gyro=gyro*(currT-deltaT_prev);
    }
    else
        return;

    //**解四元數微分方程**
    Matrix4d gyro_mat;
    gyro_mat<<  0,    -gyro[0],   -gyro[1],   -gyro[2],
                gyro[0],    0,      gyro[2],    -gyro[1],
                gyro[1], -gyro[2],        0,    gyro[0],
                gyro[2],  gyro[1],  -gyro[0],   0;

    double gyro_L2=sqrt(gyro[0]*gyro[0]+gyro[1]*gyro[1]+gyro[2]*gyro[2]);

    //**畢卡解法**
    Vector4d q_curr;
    q_curr<<q.w(),q.x(),q.y(),q.z();
    Vector4d q_new=((1-gyro_L2*gyro_L2/8)*Matrix4d::Identity()+(0.5-gyro_L2*gyro_L2/48)*gyro_mat)*q_curr;

    Quaterniond output;
    output.w()=q_new[0];
    output.x()=q_new[1];
    output.y()=q_new[2];
    output.z()=q_new[3];
    output.normalize();
    curr_pose=output;
    deltaT_prev=currT;
}

6.4 基於DCM餘弦矩陣的姿態解算

  • 基於DMC的解法基本思路與Mahony解法相似,這裏不贅述,有興趣的同學可以參考Razor_AHRS的算法
  • 傳送門:https://github.com/KristofRobot/razor_imu_9dof
    在這裏插入圖片描述

6.5 基於擴展卡爾曼濾波的姿態解算

這裏不展開卡爾曼、擴展卡爾曼的內容,只是把它當作工具使用

概覽

1 狀態變量、觀測量說明

在這裏插入圖片描述

2 狀態轉移

在這裏插入圖片描述

3 觀測矩陣

在這裏插入圖片描述

4 卡爾曼方程組

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

概覽部分參考自:四旋翼姿態解算–互補濾波和拓展卡爾曼


具體步驟

1 狀態變量

X12x1=[gyro^3x1gyro˙^3x1Acc^3x1bMag^3x1b][bbb] \begin{aligned} X_{12x1}= \begin{bmatrix} \hat{gyro}_{3x1} \\ \hat{\dot{gyro}}_{3x1} \\ \hat{Acc}_{3x1}^{b} \\ \hat{Mag}_{3x1}^{b} \end{bmatrix} \begin{bmatrix} b系三軸角速度估計 \\ 角加速度估計 \\ b系加速度估計 \\ b系磁力分量估計 \end{bmatrix} \end{aligned}

2 觀測量

Z9x1=[gyro3x1Acc3x1bMag3x1b][bbb] \begin{aligned} Z_{9x1}= \begin{bmatrix} gyro_{3x1} \\ Acc_{3x1}^{b} \\ Mag_{3x1}^{b} \end{bmatrix} \begin{bmatrix} b系三軸角速度測量 \\ b系加速度測量 \\ b系磁力分量測量 \end{bmatrix} \end{aligned}

3 狀態轉移矩陣
  • 非線性狀態轉移(預測)
    在這裏插入圖片描述
    其中,
    $
    r_{a,k}爲k時刻下的加速度,r_{m,k}爲k時刻下的磁力計輸出,\tilde w_{k}爲描述姿態發生變化的餘弦矩陣,W項爲高斯噪聲
    $

  • EKF線性化
    對非線性函數在xk^\hat{x_{k}}處求一階導,得到雅克比矩陣爲狀態轉移矩陣
    Alin,k=f(xk,wk)xk=[I3x3I3x3ΔT000I3x300raccΔT0I3x3+rgyroΔT0rmagΔT00I3x3+rgyroΔT] \begin{aligned} A_{lin,k}=\frac{\partial f(x_{k},w_{k})}{\partial x_{k}}= \begin{bmatrix} I_{3x3} &I_{3x3}\Delta T & 0 & 0 \\ 0 &I_{3x3} &0 &0 \\ -r_{acc}\Delta T &0 &I_{3x3}+r_{gyro}\Delta T &0 \\ -r_{mag}\Delta T &0 &0 &I_{3x3}+r_{gyro}\Delta T \end{bmatrix} \end{aligned}
    其中,
    raccr_{acc}爲加速度的反對稱矩陣
    rmagr_{mag}爲磁力分量的反對稱矩陣
    rgyror_{gyro}爲角速度的反對稱矩陣

  • 計算協方差矩陣估計
    P^=Alin,kPAlin,kT+Q \begin{aligned} \hat{P}=A_{lin,k}PA_{lin,k}^{T}+Q \end{aligned}

4 更新
  • 觀測矩陣
    H=[I3x300000I3x30000I3x3] \begin{aligned} H= \begin{bmatrix} I_{3x3} & 0 &0 &0 \\ 0 &0 &I_{3x3} &0\\ 0 &0 &0 &I_{3x3} \end{bmatrix} \end{aligned}
  • 觀測
    Y=ZHX^ \begin{aligned} Y=Z-H\hat{X} \end{aligned}
  • 計算卡爾曼增益
    K=P^HT(HP^HT+Rk)1 K=\hat{P}H^{T}(H\hat{P}H^{T}+R_{k})^{-1}
  • 更新狀態變量估計
    X=X^+KY X=\hat{X}+KY
  • 更新協方差矩陣
    P=(IKH)P^ P=(I-KH)\hat{P}

代碼:待更新


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章