浅谈滚球控制系统的设计与实现 作者:林宏伟 学校:某校 时间:2019-7-8 又到了两年一次的全国电子设计竞赛了,大家肯定都在认真准备比赛了,本人也在学校专心准备比赛中,闲着无聊就把13年,15年,17年的国赛题目 (控制类)全做了一遍,嗯,十分理想吧 ,现在我就和大家分享下我在完成17年滚球控制系统这个题目的思路和程序代码(亲测有效)。 ok,咋们先看一下17年滚球控制系统的具体要求,如下图所示,看任务要求知,我们需要一个边长65*65cm的正方形板子,我设计的是30*30cm的正方形板(经过测试确实是板子越大越容易实现功能,调试起来十分方便),之所以用小的是因为不会占地方,小嘛!
首先,我们先来确定这个滚球控制系统的结构,多年比赛经验,结构一定要确定好,不然后期一堆坑等着你(踩多了)。ok,下面是我的结构图。注意观察舵机臂和板子连接处的结构,舵机臂与板子连接时千万不要固定死,一定要留有扭转的结构,这样板子才不会变形,如果咋们把舵机臂和板子连接起来固定死,这样会让板子变形,但是如果加个类似万向节的结构就可以避免板子变形了(板子变形是十分严重的现象,后期调试十分奔溃!!!!) 下面是硬件和结构清单: 1.两个180舵机 2.万向节*3 一个固定板子中心点,另外两个作为舵机臂和板子的连接结构 3.舵机臂(可以自己打印也可以直接买) 4.STM32f1最小系统*1,降压*2(舵机要单独供电!!!) 接下来,我们来分析这个系统的主要部分分为多少个,其实这个滚球控制系统可以分为两个部分:识别部分和驱动部分。 识别部分:识别的话我选用openmv,因为这个模块入门非常快速,基本有点python的入门知识就可以很快入门这个openmv,识别程序如下所示,利用图像的灰度,寻找小球,仔细调节小球的阈值就可以了,这部分不需要花多少时间,例程也是直接上openmv官网参考和修改的,十分简单,主要串口通信时的通信协议!!!!! - while(True):
- clock.tick()
- Blank=0
- img = sensor.snapshot()#抓取图像
- blobs = img.find_blobs([green_threshold],x_stride=9,y_stride=9,area_threshold=6)#找点
- if blobs: #找到了小球
- for b in blobs:
- img.draw_cross(b[5],b[6]) #在右上方的监视器画十字叉丝
- else:
- Blank=1
- if Blank:
- output_str=bytearray([0xff,0xff]) #打印坐标
- print('NoFind\n')
- else:
- output_str=bytearray([int(b[5]),int(b[6])]) #打印坐标
- print('Find:')
- print(' ', b[5],b[6])
-
复制代码 PID算法如下,我是直接移植平衡小车之家的平衡小车的PID算法,这套算法十分成熟,所以个人建议不需要花太多时间去修改,最多就改改幅度值,积分限幅等,如果想理解PID,大家可以去网上搜索下PID算法的解说,网上资源十分多,我也是参考网上的资料去理解PID算法的 - float Differential,Bias,Balance_Ki=0.2;//定义差分变量和偏差
- static float Last_Bias,Integration,Balance_Integration,Flag_Target; //上一次的偏差值
- int balance;//平衡的返回值
- Bias=(Angle-Zero_Y); //===求出平衡的角度中值 和机械相关
- Differential=Bias-Last_Bias; //求得偏差的变化率
-
- Flag_Target=0;
- Integration+=Bias;
- if(Integration<-500) Integration=-500; //积分限幅
- if(Integration>500) Integration=500;
- Balance_Integration=Integration*Balance_Ki; //积分控制
-
- balance=Balance_Kp*Bias/100+Balance_Kd*Differential/10+Balance_Integration; //===计算平衡控制的舵机PWM PD控制 kp是P系数 kd是D系数
- Last_Bias=Bias; //保存上一次的偏差
- return balance; //返回值
复制代码 控制程序我采用定时中断的方式,每15ms查询一次,利用中断来实现控制小球滚到区域2,如下所示,这里的Zero_X=180,Zero_Y=105是小球在区域2时候的坐标数值,可以通过摄像头获取小球停止在区域2的坐标,也就是说这里Zero_X=180,Zero_Y=105是这套系统的期望值,我们的任务就是整定PID参数让小球可以到达期望的坐标位置上,其实PID就是对偏差进行积分微分比例运算,使偏差接近于0.开始我设定这个坐标作为期望值,然后先置零Y轴的电机控制程序(不动)后再开始调节一个X轴的PID,因为X,Y轴的PID其实都是一样的,也就是说调节好一个轴,另外一个轴也是一样的参数。开始先调节比例参数P,P的作用就是增加系统的回复力,调节到合适的时候出现的现象就是小球在区域2来回滚动,不会超过太多,滚动几圈后就会脱离(正常现象),如果P过大就会出现超调,这时候系统回复力很大,一下子就把球甩出去了(哈哈),P过小就回复不过来,整体感觉很慢!我这边是用PD控制器,调节好P后就可以开始调D,这时候P不需要置零,直接加D进去调节,混合调节,这样现象更加明显,D在这里的作用就是提高系统的与判性,也就是未卜先知,提前知道小球要滚到那里啦,而且D是抑制P的。D只能慢慢加,加到合适时候,整个系统就会十分稳定,小球也很快到达指定的区域啦! - Zero_X=180,Zero_Y=105;
-
- Position_Y=rxbuf[1];
- Position_X=rxbuf[0];
- //位置控制模式中,对舵机的速度进行限幅控制,防止舵机卡死
- if(Target_X<-Max_Target) Target_X=-Max_Target;
- if(Target_X>Max_Target) Target_X=Max_Target;
- if(Target_Y<-Max_Target) Target_Y=-Max_Target;
- if(Target_Y>Max_Target) Target_Y=Max_Target;
- if(start == 0) Target_Y = 0,Target_X = 0;
- //赋值PWM
- Set_Pwm(Target_Y,Target_X);
- Last_Target_X=Target_X; //保存上一次的值
- Last_Target_Y=Target_Y;
复制代码(由于不能发视频我就发图了。。哈哈)
这个滚球控制系统只要实现这个功能后其他功能都是一样的啦,只是修改期望值和时间而已
END |