极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12295|回复: 5

备份一下自己小车的程序

[复制链接]
发表于 2013-4-13 17:11:31 | 显示全部楼层 |阅读模式
正在调试,欢迎围观。O(∩_∩)O~

  1. #include <I2Cdev.h>
  2. #include <L298N.h>
  3. #include <MPU6050.h>
  4. #include <Wire.h>
  5. #include <stdlib.h>

  6. float ax,az,gy;//get acceleration_x,acceleration_z,rotation_y
  7. long OffsetGy,OffsetSum;
  8. float OffsetAccSumX,OffsetAccSumZ,OffsetAcc;
  9. float AngleAcc,AngleRotation,AngleMerge;//angel computed by acceleration and rotation
  10. float Kp,Kd,Ki,pid_SP,pid_CV;
  11. float Err,ErrLast,ErrAfter;//PID
  12. long LastTime,NowTime,TimeSpan,SampleTime,PIDLastTime;//
  13. //===========kalman filter parameter define============
  14. float A,B,H,Q,R,P00,P10,X00,X10,Z,U,Kg;
  15. //==========add serial communication=========
  16. String SerialString;
  17. boolean mark=0;
  18. char *comdata;

  19. bool blinkState=false;
  20. L298N l298n;
  21. MPU6050 mpu;


  22. void setup()
  23. {
  24.   //============initial kalman parameter======
  25.   A=1.0;
  26.   H=1.0;
  27.   Q=0.003;
  28.   R=0.01;
  29.   P00=5.0;
  30.   P10=0.0;
  31.   X00=0.0;
  32.   //===============end initial===========
  33.   Wire.begin();
  34.   Serial.begin(9600);
  35.   Serial.println("start");
  36.   mpu.initialize();
  37.   Serial.println(mpu.getRotationY());
  38.   Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  39.   //compute the gyroscope offset automatic
  40.   for(int i=0;i<200;i++)
  41.   {
  42.     Serial.println(mpu.getRotationY());
  43.     OffsetAccSumX+=mpu.getAccelerationX()/16384.00;
  44.     OffsetAccSumZ+=mpu.getAccelerationZ()/16384.00;
  45.     OffsetSum=OffsetSum+mpu.getRotationY();
  46.     delay(20);
  47.    }
  48.   OffsetAcc=(-1.0)*atan2(OffsetAccSumX/200.0,OffsetAccSumZ/200.0)*180/PI;
  49.   OffsetGy=OffsetSum/200;
  50.   pid_SP=0.0;
  51.   Kp=50.0;
  52.   Ki=10.0;
  53.   Kd=0.0;
  54. }

  55. void loop()
  56. {
  57.   
  58.   NowTime=millis();
  59.   TimeSpan=NowTime-LastTime;
  60.   LastTime=NowTime;
  61.   Serial.flush();
  62.   //==============add serial communication=======
  63.   while(Serial.available()>0)
  64.   {
  65.     SerialString += char(Serial.read());
  66.     delay(2);
  67.     mark=1;
  68.   }
  69.   if (mark)
  70.   {
  71.     SerialString.trim();
  72.     //int len=SerialString.length();
  73. //    int PIndex=SerialString.indexOf('P');
  74. //    int IIndex=SerialString.indexOf('I');
  75. //    int DIndex=SerialString.indexOf('D');
  76. //    int SIndex=SerialString.indexOf('S');
  77.     //int PComma=SerialString.indexOf(',');
  78.     //int IIndex=PIndex+1;
  79.    
  80.     //int IComma=SerialString.indexOf(',',IIndex);
  81.     //==============set only one parameter each time===========
  82.     String _Para="";
  83.     switch(SerialString[0])
  84.     {
  85.       case 'p':
  86.       case 'P':
  87.         _Para=SerialString.substring(1);
  88.         _Para.trim();
  89.         comdata=&_Para[0];
  90.         Kp=atof(comdata);
  91.         
  92.         break;
  93.       case 'i':
  94.       case 'I':
  95.         _Para=SerialString.substring(1);
  96.         _Para.trim();
  97.         comdata=&_Para[0];
  98.         Ki=atof(comdata);
  99.         
  100.         break;
  101.       case 'd':
  102.       case 'D':
  103.         _Para=SerialString.substring(1);
  104.         _Para.trim();
  105.         comdata=&_Para[0];
  106.         Kd=atof(comdata);
  107.         
  108.         break;
  109.       case 's':
  110.       case 'S':
  111.         _Para=SerialString.substring(1);
  112.         _Para.trim();
  113.         comdata=&_Para[0];
  114.         pid_SP=atof(comdata);
  115.         
  116.         break;
  117.       default:
  118.         break;
  119.     }
  120. //    String _mkp=SerialString.substring(PComma+1,IIndex-1);
  121. //    _mkp.trim();
  122. //    comdata=&_mkp[0];
  123. //    Kp=atof(comdata);
  124. //    String _mki=SerialString.substring(IComma+1);
  125. //    _mki.trim();
  126. //    comdata=&_mki[0];
  127. //    Ki=atof(comdata);
  128.    
  129.     mark=0;
  130.   }
  131.   //=================test kalman filter==========================
  132.   ax=mpu.getAccelerationX()/16384.00;
  133.   az=mpu.getAccelerationZ()/16384.00;
  134.   AngleAcc=(-1.0)*atan2(ax,az)*180/PI;
  135.   gy=(mpu.getRotationY()-OffsetGy)/131.00;
  136.   AngleRotation=AngleRotation+gy*TimeSpan/1000.00;
  137.   //=============kalman calculate============
  138.   B=TimeSpan/1000.0;
  139.   U=gy;
  140.   Z=AngleAcc;
  141.   X10=A*X00+B*U; //=======formula 1
  142.   P10=A*P00*(1/A)+Q;//formula 2
  143.   Kg=P10*(1/H)/(H*P10*(1/H)+R);//formula 3
  144.   
  145.   X00=X10+Kg*(Z-H*X10);//formula 4
  146.   
  147.   //P00=(1-Kg*H)*P10;//formula 5
  148.   P00=(1-Kg*H)*P10*(1-Kg*H)+Kg*R*Kg;
  149.   AngleMerge=X00;
  150.   //================end test kalman filter======================
  151.   //MergeAngle();

  152.   PID();
  153.   if(1.0<AngleMerge)
  154.   {
  155.     l298n.MotorAForward(pid_CV);
  156.     l298n.MotorBForward(pid_CV);
  157.   }
  158.   else if(-1.0>AngleMerge)
  159.   {
  160.     l298n.MotorAReversal(pid_CV);
  161.     l298n.MotorBReversal(pid_CV);   
  162.   }
  163.   else
  164.   {
  165.     l298n.MotorAStop();
  166.     l298n.MotorBStop();
  167.   }
  168.   Serial.print(AngleRotation);
  169.   Serial.print(",");
  170.   Serial.print(AngleMerge);
  171.   Serial.print(",");
  172.   Serial.print(AngleAcc);
  173.   Serial.print(",");
  174.   Serial.print(pid_CV);
  175.   Serial.print(",");
  176.   Serial.print(Kp);
  177.   Serial.print(",");
  178.   Serial.println(Ki);
  179.   delay(100);

  180. }
  181. void PID()
  182. {
  183.   //===========04-13 add sample time=============
  184.   
  185.   if((NowTime-PIDLastTime)>SampleTime)
  186.   {
  187.     PIDLastTime=NowTime;
  188.    
  189.     ErrAfter=ErrLast;
  190.     ErrLast=Err;
  191.     //Err=pid_SP-abs(AngleMerge);
  192.     Err=pid_SP-AngleMerge;
  193.     float deltOut=Kp*Err+Ki*ErrLast+Kd*ErrAfter;
  194.    
  195.     pid_CV=min(255.0,abs(pid_CV+deltOut));
  196.     pid_CV=max(80,pid_CV);//limit the min PWM output
  197.   }
  198. }
  199. void MergeAngle()
  200. {
  201.   //compute AngleAcc
  202.   ax=mpu.getAccelerationX()/16384.00;
  203.   az=mpu.getAccelerationZ()/16384.00;
  204.   AngleAcc=(-1.0)*atan2(ax,az)*180/PI-OffsetAcc;
  205.   gy=(mpu.getRotationY()-OffsetGy)/131.00;
  206.   AngleRotation=AngleRotation+gy*TimeSpan/1000.00;

  207.   AngleMerge=0.9*AngleRotation+0.1*AngleAcc;
  208. }
复制代码
回复

使用道具 举报

发表于 2013-4-16 13:52:34 | 显示全部楼层
L298N.h的库文件,哪里有下?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-4-16 14:27:34 | 显示全部楼层
firewise 发表于 2013-4-16 13:52
L298N.h的库文件,哪里有下?

自己写的,可以搜一下我以前的帖子。你也可以根据自己习惯写一个。
回复 支持 反对

使用道具 举报

发表于 2013-4-16 16:31:28 | 显示全部楼层
已找到了,谢楼主。。。
新手,要慢慢消化才行
回复 支持 反对

使用道具 举报

发表于 2013-8-12 22:07:21 | 显示全部楼层
下载了你的程序试了一下,发现这中间的确有一个死区,就是当处于水平位置的时候,两路驱动全都送出了信号,这个很厉害。。。。。。。
回复 支持 反对

使用道具 举报

发表于 2013-9-5 19:43:17 | 显示全部楼层
剛剛學習android,感謝無私分享
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-8 04:38 , Processed in 0.096610 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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