捷聯慣導算法心得

因爲感覺寫的太好了,所以就轉了!

詳細可以參考原來的帖子:http://www.amobbs.com/thread-5492189-1-1.html

---------------------------------------------------------------------------------------------------------------------------------

1、四個概念:“地理”座標系、“機體”座標系、他們之間換算公式、換算公式用的係數。

地理座標系:東、北、天,以下簡稱地理。在這個座標系裏有重力永遠是(0,0,1g),地磁永遠是(0,1,x)(地磁的垂直不關心)兩個三維向量。
機體座標系:以下簡稱機體,上面有陀螺、加計、電子羅盤傳感器,三個三維向量。
換算公式:以下簡稱公式,公式就是描述機體姿態的表達方法,一般都是用以地理爲基準,從地理換算到機體的公式,有四元數、歐拉角、方向餘弦矩陣。
換算公式的係數:以下簡稱係數,四元數的q0123、歐拉角的ROLL/PITCH/YAW、餘弦矩陣的9個數。係數就是描述機體姿態的表達方法的具體數值。

姿態,其實就是公式+係數的組合,一般經常用人容易理解的公式“歐拉角”表示,係數就是橫滾xx度俯仰xx度航向xx度。

2、五個數據源:重力、地磁、陀螺、加計、電子羅盤,前兩個來自地理,後三個來自機體

3、陀螺向量:基於機體,也在機體上積分,因爲地理上無參考數據源,所以很獨立,直接在公式的老係數上積分,得到新系數。
狹義上的捷聯慣導算法,就是指這個陀螺積分公式,也分爲歐拉角、方向餘弦矩陣、四元數,他們的積分算法有增量法、數值積分法(X階龍格-庫塔)等等

4、加計向量、重力向量:加計基於機體,重力基於地理,重力向量(0,0,1g)用公式換算到機體,與機體的加計向量算出誤差。理論上應該沒有誤差,這誤差逆向思維一下,其實就是換算公式的係數誤差。所以這誤差可用於糾正公式的係數(橫滾、俯仰),也就是姿態。

5、電子羅盤向量、地磁向量:同上,只不過要砍掉地理上的垂直向量,因爲無用。只留下地理水平面上的向量。誤差可以用來糾正公式的係數(航向)。

6、就這樣,係數不停地被陀螺積分更新,也不停地被誤差修正,它和公式所代表的姿態也在不斷更新。
如果積分和修正用四元數算法(因爲運算量較少、無奇點誤差),最後用歐拉角輸出控制PID(因爲角度比較直觀),那就需要有個四元數係數到歐拉角係數的轉換。常用的三種公式,它們之間都有轉換算法。

再搞個直白一點的例子:
機體好似一條船,地理就是那地圖,姿態就是航向(船頭在地圖上的方位),重力和地磁是地圖上的燈塔,陀螺/積分公式是舵手,加計和電子羅盤是瞭望手。
舵手負責估計和把穩航向,他相信自己,本來船向北開的,就一定會一直往北開,覺得轉了90度彎,那就會往東開。
當然如果舵手很牛逼,也許能估計很準確,維持很長時間。不過只信任舵手,肯定會迷路,所以一般都有地圖和瞭望手來觀察誤差。
瞭望手根據地圖燈塔方位和船的當前航向,算出燈塔理論上應該在船的X方位。然而看到實際燈塔在船的Y方位,那肯定船的當前航向有偏差了,偏差就是ERR=X-Y。
舵手收到瞭望手給的ERR報告,覺得可靠,那就聽個90%*ERR,覺得天氣不好、地圖誤差大,那就聽個10%*ERR,根據這個來糾正估算航向。。



------------------------------------------------------
來點乾貨,注意以下的歐拉角都是這樣的順序:先航向-再俯仰-然後橫滾
公式截圖來自:袁信、鄭鍔的《捷聯式慣性導航原理》,鄧正隆的《慣性技術》。
--------------------------------------------------
根據加計計算初始歐拉角
這個無論歐拉角算法還是四元數算法還是方向餘弦矩陣都需要,因爲加計和電子羅盤給出歐拉角的描述方式比較方便。
imu.euler.x = atan2(imu.accel.y, imu.accel.z);
imu.euler.y = -asin(imu.accel.x / ACCEL_1G);
ACCEL_1G 爲9.81米/秒^2,accel.xyz的都爲這個單位,算出來的euler.xyz單位是弧度
航向imu.euler.z可以用電子羅盤計算
--------------------------------------------------
歐拉角微分方程
如果用歐拉角算法,那麼這個公式就夠了,不需要來回轉換。

矩陣上到下三個角度(希臘字母)是roll pitch和yaw,公式最左邊的上面帶點的三個是本次更新後的角度,不帶點的是上個更新週期算出來的角度。
Wx,y,z是roll pitch和yaw方向的三個陀螺在這個週期轉動過的角度,單位爲弧度,計算爲間隔時間T*陀螺角速度,比如0.02秒*0.01弧度/秒=0.0002弧度.


--------------------------------------------------
以下是四元數
--------------------------------------------------
四元數初始化
q0-3爲四元數四個值,用最上面公式根據加計計算出來的歐拉角來初始化

--------------------------------------------------
四元數微分方程
四元數更新算法,一階龍庫法,同樣4個量(入、P1-3)也爲四元數的四個值,即上面的q0-3。
Wx,y,z是三個陀螺的這個週期的角速度,比如歐拉角微分方程中的0.01弧度/秒,T爲更新週期,比如上面的0.02秒。

再來一張,另外一本書上的,仔細看和上面是一樣的delta角度,就是上面的角速度*週期,單位爲弧度

--------------------------------------------------
四元數微分方程更新後的規範化
每個週期更新完四元數,需要對四元數做規範化處理。因爲四元數本來就定義爲四維單位向量。
求q0-3的平方和,再開根號算出的向量長度length。然後每個q0-3除這個length。

--------------------------------------------------
四元數轉歐拉角公式
把四元數轉成了方向餘弦矩陣中的幾個元素,再用這幾個元素轉成了歐拉角
先從四元數q0-3轉成方向餘弦矩陣:

再從方向餘弦矩陣轉成歐拉角


代碼:
        //更新方向餘弦矩陣
        t11=q.q0*q.q0+q.q1*q.q1-q.q2*q.q2-q.q3*q.q3;
        t12=2.0*(q.q1*q.q2+q.q0*q.q3);
        t13=2.0*(q.q1*q.q3-q.q0*q.q2);
        t21=2.0*(q.q1*q.q2-q.q0*q.q3);
        t22=q.q0*q.q0-q.q1*q.q1+q.q2*q.q2-q.q3*q.q3;
        t23=2.0*(q.q2*q.q3+q.q0*q.q1);
        t31=2.0*(q.q1*q.q3+q.q0*q.q2);
        t32=2.0*(q.q2*q.q3-q.q0*q.q1);
        t33=q.q0*q.q0-q.q1*q.q1-q.q2*q.q2+q.q3*q.q3;
        //求出歐拉角
        imu.euler.roll = atan2(t23,t33);
        imu.euler.pitch = -asin(t13);
        imu.euler.yaw = atan2(t12,t11);
        if (imu.euler.yaw < 0){
                imu.euler.yaw += ToRad(360);
        }
----------------------------------------------------
以下代碼摘自網上,很巧妙,附上註釋,有四元數微分,有加計耦合。
沒電子羅盤,其實耦合原理也一樣。

  1. //=====================================================================================================
  2. // IMU.c
  3. // S.O.H. Madgwick
  4. // 25th September 2010
  5. //=====================================================================================================
  6. // Description:
  7. //
  8. // Quaternion implementation of the 'DCM filter' [Mayhony et al].
  9. //
  10. // User must define 'halfT' as the (sample period / 2), and the filter gains 'Kp' and 'Ki'.
  11. //
  12. // Global variables 'q0', 'q1', 'q2', 'q3' are the quaternion elements representing the estimated
  13. // orientation.  See my report for an overview of the use of quaternions in this application.
  14. //
  15. // User must call 'IMUupdate()' every sample period and parse calibrated gyroscope ('gx', 'gy', 'gz')
  16. // and accelerometer ('ax', 'ay', 'ay') data.  Gyroscope units are radians/second, accelerometer
  17. // units are irrelevant as the vector is normalised.
  18. //
  19. //=====================================================================================================

  20. //----------------------------------------------------------------------------------------------------
  21. // Header files

  22. #include "IMU.h"
  23. #include <math.h>

  24. //----------------------------------------------------------------------------------------------------
  25. // Definitions

  26. #define Kp 2.0f                        // proportional gain governs rate of convergence to accelerometer/magnetometer
  27. #define Ki 0.005f                // integral gain governs rate of convergence of gyroscope biases
  28. #define halfT 0.5f                // half the sample period

  29. //---------------------------------------------------------------------------------------------------
  30. // Variable definitions

  31. float q0 = 1, q1 = 0, q2 = 0, q3 = 0;        // quaternion elements representing the estimated orientation
  32. float exInt = 0, eyInt = 0, ezInt = 0;        // scaled integral error

  33. //====================================================================================================
  34. // Function
  35. //====================================================================================================

  36. void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az) {
  37.         float norm;
  38.         float vx, vy, vz;
  39.         float ex, ey, ez;         
  40.        
  41.         // normalise the measurements
  42.         norm = sqrt(ax*ax + ay*ay + az*az);      
  43.         ax = ax / norm;
  44.         ay = ay / norm;
  45.         az = az / norm;      
  46. 把加計的三維向量轉成單位向量。
  47.        

  48.         // estimated direction of gravity
  49.         vx = 2*(q1*q3 - q0*q2);
  50.         vy = 2*(q0*q1 + q2*q3);
  51.         vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;

  52. 這是把四元數換算成《方向餘弦矩陣》中的第三列的三個元素。
  53. 根據餘弦矩陣和歐拉角的定義,地理座標系的重力向量,轉到機體座標系,正好是這三個元素。
  54. 所以這裏的vx\y\z,其實就是當前的歐拉角(即四元數)的機體座標參照系上,換算出來的重力單位向量。


  55.         // error is sum of cross product between reference direction of field and direction measured by sensor
  56.         ex = (ay*vz - az*vy);
  57.         ey = (az*vx - ax*vz);
  58.         ez = (ax*vy - ay*vx);

  59. axyz是機體座標參照系上,加速度計測出來的重力向量,也就是實際測出來的重力向量。
  60. axyz是測量得到的重力向量,vxyz是陀螺積分後的姿態來推算出的重力向量,它們都是機體座標參照系上的重力向量。
  61. 那它們之間的誤差向量,就是陀螺積分後的姿態和加計測出來的姿態之間的誤差。
  62. 向量間的誤差,可以用向量叉積(也叫向量外積、叉乘)來表示,exyz就是兩個重力向量的叉積。
  63. 這個叉積向量仍舊是位於機體座標系上的,而陀螺積分誤差也是在機體座標系,而且叉積的大小與陀螺積分誤差成正比,正好拿來糾正陀螺。(你可以自己拿東西想象一下)由於陀螺是對機體直接積分,所以對陀螺的糾正量會直接體現在對機體座標系的糾正。



  64.         // integral error scaled integral gain
  65.         exInt = exInt + ex*Ki;
  66.         eyInt = eyInt + ey*Ki;
  67.         ezInt = ezInt + ez*Ki;

  68.         // adjusted gyroscope measurements
  69.         gx = gx + Kp*ex + exInt;
  70.         gy = gy + Kp*ey + eyInt;
  71.         gz = gz + Kp*ez + ezInt;

  72. 用叉積誤差來做PI修正陀螺零偏




  73.         // integrate quaternion rate and normalise
  74.         q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;
  75.         q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;
  76.         q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;
  77.         q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;  
  78. 四元數微分方程

  79.        

  80.         // normalise quaternion
  81.         norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
  82.         q0 = q0 / norm;
  83.         q1 = q1 / norm;
  84.         q2 = q2 / norm;
  85.         q3 = q3 / norm;
  86. 四元數規範化
  87. }

  88. //====================================================================================================
  89. // END OF CODE
  90. //====================================================================================================

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