我找了很久終于找到了MPU6050芯片四元數姿態更新方法(公示版)c語言程序
0.png (43.36 KB, 下載次數: 148)
下載附件
2017-8-7 23:40 上傳
單片機源程序如下:
- /*
- 1主函數在最后面
- 2作者:黑市,黑視,智涅
- 3四元數更新用的是一階算法,還有二階三階甚至全階,階數越高精度越好,不過沒多大必要。
- 一階二階這些簡化算法就是用簡單的值取代了一些三角函數而已
- 4詳細書籍可以看《捷聯式慣性導航原理》,袁信著。我以前看了這本書PDF版好久了,估計一半還沒能吃透。
- 5關于利用加速度計來修正姿態,大家貌似都是做飛機的,飛機上的加速度計的情況跟我做的東西差別太大,
- 應該不能直接引用我那一套,大家還是引用網上例如權重法來進行修正吧!用羅盤修正姿態就更不用說了~
- */
- #define EulerAngle_Type float //定義類型
- #define Quaternion_Type float
- #define Acc_Type int
- #define Gyro_Type int
- #define Euler_Martix_Type float
- struct EulerAngle //歐拉角結構體
- {
- EulerAngle_Type Roll, Pitch, Yaw;
- }
- struct Quaternion //四元數結構體
- {
- Quaternion_Type q0, q1, q2, q3;
- }
- struct Acc //加速度值結構體
- {
- Acc_Type x, y, z;
- }
- struct Gyro //陀螺儀值結構體
- {
- Gyro_Type x, y, z;
- }
- struct Euler_Martix //歐拉(姿態)矩陣結構體
- {
- Euler_Martix_Type T11,T12,T13, T21,T22,T23, T31,T32,T33;
- }
- Quaternion Normalize(Quaternion e) //四元數歸一化
- {
- Quaternion_Type s = (Quaternion_Type)Math.Sqrt(e.q0 * e.q0 + e.q1 * e.q1 + e.q2 * e.q2 + e.q3 * e.q3);
- e.q0 /= s;
- e.q1 /= s;
- e.q2 /= s;
- e.q3 /= s;
- return e;
- }
- Quaternion Multiply_L1(Acc lacc) //一階算法
- {
- Quaternion Q_result;
- Q_result.q0 = BQ.q0 - BQ.q1 * lacc.x / 2 - BQ.q2 * lacc.y / 2 - BQ.q3 * lacc.z / 2;
- Q_result.q1 = BQ.q1 + BQ.q0 * lacc.x / 2 + BQ.q2 * lacc.z / 2 - BQ.q3 * lacc.y / 2;
- Q_result.q2 = BQ.q2 + BQ.q0 * lacc.y / 2 - BQ.q1 * lacc.z / 2 + BQ.q3 * lacc.x / 2;
- Q_result.q3 = BQ.q3 + BQ.q0 * lacc.z / 2 + BQ.q1 * lacc.y / 2 - BQ.q2 * lacc.x / 2;
- Q_result = Quaternion_Normalize(Q_result);
- return Q_result;
- }
- Euler_Martix Q_to_EM(Quaternion e) //把四元數變換成歐拉角(姿態)矩陣T
- {
- Euler_Martix result;
- Euler_Martix_Type q00,q01,q02,q03,q11,q12,q13,q22,q23,q33;
- q00=e.q0*e.q0;
- q01=e.q0*e.q1;
- q02=e.q0*e.q2;
- q03=e.q0*e.q3;
- q11=e.q1*e.q1;
- q12=e.q1*e.q2;
- q13=e.q1*e.q3;
- q22=e.q2*e.q2;
- q23=e.q2*e.q3;
- q33=e.q3*e.q3;
- result.T11=q00+q11-q22-q33;
- result.T12=2*(q12+q03);
- result.T13=2*(q13-q02);
- result.T21=2*(q12-q03);
- result.T22=q22-q33+q00-q11;
- result.T23=2*(q23+q01);
- result.T31=2*(q13+q02);
- result.T32=2*(q23-q01);
- result.T33=q33-q22-q11+q00;
- return result;
- }
- Quaternion Ea_to_Qu(EulerAngle ea) //把歐拉角變換成四元數 后來不用這個方法了,用矩陣那個了
- {
- Quaternion result;
- Quaternion_Type CosY = Math.Cos(ea.Yaw * .5);
- Quaternion_Type SinY = Math.Sin(ea.Yaw * .5);
- Quaternion_Type CosP = Math.Cos(ea.Pitch * .5f);
- Quaternion_Type SinP = Math.Sin(ea.Pitch * .5);
- Quaternion_Type CosR = Math.Cos(ea.Roll * .5f);
- Quaternion_Type SinR = Math.Sin(ea.Roll * .5f);
-
- result.q0 = CosY * CosP * CosR + SinY * SinP * SinR;
- result.q1 = CosY * CosP * SinR - SinY * SinP * CosR;
- result.q2 = CosY * SinP * CosR + SinY * CosP * SinR;
- result.q3 = SinY * CosP * CosR - CosY * SinP * SinR;
- return result;
- }
- Acc coordinate_body_to_inertia(Euler_Martix EM,Acc lacc) //將體坐標加速度變換到慣性坐標
- {
- //做飛機不需要,省略
- }
- EulerAngle EM_to_EU(Euler_Martix lem) //從姿態矩陣中提取姿態角
- {
- EulerAngle result;
- result.Yaw = Math.Atan2(lem.T12, lem.T11);
- result.Pitch = -Math.Asin(lem.T13);
- result.Roll = Math.Atan2(lem.T23, lem.T33);
- return result;
- }
- void main()
- {
- Quaternion BQ;//定義姿態四元素
- Euler_Martix BEM;//定義歐拉矩陣
- EulerAngle BEA;//定義歐拉角
-
- BQ.q0=1;//初始化四元數
- BQ.q1=BQ.q2=BQ.q3=0;//初始化四元數
- char gx,gy,gz;//定義陀螺儀三個軸,用來裝值
-
- while(1)//要不斷更新,所以弄個循環,你要知道你的更新速率,才能轉化下面的一些參數。
- //根據轉動的不可交互性,更新速率越快越好,看書!
- {
- gx=25;
- gy=14;
- gz=4;
- //以上為讀取陀螺儀的三個值,我隨便賦值作為例子哈
-
- EulerAngle lea;//定義歐拉小轉角,每次更新的小轉角,下面就用到
-
- lea.Yaw = ((float)gx / 62200 * Math.PI);
- lea.Pitch = ((float)gy / 62200 * Math.PI);
- lea.Roll = ((float)gz/ 62200 * Math.PI);
- //把陀螺儀的三個值轉化為角度值(根據自己的采樣率、精度等參數轉化),不懂請請自行查資料搞懂
-
- BQ = Multiply_L1(BQ, lea);//更新姿態四元素,由舊四元數和小轉角更新得到新四元數
-
- BEM = Q_to_EM(BQ);//將更新完的姿態四元素轉成歐拉矩陣
- BEA = EM_to_EU(BEM);//從歐拉矩陣中提取歐拉角
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
四元數.zip
(2.1 KB, 下載次數: 190)
2017-8-7 22:49 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|