智能车制作

 找回密码
 注册

扫一扫,访问微社区

楼主: Malc
打印 上一主题 下一主题

我的平衡车设计--软件篇

    [复制链接]

0

主题

115

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
5505
威望
2195
贡献
1290
兑换币
1430
注册时间
2013-4-11
在线时间
1010 小时
111#
发表于 2014-4-26 19:34:57 | 只看该作者
谢啦
回复 支持 反对

使用道具 举报

6

主题

227

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
4239
威望
1991
贡献
1328
兑换币
1288
注册时间
2013-1-12
在线时间
460 小时
112#
发表于 2014-4-28 13:48:17 | 只看该作者
学姐,可否加QQ请教,新手求带。1515949177.谢谢
回复 支持 反对

使用道具 举报

4

主题

796

帖子

0

精华

跨届大侠

Rank: 10Rank: 10Rank: 10

积分
10578

优秀会员奖章活跃会员奖章论坛元老奖章在线王奖章

威望
5540
贡献
3174
兑换币
3043
注册时间
2013-9-30
在线时间
932 小时
113#
发表于 2014-5-1 17:10:14 | 只看该作者
本帖最后由 wmslecz 于 2014-5-1 17:53 编辑
Malc 发表于 2014-4-16 17:43

学姐..又打扰您了..嘿嘿..五一节快乐哈....一直都没有想通一个问题...现在任然有转弯加减速的问题..转弯的时候我发现加速度计角度输出会有很大的变化(角度换算出来大概可以达到5°的误差)...现在车子速度环走的特别不稳...想问下学姐你们对于加速度计是怎么处理的?我用的是卡尔曼....出现的效果是角度很平滑...跟踪加速度计很快....但是就是有转弯就变速的过程..一直很头疼..谢谢学姐哈....顺便发一张励志图片...我很喜欢的桌面..嘿嘿.还有就是学姐..你们对于行车的时候对速度控制是怎么一种给的方法..我现在的情况就是在定时器中慢慢给到最大..然后一旦出现速度突然降低就会导致车子平衡失调然后..车子前倾很厉害..最后倒着跑...这个是最奇怪的.....

本帖子中包含更多资源

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

x
回复 支持 反对

使用道具 举报

4

主题

796

帖子

0

精华

跨届大侠

Rank: 10Rank: 10Rank: 10

积分
10578

优秀会员奖章活跃会员奖章论坛元老奖章在线王奖章

威望
5540
贡献
3174
兑换币
3043
注册时间
2013-9-30
在线时间
932 小时
114#
发表于 2014-5-1 19:12:25 | 只看该作者
本帖最后由 wmslecz 于 2014-5-1 19:15 编辑
Malc 发表于 2014-4-13 11:34
pid里的d就是微分项,陀螺仪的输出就是转动角速度,也就是转动角度的微分

复制代码
学姐....再请教您一下哈...你修改过了官方的速度方案...官方的速度方案貌似确实不是很稳定....我看学姐您修改了很多...甚至将官方的PI控制改成了PID的控制....但是您再帖子开头说的将PI控制简化成了P控制...您贡献的代码中有些不是很懂学姐您的意思?
  1. void SpeedControl (void)
  2. {
  3.   float fP, fDelta;
  4.         float fI;
  5.         float fD;
  6.         float P;
  7.         
  8.         static lastErr=0;

  9.         
  10.         g_fCarSpeed = (LspeedJF+RspeedJF) / 2;    //获取速度的思路是每一次定时器中断后对速度进行累加  直道调用该函数后才进行相应的清空操作
  11.         LspeedJF=RspeedJF=0;
  12.         
  13.         g_fCarSpeed*=1.0;                                 //个人理解是整数转换成浮点数..我个人觉得是多余的...
  14.         g_fCarSpeed=FIR2(g_fCarSpeed);             //FIR滤波  得到速度

  15.         /*
  16.         if(fabs(g_fCarSpeed*MMperPulse*scPeriod/1000-SetSpeedMM)<100)//300
  17.          P=SPEED_CONTROL_P*0.2;
  18.         else if(fabs(g_fCarSpeed*MMperPulse*scPeriod/1000-SetSpeedMM)<150) //500
  19.          P=SPEED_CONTROL_P*0.3;
  20.         else if(fabs(g_fCarSpeed*MMperPulse*scPeriod/1000-SetSpeedMM)<200) //500
  21.          P=SPEED_CONTROL_P*0.4;
  22.         else if(fabs(g_fCarSpeed*MMperPulse*scPeriod/1000-SetSpeedMM)<250) //500
  23.          P=SPEED_CONTROL_P*0.5;
  24.         else if(fabs(g_fCarSpeed*MMperPulse*scPeriod/1000-SetSpeedMM)<300) //500
  25.          P=SPEED_CONTROL_P*0.6;
  26.         else if(fabs(g_fCarSpeed*MMperPulse*scPeriod/1000-SetSpeedMM)<350) //500
  27.          P=SPEED_CONTROL_P*0.7;
  28.         else if(fabs(g_fCarSpeed*MMperPulse*scPeriod/1000-SetSpeedMM)<400) //500
  29.          P=SPEED_CONTROL_P*0.8;
  30.         else
  31.          P=SPEED_CONTROL_P;
  32.         */
  33.         P=SPEED_CONTROL_P;                           //速度P为何要这种赋值操作?    为何不直接使用这个值?
  34.         fDelta = SetSpeed- g_fCarSpeed;         //速度误差
  35.         fDelta=FIR5(fDelta);                         //再次进行滤波..不知道这种效果如何
  36.         
  37.         if(fDelta>=0)                                 //偏差>0   输出参数K值以及其符号的确定
  38.           k=map(fDelta,0,1000,0,45);
  39.          
  40.                   // long map(long x, long in_min, long in_max, long out_min, long out_max)
  41.         // {
  42.           // return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  43.         // }
  44.          
  45.         else
  46.           k=map(fDelta,0,-1000,0,45);
  47.   speedK=tangent[k];                           //SPEEDK 应该是一个tan[x]的一维表...但学姐没有给出相应的值..或许就是-pi/2 到pi/2 放大100倍后的值吧?
  48.          
  49.         fP = fDelta * P*speedK;
  50.         fI = fDelta * SPEED_CONTROL_I*speedK;                //积分量
  51.         fD = (fDelta-lastErr) * SPEED_CONTROL_D*speedK;
  52.         lastErr=fDelta;
  53.         g_fSpeedControlIntegral += fI;                                //积分
  54.         
  55.         

  56.         g_fSpeedControlOutOld = g_fSpeedControlOutNew;

  57.         g_fSpeedControlOutNew = fP + g_fSpeedControlIntegral-fD;                //PID
  58.         
  59.         if(g_fSpeedControlOutNew > SPEED_CONTROL_OUT_MAX)                 //限幅
  60.                 g_fSpeedControlOutNew = SPEED_CONTROL_OUT_MAX;
  61.         if(g_fSpeedControlOutNew < SPEED_CONTROL_OUT_MIN)         
  62.                 g_fSpeedControlOutNew = SPEED_CONTROL_OUT_MIN;
  63.         
  64.         
  65.         }
复制代码
学姐.....嘿嘿....又麻烦你了...最近被这个困扰着...打扰学姐了..嘿嘿..学学学姐...
回复 支持 反对

使用道具 举报

8

主题

119

帖子

0

精华

跨届大侠

Rank: 10Rank: 10Rank: 10

积分
6089
威望
2660
贡献
1737
兑换币
1625
注册时间
2011-7-22
在线时间
846 小时
115#
 楼主| 发表于 2014-5-2 10:31:15 | 只看该作者
wmslecz 发表于 2014-5-1 19:12
学姐....再请教您一下哈...你修改过了官方的速度方案...官方的速度方案貌似确实不是很稳定....我看学姐您 ...

我的车子速度这块也确实没做好,后来因为时间问题,就没有接着去研究了,比赛的时候就是用直立控制去加减速的,因为我的车直立控制做的比较好吧,如果给定一个角度,他会立刻达到这个角度,所以加速的时候,将平衡点前倾n°,就实现了加速,遇到拐角,再改回平衡点,你可以参考一下我的视频:
http://v.youku.com/v_show/id_XNjQ1OTA2NzUy.html
下面这个视频里,就没有给加速,所以遇到了直线就会变慢:
http://v.youku.com/v_show/id_XNjQ1OTAxMTAw.html
我再解释一下我的代码吧:
P=SPEED_CONTROL_P;                           //速度P为何要这种赋值操作?    为何不直接使用这个值?
SPEED_CONTROL_P是个全局变量,定义在头文件中,这样的好处是,可以用BDM直接在线调试这个变量,非常方便,如果这个变量是在函数里,就不能在线调试了
tangent[k]也在头文件中
在头文件中,P=SPEED_CONTROL_I=0;P=SPEED_CONTROL_D=0;也就是说我只用了P控制
另外我觉得我的程序速度控制没做好的原因可能是速度积分没有限幅,虽然我给速度积分输出项限幅了,但是没有给fI限幅,所以只要加了I参数就很难调,你可以试一下


INCLUDES.h:
  1. #ifndef INCLUDES_H
  2. #define INCLUDES_H

  3. #define PI 3.14159265358979323846


  4. #define true 1
  5. #define false 0
  6. #define gyroPin_Z1 5
  7. #define gyroPin_X1 6
  8. #define accPin_Z 4
  9. #define accPin_Y 3
  10. #define accPin_X 2
  11. float gyroOffset=121;
  12. float gyroZ,accX,accY,accZ;
  13. float angleG=0;

  14. //端口定义
  15. #define FLED  PORTK_PK0
  16. #define BMQR  PORTA_PA4  //编码器复位
  17. #define TSL_SI  PORTA_PA1    //定义线性传感器的端口 SI
  18. #define TSL_CLK PORTA_PA0    //定义线性传感器的端口 CLK
  19. #define TSL_SI1  PORTA_PA3    //定义线性传感器的端口 SI
  20. #define TSL_CLK1 PORTA_PA2    //定义线性传感器的端口 CLK

  21. //控制参数
  22. #define PRINT_AD        (1)       //设置串口打印数据类型,0:打印二值化数据,1:打印AD值
  23. #define THRESHOLD       (100)     //设置二值化阈值
  24. #define WINDOW_WIDTH    (128)     //设置串口打印的像素个数,最大128,最小0

  25. //直立控制
  26. float TLYLDZ1=1950;
  27. float TLYLDZ2=1950;
  28. float TLYLDX1=1950;
  29. float TLYLDX2=1950;
  30. //#define TLYLD 1950           //陀螺仪零点,前倾则增加
  31. float TLYBL=0.536;          //陀螺仪比例
  32. float TLYBLZ2=0.536;          //陀螺仪比例
  33. float TLYBLX1=0.536;         //陀螺仪比例
  34. float TLYBLX2=0.536;          //陀螺仪比例

  35. #define JSDLD 1365           //加速度计零点,往前跑则增加
  36. float KP=700.0;
  37. float KD=20.5;  
  38. float Tg =2.0;
  39. float kjifen=150.0;



  40. //速度控制
  41. float SPEED_CONTROL_P=30;
  42. float SPEED_CONTROL_I=0;
  43. float SPEED_CONTROL_D=0.0;
  44. int k=1;
  45. float speedK=1;
  46. #define M_SQ 0   //电机死区
  47. int M_SQL=1500;   //电机死区
  48. int M_SQR=1200;   //电机死区
  49. #define CAR_SPEED_SET_MAX -500
  50. int CAR_SPEED_SET =0;
  51. #define SPEED_CONTROL_OUT_MAX 8000
  52. #define SPEED_CONTROL_OUT_MIN -8000

  53. #define gyroPin_Z 5
  54. #define accPin_Z 4
  55. #define accPin_Y 3
  56. #define accPin_X 2

  57. int accOffset=1365;
  58. float angleAZ=0,angleAX=0,angleAY=0,angleA=0,angleFilter=0;

  59. //定义全局变量
  60. unsigned char c,cc;
  61. int CCDTime=0,ccdMultiple=1,CCDBL=3;
  62. byte ADV[2][128]={0,0};         //声明数组,用于存放采集的线性数值
  63. byte CCDLine[128]={0};
  64. int CCDDebugSwitch=1,CCDDebugSwitch2=0;
  65. float FZBL= 0.5;//0.35
  66. float FZBL1=0.6;
  67. int CCDt;
  68. long CCDa;
  69. #define DCCD 5
  70. int FZ,CCDAvr,Rblack,LastRblack,Lblack,LastLblack,LineCenter=64;
  71. int CCDEdge=0,Threshold,ThresholdMax,ThresholdMin;
  72. int CCDAvr0=0,obstacleSign=0,obstacleCounter=0;
  73. char scratchLine=false,StopCarOn;
  74. int scratchLineCount=0;
  75. unsigned long scratchLineTimer;
  76. int edge[20]={0};
  77. int FZ1,CCDAvr1,Rblack1,LastRblack1,Lblack1,LastLblack1,LineCenter1=64;
  78. int LastC1=64,LastC2=64,LastC3=64;;
  79. int trackWidth=73;
  80. float sWeight=0.6;
  81. float dWeight=0.4;
  82. char CCDFirstTime=true;
  83. float gyro,Aangle;
  84. int Lspeed,Rspeed,LspeedJF,RspeedJF;
  85. float gyro,angle,jifen;
  86. int speed,AngleControlOut;  

  87. float KDIR=70,DDIR=-5;      //转向比例系数
  88. int dcPeriod=1;
  89. float DError,DLastError,DDError;;
  90. float g_fDirectionControlOutNew=0,g_fDirectionControlOutOld=0,g_fDirectionControlOut=0,ZX;
  91. int g_nDirectionControlPeriod;
  92. int g_nDirectionControlCount;
  93. char MotorEnable=true;
  94. int LOUT,ROUT;
  95. float g_fCarSpeed,g_fSpeedControlIntegral=0,g_fSpeedControlOutOld=0,g_fSpeedControlOutNew=0,g_fSpeedControlOut=0;
  96. int g_nSpeedControlCount = 0;
  97. int g_nSpeedControlPeriod = 0;
  98. int scPeriod=8;  
  99. int ControlFlag=0;
  100. int Lspeed,Rspeed,LspeedJF,RspeedJF;
  101. float gyro,Aangle;
  102. #define CMD_TURN_LEFT '!'
  103. #define CMD_TURN_RIGHT '@'
  104. #define CMD_FORWARD '#'
  105. #define CMD_BACKWARD '


  106. #define CMD_RUN '%'
  107. #define CMD_STOP '^'   
  108. #define CMD_SET_SPEED '&'
  109. #define CMD_SET_GYROOFFSET '&'

  110. char debug=1;
  111. unsigned long gyroTimer=0;
  112. float weightFlag=0;
  113. float GyroSense=0.01;
  114. float GyroSense2=0.67;
  115. float AccSense=800;//mV
  116. float gravity=0,gravityG=1,gravityError;
  117. float gravityGate=0.06,gravityVibrationGate=0.2;
  118. float weight=0.99;
  119. float weight1=0.995,weight2=0.98;
  120. float Setpoint=-56,OriginPoint=-56,Input=0,Output=0; //前倾角度增大,后仰减小
  121. int ValueK;
  122. float kp=60,kd=1;//kp=1250,kd=18;  kp=60,kd=1;
  123. float ka=0.1;
  124. float Error,dErr,LastErr=0;
  125. float val_kp,val_kd;

  126. float MMperPulse=0.14165,PulseperMM=7.05965;
  127. float SetSpeed=0,SetSpeedMM=0,fspeed,sp=1,si=0;
  128. float SError=0,SErrI=0;
  129. float SOutput=0;

  130. float angleG2=0,angleFilter2=0;
  131. float angleGY=0,angleFilterY=0;
  132. float angleA2=0;

  133. unsigned char  CCDBuf[128]=0;
  134. int CCDBuf2[128]=0,CCDBuf3[128]=0;
  135. float tangent[46]={
  136.   1.000000,1.035530,1.072369,1.110612,1.150368,1.191754,1.234897,1.279942,1.327045,
  137.   1.376382,1.428148,1.482561,1.539865,1.600334,1.664279,1.732051,1.804048,1.880726,
  138.   1.962610,2.050304,2.144507,2.246037,2.355852,2.475087,2.605089,2.747477,2.904211,
  139.   3.077683,3.270852,3.487414,3.732050,4.010781,4.331475,4.704630,5.144553,5.671281,
  140.   6.313751,7.115368,8.144345,9.514362,11.430049,14.300661,19.081127,28.636232,57.289875,57.289875,
  141. };
  142. #endif
复制代码


回复 支持 反对

使用道具 举报

4

主题

796

帖子

0

精华

跨届大侠

Rank: 10Rank: 10Rank: 10

积分
10578

优秀会员奖章活跃会员奖章论坛元老奖章在线王奖章

威望
5540
贡献
3174
兑换币
3043
注册时间
2013-9-30
在线时间
932 小时
116#
发表于 2014-5-2 19:41:03 | 只看该作者
Malc 发表于 2014-5-2 10:31
我的车子速度这块也确实没做好,后来因为时间问题,就没有接着去研究了,比赛的时候就是用直立控制去加减 ...

嗯嗯...谢谢学长..嘿嘿..审核终于过了...今天我又重构了一下代码..车子现在直立的硬度又提高了...
回复 支持 反对

使用道具 举报

13

主题

250

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3621
威望
1776
贡献
1079
兑换币
1136
注册时间
2013-11-19
在线时间
383 小时
117#
发表于 2014-6-22 16:34:22 | 只看该作者
projecta 发表于 2014-3-25 17:04
最近直立车老抖,加了低通就好了,有用

同学,低通的程序是怎么样的?给个资料也行,谢谢了
回复 支持 反对

使用道具 举报

13

主题

250

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3621
威望
1776
贡献
1079
兑换币
1136
注册时间
2013-11-19
在线时间
383 小时
118#
发表于 2014-6-22 16:37:25 | 只看该作者
wmslecz 发表于 2014-3-27 22:42
嘿嘿..好的..谢谢学姐...我用的是FIR 9阶 wp=2 ws=3  然后加之卡尔曼出来的..我试试把陀螺仪的信任度弄大 ...

同学,能分享些FIR低通滤波的资料吗
回复 支持 反对

使用道具 举报

13

主题

250

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3621
威望
1776
贡献
1079
兑换币
1136
注册时间
2013-11-19
在线时间
383 小时
119#
发表于 2014-6-22 16:37:50 | 只看该作者
直立摄像头 发表于 2014-4-4 09:47
惯性滤波吧

能不能给下几种滤波的资料呀,很需要,谢谢了
回复 支持 反对

使用道具 举报

13

主题

250

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3621
威望
1776
贡献
1079
兑换币
1136
注册时间
2013-11-19
在线时间
383 小时
120#
发表于 2014-6-22 16:47:41 | 只看该作者
Malc 发表于 2014-5-2 10:31
我的车子速度这块也确实没做好,后来因为时间问题,就没有接着去研究了,比赛的时候就是用直立控制去加减 ...

学姐,FIR低通滤波的资料整理好了吗,现在特别需要啊,没整理好的给个也行啊、、
回复 支持 反对

使用道具 举报

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

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-6-29 12:25 , Processed in 0.053152 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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