极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 29652|回复: 15

平衡小车站起来

[复制链接]
发表于 2013-8-5 00:00:21 | 显示全部楼层 |阅读模式
本帖最后由 tanbocandy 于 2013-8-5 00:17 编辑

在这里感谢 弘毅 ,pww999,Randy,arduino官网,基本是看他们的帖子学习的,经过大半个月的理论学习,实验,加上一个星期的制作过程(主要是做架子,调试),我的小车算是能站立,但是有个问题:我用蓝牙控制小车前后(还不带原地旋转)移动,小车老是要倒,程序是参照PWW999的,在接受到命令后,改变平衡的角度,不知道是程序原因还是硬件问题(电机是12V,8KG,100转),程序在后面发出来,全部是用的库,所以看起来还是比较简单的,如果看了我前面两个帖子(MPU6050卡尔曼,和电机PID)的内容都可以看懂这个程序,我的小车平衡角度是180。
还是哪个问题,小车不能前后移动,一动就倒。

  1. #include <PID_v1.h>
  2. #include "Wire.h"
  3. #include"Kalman.h"
  4. #include "I2Cdev.h"
  5. #include "MPU6050.h"
  6. #define Left1 10
  7. #define Left2 11
  8. #define Right1 5
  9. #define Right2 6
  10. #define drift 20

  11. double Setpoint, Input, Output;
  12. double temp_kp,temp_ki,temp_kd;
  13. //Kp=0.1,Ki=0.05,Kd=0,change depend on your system
  14. PID myPID(&Input,&Output,&Setpoint,1,0,0,DIRECT);
  15. MPU6050 accelgyro;
  16. Kalman kalmanX; // Create the Kalman instances
  17. //Kalman kalmanY;
  18. //Kalman kalmanZ;

  19. int16_t ax, ay, az;
  20. int16_t gx, gy, gz;
  21. uint32_t timer;
  22. int bluetooth_read;
  23. int Lspeed_need,Rspeed_need;

  24. double accXangle, accYangle,accZangle; // Angle calculate using the accelerometer
  25. double gyroXangle, gyroYangle,gyroZangle; // Angle calculate using the gyro
  26. double kalAngleX, kalAngleY; // Calculate the angle using a Kalman filter

  27. void setup()
  28. {
  29.   
  30.     pinMode(Left1,OUTPUT);
  31.     pinMode(Left2,OUTPUT);
  32.     pinMode(Right1,OUTPUT);
  33.     pinMode(Right2,OUTPUT);
  34.   
  35.     car_stop();  
  36.     // join I2C bus (I2Cdev library doesn't do this automatically)
  37.     Wire.begin();

  38.     // initialize serial communication
  39.     // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
  40.     // it's really up to you depending on your project)
  41.     Serial.begin(9600);
  42.     // initialize device
  43.     accelgyro.initialize();
  44.     // verify connection
  45.     accelgyro.testConnection();
  46.     timer=micros();
  47.     Setpoint=180.00;
  48.     myPID.SetSampleTime(10);
  49.     myPID.SetMode(AUTOMATIC);
  50. }

  51. void loop()
  52. {
  53.     // read raw accel/gyro measurements from device
  54.     data_recv();
  55.     temp_kp=analogRead(A0)*0.15;
  56.     temp_ki=analogRead(A1)*0.0002;
  57.     temp_kd=analogRead(A2)*0.08;
  58.     myPID.SetTunings(temp_kp,temp_ki,temp_kd);
  59.    
  60.     accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  61.     accXangle = (atan2(ay,az)+PI)*RAD_TO_DEG;
  62.    // accYangle = (atan2(ax,az)+PI)*RAD_TO_DEG;
  63.    
  64.     double gyroXrate = (double)gx/131.0;
  65.     //double gyroYrate =-((double)gy/131.0);

  66.    
  67.     gyroXangle+= gyroXrate*((double)(micros()-timer)/1000000); // Calculate gyro angle without any filter  
  68.    // gyroYangle+= gyroYrate*((double)(micros()-timer)/1000000);

  69.    
  70.     kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter
  71.    // kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000);
  72.     timer = micros();
  73.     if((kalAngleX>(Setpoint-drift))&&(kalAngleX<(Setpoint+drift)))
  74.     {
  75.             if((kalAngleX>Setpoint)&&(kalAngleX<(Setpoint+drift)))
  76.         {   
  77.             myPID.SetControllerDirection(REVERSE);
  78.             Input=kalAngleX;   
  79.             myPID.Compute();
  80.             analogWrite(Left2,Output);       //PWM out put
  81.             analogWrite(Right2,Output);       //PWM out put
  82.             analogWrite(Left1,0);       //PWM out put
  83.             analogWrite(Right1,0);   //PWM out put
  84.         }
  85.         if((kalAngleX<Setpoint)&&(kalAngleX>(Setpoint-drift)))
  86.         {
  87.             myPID.SetControllerDirection(DIRECT);
  88.             Input=kalAngleX;
  89.             myPID.Compute();
  90.             analogWrite(Left1,min(Output+Lspeed_need,255));       //PWM out put
  91.             analogWrite(Right1,min(Output+Lspeed_need,255));       //PWM out put
  92.             analogWrite(Left2,0);       //PWM out put
  93.             analogWrite(Right2,0);       //PWM out put
  94.         }
  95.     }
  96.     else
  97.     {
  98.       car_stop();  
  99.     }
  100.    // Serial.print(accXangle);Serial.print(",");
  101.    // Serial.print(gyroXangle);Serial.print(",");
  102.     Serial.println(kalAngleX);
  103.     Serial.println(temp_kp);
  104.     Serial.println(temp_ki);
  105.     Serial.println(temp_kd);

  106.     //  Serial.print("\t");
  107.     //Serial.print(accYangle);Serial.print(",");
  108.     //Serial.print(gyroYangle);Serial.print(",");
  109.     //Serial.print(kalAngleY);Serial.print("\r\n");   

  110. }
  111.     void car_stop()
  112. {
  113.       analogWrite(Left1,0);       //PWM out put
  114.       analogWrite(Right1,0);       //PWM out put
  115.       analogWrite(Left2,0);       //PWM out put
  116.       analogWrite(Right2,0);
  117. }

  118. void data_recv()
  119. {
  120.     if(Serial.available()>0)
  121.     {
  122.         bluetooth_read=Serial.read();
  123.         switch (bluetooth_read)
  124.         {
  125.             case 0x11:
  126.                  Setpoint=183.00;
  127.                 break;
  128.             case 0x22:
  129.                   Setpoint=177.00;
  130.                 break;
  131.         /*     case 33:
  132.                   Lspeed_need=10;
  133.                   Rspeed_need=-10;
  134.                   break;
  135.               case 44:
  136.                   Lspeed_need=-10;
  137.                   Rspeed_need=10;
  138.                  break;        */
  139.         }
  140.     }
  141.     else
  142.     {
  143.         Setpoint=180.00;
  144.     }
  145. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2013-8-5 02:06:22 | 显示全部楼层
本帖最后由 pww999 于 2013-8-5 02:14 编辑

效果不错嘛,改变前后角度数值大小,太大会一下就倒,太小又只会点下头!(你电池放在上面,头重脚轻了吧)
如果不知道大概前后数值,可以增加一电位器,从小调节(或者*0.1,,,0.01缩小调节范围)
回复 支持 反对

使用道具 举报

发表于 2013-8-5 08:31:42 | 显示全部楼层
做的挺好,重心很低。学习了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-5 12:31:56 | 显示全部楼层
pww999 发表于 2013-8-5 02:06
效果不错嘛,改变前后角度数值大小,太大会一下就倒,太小又只会点下头!(你电池放在上面,头重脚轻了吧)
...

我看一个国外的网站上说重量在高处会更容易保持平衡,就像人把扫帚倒立起来一样,所以我把电池放在上面的。。。难道被国外的坑了。。。
回复 支持 反对

使用道具 举报

发表于 2013-8-5 13:44:49 | 显示全部楼层
觉得重力在下面好吧,象不倒翕?
回复 支持 反对

使用道具 举报

发表于 2013-8-5 14:16:51 | 显示全部楼层
是用的6050么???感觉比之前平稳许多,不知道跑起来效果会怎样???
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-5 17:07:07 | 显示全部楼层
学慧放弃 发表于 2013-8-5 14:16
是用的6050么???感觉比之前平稳许多,不知道跑起来效果会怎样???

就是用的6050  我用的是PI控制,但是我看其他好多人都是用的PD,就是跑不起来,跑了就到,PWW999说是前进和后退的角度没调对,我还没试出来。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-5 17:07:53 | 显示全部楼层
pww999 发表于 2013-8-5 13:44
觉得重力在下面好吧,象不倒翕?

这个也是我郁闷的地方啊,到底是不倒翁还是像扫帚那样。。。。
回复 支持 反对

使用道具 举报

发表于 2013-8-5 20:03:53 | 显示全部楼层
tanbocandy 发表于 2013-8-5 17:07
就是用的6050  我用的是PI控制,但是我看其他好多人都是用的PD,就是跑不起来,跑了就到,PWW999说是前进 ...

恩恩,加油,但是国外两轮平衡车都可以站人呢,貌似也是PI控制的
回复 支持 反对

使用道具 举报

发表于 2013-8-6 19:59:49 | 显示全部楼层
很不错,我什么时候能做一个呢...
回复 支持 反对

使用道具 举报

发表于 2013-11-25 12:49:13 | 显示全部楼层
不错额,我在用STM32做
回复 支持 反对

使用道具 举报

发表于 2013-12-9 20:30:51 | 显示全部楼层
你用的是什么样的arduino 主板
回复 支持 反对

使用道具 举报

发表于 2013-12-20 22:26:49 | 显示全部楼层
楼主的kalman.h哪里来的
回复 支持 反对

使用道具 举报

发表于 2013-12-20 22:45:35 | 显示全部楼层
分享下调试过程吧。
回复 支持 反对

使用道具 举报

发表于 2013-12-29 17:33:27 | 显示全部楼层
很好啊,,,坐等楼主让它跑起来
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-14 08:53 , Processed in 0.065946 second(s), 28 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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