写过一些程序以后,想让MCU自己“思考”起来,真正带算法会思考的程序。PID就是一种会思考的自动算法。
PID由“比例(proportional)、积分(integral)、微分(derivative)”构成,对偏差进行比例、积分、微分的计算从而去达到设定目标的控制,是一种会思考的算法。
比如无人机、平衡车、汽车的定速巡航、热水器的温度控制器等就运用了PID算法:需要将某一个物理量“保持稳定”(比如维持平衡,稳定温度、转速等),PID算法非常实用。
比如,控制一个“热得快”,让一锅水的温度保持在60℃
这么简单的任务,为啥要用到微积分的理论呢你一定在想:
这个控制非常简单,小于60度就让它加热,大于60度就断电,就可以了?几行代码用分分钟写出来。
没错,在要求不高的情况下,确实可以这么弄。
如果控制对象是一辆汽车呢?
要是希望汽车的车速保持在55km/h不动,你还敢这样做么?
设想一下,假如汽车的定速巡航在某一时间测到车速是50km/h。它立刻命令发动机:加速!
结果,发动机那边突然来了个100%全油门,嗡的一下,汽车急加速到了60km/h。这时电脑又发出命令:刹车!,这样人都会晕头吐了。
所以,在大多数场合中,用“开关量”来控制一个物理量,就显得比较简单粗暴了。而且,控制对象具有惯性。比如你将一个加热器拔掉,它的“余热”(即热惯性)可能还会使水温继续升高一小会。
这时,就需要一种算法:
它可以控制物理量带到目标附近
它可以“预见”这个量的变化趋势
它可以消除因为散热、阻力等因素造成的静态误差
因此运用PID算法就可以完美解决。
P,I,D是三种不同的调节作用,既可以单独使用,也可以两个使用(PI,PD),也可以三个一起用(PID)。
Kp(比例系数)
P是控制比例。比例的作用最明显。
比如控制水温,有它现在的当前值,也有设定值。当两者差距不大时,就让加热器“轻轻地”加热一下;要是因为某些原因,温度降低了很多,就让加热器“稍稍用力”加热一下;要是当前温度比目标温度低得多,就让加热器“开足马力”加热,尽快让水温到达目标附近。
让偏差与Kp建立一个一次函数的关系,就可以实现最基本的“比例”控制了,Kp越大,调节作用越大,Kp调小会让调节作用更小。
比如制作一个平衡车,有了P的作用,你会发现,平衡车在平衡角度附近来回“摇晃”,比较难稳住。这时适当的加入Kd就可以解决摇晃的问题。
Kd(微分系数)
D是控制超调作用,防止震荡。
不难发现,只有P好像不能让平衡车站起来,水温也控制得晃晃悠悠,好像整个系统不是特别稳定,总是在“抖动”。
需要一个控制作用,让被控制的物理量的“变化速度”趋于0,即类似于“阻尼”的作用。
因为,当比较接近目标时,P的控制作用就比较小了。越接近目标,P的作用越温柔。有很多内在的或者外部的因素,使控制量发生小范围的摆动。D的作用就是让物理量的速度趋于0,
只要这个量具有了速度,D就向相反的方向用力,尽力刹住这个变化。
Kd参数越大,向速度相反方向刹车的力道就越强。
如果是平衡车,加上P和D两种控制作用,如果参数调节合适,它应该可以站起来了。
等等,PID好像还有一位。看起来PD就可以让物理量保持稳定,那还要I干嘛?
Ki(积分系数)
I是控制静态误差,减小静态误差作用,达到平衡,接近目标的作用。
例如给水加热。假如有个人把我们的加热装置带到了非常冷的地方,开始烧水了,需要烧到60℃。
在P的作用下,水温慢慢升高。直到升高到55℃时,他发现了一个不好的事情:天气太冷,水散热的速度,和P控制的加热的速度相等了。
这可怎么办?
P这样想:跟目标已经很近了,只需要轻轻加热就可以了。
D这样想:加热和散热相等,温度没有波动,不用调整什么了。
因此,水温永远地停留在55℃,永远到不了60℃。
根据常识,我们知道,应该进一步增加加热的功率。可是增加多少该如何计算呢?
前辈科学家们想到的方法是真的巧妙。设置一个积分量。只要偏差存在,就不断地对偏差进行积分(累加),并反应在调节力度上。
这样一来,随着时间的推移,只要没达到目标温度,这个积分量就不断增加。系统就会慢慢意识到:还没有到达目标温度,该增加功率了。
到了目标温度后,假设温度没有波动,积分值就不会再变动。这时,加热功率仍然等于散热功率,温度是稳稳的60℃。
Ki的值越大,积分时乘的系数就越大,积分效果越明显。
I在使用时还有个问题:需要设定积分限制。防止在刚开始加热时,就把积分量积得太大,难以控制。
PID算法有位值式和增量式算法
PID位值式算法:
公式
U(t)=Kp*e(k)+Ki*∑e(k)+Kd*[e(k)−e(k−1)]
比例P : e(k) 本次偏差(用户设定的值(目标值) - 控制对象的当前的状态值)
积分I : ∑e(i) 误差的累加(连续域上的积分对应离散的求和)
微分D : e(k) - e(k-1) 这次误差-上次误差(连续域上的微分对应差分)
U(t):代表输出
位置式PID是当前系统的实际位置,与想要达到的预期位置的偏差,进行PID控制;直接赋值新的PWM调节更加灵敏。
使用时,Ki会不断的积累误差,一旦控制输出出错(控制对象的当前的状态值出现问题 ),u(k)的大幅变化会引起系统的大幅变化,所以在u(k)达到最大和最小时,要停止积分作用,并且要有积分限幅和输出限幅。
位置式 PID 适用于执行机构不带积分部件的对象,如平衡车和温控系统等。
PID增量式算法:
公式
U(t)=Kp*[e(k)−e(k−1)]+Ki*e(k)+Kd*[e(k)−2e(k−1)+e(k−2)]
比例P : e(k)-e(k-1) 这次误差-上次误差
积分I : e(i) 误差
微分D : e(k) - 2e(k-1)+e(k-2) 这次误差-2*上次误差+上上次误差
U(t):输出的增量,相当于对位置式进行了微分后返回的东西再积分
增量式PID根据公式可以看出,一旦确定了 Kp、Ki 、Kd,使用前后三次测量值的偏差, 即可由公式求出控制增量。
而得出的控制量u(k)对应的是近几次位置误差的增量,而不是对应与实际位置的偏差没有误差累加。
增量式PID中不需要累加。控制增量Δu(k)的确定仅与最近3次的采样值有关,容易通过加权处理获得比较好的控制效果,并且在系统发生问题时,增量式不会严重影响系统的工作
如果在我未开启电机驱动而开启了PID计算时输出的PWM会不断攀升。
增量型 PID,是对位置型 PID 取增量,这时控制器输出的是相邻两次采样时刻所计算的位置值之差,得到的结果是增量,即在上一次的控制量的基础上需要增加(负值意味减少)控制量。
学习了这些知识,是不是蠢蠢欲动啦,赶紧开干起来吧!做自己的智能控制吧!让子弹分起来!