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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6647|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

無人機加速計、氣壓計、GPS數(shù)據(jù)融合

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:85785 發(fā)表于 2019-8-9 22:54 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
在無人機控制當中,傳感器的參與那是必不可少的,特別是陀螺儀,最經(jīng)典的為MPU6050,目前大部分的無人機都是用的這個器件。熟悉MPU6050的都知道,這個傳感器可以輸出三軸加速計、三軸陀螺儀;加速計,顧名思義,直接測得物體的加速度。理論上  加速度積分得到速度,速度再積分得到位移:S = V0 * t + 1/2 * a * t ^ 2;V = v0 + a * t;按照此理想情況下:一個加速計直接積分算得速度跟位移就得了呀,為啥還要氣壓計、GPS呢。無人機為了定點懸停,需要計算XYZ三軸的速度跟位移,而加速度計有一個致命的缺點就是它積分會漂移,而且是漂移非常大的那種,如果直接用這個數(shù)據(jù)做控制,飛機都不知道要飄到哪里去了。所以才借助外部傳感器氣壓計、GPS修正加速計的漂移。加速計在無人機三軸位置速度計算時也有很大的優(yōu)點,就是其靈敏度相對很高,無人機稍微動一點加速計都可以感受的出來,然后把數(shù)據(jù)傳到無人機,無人機得以做相應(yīng)的調(diào)整。

數(shù)據(jù)融合

具體數(shù)據(jù)怎么融合呢?我們先來總結(jié)一下加速計、氣壓計、gps各自的優(yōu)缺點:加速計:優(yōu)點反應(yīng)速度快,缺點積分漂移嚴重。氣壓計GPS:優(yōu)點絕對位置比較平穩(wěn),缺點反應(yīng)速度比較慢。所以就有了互補濾波這個偉大的,簡單易懂的濾波算法。

以下為互補濾波代碼:

void Gps_Acc_Delay(void){ volatile uint8 i; for (i = 0; i < XY_VEL_HISTORY - 1; i++) {  x_vel_history = x_vel_history[i+1];  y_vel_history = y_vel_history[i+1];    x_pos_history = x_pos_history[i+1];  y_pos_history = y_pos_history[i+1]; } x_vel_history[XY_VEL_HISTORY - 1] = x_est[1]; y_vel_history[XY_VEL_HISTORY - 1] = y_est[1]; x_pos_history[XY_VEL_HISTORY - 1] = x_est[0]; y_pos_history[XY_VEL_HISTORY - 1] = y_est[0];}void ObservationOPT_Update(float pos_x,float vel_x,float pos_y,float vel_y)  //have data and update{ uint8 i; corrOPT_xpos = pos_x-x_est[0]; corrOPT_xvel = vel_x-x_est[1]; corrOPT_ypos = pos_y-y_est[0]; corrOPT_yvel = vel_y-y_est[1]; return;}void ObservationUpdate(int baro_disdance,int16 baro_vel){ uint8 i; corr_baro = (float)baro_disdance - z_est[0]; if (fly_status.HOLD_STATUS == HOLD_STOP) {  z_est[0] = baro_disdance;  z_est[1] = 0; } return;}void TimeUpdate(struct vertical_information *pAltitude,realacc* acc){ static float high_pass_zvel = 0; z_est[2]=acc->zz-z_bias; accel_filter_predict(INAV_T,z_est); z_est[0] += corr_baro * w_z_baro * INAV_T; z_bias -= corr_baro * 0.001f * INAV_T; z_est[1] += corr_baro * baro_vel_gain * INAV_T; high_pass_zvel = z_est[1]; pAltitude->altitude_hat=z_est[0]; pAltitude->velocity_hat=high_pass_zvel; ObservationOPT_Update(x_est[0],optflow.velx,y_est[0],optflow.vely); x_est[2]=acc->xx-x_bias; accel_filter_predict(INAV_TXY,x_est);  x_est[0] += corrGPS_xpos * x_pos_gain * INAV_TXY; x_est[1] += (corrOPT_xvel*0 + corrGPS_xpos * 1.0f + corrGPS_xvel * 0.2f) * x_vel_gain * INAV_TXY; y_est[2]=acc->yy-y_bias; accel_filter_predict(INAV_TXY,y_est);  y_est[0] += corrGPS_ypos * y_pos_gain * INAV_TXY; y_est[1] += (corrOPT_yvel*0 + corrGPS_ypos * 1.0f + corrGPS_yvel * 0.2f) * y_vel_gain * INAV_TXY; if (GPS_is_Good) {  if (corrGPS_xvel > -10 && corrGPS_xvel < 10)    x_bias -= (corrGPS_xpos*0.3f + corrGPS_xvel) * INAV_TXY * 0.1f;  if (corrGPS_yvel > -10 && corrGPS_yvel < 10)    y_bias -= (corrGPS_ypos*0.3f + corrGPS_yvel) * INAV_TXY * 0.1f; } else {  x_est[1] = Body_dat.vel_x;  y_est[1] = Body_dat.vel_y;  x_est[0] = Body_dat.pos_x1;  y_est[0] = Body_dat.pos_y1; } pos_vel_xy.posx = Body_dat.pos_x1; pos_vel_xy.posy = Body_dat.pos_y1; pos_vel_xy.velx = x_est[1]; pos_vel_xy.vely = y_est[1];}

以上代碼就是無人機里的互補濾波修正。如有不懂歡迎留言或扣我1836703877。無人機四軸本人做了五年,以上代碼全部自己寫,上傳的沒來的及添加注釋,但是代碼時成功在飛機上跑的并且無人機出貨的。

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏7 分享淘帖 頂2 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:328014 發(fā)表于 2019-8-10 16:10 | 只看該作者
好東東啊,樓主能把代碼放在代碼框中嗎?
回復(fù)

使用道具 舉報

板凳
ID:85785 發(fā)表于 2019-8-12 19:55 | 只看該作者
可以的,待我整理一下
回復(fù)

使用道具 舉報

地板
ID:599768 發(fā)表于 2019-8-13 15:30 | 只看該作者
無人機 未來發(fā)展前途廣闊
大家說一下哪家的無人機技術(shù)優(yōu)秀
回復(fù)

使用道具 舉報

5#
ID:85785 發(fā)表于 2019-8-14 10:36 | 只看該作者
目前來看,還是大疆的比較牛逼,各方面穩(wěn)定,控制,都沒得說
回復(fù)

使用道具 舉報

6#
ID:85785 發(fā)表于 2019-8-14 10:38 | 只看該作者
  1. _POS_NOWstatus pos_vel_xy;
  2. float z_est[3]={0,0,0},x_est[3]={0,0,0},y_est[3]={0,0,0};
  3. typedef struct {
  4. float R[3][3];                    /**< Rotation matrix body to world, (Tait-Bryan, NED)*/
  5. }vehicle_attitude_s;

  6. vehicle_attitude_s      vehicle_att;
  7. vehicle_attitude_s      vehicle_optical;
  8. realacc real_acceleration;
  9. _vertical_information  baro_acc_alt;

  10. //#define ALT_VEL_HISTORY 10
  11. //volatile float alt_vel_history[ALT_VEL_HISTORY] = {0};

  12. //#define XY_VEL_HISTORY 3
  13. //volatile float x_vel_history[XY_VEL_HISTORY] = {0}, y_vel_history[XY_VEL_HISTORY] = {0};

  14. static float z_bias = 0,x_bias = 0,y_bias = 0;
  15. float w_z_baro=0.5f;
  16. static float corr_baro = 0;//corr_baro_filter = 0;
  17. static float corr_xvel = 0,corr_yvel = 0;
  18. static float corr_xpos = 0,corr_ypos = 0;

  19. static float acck = 0;

  20. void accel_filter_predict(float dt,float x[3])
  21. {
  22.         x[0] += x[1] * dt + x[2] * dt * dt / 2.0f;
  23.         x[1] += x[2] * dt;
  24. }

  25. void inertial_filter_correct(float e,float dt,float x[3],int i,float w,float vp)
  26. {
  27.   float ewdt = e * w * dt;
  28.         x[i] += ewdt;
  29.         if(i == 0)
  30.         {
  31.                 x[1] += vp*w * ewdt;
  32.         }
  33. }

  34. void check_stop(int16 accz_velocity,int16 accz)
  35. {
  36.         static uint8 slow_down_count=0;
  37.         static uint16 down_time=0;
  38.         down_time++;
  39.         if(fly_status.HOLD_STATUS == HOLD_DOWN)
  40.         {
  41.                 if(down_time>=200)
  42.                 {
  43.                         if((accz_velocity>=0&&accz<50&&accz>-50) || (accz_velocity>=50) || (accz>300 || accz<-300))
  44.                         {
  45.                                 slow_down_count++;
  46.                                 if(slow_down_count>3)
  47.                                 {
  48.                                         fly_status.HOLD_STATUS=HOLD_STOP;
  49.                                 }
  50.                         }
  51.                         else if(slow_down_count>0)
  52.                         {
  53.                                 if(accz_velocity<0)
  54.                                         slow_down_count=0;
  55.                                 else
  56.                                         slow_down_count--;
  57.                         }
  58.                 }
  59.         }
  60.         else
  61.         {
  62.                 down_time=0;
  63.                 slow_down_count=0;
  64.         }
  65. }


  66. void accel_baro_mag_gps_calculator(int16 accel_x,int16 accel_y,int16 accel_z)
  67. {
  68.         static uint8 usart1_count = 0;
  69.        
  70.         static int16 acc_xyz[3];
  71.         static float no_filteraccxx,no_filteraccyy,no_filteracczz;
  72.        
  73.         if (accel_x != 0 && accel_y != 0 && accel_z != 0)
  74.         {
  75.                 acck=(1/Fylib_Qrsqrt(accel_x*accel_x + accel_y*accel_y+accel_z*accel_z)-MV_ACC_RP)/MV_ACC_RP;
  76.                         if(acck<0) acck=-acck;
  77.         }
  78.        
  79.         acc_xyz[0]=accel_x*980/MV_ACC_RP;acc_xyz[1]=accel_y*980/MV_ACC_RP;acc_xyz[2]=accel_z*980/MV_ACC_RP;
  80.         //&Eacute;&Iuml;&Otilde;&yacute;&Iuml;&Acirc;&cedil;&ordm;&pound;&not;±±&Otilde;&yacute;&Auml;&Iuml;&cedil;&ordm;&pound;&not;&para;&laquo;&Otilde;&yacute;&Icirc;÷&cedil;&ordm;
  81.         no_filteracczz=-acc_xyz[1]*vehicle_att.R[2][0]-acc_xyz[0]*vehicle_att.R[2][1]+acc_xyz[2]*vehicle_att.R[2][2]-980;
  82.         no_filteraccxx=-(-acc_xyz[1]*vehicle_optical.R[0][0]-acc_xyz[0]*vehicle_optical.R[0][1]+acc_xyz[2]*vehicle_optical.R[0][2]);
  83.         no_filteraccyy=(acc_xyz[1]*vehicle_optical.R[1][0]+acc_xyz[0]*vehicle_optical.R[1][1]-acc_xyz[2]*vehicle_optical.R[1][2]);
  84.        
  85. //        no_filteracczz += (float)(agx + agy);
  86. //        no_filteraccxx += (float)(agy + agz);
  87. //        no_filteraccyy += (float)(agx + agz);
  88.        
  89.        
  90.         //high_pass
  91.         real_acceleration.xx=(int16)no_filteraccxx;
  92.         real_acceleration.yy=(int16)no_filteraccyy;
  93.         real_acceleration.zz=(int16)no_filteracczz;
  94.        
  95.         TimeUpdate(&baro_acc_alt,(realacc*)&real_acceleration);
  96.        
  97.         check_stop(baro_acc_alt.velocity_hat,no_filteracczz);
  98.        
  99.         usart1_count++;
  100.         if(usart1_count>=1)
  101.         {
  102.                 usart1_count = 0;
  103. //          SendDatShowINT((int)z_est[0],(int)(baro_data.baro_home),(int)(baro_data.velocity*3.1f),(int)baro_to_alt);
  104.         SendDatShow((int)y_est[1],(int)x_est[1],(int)(acck * 100),(int)baro_data.baro_home);
  105.         }
  106.        
  107.        
  108. }

  109. void ahrs_update_R_bf_to_ef(float angle_pitch,float angle_roll,float angle_yaw)
  110. {
  111.         float sin_pitch = sin(angle_pitch * M_DEG_TO_RAD);
  112.         float cos_pitch = cos(angle_pitch * M_DEG_TO_RAD);
  113.         float sin_roll = sin(angle_roll * M_DEG_TO_RAD);
  114.         float cos_roll = cos(angle_roll * M_DEG_TO_RAD);
  115.         float sin_yaw = sin(angle_yaw * M_DEG_TO_RAD);
  116.         float cos_yaw = cos(angle_yaw * M_DEG_TO_RAD);
  117.        
  118.         vehicle_att.R[0][0] = cos_pitch * cos_yaw;
  119.         vehicle_optical.R[0][0]=cos_pitch;
  120.         vehicle_att.R[0][1] = sin_roll * sin_pitch * cos_yaw + cos_roll * sin_yaw;
  121.         vehicle_optical.R[0][1] = 0;//sin_roll * sin_pitch + cos_roll;
  122.         vehicle_att.R[0][2] = cos_roll * sin_pitch * cos_yaw - sin_roll * sin_yaw;
  123.         vehicle_optical.R[0][2] = sin_pitch;//cos_roll * sin_pitch - sin_roll;
  124.        
  125.         vehicle_att.R[1][0] = cos_pitch * sin_yaw;
  126.         vehicle_optical.R[1][0] = 0;//cos_pitch;
  127.         vehicle_att.R[1][1] = -sin_roll * sin_pitch * sin_yaw - cos_roll * cos_yaw;
  128.         vehicle_optical.R[1][1] =cos_roll;// -sin_roll * sin_pitch - cos_roll;
  129.         vehicle_att.R[1][2] = cos_roll * sin_pitch * sin_yaw + sin_roll * cos_yaw;
  130.         vehicle_optical.R[1][2] =-sin_roll;// cos_roll * sin_pitch;// + sin_roll;
  131.        
  132.         vehicle_att.R[2][0] = -sin_pitch;
  133.         vehicle_att.R[2][1] = sin_roll * cos_pitch;
  134.         vehicle_att.R[2][2] = cos_roll * cos_pitch;       
  135.        
  136.        
  137. }

  138. #define HIGH_PASS_PARAM 0.999f
  139. float baro_vel_gain = 0.2f, x_vel_gain = 1.8f, y_vel_gain = 1.8f;

  140. float baro_gain=0.05f;

  141. void TimeUpdate(struct vertical_information *pAltitude,realacc* acc)
  142. {
  143.         static float high_pass_zvel = 0;//, z_est1f = 0;
  144.         z_est[2]=acc->zz-z_bias;
  145.         accel_filter_predict(INAV_T,z_est);
  146.         z_est[0] += corr_baro * w_z_baro * INAV_T;
  147.         z_bias -= corr_baro * 0.001f * INAV_T;
  148.        
  149.        
  150.         z_est[1] += corr_baro * baro_vel_gain * INAV_T;
  151.        
  152. //        if (z_est[1] >-20 && z_est[1] <20)
  153. //          high_pass_zvel = (high_pass_zvel + z_est[1] - z_est1f) * HIGH_PASS_PARAM;
  154. //        else
  155.                 high_pass_zvel = z_est[1];
  156. //        z_est1f = z_est[1];
  157.        
  158.         pAltitude->altitude_hat=z_est[0];
  159.         pAltitude->velocity_hat=high_pass_zvel;
  160.        
  161.         ObservationOPT_Update(x_est[0],optflow.velx,y_est[0],optflow.vely);
  162.        
  163.         x_est[2]=acc->xx-x_bias;
  164.         accel_filter_predict(INAV_T,x_est);
  165.         x_est[1] += corr_xvel * x_vel_gain * INAV_T;
  166.        
  167.         y_est[2]=acc->yy-y_bias;
  168.         accel_filter_predict(INAV_T,y_est);
  169.         y_est[1] += corr_yvel * y_vel_gain * INAV_T;
  170.        
  171.         pos_vel_xy.posx = 0;
  172.         pos_vel_xy.posy = 0;
  173.         pos_vel_xy.velx = optflow.velx;//x_est[1];
  174.         pos_vel_xy.vely = optflow.vely;//y_est[1];
  175. }

  176. __AVERAGE_DATAF altitude_vcal={0,0};

  177. float ABS_f(float values)
  178. {
  179.         if (values < 0 )
  180.                 return -values;
  181.         else
  182.                 return values;
  183. }

  184. void ObservationUpdate(int baro_disdance,int16 baro_vel)
  185. {
  186.         uint8 i;
  187.         corr_baro = (float)baro_disdance - z_est[0];
  188.        
  189.         if (corr_baro >20 || corr_baro <-20)
  190.                 baro_vel_gain = 0.4f;
  191.         else
  192.                 baro_vel_gain = 0.2f;
  193.        
  194.         if (fly_status.HOLD_STATUS == HOLD_STOP)
  195.         {
  196.                 z_est[0] = baro_disdance;
  197.                 z_est[1] = 0;
  198.         }
  199.        
  200.         return;
  201. }

  202. void ObservationOPT_Update(float pos_x,float vel_x,float pos_y,float vel_y)
  203. {
  204.         uint8 i;
  205.         corr_xpos = pos_x-x_est[0];
  206.         corr_xvel = vel_x-x_est[1];//x_vel_history[0]);
  207.         corr_ypos = pos_y-y_est[0];
  208.         corr_yvel = vel_y-y_est[1];//y_vel_history[0]);
  209.        
  210. //        for (i = 0; i < XY_VEL_HISTORY - 1; i++)
  211. //        {
  212. //                x_vel_history[i] = x_vel_history[i+1];
  213. //                y_vel_history[i] = y_vel_history[i+1];
  214. //        }
  215. //        x_vel_history[XY_VEL_HISTORY - 1] = x_est[1];
  216. //        y_vel_history[XY_VEL_HISTORY - 1] = y_est[1];
  217.         return;
  218. }
復(fù)制代碼


以上代碼是我的加速計跟光流,氣壓計的融合算法
回復(fù)

使用道具 舉報

7#
ID:618189 發(fā)表于 2019-9-29 22:10 | 只看該作者
現(xiàn)在正需要這個研究下,謝謝樓主
回復(fù)

使用道具 舉報

8#
ID:694705 發(fā)表于 2020-3-10 13:50 | 只看該作者
謝謝分享,學(xué)習(xí)
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 蜜桃在线播放 | 中文字幕一区二区三区四区 | 毛片网在线观看 | 成人动漫一区二区 | 成人黄色在线视频 | 国产我和子的乱视频网站 | 亚洲精品在线看 | 日韩一区精品 | 三级黄视频在线观看 | 亚洲首页| 国产精品久久久久久久久图文区 | 日韩一区二区黄色片 | 91日韩在线 | 久久男人 | www.中文字幕av | 亚洲成人免费视频在线 | 韩日一区二区 | 亚洲福利在线观看 | 久久小视频 | 久草久| 国产亚洲网站 | 久久不射电影网 | www.国产精 | 黄色一级片aaa | 国产高清视频一区 | 亚洲视频免费在线看 | 国产精品国产精品国产专区不卡 | 欧美久久久久久久久 | 男女激情网 | 欧美在线激情 | 综合久久久 | 一区二区不卡视频 | 五月婷婷视频 | 天天艹逼网 | 亚洲成人一区二区 | 国产线视频精品免费观看视频 | 中文字幕精品一区久久久久 | 本道综合精品 | 亚洲xx在线 | 国产精品成人一区二区三区 | 国产一级片在线观看视频 |