GD32F103+MPU9150四旋翼飛行器第一步:姿態融合算法

前言:

相比直升機來說,四旋翼乃至多旋翼飛行器的機械結構簡單,操控靈活,飛行穩定,體積也能做的更小,當然也能更大,它將直升機複雜的機械結構設計難度轉化到了電子電路和算法上面,因此四旋翼飛行器的設計更容易上手,更民衆化。

 四旋翼飛行器的軟件核心包括兩大部分:姿態融合算法和控制算法;硬件核心便是MCU和傳感器。

 先介紹下姿態融合算法,姿態融合說白了就是將3軸加速度、3軸角速度和3軸磁場強度融合成四元數,再將四元數轉化爲歐拉角,最後將歐拉角最爲控制量輸送到所有電機以達控制飛行器姿態的目的。歐拉角包括偏航角Yaw、俯仰角Pitch和滾動角Roll。我用的算法是Madgwick寫的AHRSUpdateIMUUpdate,簡單有效,其中AHRSUpdate是融合了陀螺儀、加速度計和磁力計,而IMUUpdate只融合了陀螺儀和加速度計,就優缺點來說,IMUupdate算法只融合了加速度計和陀螺儀的數據,還需要使用互補濾波算法來融合磁力計以修正偏航角Yaw,不然飛行器會找不到北,但是這種互補濾波有個小問題,就是假如定義偏航角的範圍是0-360度,那麼當機頭大概從北偏西1度轉到北偏東364度時,機頭會經過0(360)這個點,那麼這時,yaw不會直接1-0-364這麼變化,而是會被逆向積分從 1-20-180-270-364這麼轉一圈,這是個不好的現象,實驗了半天也沒有解決,而AHRSupdate很好的解決了這個問題,不過由於AHRSupdate把磁力計的數據融合進了所有歐拉角,因此當傳感器受到外圍強磁場干擾時,就會造成全方位失控,導致墜機,而使用IMUupdate算法,頂多飛行器會轉圈而已。

 傳感器我用的是invensense公司的MPU9150MPU9150芯片集成了加速度計、陀螺儀和磁力計,並且內置硬件DMP用於姿態融合,不過不好用;MCU則用是Gigadevice公司的GD32F103系列,由於我也是剛接觸四旋翼飛行器,第一個目的當然是能夠平穩的飛起來,暫不考慮加入其他外圍設備。後續可能會考慮使用GD32F107或者GD32F2xx系列,可擴展攝像頭小玩一把航拍,當然更好的是GD32F4xx系列(期盼中),自帶浮點運算單元,由於我軟件太菜,算法中出現大量的浮點運算導致姿態更新頻率和控制頻率達不到很高。

 做四軸飛行器也是爲了好玩,目前我只完成了第一步:姿態融合。接下來纔是更重要的,選擇合適的機架、電調、電機、螺旋槳,寫PID控制代碼,系統整合以後還要調試各種參數,抗干擾,抗震動,最後還要加各種應用器件。在此鼓勵一下自己,堅持就是勝利,慢慢磨洋工。

    我現在軟件實現的功能:算法用AHRSupdate、陀螺儀零偏校準、加速度計平滑濾波、磁力計平面校準,以後看情況可能會慢慢更新加速度計精確校準、磁力計橢球擬合校準、陀螺儀溫度補償等。

第一部分:硬件

1.傳感器:MPU9150INVENSENSE公司的,單芯片內集成了加速度計、陀螺儀和磁力計,並且內置DMP用於姿態融合,不過只融合了加速度計和陀螺儀,沒有融合磁力計進去,具有自校準功能,價格比MPU6050貴很多,但是省PCB面積,省事,軸向重合度高。實際上就是把MPU6050和磁力計AK8975放在同一個芯片裏,程序還是使用MPU6050的驅動,缺點是會偶爾丟失數據,自帶的姿態融合算法的更新頻率不高);

2.MCUGD32F103CBGigadevice公司的,ARMcortex-M3內核,32MCU,主頻最高108Mhz48Pin,與ST同型號的32MCU 直接兼容,性價比更高,外接8M晶振,也可使用內部8M晶振,晶振遠離傳感器,避免干擾磁力計,不過當時考慮不周,這個芯片的timer太少了,以後會先採用GD32F103VCT6或者GD32F107VCT6);

3.電源芯片:TLV70233DBVRTILDO,輸入2-6V,輸出3.3V,只需要外接2X7R無極性陶瓷電容,價格太高)

4.串口:MAX3232(方便調試)

5.USB供電,輸出電壓5V

6.目前機架、電調、電池、電機和螺旋槳已買好,來張圖,比較大衆化:

 

上圖:

1PCB3D效果圖,測試版,先追求調通得出姿態角,後續改版會做大的調整:

 

第二部分:軟件

1.使用keiluvision4.1.0,工具鏈:RealViewMDK-ARM Version4.12

2.驅動:官方的MPU6050驅動inv_mpu.cinv_mpu_dmp_motion_driver.c

先看幾個圖,然後再說座標軸的設定和算法部分。

上圖:

1:系統初始化,順序從上到下依次是:初始化MPU、設置需要使用哪些傳感器、設置陀螺儀測量範圍(我設的是正負500/s)、設置加速度計測量範圍(我設的是正負4g)、配置fifo、設置採樣率、裝載DMP、設置陀螺儀軸向(比較重要)、使能DMP的一些玩意兒、設置DMPFIFO、自校準陀螺儀和加速度計、開啓DMP、開始姿態融合,見下圖:

 

2:由四元數求出的最終姿態角,其中Yaw爲航向角,表示機頭偏離正北方多少度,範

-180+180Pitch爲俯仰角,表示機頭正方向與水平線的夾角,範圍-90+90Roll爲翻滾角,表示機翼與水平線的夾角,範圍:-180+180。下圖爲機身水平,且機頭正北偏西37度左右的數據:

 

3:下圖爲機翼水平,機頭指向正北,且機頭向下25度的數據

 

4:下圖爲機頭指向正北,保持水平,且機翼的右翼向下傾斜23度的數據

 

5:看下歐拉角的奇異點,在奇異點處一個轉動狀態對應無窮多組自由度值,當物體轉到這些奇異點附近,便沒法求解。圖中當Pitch+90度時,機體的姿態便沒法控制,Roll的軸向發生了變化。如下圖:

 


第三部分:如何確定自己的軸向

首先,軸向的定義跟初始化四元數和最後結算的歐拉角有關,跟四元數更新算法無關,換句話說,不管你的軸向如何定義,姿態融合算法隨便用,但是初始化四元數的公式和最後結算歐拉角的公式要做適當的改變,這個後面算法中有說。加速度計也好,陀螺儀也好,磁力計也好,他們的軸向都要滿足右手定理,如下圖:

 

再附上一段註釋用於解釋如何定義合理的軸向,以及如何正確旋轉傳感器的軸向,解釋這麼多其實就是說定義好的軸向要滿足右手定理,如下圖:

 

下圖,旋轉前是[x y z],旋轉後就是[-y x z]

 下圖是如何確定旋轉角度的正方向,用右手握住座標軸,拇指指向軸向的正方向,四個指頭彎曲的方向就是旋轉角度的正方向,在初始化四元數時,計算出的歐拉角的正方向也要滿足這個條件:

 

我的程序使用的軸向如下圖所示,未作任何改變:

 


第四部分:算法

第一步是校準,加速度計和陀螺儀我用的是MPU9150內部自校準,磁力計的校準採用如下方法:見附件-磁力計校準

第二步是初始化四元數,常見的軸向定義是繞x軸旋轉是Roll,繞y軸旋轉是Pitch,繞z軸旋轉是Yaw,我的程序中也有這樣的定義,不過被我註釋掉了,這裏舉個另外一種軸向定義來對初始化四元數進行說明,方便比較,也是我目前正在用的軸定義。

下面我們來定義繞x軸旋轉是Pitch,繞y軸旋轉是Roll,繞z軸旋轉是Yaw,軸向的正方向如上圖一樣,不變。

先對加速度計和磁力計的數據進行處理,得到init_xx來供我們使用如下圖:

然後通過公式計算出初始化的RollPitchYaw,注意加負號保證旋轉角度的正方向,如下圖:

其中Yaw的正方向未必對,可以自己去驗證下,具體參考公式見附件-ST電子羅盤計算Yaw

然後由上面的歐拉角求出初始化四元數,這時要注意旋轉順序的不同,公式也不同,大部分旋轉順序是Z-Y-X,我的程序裏也用的這個順序,在這裏我們按Z-X-Y的順序來旋轉,並得出求四元數的公式以做比較,其旋轉矩陣:

q=qyaw*qpitch*qroll=

(cos(0.5*Yaw)+ksin(0.5*Yaw)) *(cos(0.5*Pitch)+isin(0.5* Pitch)) * (cos(0.5*Roll)+jsin(0.5* Roll))

得出初始化四元數計算公式如下圖所示:

其中ijk之間相乘的順序不能隨意變,在前的先計算,在後的後計算相乘的公式如下圖:

至此初始化四元數完成。

第三步就是使用AHRSUpdate算法了,用完以後再根據公式計算出歐拉角,此公式跟旋轉順序和旋轉使用的軸向有關,我們的旋轉順序是Z-X-Y,且繞ZYaw,繞XPitch,繞YRoll,推到過程如下圖:

首先得出3個方向餘旋矩陣:

下圖繞ZYaw

下圖繞Xpitch

下圖繞YRoll

然後按照我們的Z-X-Y順序求得C=Croll * Cpitch * Cyaw,如下圖:

 


將上圖的方向餘旋矩陣C與下圖的四元數姿態矩陣做對比,即可求出歐拉角,注意上圖的方向餘旋矩陣C是隨着我們對座標軸的定義變化而變化的,而下圖的四元數姿態矩陣是固定的:

 

最後一步就是求出歐拉角,公式如下圖:

 

以下是靜止時,剛上電時的數據:

 


以下是上電半個小時以後的數據:

 

可以看出正常的靜止狀態下,數據的波動範圍是不超過1度的,也不會有漂移。具體效果還需要上機架飛起來以後再做調整。


最後總結一下:

我的代碼中,0°<yaw<360°, -90°<pitch<+90°,-180°<roll<180°,並且我定義:Yaw北偏西爲正,pitch往上爲正,roll“右翼下沉爲正。傳感器座標軸:繞y旋轉是 roll,繞x旋轉爲pitch,繞z旋轉爲yaw。代碼裏只有姿態更新,72Mhz主頻下更新頻率在350-400Hz108Mhz下可以達到400-500Hz,目前我採用定時器定時,代碼跑108Mhz,使姿態更新頻率控制在400Hz

注意跑108Mhz時,需要修改延遲函數和串口函數,適當增加一下延遲函數的數值避免I2C通信失敗,修改串口函數是爲了避免108Mhz下串口亂碼問題,具體修改方式參考論壇頂置帖子http://bbs.21ic.com/iclist-182-1.html

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