极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 9828|回复: 12

贡献我的四轴代码

[复制链接]
发表于 2013-8-20 17:17:30 | 显示全部楼层 |阅读模式
  1. #include <I2Cdev.h>
  2. #include <MPU6050.h>
  3. #include <Wire.h>

  4. //=============mpu6050 declarations===========
  5. MPU6050 accelgyro;
  6. static double Gx_offset = -1.46;//soldered as LENGBEI
  7. static double Gy_offset = -0.07;
  8. static double Ax_offset = -0.21;
  9. static double Ay_offset = -1.7;


  10. int16_t ax,ay,az;
  11. int16_t gx,gy,gz;//raw data from sensors
  12. double aax,aay,aaz,ggx,ggy,ggz;
  13. double Ax,Ay,Az;//单位 g(9.8m/s^2)
  14. double Gx,Gy,Gz;//单位 °/s

  15. //=================mesure declarations=============
  16. double estima_X = 0.2;
  17. double estima_Y = 0.2;
  18. double es_GX;
  19. double es_GY;
  20. double fusion_angle_Y;
  21. double fusion_angle_X;
  22. double now_error_X, last_error_X, error_diff_X, error_int_X;
  23. double now_error_Y, last_error_Y, error_diff_Y, error_int_Y;
  24. double Angel_accX,Angel_accY,Angel_accZ;

  25. //===============control & accuracy declarations========  
  26. double basic_power = 5;     // z acc balancing, need calibration each time
  27. double rot_power_X, rot_power_Y;
  28. double orientX=0;
  29. double orientY=0;
  30. long tic_1,tic_2,tic_3, duration;
  31. int time_span_milli =20;
  32. float time_span =0.02;
  33. int moterPins[4];
  34. int moterPowers[4];
  35.    
  36. void set_Motors(){
  37.   pinMode(11,OUTPUT);
  38.   pinMode(10,OUTPUT);
  39.   pinMode(9,OUTPUT);
  40.   pinMode(6,OUTPUT);
  41.   analogWrite(10, 0);
  42.   analogWrite(6, 0);
  43.   analogWrite(11,0);
  44.   analogWrite(9, 0);
  45.   delay(100);
  46. }

  47. void setup()
  48. {
  49.   Wire.begin();
  50.   Serial.begin(9600);
  51.   set_Motors();
  52.   accelgyro.initialize();
  53.   delay(100);
  54.   autoCalibration();
  55.   delay(100);
  56. }

  57. void autoCalibration(){
  58.   Gx_offset=0.0;
  59.   Gy_offset=0.0;
  60.   double sum_1 =0;
  61.   double sum_2 =0;
  62.   double sum_3 =0;
  63.   double sum_4 =0;
  64.   for (int i=0; i<500; i++){
  65.    accelgyro.getMotion6(&ax,&ay,&az,&gx,&gy,&gz);
  66.    ggx=gx/131.00;
  67.    ggy=gy/131.00;
  68.    Ax=ax/16384.00;
  69.    Ay=ay/16384.00;
  70.    Az=az/16384.00;  
  71.    Angel_accX =atan(Ay/sqrt(Ax*Ax+Az*Az))*180/3.14 ;
  72.    Angel_accY =-atan(Ax/sqrt(Az*Az+Ay*Ay))*180/3.14;   
  73.    sum_1 = sum_1 + ggx;
  74.    sum_2 = sum_2 + ggy;
  75.    sum_3 = sum_3 + Angel_accX;
  76.    sum_4 = sum_4 + Angel_accY;
  77.    delay(1);
  78.   }
  79.   Gx_offset = sum_1/500;
  80.   Gy_offset = sum_2/500;
  81.   Ax_offset = sum_3/500;
  82.   Ay_offset = sum_4/500;
  83. //   Serial.print("Gx_offset= ");
  84. //   Serial.print(sum_1/1000);
  85. //   Serial.print("  Gy_offset= ");
  86. //   Serial.println(sum_2/1000);   
  87. }



  88. void loop()
  89. {
  90.    tic_1=millis();
  91.    int emer_stat = 0;
  92.    //------------------------command tests-----------------------------------
  93.    while (Serial.available()>=1){
  94.         char datatype = Serial.read();
  95.         if (datatype == 'S'){
  96.              digitalWrite(13, HIGH);   
  97.              delay(1);               
  98.              digitalWrite(13, LOW);   
  99.              delay(1);
  100.         }else if(datatype == 'M'){
  101.             orientX=0;
  102.             orientY=0;
  103.         }else if(datatype == 'z'){
  104.             orientX=0;
  105.         }else if(datatype == 'y'){
  106.             orientY=0;
  107.         }else if(datatype == 'L'){
  108.            basic_power = basic_power+10;
  109.         }else if(datatype == 'R'){
  110.            basic_power = basic_power-10;
  111.         }else if(datatype == 'P'){
  112.            basic_power = basic_power+1;
  113.         }else if(datatype == 'K'){
  114.            basic_power = basic_power-1;
  115.         }else if(datatype == 'Q'){
  116.            if (orientX <=18){
  117.              orientX=orientX+2;
  118.            }         
  119.         }else if(datatype == 'W'){
  120.            if (orientX >= -18){
  121.              orientX=orientX-2;               
  122.              digitalWrite(13, HIGH);   
  123.            }
  124.         }else if(datatype == 'D'){
  125.            if (orientY <= 18){
  126.              orientY=orientY+2;
  127.            }         
  128.         }else if(datatype == 'G'){
  129.            if (orientY >=-18){
  130.              orientY=orientY-2;
  131.            }         
  132.         }else if (datatype == 'V'){
  133.              int value = Serial.parseInt();
  134.              if ((value<=255)&&(value>=0)){
  135.                basic_power = value;
  136.              }
  137.         }else if (datatype == 'X'){

  138.         }else if (datatype == 'Y'){
  139.       
  140.         }else if (datatype == 'j'){
  141.           orientY = 10;
  142.         }else if (datatype == 'k'){
  143.           orientY = 5;
  144.         }else if (datatype == 'l'){
  145.           orientY = -5;
  146.         }else if (datatype == 'm'){
  147.           orientY = -10;
  148.         }else if (datatype == 'n'){
  149.           orientX = -5;
  150.         }else if (datatype == 'o'){
  151.           orientX = 5;
  152.         }else if (datatype == 'p'){
  153.           orientX = 10;
  154.         }else if (datatype == 'y'){
  155.           orientY = 0;
  156.         }else if (datatype == 'z'){
  157.           orientX = 0;
  158.         }   
  159.    }
  160.    
  161. //--------------------------do NOT touch-----------------------------------------
  162.    
  163.    
  164. // obtaining and filtering Acc angles   
  165.    accelgyro.getMotion6(&ax,&ay,&az,&gx,&gy,&gz);
  166.    Ax=ax/16384.00;
  167.    Ay=ay/16384.00;
  168.    Az=az/16384.00;  
  169.    Angel_accX =atan(Ay/sqrt(Ax*Ax+Az*Az))*180/3.14 -Ax_offset; //offset
  170.    Angel_accY =-atan(Ax/sqrt(Az*Az+Ay*Ay))*180/3.14 -Ay_offset; //offset  
  171.    estima_X = estima_cal(estima_X, Angel_accX, 0.2);
  172.    estima_Y = estima_cal(estima_Y, Angel_accY, 0.2);   
  173. //   Serial.print("estima_X=");
  174. //   Serial.print(estima_X);
  175. //   Serial.print("estima_Y=");
  176. //   Serial.println(estima_Y);      
  177.    
  178. // obtaining Gyro angles   without filter simply because I'm lasy
  179.    ggx=gx/131.00;
  180.    ggy=gy/131.00;
  181.    ggz=gz/131.00;
  182.    Gx=Gx+(ggx-Gx_offset)*time_span;
  183.    Gy=Gy+(ggy-Gy_offset)*time_span;
  184.    autoCorrection();
  185. //   Serial.print("Gx=");
  186. //   Serial.print(Gx);
  187. //   Serial.print(" Gy=");
  188. //   Serial.println(Gy);


  189. //fusion angles by combining 40% last observe + 30% Acc + 30% Gyro

  190.   fusion_angle_X = update_Estimat(fusion_angle_X, estima_X, Gx );
  191.   fusion_angle_Y = update_Estimat(fusion_angle_Y, estima_Y, Gy );
  192. //   Serial.print("fusion_X=");
  193. //   Serial.print(fusion_angle_X);
  194. //   Serial.print("fusion_Y=");
  195. //   Serial.println(fusion_angle_Y);     
  196.    
  197. //   if (fusion_angle_Y>=80){
  198. //             digitalWrite(13, HIGH);   
  199. //             delay(1);               
  200. //             digitalWrite(13, LOW);   
  201. //             delay(1);
  202. //   }
  203.    
  204. //---------------------------------PID's----------------------------------------
  205.   uodate_error(orientX, orientY ,fusion_angle_X, fusion_angle_Y);
  206.   
  207.   double command_Y_raw = PID_control(now_error_Y, error_diff_Y, error_int_Y);
  208.   double command_X_raw = PID_control(now_error_X, error_diff_X, error_int_X);
  209.   int command_X = int (command_X_raw);
  210.   int command_Y = int (command_Y_raw);
  211.   
  212.   moterPowers[1] =basic_power + command_X;
  213.   moterPowers[0] =basic_power - command_X;
  214.   moterPowers[3] =basic_power + command_Y;
  215.   moterPowers[2] =basic_power - command_Y;
  216.    
  217.   emergency_STOP(emer_stat);

  218. //---------------------------------fuzzy's----------------------------------------
  219. //   int command_X = fussy_command (fusion_angle_X);
  220. //   int command_Y = fussy_command (fusion_angle_Y);
  221. //  moterPowers[0] =basic_power + command_X + int(orientX);
  222. //  moterPowers[1] =basic_power - command_X - int(orientX);
  223. //  moterPowers[2] =basic_power + command_Y + int(orientY);
  224. //  moterPowers[3] =basic_power - command_Y - int(orientY);


  225. //----------------------executing state for time_span_milli------------------------

  226.    for (int i=0; i<=3; i++){
  227.      if (moterPowers[i]< 0){
  228.        moterPowers[i] = 0;
  229.      }else if (moterPowers[i] >255){
  230.        moterPowers[i] = 255;
  231.      }
  232.    }
  233.    
  234. //   Serial.print("po 10 = ");
  235. //   Serial.print(moterPowers[0]);
  236. //   Serial.print("   po 6 = ");
  237. //   Serial.print(moterPowers[1]);   
  238. //   Serial.print("   po 11 = ");
  239. //   Serial.print(moterPowers[2]);
  240. //   Serial.print("   po 9 = ");
  241. //   Serial.println(moterPowers[3]);  
  242.    
  243.    analogWrite(10, moterPowers[0]);
  244.    analogWrite(6, moterPowers[1]);
  245.    analogWrite(11, moterPowers[2]);
  246.    analogWrite(9, moterPowers[3]);

  247.    tic_2=millis();
  248.    duration = tic_2 - tic_1;
  249.    if(duration > time_span_milli){
  250.      duration=0;
  251.    }
  252.    //Serial.println(time_span_milli - duration);
  253.    delay (time_span_milli - duration);
  254.    
  255. }


  256. //--------------------------accesory functions----------------------------------------
  257. double estima_cal (double estima, double metron, double KG){
  258.   double result1 = estima + KG*(metron - estima);
  259.   return result1;
  260. }
  261. double PID_control(double error, double error_diff, double error_int ){
  262.   double P=0.7;
  263.   double D=0.2;
  264.   double I=0;
  265.   double command = P*error + I*error_int + D*error_diff;
  266.   return command;
  267. }
  268. void uodate_error(double consigne_X, double consigne_Y, double mesure_X, double mesure_Y){
  269.   now_error_X = consigne_X - mesure_X;
  270.   now_error_Y = consigne_Y - mesure_Y;
  271.   error_diff_X = (now_error_X - last_error_X)/time_span;
  272.   error_diff_Y = (now_error_Y - last_error_Y)/time_span;
  273.   error_int_X = error_int_X + now_error_X*time_span;
  274.   error_int_Y = error_int_Y + now_error_Y*time_span;
  275.   last_error_X =now_error_X;
  276.   last_error_Y =now_error_Y;
  277. }
  278. double update_Estimat(double estimate, double metron_1, double metron_2){
  279.   double temp = 0.4* estimate + 0.3*metron_1 + 0.3*metron_2;
  280.   return temp;
  281. }
  282. void emergency_STOP(int choice){
  283. if (choice == 0){
  284.     //do nothing
  285. }else if(choice == 1){
  286.    //brutal descending
  287.     basic_power =5;
  288. //    moterPowers[1] =5;
  289. //    moterPowers[2] =5;
  290. //    moterPowers[3] =5;
  291. }else if(choice == 2){
  292.     //douce descending
  293.     moterPowers[0] = moterPowers[0]-10;
  294.     moterPowers[1] = moterPowers[1]-10;
  295.     moterPowers[2] = moterPowers[2]-10;
  296.     moterPowers[3] = moterPowers[3]-10;
  297. }
  298. }

  299. double PorportionDet(double limA, double limB, double outA, double outB, double x){
  300.   double a = (x - limB) / (limA-limB);
  301.   double result = a*outA + (1-a)*outB;
  302.   return result;
  303. }

  304. int fussy_command(double input){
  305.    double PWM_command;
  306.    if (input>=45 ){
  307.      PWM_command = 30;
  308.    }else if(input<45 & input>=25 ){
  309.      PWM_command = PorportionDet(45, 25, 30, 10, input );
  310.    }else if(input<25 & input>=5){
  311.      PWM_command = PorportionDet(25, 5, 10, 3, input );     
  312.    }else if(input<5 & input>=-5){
  313.      PWM_command = PorportionDet(5, -5, 3, -3, input );         
  314.    }else if(input<-5 &input>=-25){
  315.      PWM_command = PorportionDet(-5, -25, -3, -10, input );              
  316.    }else if(input<-25 & input>=-45){
  317.      PWM_command = PorportionDet(-25, -45, -10, -30, input );         
  318.    }else if(input<-45){
  319.      PWM_command =-30;
  320.    }
  321.    int regu_pwm =int(PWM_command);
  322.    return regu_pwm;
  323. }
  324. void autoCorrection (){
  325.   if ( Angel_accX > -1.3 & Angel_accX < 1.3 ){
  326.     Gx=Angel_accX /2;
  327.   }
  328.   if ( Angel_accY > -1.3 & Angel_accY < 1.3 ){
  329.     Gy=Angel_accY /2;
  330.   }
  331. }
复制代码



除了PID不太稳定,其他还好
回复

使用道具 举报

 楼主| 发表于 2013-8-20 17:19:43 | 显示全部楼层
回复 支持 反对

使用道具 举报

发表于 2013-8-20 17:22:10 | 显示全部楼层
期待。谢谢分享。设备马上到齐了,调试下看看
回复 支持 反对

使用道具 举报

发表于 2013-8-20 20:15:22 | 显示全部楼层
谢谢楼主无私的共享,飞得平稳度怎样???
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-20 21:01:31 | 显示全部楼层
不好,容易晃,还需要细调PID参数
回复 支持 反对

使用道具 举报

发表于 2013-8-21 09:00:33 | 显示全部楼层
{:soso_e179:}{:soso_e179:}{:soso_e179:}{:soso_e179:}{:soso_e179:}{:soso_e179:}{:soso_e179:}
我怎么看不见下面那两张图
回复 支持 反对

使用道具 举报

发表于 2013-12-4 20:50:45 | 显示全部楼层
这个要必须顶,有没有视频呢
回复 支持 反对

使用道具 举报

发表于 2014-9-24 20:21:35 | 显示全部楼层
感谢楼主!!能否附上说明呢,新手不会接线。。
回复 支持 反对

使用道具 举报

发表于 2014-10-2 01:43:19 | 显示全部楼层
能飞不?,如果行,详细教程可以有
回复 支持 反对

使用道具 举报

发表于 2014-10-2 12:19:06 | 显示全部楼层
感謝樓主無私分享.
可否提供一點硬件的資料, 以及接線方法, 好讓大家學習學習.
回复 支持 反对

使用道具 举报

发表于 2015-2-8 12:22:27 | 显示全部楼层
感谢楼主分享的代码啊,我用LED灯测试成功了。不过连接电调似乎还要加上空占比发生程序,还有这个代码里面还没有滤波吧,出来的曲线跳动较大。
回复 支持 反对

使用道具 举报

发表于 2015-2-11 16:58:16 | 显示全部楼层
感谢分享,关注中
回复 支持 反对

使用道具 举报

发表于 2015-7-30 10:50:24 | 显示全部楼层
赞一个,第一个帖子给你了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-18 05:33 , Processed in 0.039508 second(s), 28 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表