1、平衡小车之家出品1平衡小车调试指南接下来将和大家一起以工程的思想去完成一个平衡小车的调试,包括平衡小车的直立环、速度环、转向环,一般我们是先调试直立环,再调试速度环,最好调试转向环。另外需要说明的是,因为我们使用的电机性能非常好,对PID参数不敏感,也就是说每个参数的取值范围都很广,这将对我们接下来的调试有很大的帮助。1.1 平衡小车直立控制调试平衡小车直立环使用PD(比例微分)控制器,其实一般的控制系统单纯的P控制或者PI控制就可以了,但是那些对干扰要做出迅速响应的控制过程需要D(微分)控制。下面是直立PD控制的代码:intbalance(floatAngle,float Gyro) flo
2、at Bias,kp=300,kd=1;intbalance;Bias=Angle-0; /计算直立偏差balance=kp*Bias+Gyro*kd; /计算直立PWMreturn balance; /返回直立PWM入口参数是平衡小车倾角和Y轴陀螺仪(这个取决MPU6050的安装),我们的小车前进方向是MPU6050的X轴的正方向,电机轴与Y轴平行。前面两行是相关变量的定义,第三行是计算角度偏差,第四行通过PD控制器计算直立PWM,最后一行是返回。调试过程包括确定平衡小车的机械中值、确定kp值的极性(也就是正负号)和大小、kd值的极性和大小等步骤。在调试直立环的时候,我们要屏蔽速度环和转向环
3、,如下图所示:平衡小车之家出品21.1.1确定平衡小车的机械中值把平衡小车放在地面上,绕电机轴旋转平衡小车,记录能让小车接近平衡的角度,一般都在0附近的。我们调试的小车正好是0度,所以就是 Bias=Angle-0;1.1.2确定kp值的极性(令kd=0)首先我们估计kp的取值范围。我们的PWM设置的是7200代表占空比100%,假如我们设定kp值为720,那么平衡小车在10的时候就会满转。根据我们的感性认识,这显然太大了,那我们就可以估计kp值在0720之间,首先大概我们给一个值kp=-200,我们可以观察到,小车往哪边倒,电机会往那边加速让小车到下,就是一个我们不愿看到的正反馈的效果。说明
4、kp值的极性反了,接下来我们设定kp=200,这个时候可以看到平衡小车有直立的趋势,虽然响应太慢,但是,我们可以确定kp值是正的。具体的数据接下来再仔细调试。1.1.3确定kp值的大小(令kd=0,请结合本小节开头的直立控制函数理解)确定参数的原则是:kp一直增加,直到出现大幅度的低频抖动。设定kp=200,这个时候我们可以看到,小车虽然有平衡的趋势,但是显然响应太慢了。设定kp=350,这个时候我们可以看到,小车虽然有平衡的趋势,而且响应有所加快,但是响应还是不足以让小车保持平衡。设定kp=500,这个时候我们可以看到,小车的响应明显加快,而且来回推动小车的时候,会有大幅度的低频抖动。说明这
5、个时候kp值已经足够大了,需要增加微分控制削弱p控制,抑制低频抖动。1.1.4确定kd值的极性(令kp=0)我们得到的MPU6050输出的陀螺仪的原始数据,通过观察数据,我们发现最大值不会超过4位数,再根据7200代表占空比100%,所以我们估算kd值应该在02之间,我们先设定kd=-0.5,当我们拿起小车旋转的时候,车轮会反向转动,并没有能够实现跟随效果。这说明了kd的极性反了。接下来,我们设定kd=0.5,这个时候我们可以看到,当我们旋转小车的时候,车轮会同向以相同的速平衡小车之家出品3度跟随转动,这说明我们实现了角速度闭环,至此,我们可以确定kd的极性是正的。具体的数据接下来再仔细调试。
6、1.1.5确定kd值的大小(令kp=500,请结合本小节开头的直立控制函数理解)确定参数的原则是:kd一直增加,直到出现高频抖动。设定kd=0.5,这个时候我们可以看到,低频大幅度频抖动已经基本消除。设定kd=1,这个时候我们可以看到,整体性能已经非常棒。设定kd=1.7,这个时候我们可以看到,小车开始出现高频剧烈抖动(调试过程遇到这种情况请马上关闭小车,长时间高频抖动会导致驱动被烧坏的)至此,我们可以确定得到kp=500,kd=1.7是P、D参数的最大值。然后我们进行最关键的一步,对每个系数乘以0.6,取整得到kp=300,kd=1,这就是最终我们需要的参数,这样做的原因是,我们之前得到的参
7、数是kp、kd最大值,理想值是根据我们的工程经验,对每个数据乘以0.6得到。这个时候我们可以看到,小车没有任何的抖动,非常平稳,但是依然无法保持长时间的直立,直立很短一段时间后会往一个方向加速倒下。这个等我们下面加上速度环才能得到更好的性能。只有直立环是很难让小车达到很好的直立效果的。至此,直立调试部分就告一段落了。1.2 平衡小车速度控制调试平衡小车速度环使用PI(比例积分)控制器,这也是速度控制最常使用的控制器。PI调节器是一种线性控制器,它根据给定值与实际输出值构成控制偏差,将偏差的比例(P)和积分(I)通过线性组合构成控制量,对被控对象进行控制。下面是速度PI控制的代码(不包括遥控部分
8、,遥控部分后面再单独讲解):intvelocity(int encoder_left,int encoder_right) staticfloatVelocity,Encoder_Least,Encoder;staticfloat Encoder_Integral;float kp=80,ki=0.4;平衡小车之家出品4Encoder_Least =(Encoder_Left+Encoder_Right)-0;Encoder *=0.7;Encoder += Encoder_Least*0.3;Encoder_Integral +=Encoder;Velocity=Encoder*kp+Enc
9、oder_Integral*ki;returnVelocity;前面3行是相关变量的定义,第四行是获取最新的速度偏差,第5和第6行是对速度偏差进行低通滤波,第7行是对偏差积分得到位移。第8行是使用速度PI控制器计算速度控制PWM,第9行是返回。以上代码实现的效果是:使小车在保持平衡的同时速度为零。调试过程包括计算速度偏差、确定kp和ki值的极性(也就是正负号)与大小。1.2.1计算速度偏差根据公式 偏差=测量值-目标值测量值我们使用左右编码器之和表示,我们没有必要纠结于是否要除以2,因为这样就引入舍去误差,我们需要的其实是一个可以表示速度变化的变量。另外,我们的目标速度设置为零。所以,可以得到
10、Encoder_Least =(Encoder_Left+Encoder_Right)-0;然后,我们对速度值进行低通滤波,具体的系数由工程经验得到。这样做的目的是为了减缓速度值的变化,防止速度控制对直立造成干扰,因为平衡小车系统里面,直立控制是主要的,其他控制对于直立来说都是一种干扰。具体实现代码如下:Encoder *=0.7;Encoder += Encoder_Least*0.3;1.2.2确定kp与ki值的极性平衡小车之家出品5为了调试方便,接下来我, 先关闭之前已经调试好的直立控制部分,如下图所示:积分项由偏差的积分得到,所以积分控制和比例控制的极性相同的,而根据工程经验,在不同的
11、系统中,PID参数相互之间会有一定的比例关系。在我们的平衡小车速度控制系统里面,一般我们可以把ki值设置为ki=kp/200;这样,只要我们可以得到kp值的大小和极性,就可以完成速度控制部分的参数整定了。显然,这样大大缩短了PID参数整定的时间。我们通过STM32定时器的编码器接口模式对编码器进行四倍频,并使用M法测速(每10ms的脉冲数)得到小车的速度信息,通过观察数据,我们发现两路编码器相加最大值在160左右,而由经验可知,一般平衡小车行驶的最快速度不会超过电机最大速度的40%,再根据7200代表占空比100%,我们可以大概估算 kp最大值=7200/(160*40%)=112.5另外要说
12、明的是,虽然这里的PI控制器也是速度控制常用的一种控制,但是和普通的调速系统不一样,这里的速度控制是正反馈的,当小车以一定的速度运行的时候,我们要让小车停下来,小车需要行驶更快的速度去“追”,小车运行的速度越快,去“追”的速度也就越快,所以这是一个正反馈的效果。如果使用常规的速度负反馈,当小车以一定的速度运行的时候,我们通过减速让小车慢下来,小车会因为惯性向前倒下。下面介绍一种确定速度控制是正反馈还是负反馈的方法。根据之前的估计,先设定kp=-50,ki=kp/200,当我们拿起小车,旋转其中一个小车轮胎的时候,根据我们设定的速度偏差Encoder_Least =(Encoder_Left+E
13、ncoder_Right)-0;另外一个车轮会反向转动,让偏差趋向于零。这就是常规的速度控制里面的负反馈,不是我们需要的效果。接下来设定kp=50,ki=kp/200,此时,当我们旋转其中一个小车轮胎的时候,两个轮胎会往相同的方向加速,直至电机的最大速度,这是典型的正反馈效果,也是我们期望看到的。至此,我们可以确定kp,ki平衡小车之家出品6的符号应该是正的。1.2.3.确定kp与ki的大小(开启直立控制)下面我们进行平衡小车速度控制kp与ki值的整定,此时需要打开直立环,因为我们需要结合直立环观察速度环对直立环的影响,如下图所示:在平衡小车速度控制系统里面,一般我们可以把ki值设置为ki=k
14、p/200,所以我们只需要对kp值进行整定即可。在调试的过程中设定速度控制的目标为零,所以,调试的理想结果应该是:小车保持平衡的同时,速度接近于零。实际上,因为小车存在比较大的转动惯量和惯性,并且齿轮减速器存在死区,很难调试到让小车完全保持静止的,我们调试平衡小车只是为了学习PID控制算法,所以,没有必要花太多的时间去调参数,让小车完全静止,只要能够大概实现我们需要的功能,并在这个过程对PID有进一步的了解即可。首先,设定kp=40,ki=kp/200这个时候我们可以看到,小车的速度控制比较弱,很难让速度恒定。设定kp=60,ki=kp/200这个时候我们可以看到,小车的速度控制的响应有所加快
15、,但是来回摆动还是有点大,还是不足以让小车保持接近于静止的状态。设定kp=80,ki=kp/200这个时候我们可以看到,小车已经性能很完美了,我们接下来尝试加大kp值看一下效果。设定kp=100,ki=kp/200这个时候我们可以看到,小车虽然回正力度增大了,而且响应更加快了,但是稍微加入一点的干扰都会让小车大幅度摆动,抗干扰能力明显不足,所以这组参数不可取。至此,我们可以确定得到kp=80,kd=0.4是速度控制P、I参数的理想值。我们再来体检一下速度控制负反馈在平衡小车里面的效果,设定kp=-80,ki=kp/200这个时候我们可以看到,小车会迅速往一个方向倒下。也就是说常规的速度负反馈在
16、我们这边是“帮倒忙”了!至此,速度控制调试部分就告一段落了,如果要加入遥控前进后退功能的话,速度PI控制函数应该改成如下所示(其中加粗部分为是实现遥控功能的代码):平衡小车之家出品7int velocity(int encoder_left,int encoder_right) static floatVelocity,Encoder_Least,Encoder,Movement;static float Encoder_Integral;float kp=80,ki=0.4;if(1=Flag_Qian) Movement=-90; /=如果前进标志位置1 位移为负elseif(1=Flag
17、_Hou) Movement=90; /=如果后退标志位置1 位移为正else Movement=0;Encoder_Least =(Encoder_Left+Encoder_Right)-0; /获取最新速度偏差=测量速度(左右编码器之和)-目标速度(此处为零)Encoder*= 0.7; /=一阶低通滤波器Encoder+= Encoder_Least*0.3; /=一阶低通滤波器Encoder_Integral +=Encoder; /=积分出位移 积分时间:10msEncoder_Integral=Encoder_Integral-Movement; /接收遥控器数据,控制前进后退if
18、(Encoder_Integral10000) Encoder_Integral=10000; /积分限幅if(Encoder_Integral-10000) Encoder_Integral=-10000; /限制遥控最大速度Velocity=Encoder*kp+Encoder_Integral*ki; /=速度控制if(Turn_Off(Angle_Balance,Voltage)=1) Encoder_Integral=0; /电机关闭后清除积分returnVelocity; 关于这个包括了遥控前进后退的速度控制函数,做如下解析:1.在usart3.c中的串口3接收中断函数,改变Flag_Qian和Flag_Hou,进而遥控小车。2.Encoder_Integral=Encoder_Integral-Movement; 遥控的速度通过积分融入速度控制器,减缓了速度突变对直立控制的影响。3.积分限幅是增加了遥控之后必不可少的,如果没有积分限幅,就无法限制小车的最大前进速度。这样在遥控的过程中,小车很容易倒下。换句话说积分的最大赋值决定了小车的最大前进速度,而Movement值决定了小车的给定速度。