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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9220|回復: 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 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 伊人精品在线 | 一级特黄网站 | 人人cao| 亚洲精品视频免费看 | 视频一区二区中文字幕日韩 | 日韩成人免费视频 | 国产盗摄视频 | 一区二区三区国产 | 国产精品a久久久久 | 欧美综合一区 | 欧美在线高清 | 久久久久久国模大尺度人体 | 粉嫩高清一区二区三区 | 一本一道久久a久久精品综合蜜臀 | 欧美一级二级在线观看 | 午夜视频一区二区 | 九九久久精品 | 精品国产一级 | 久久久久久免费精品一区二区三区 | av手机在线免费观看 | 国产成人福利 | 九九热在线免费视频 | 欧美一区二区三区精品 | 国产欧美一区二区三区在线看蜜臀 | 国产精品国产精品国产专区不蜜 | 成人在线视频观看 | 日韩一级 | 男人的天堂avav | 久久成人免费 | 97超级碰碰 | 免费的色网站 | 亚洲a人| 亚洲精品福利视频 | 亚洲91精品 | 三级高清 | 国产精品高清一区二区三区 | 久久99精品国产99久久6男男 | 精品一区二区久久久久久久网站 | 成人在线视频网 | 成人一区二区三区视频 | 国产精品国产成人国产三级 |