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

標題: STM32代碼MPU6050的姿態結算,摘用cleanfight的姿態解算代碼 [打印本頁]

作者: chrain5    時間: 2018-1-20 10:53
標題: 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)



作者: home8976    時間: 2018-8-22 14:33
過來看看
作者: lyjpla    時間: 2019-10-4 21:45
謝謝!非常有參考價值

作者: 楓葉-嵌入式    時間: 2019-10-6 11:25
這個資料很不錯,正需要
作者: 18519187648    時間: 2022-9-17 17:09
你這怎么用啊,一些參數都沒寫說明
作者: lm7298    時間: 2022-9-19 15:35
資料很不錯,正好需要,感謝




歡迎光臨 (http://m.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 99cao| 日日骚av| 欧美bbb| 亚洲精品www久久久久久广东 | 激情五月综合网 | 国产成人免费在线视频 | 中文字幕高清在线 | 在线视频黄 | 69av在线播放 | 激情六月天 | 天堂av网站 | 亚洲人在线观看 | 国产精品美女久久久久久久久 | 日韩精品在线视频 | 九九精品在线视频 | 午夜在线观看视频网站 | 国产乱码一区二区 | 日韩免费在线视频 | 免费视频国产 | 97精品国产97久久久久久免费 | 亚洲综合激情网 | 亚洲成年人在线观看 | 久久综合五月天 | 中文字幕在线观看日韩 | 亚洲一级片 | 99视频在线精品免费观看2 | 免费国产视频 | 四川一级毛毛片 | 成人精品免费 | 亚洲成年人| 欧美亚洲一区 | 国产精品福利在线观看 | 黄色片免费在线观看 | 成人免费看片39 | 国产视频一区二区在线 | 99精品网站 | 天天摸天天操 | 亚洲欧洲色 | 亚洲精品1| 成年免费视频黄网站在线观看 | 欧美天堂在线 |