淺析IMU代碼

IMU的代碼的引自https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/imumargalgorithm30042010sohm/IMU.zip

複製代碼
 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 //----------------------------------------------------------------------------------------------------
22 // Header files
23 
24 #include "IMU.h"
25 #include <math.h>
26 
27 //----------------------------------------------------------------------------------------------------
28 // Definitions
29 
30 #define Kp 2.0f            // proportional gain governs rate of convergence to accelerometer/magnetometer
31 #define Ki 0.005f        // integral gain governs rate of convergence of gyroscope biases
32 #define halfT 0.5f        // half the sample period
33 
34 //---------------------------------------------------------------------------------------------------
35 // Variable definitions
36 
37 float q0 = 1, q1 = 0, q2 = 0, q3 = 0;    // quaternion elements representing the estimated orientation
38 float exInt = 0, eyInt = 0, ezInt = 0;    // scaled integral error
39 
40 //====================================================================================================
41 // Function
42 //====================================================================================================
43 
44 void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az) {
45     float norm;
46     float vx, vy, vz;
47     float ex, ey, ez;         
48     
49     // normalise the measurements
50     norm = sqrt(ax*ax + ay*ay + az*az);       
51     ax = ax / norm;
52     ay = ay / norm;
53     az = az / norm;      
54     
55     // estimated direction of gravity
56     vx = 2*(q1*q3 - q0*q2);
57     vy = 2*(q0*q1 + q2*q3);
58     vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;
59     
60     // error is sum of cross product between reference direction of field and direction measured by sensor
61     ex = (ay*vz - az*vy);
62     ey = (az*vx - ax*vz);
63     ez = (ax*vy - ay*vx);
64     
65     // integral error scaled integral gain
66     exInt = exInt + ex*Ki;
67     eyInt = eyInt + ey*Ki;
68     ezInt = ezInt + ez*Ki;
69     
70     // adjusted gyroscope measurements
71     gx = gx + Kp*ex + exInt;
72     gy = gy + Kp*ey + eyInt;
73     gz = gz + Kp*ez + ezInt;
74     
75     // integrate quaternion rate and normalise
76     q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;
77     q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;
78     q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;
79     q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;  
80     
81     // normalise quaternion
82     norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
83     q0 = q0 / norm;
84     q1 = q1 / norm;
85     q2 = q2 / norm;
86     q3 = q3 / norm;
87 }
88 
89 //====================================================================================================
90 // END OF CODE
91 //====================================================================================================
複製代碼

 

複製代碼
 1 //=====================================================================================================
 2 // IMU.h
 3 // S.O.H. Madgwick
 4 // 25th September 2010
 5 //=====================================================================================================
 6 //
 7 // See IMU.c file for description.
 8 // 
 9 //=====================================================================================================
10 #ifndef IMU_h
11 #define IMU_h
12 
13 //----------------------------------------------------------------------------------------------------
14 // Variable declaration
15 
16 extern float q0, q1, q2, q3;    // quaternion elements representing the estimated orientation
17 
18 //---------------------------------------------------------------------------------------------------
19 // Function declaration
20 
21 void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az);
22 
23 #endif
24 //=====================================================================================================
25 // End of file
26 //=====================================================================================================
複製代碼

 

淺析

將加速度的原始數據,歸一化,得到單位加速度  
 // normalise the measurements
   norm = sqrt(ax*ax + ay*ay + az*az);       
   ax = ax / norm;
   ay = ay / norm;
   az = az / norm; 

參考https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation

 

引用AN5022 Quaternion Algebra.pdf

 

或者

出自《整合 GNSS 與 INS 量測資訊的地平面運動軌跡估測》鄭  期  元的論文

下面把四元數換算成方向餘弦中的第三行的三個元素。剛好vx,vy,vz 其實就是上一次的歐拉角(四元數)的機體座標參考系換算出來的重力的單位向量【沒弄懂的可以參考上面的資料】。

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

 

 

複製代碼
ax、ay、az是機體座標參照系上,加速度計測出來的重力向量,也就是實際測出來的重力向量。
ax、ay、az是測量得到的重力向量,
vx、vy、vz是陀螺積分後的姿態來推算出的重力向量,它們都是機體座標參照系上的重力向量。
那它們之間的誤差向量,就是陀螺積分後的姿態和加計測出來的姿態之間的誤差。
向量間的誤差,可以用向量叉積(也叫向量外積、叉乘)來表示,exyz就是兩個重力向量的叉積。
這個叉積向量仍舊是位於機體座標系上的,而陀螺積分誤差也是在機體座標系,而且叉積的大小與陀螺積分誤差成正比,正好拿來糾正陀螺。
(你可以自己拿東西想象一下)由於陀螺是對機體直接積分,所以對陀螺的糾正量會直接體現在對機體座標系的糾正。
// error is sum of cross product between reference direction of field and direction measured by sensor ex = (ay*vz - az*vy); ey = (az*vx - ax*vz); ez = (ax*vy - ay*vx);
複製代碼

 

 可以參考的文章

 http://blog.csdn.net/qq_21842557/article/details/50993809

http://www.anobbs.com/forum.php?mod=viewthread&tid=1185

發佈了25 篇原創文章 · 獲贊 47 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章