久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9139|回復: 5
打印 上一主題 下一主題
收起左側

STM32代碼MPU6050的姿態結算,摘用cleanfight的姿態解算代碼

  [復制鏈接]
跳轉到指定樓層
樓主
STM32代碼MPU6050的姿態結算,摘用cleanfight的姿態解算代碼,,,效果可以

單片機源程序如下:
  1. #include "imu.h"
  2. #include "imu.h"
  3. #include  "math.h"
  4. #include "flycontro.h"

  5. #define SPIN_RATE_LIMIT 20

  6. #ifndef sq
  7. #define sq(x) ((x)*(x))
  8. #endif
  9. #define sin_approx(x)   sinf(x)
  10. #define cos_approx(x)   cosf(x)
  11. #define atan2_approx(y,x)   atan2f(y,x)
  12. #define acos_approx(x)      acosf(x)
  13. #define tan_approx(x)       tanf(x)
  14. // Use floating point M_PI instead explicitly.
  15. #define M_PIf       3.14159265358979323846f




  16. Attitudat_Struct Accel,Gyro,Angle; //MPU姿態數據
  17. Attitudat_Struct Gyro_Offset;  //陀螺儀零漂數據
  18. short Accel_X,Accel_Y,Accel_Z,Gyro_X,Gyro_Y,Gyro_Z;
  19. void MPU_GetAngleDat(void)
  20. {
  21.   int  Accel_Xtemp,Accel_Ytemp,Accel_Ztemp,Accel_Xtempout,Accel_Ytempout,Accel_Ztempout;
  22. /// static float Yawerr=0,lastYawerr=0;
  23.   MPU_Get_Accelerometer(&Accel_X,&Accel_Y,&Accel_Z);        //得到加速度傳感器數據
  24.   MPU_Get_Gyroscope(&Gyro_X,&Gyro_Y,&Gyro_Z);        //得到陀螺儀數據
  25.   
  26.         Accel_Xtemp  = Accel_X;
  27.         Accel_Ytemp  = Accel_Y;
  28.         Accel_Ztemp  = Accel_Z;

  29.   Prepare_Data(&Accel_Xtemp,&Accel_Ytemp,&Accel_Ztemp,&Accel_Xtempout ,&Accel_Ytempout,&Accel_Ztempout);

  30.         Accel.X = Accel_Xtempout;     ////8192
  31.         Accel.Y = Accel_Ytempout;
  32.   Accel.Z = Accel_Ztempout;        
  33.        
  34.         Gyro.X = (Gyro_X - Gyro_Offset.X) ;
  35.         Gyro.Y = (Gyro_Y - Gyro_Offset.Y) ;
  36.         Gyro.Z = (Gyro_Z - Gyro_Offset.Z) ;

  37. }


  38. u8 Gyro_calibration(void)
  39. {
  40. //u16 i;
  41. //short  Gyro_X,Gyro_Y,Gyro_Z;
  42. static long int GyroofsetX=0,GyroofsetY=0,GyroofsetZ=0;
  43. static u16 i= 0;
  44. //        for(i=0;i<1000;i++)
  45. //         {
  46. // MPU_Get_Gyroscope(&Gyro_X,&Gyro_Y,&Gyro_Z);        //得到陀螺儀數據
  47.     GyroofsetX+=Gyro_X;
  48.                 GyroofsetY+=Gyro_Y;
  49.                 GyroofsetZ+=Gyro_Z;
  50.           i++;
  51. //                delay_ms(5);
  52. //   }
  53. //       
  54.         if(i==1000)
  55.         {
  56.    i=0;
  57.    Gyro_Offset.X = GyroofsetX/1000;
  58.    Gyro_Offset.Y = GyroofsetY/1000;
  59.    Gyro_Offset.Z = GyroofsetZ/1000;
  60.          GyroofsetX=GyroofsetY=GyroofsetZ=0;
  61.                 return 1;
  62.         }

  63.         return 0;
  64. }


  65. void Prepare_Data(int *accx,int *accy,int *accz,int *accoutx,int *accouty,int *accoutz)
  66. {  
  67.         static uint8_t         filter_cnt=0;
  68.         static int16_t        ACC_X_BUF[FILTER_NUM],ACC_Y_BUF[FILTER_NUM],ACC_Z_BUF[FILTER_NUM];
  69.         int32_t temp1=0,temp2=0,temp3=0;
  70.         uint8_t i;       
  71.         ACC_X_BUF[filter_cnt] = *accx;
  72.         ACC_Y_BUF[filter_cnt] = *accy;
  73.         ACC_Z_BUF[filter_cnt] = *accz;
  74.         for(i=0;i<FILTER_NUM;i++)//滑動平滑濾波
  75.         {
  76.                 temp1 += ACC_X_BUF[i];
  77.                 temp2 += ACC_Y_BUF[i];
  78.                 temp3 += ACC_Z_BUF[i];
  79.         }
  80.         *accoutx = temp1 / FILTER_NUM;
  81.         *accouty = temp2 / FILTER_NUM;
  82.         *accoutz = temp3 / FILTER_NUM;
  83.         filter_cnt++;
  84.         if(filter_cnt==FILTER_NUM)        filter_cnt=0;

  85. }












  86. float q0 = 1.0f, q1 = 0.0f, q2 = 0.0f, q3 = 0.0f;    // quaternion of sensor frame relative to earth frame
  87. static float rMat[3][3];

  88. float dcmKiGain = 0.005;
  89. float dcmKpGain = 2.0;

  90. static float invSqrt(float x)
  91. {
  92.     return 1.0f / sqrtf(x);
  93. }

  94. void imuMahonyAHRSupdate(float dt, float gx, float gy, float gz,
  95.                                                                                                         bool useAcc, float ax, float ay, float az,
  96.                                                                                                         bool useMag, float mx, float my, float mz,
  97.                                                                                                         bool useYaw, float yawError)
  98. {
  99.     static float integralFBx = 0.0f,  integralFBy = 0.0f, integralFBz = 0.0f;    // integral error terms scaled by Ki
  100.     float recipNorm;
  101.     float hx, hy, bx;
  102.     float ex = 0, ey = 0, ez = 0;
  103.     float qa, qb, qc;
  104.    
  105.     // Calculate general spin rate (rad/s)
  106.     float spin_rate = sqrtf(sq(gx) + sq(gy) + sq(gz));
  107.           float ez_ef;
  108.     // Use raw heading error (from GPS or whatever else)
  109.     if (useYaw) {
  110.         while (yawError >  M_PIf) yawError -= (2.0f * M_PIf);
  111.         while (yawError < -M_PIf) yawError += (2.0f * M_PIf);

  112.         ez += sin_approx(yawError / 2.0f);
  113.     }

  114.     // Use measured magnetic field vector  
  115.     recipNorm = sq(mx) + sq(my) + sq(mz);
  116.     if (useMag && recipNorm > 0.01f)
  117.                         {
  118.         // Normalise magnetometer measurement ?????????
  119.         recipNorm = invSqrt(recipNorm);
  120.         mx *= recipNorm;
  121.         my *= recipNorm;
  122.         mz *= recipNorm;
  123.                                 // For magnetometer correction we make an assumption that magnetic field is perpendicular to gravity (ignore Z-component in EF).
  124.                                 // This way magnetic field will only affect heading and wont mess roll/pitch angles

  125.                                 // (hx; hy; 0) - measured mag field vector in EF (assuming Z-component is zero)
  126.                                 // (bx; 0; 0) - reference mag field vector heading due North in EF (assuming Z-component is zero)
  127.         hx = rMat[0][0] * mx + rMat[0][1] * my + rMat[0][2] * mz;
  128.         hy = rMat[1][0] * mx + rMat[1][1] * my + rMat[1][2] * mz;
  129.         bx = sqrtf(hx * hx + hy * hy);

  130.         // magnetometer error is cross product between estimated magnetic north and measured magnetic north (calculated in EF)
  131.         ez_ef = -(hy * bx);

  132.         // Rotate mag error vector back to BF and accumulate
  133.         ex -= rMat[2][0] * ez_ef;
  134.         ey -= rMat[2][1] * ez_ef;
  135.         ez += rMat[2][2] * ez_ef;
  136.     }

  137.     // Use measured acceleration vector ?????????
  138.     recipNorm = sq(ax) + sq(ay) + sq(az);
  139.     if (useAcc && recipNorm > 0.01f)
  140.                         {
  141.         // Normalise accelerometer measurement ?????????
  142.         recipNorm = invSqrt(recipNorm);
  143.         ax *= recipNorm;
  144.         ay *= recipNorm;
  145.         az *= recipNorm;

  146.         // Error is sum of cross product between estimated direction and measured direction of gravity
  147.         ex += (ay * rMat[2][2] - az * rMat[2][1]);
  148.         ey += (az * rMat[2][0] - ax * rMat[2][2]);
  149.         ez += (ax * rMat[2][1] - ay * rMat[2][0]);
  150.     }

  151.     // Compute and apply integral feedback if enabled
  152.     if(dcmKiGain > 0.0f) {   //imuRuntimeConfig->dcm_ki
  153.         // Stop integrating if spinning beyond the certain limit????,??????????
  154.         if (spin_rate < DEGREES_TO_RADIANS(SPIN_RATE_LIMIT)) {
  155.        //     float dcmKiGain = dcm_ki;
  156.             integralFBx += dcmKiGain * ex * dt;    // integral error scaled by Ki
  157.             integralFBy += dcmKiGain * ey * dt;
  158.             integralFBz += dcmKiGain * ez * dt;
  159.         }
  160.     }
  161.     else {
  162.         integralFBx = 0.0f;    // prevent integral windup
  163.         integralFBy = 0.0f;
  164.         integralFBz = 0.0f;
  165.         }

  166.     // Calculate kP gain. If we are acquiring initial attitude (not armed and within 20 sec from powerup) scale the kP to converge faster
  167.     //   dcmKpGain =  dcm_kp ;//* imuGetPGainScaleFactor();

  168.     // Apply proportional and integral feedback??????
  169.     gx += dcmKpGain * ex + integralFBx;
  170.     gy += dcmKpGain * ey + integralFBy;
  171.     gz += dcmKpGain * ez + integralFBz;

  172.     // Integrate rate of change of quaternion??????
  173.     gx *= (0.5f * dt);
  174.     gy *= (0.5f * dt);
  175.     gz *= (0.5f * dt);

  176.     qa = q0;
  177.     qb = q1;
  178.     qc = q2;
  179.     q0 += (-qb * gx - qc * gy - q3 * gz);
  180.     q1 += (qa * gx + qc * gz - q3 * gy);
  181.     q2 += (qa * gy - qb * gz + q3 * gx);
  182.     q3 += (qa * gz + qb * gy - qc * gx);
  183.     // Normalise quaternion
  184.     recipNorm = invSqrt(sq(q0) + sq(q1) + sq(q2) + sq(q3));
  185.     q0 *= recipNorm;
  186.     q1 *= recipNorm;
  187.     q2 *= recipNorm;
  188.     q3 *= recipNorm;

  189.     // Pre-compute rotation matrix from quaternion
  190.     imuComputeRotationMatrix();
  191. #if 0         
  192. //                 Angle.Y = asin(-2 * q1 * q3  + 2 * q0* q2)* 57.3 ; // pitch  
  193. //          Angle.X = atan2( 2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll
  194. //          Angle.Z = atan2(2 * q1 * q2  + 2 * q0 * q3, -2 * q2*q2 - 2 * q3* q3 + 1)* 57.3; // yaw
  195. #else         
  196.          imuUpdateEulerAngles(&Angle.X,&Angle.Y,&Angle.Z);
  197. #endif

  198. }

  199. void imuComputeRotationMatrix(void)
  200. {
  201.     float q1q1 = sq(q1);
  202.     float q2q2 = sq(q2);
  203.     float q3q3 = sq(q3);

  204.     float q0q1 = q0 * q1;
  205.     float q0q2 = q0 * q2;
  206. ……………………

  207. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
imu.zip (3.66 KB, 下載次數: 176)


評分

參與人數 2黑幣 +55 收起 理由
fanwangxing + 5
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:388895 發表于 2018-8-22 14:33 | 只看該作者
過來看看
回復

使用道具 舉報

板凳
ID:206977 發表于 2019-10-4 21:45 | 只看該作者
謝謝!非常有參考價值
回復

使用道具 舉報

地板
ID:618028 發表于 2019-10-6 11:25 | 只看該作者
這個資料很不錯,正需要
回復

使用道具 舉報

5#
ID:1045035 發表于 2022-9-17 17:09 | 只看該作者
你這怎么用啊,一些參數都沒寫說明
回復

使用道具 舉報

6#
ID:1041367 發表于 2022-9-19 15:35 | 只看該作者
資料很不錯,正好需要,感謝
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品免费一区二区三区 | 亚洲一区二区三区在线视频 | 欧美黄色精品 | 免费黄色av网站 | 欧美成人高清 | 午夜视频免费在线观看 | 亚洲欧美国产毛片在线 | 亚洲成人免费视频 | 国产精品免费一区二区三区四区 | 欧美一区二区在线 | 日韩国产中文字幕 | 国产一区二区三区四区 | 日本久久网 | 免费在线a视频 | 99婷婷 | 天天操夜夜操 | 一区二区精品视频 | 狠狠夜夜 | 亚洲国产中文字幕 | 亚洲一区二区三区福利 | 亚洲日本免费 | 日日干日日操 | 日韩一区二区在线视频 | 国产一级在线观看 | 成人在线观看免费视频 | 久久精品99国产精品 | 久久久久国产精品免费免费搜索 | 日日日操 | 日韩一区精品 | 国产免费一区二区 | 97超碰免费 | 亚洲影视在线 | 91视视频在线观看入口直接观看 | 国产精品综合一区二区 | 久久久久久91香蕉国产 | 亚洲欧美中文字幕 | 亚洲综合二区 | 亚洲一区二区在线电影 | 中文字幕av免费 | 在线观看免费国产 | 99视频免费在线 |