PID算法

所谓的PID,指的是proportion,integration,differentiation,比例,积分,微分。

PID的基本思路是根据偏差量的大小,运用比例P、积分I、微分D计算出一个控制量 uu,将这个控制量输入被控制的系统,系统接收到该输入量后会输出一个相应的输出量,PID控制器再检测该输出量,并再计算偏差,然后再循环以上过程。

u(t)=Kp(e(t)+1Ti0te(t)dt+Tdde(t)dt)u(t)=K_p \Bigg( e(t)+\dfrac{1}{T_i}\int^t_0e(t)dt+T_d\dfrac{de(t)}{dt}\Bigg)

  • KpK_p —— 控制器的比例系数;
  • TiT_i —— 积分时间常数;
  • TdT_d —— 微分时间常数;
  • u(t)u(t) —— PID控制器的输出信号;
  • e(t)e(t) —— 给定值r(t)r(t)与测量值之差。

公式可简化为:

对于离散值:

u(t)=Kpe(t)+Kin=0te(t)+Kd(e(t)e(t1))u(t)=K_p * e(t) + K_i * \sum_{n=0}^t e(t) + K_d * (e(t) - e(t-1))

  • KpK_p —— 控制器的比例系数;
  • KiK_i —— 控制器的积分系数;
  • KdK_d —— 控制器的微分系数;
  • u(t)u(t) —— PID控制器的输出信号;
  • e(t)e(t) —— 给定值r(t)r(t)与测量值之差。
  • e(t1)e(t-1) —— 上一次给定值r(t)r(t)与测量值之差。

一些文档中:

  • Ki=KpTTiK_i=K_p*\dfrac{T}{T_i}
  • Kd=KpTdTK_d=K_p*\dfrac{T_d}{T}
  • TiT_i 为控制器的积分时间,也称积分系数,TdT_d 为控制器的微分时间,也称微分系数。以 TT 作为采样周期

对于连续值:

u(t)=Kpe(t)+Ki0te(τ)dτ+Kdde(t)dtu(t)=K_p \, e(t) + K_i \int^t_0e(\tau)d\tau + K_d \, \dfrac{de(t)}{dt}

PID是一种闭环控制系统,闭环控制(Closed Loop Control System):需要将控制的结果反馈回来与希望值比较,并根据它们的误差调整控制作用的系统。例如:

  • 调节水龙头——首先在头脑中对水流有一个期望的流量,水龙头打开后由眼睛观察现有的流量大小与期望值进行比较,并不断的用手进行调节形成一个反馈闭环控制;
  • 骑自行车——同理,需要不断的修正行进的方向与速度形成闭环控制。

闭环控制系统通常会由以下6个环节组成。

我们拿“维持水缸水位高度在1米”为例,来详解闭环控制中的每个环节:

  • 传感器:人工测量当前水位高度
  • 目标量:维持水缸水位高度在1米
  • 偏差量目标量 - 当前水位高度
  • 控制器:根据偏差量计算出执行量
  • 执行量:传给执行器的入参
  • 执行器:人工用水桶向水缸中加水

其中传感器目标量偏差量执行量执行器 这5个环节都比较简单,一眼就能看明白意思。最关键的环节控制器相对复杂一些,在控制器环节选择不同的控制算法,根据偏差量计算出执行量也不同。

各部分理解

以经典的注水问题为例。小明现在有一个任务:有个水桶,水桶的水位高度需要时刻保持1m,目前水桶的水是0.2m,小明采用比例的方式加水(即P),即每次测量与1m 的误差,并加入与误差成比例的水量。

  • 传感器:人工测量水缸初始水位高度是0.2米
  • 目标量:维持水缸水位高度在1米
  • 偏差量:1米 - 0.2米 = 0.8米
  • 控制器:使用PID算法的比例控制,根据偏差量计算出执行量
  • 执行量:传给执行器的入参
  • 执行器:人工用水桶向水缸中加水

比例部分P

Kp=0.5K_p=0.5,公式可以抽象为下式:

执行量=比例P=比例P系数×偏差量执行量 = 比例P = 比例P系数\times 偏差量

第一次的误差:e(1)=10.2=0.8e(1)=1-0.2=0.8,于是加入的水为 Kpe(1)=0.5×0.8=0.4K_p*e(1)=0.5\times0.8=0.4,此时桶内水 0.60.6

第二次的误差:e(2)=10.6=0.4e(2)=1-0.6=0.4,于是加入的水为 Kpe(2)=0.5×0.6=0.3K_p*e(2)=0.5\times0.6=0.3,此时桶内水 0.90.9

第三次的误差:e(3)=10.9=0.1e(3)=1-0.9=0.1,于是加入的水为 Kpe(3)=0.5×0.1=0.05K_p*e(3)=0.5\times 0.1=0.05,此时桶内水 0.950.95

以此类推,不断加下去,通过P控制就可以将水加满到1。

 

上述例子比较简单,单靠比例P就能完成任务,但现实情况往往只有比例P是不够的,我们再来看一个更复杂的情况,假设比例P系数仍然是0.5,但在每次加水的间隔,水缸都会漏掉0.1米高度的水。我们再从头模拟加水实验,看看具体结果会怎样?

如上图结果所示,当水位达到0.8之后,水位就不会继续增加了。因为,当水位等于0.8时,偏差量是0.2,每次往水缸中加水的量为执行量= 比例P= 0.2 * 0.5 = 0.1,而每次加水的间隔,水缸都会漏掉0.1米高度的水,所以加入的水和流出的水相抵消。

虽然,此时控制系统已达稳定状态,但实际值目标量之间的会存在一个稳定差值,这个差值叫稳态误差稳态误差非常常见,比如:控制空调温度会因为空气温差而降温、控制无人机固定高度会受重力影响往下掉、控制汽车定速巡航会有空气阻力和摩擦力的影响而减速,这些场景都会产生稳态误差。

关于系统稳态误差,引用胡寿松老爷子自动控制原理一书中的描述:

控制系统的稳态误差,是系统控制准确度的一种度量,通常称为稳态性能。在控制系统设计中,稳态误差是一项重要的技术指标,对于一个实际的控制系统,由于系统结构,输入作用的类型(控制量或扰动量) ,输入函数的形式(阶跃,斜坡或加速度)不同,控制系统的稳态输出不可能在任何情况下与输入量一致,也不可能在任何形式的扰动作用下都能准确地恢复到平衡位置。此外,控制系统中不可避免的存在摩擦,间隙,不灵敏区,零位输出等非线性因素,都会造成附加稳态误差。因此,控制系统的稳态误差是不可避免的,控制系统设计的任务之一,就是尽量减小系统的稳态误差,或者使稳态误差小于某一容许值。显然,只有当系统稳定时,研究稳态误差才有意义。对于不稳定系统而言,根本不存在研究稳态误差的可能性。

单单只用比例P控制闭环回路,是无法避免稳态误差问题的,因为比例P系数无法根据时间或次数累加,当存在外界干扰因素时,比例P系数无法动态调整大小,那么稳态误差就会一直存在。

假如我们引入时间的维度,就能获得2个神器 增幅器-积分I抑制器-微分D,他们分别解决比例P过小和过大的情况,比例P过小的话由增幅器-积分I 补充即可解决稳态误差问题,比例P过大由抑制器-微分D消减来防止过度震荡。

 

积分部分 I(增幅器)

Kin=0te(t)=Kin=0t1e(t)+Ki×e(t)K_i * \sum_{n=0}^t e(t)=K_i * \sum_{n=0}^{t-1} e(t)+K_i \times e(t)

我们先来看看增幅器积分I,它也可以理解为累加经验,当比例P过小,可以由积分I补充,它的原理是利用过去的时间不断累加。具体公式可抽象为:

比例P=比例P系数×偏差量(前文介绍的比例部分)积分I=上一次积分I+积分I系数×偏差量执行量=比例P+积分I比例P = 比例P系数\times 偏差量(前文介绍的比例部分)\\ 积分I = 上一次积分I + 积分I系数\times 偏差量\\ 执行量 = 比例P + 积分I

想象一下,如果用只比例P控制存在稳态误差,说明比例P过小,这时积分I就会不断累加到一个很大的值,来补充比例P,从而影响执行量

如果最终控制效果在目标量附近抖动,我们就能得到一个正负交替的偏差量,会在目标附近不断产生正负数累加到积分I积分I就会不断趋近于零,最终使控制效果趋于稳定。

仍然是上面的例子,Ki=0.2K_i=0.2

第一次,误差为 e(1)=0.8e(1)=0.8, 比例部分 Kpe(1)=0.4Kp*e(1)=0.4, 积分部分 Kie(1)=0.16K_i*e(1)= 0.16,加入水量 uuu(1)=0.4+0.16=0.56u(1)=0.4+0.16=0.56. 最终水位 0.2+0.560.1=0.66m0.2+0.56-0.1= 0.66m

第二次,误差为 e(2)=0.34e(2)=0.34,比例部分 Kpe(2)=0.17Kp*e(2)=0.17,积分部分 Kp(e(1)+e(2))=0.23(0.228)Kp*(e(1)+e(2))= 0.23(0.228),加入水量uu0.17+0.23=0.40.17+0.23=0.4。最终水位 0.66+0.40.1=0.96m0.66+0.4-0.1=0.96m

以此类推:

上一轮实验只用比例P控制存在稳态误差。本轮实验加入了积分I之后就有了累加效果,在未达到控制效果之前积分I会持续累加,在达到目标量之后积分I因为惯性会继续过量控制 ,同时偏差量会由正转负再转正,积分I也会由正转负再转正,最终积分I会持续抵消掉每次漏水0.1,控制效果趋于稳定 。

增幅器有他的危险性,如果系统出现意外或错误,增幅器可能会被累加到无限大,导致系统不可用,所以增幅器需要有一定的限制。

  • 限制幅度,在任意时刻都给积分I设定最大值和最小值。
  • 不运行时清零,当系统判断没有运行时,主动将积分I清零。

 

微分部分 D (抑制器)

前面我们已经分析了,积分环节能消除稳态误差,但是积分环境又会带来另外一个问题:积分环节会带来惯性。而且随着 KiK_i 值的变大,惯性也会边大,也就是前面提到的在达到目标量之后积分I因为惯性会继续过量控制。

为了消减惯性,我们引入微分运算,也就PID中的D。抑制器微分D,它也可以理解为预测未来,用当前的偏差量上一次偏差量,得到的结果就可能是下一次偏差量,用下一次偏差量提前参与到计算中,就可以防止执行量过大,产生超出目标量的问题。具体公式可抽象为:

比例P=比例P系数×偏差量(比例部分)积分I=上一次积分I+积分I系数×偏差量(积分部分)微分D=微分D系数×(偏差量上一次偏差量)(微分部分)执行量=比例P+积分I+微分D比例P = 比例P系数\times 偏差量(比例部分)\\ 积分I = 上一次积分I + 积分I系数\times 偏差量(积分部分)\\ 微分D = 微分D系数\times (偏差量 - 上一次偏差量) (微分部分)\\ 执行量 = 比例P + 积分I + 微分D

换个“汽车刹车”的例子,平稳驾驶的车辆,当发现前面有红灯时,为了使得行车平稳,基本上提前几十米就松油门踩刹车。当车辆离停车线非常近的时候,则使劲踩刹车使车辆停下来,整个过程可以看做一个加入微分D的控制策略。

可以看到,在刹车过程中,因为偏差量是越来越小的,所以 微分D=微分D系数×(偏差量上一次偏差量)微分D= 微分D系数\times (偏差量-上一次偏差量)一定是负数,在控制中加入一个负数项,他存在的作用就是为了防止汽车由于刹车不及时而闯过停车线。

从常识上理解,越靠近停车线,就越应该踩深刹车,不能让车过线,所以这个 微分D的作用,可以理解为刹车。当车离停车线很近,并且车速还很快时,这个 微分D的绝对值(实际上是一个负数)就会很大,表示应该大力踩刹车尽快让车停下来。

再回到上面“水缸加水”的例子,当发现水缸里的水快要接近目标量时,加入 微分D可以减少过量加水的幅度,说白了就是减少控制过程中的震荡。假设 Kd=0.2K_d=0.2,我们再从头模拟加水实验,具体数值如下。

第一次: 误差为 e(1)=0.8e(1)=0.8, 比例部分 Kpe(1)=0.4Kp*e(1)=0.4, 积分部分 Kie(1)=0.16K_i*e(1)= 0.16,微分部分 Kd(e(1)0)=0.16K_d*(e(1)-0)=0.16 ,所以 加入水量 uu0.4+0.16+0.16=0.720.4+0.16+0.16=0.72. 最终水位 0.2+0.720.1=0.82m0.2+0.72-0.1= 0.82m

第二次: 误差为 e(2)=0.18e(2)=0.18,比例部分 Kpe(2)=0.09Kp*e(2)=0.09,积分部分 Kp(e(1)+e(2))=0.2Kp*(e(1)+e(2))= 0.2,微分部分为Kd(e(2)e(1))=0.12K_d*(e(2)-e(1))=-0.12,加入水量 uu0.18+0.20.12=0.260.18+0.2-0.12=0.26。最终水位 0.72+0.260.1=0.88m0.72+0.26-0.1=0.88m

上一轮实验使用比例P积分I联合控制,最高水位达到1.3,超过目标量之后,水位最低回落至0.83。本轮实验加入了抑制器微分D之后,最高水位仅达到1.23,超过目标量之后,水位最低回落至0.88,相比上一轮实验,本轮震荡幅度明显减小,这就是微分D的抑制作用。

分享一个动图,很好的展示了比例P积分I微分D的控制效果,其中红色虚线是目标量,曲线是用当前值的变化趋势。

总结与调参

  • 比例P积分I微分D都跟偏差量有关
  • 比例P取决于当前的偏差量
  • 积分I累计过去所有偏差量之和
  • 微分D预测下一时刻偏差量

PID调参口诀

参数整定找最佳,从小到大顺序查;
先是比例后积分,最后再把微分加;
曲线振荡很频繁,比例度盘要放大;
曲线漂浮绕大湾,比例度盘往小扳;
曲线偏离回复慢,积分时间往下降;
曲线波动周期长,积分时间再加长;
曲线振荡频率快,先把微分降下来;
动差大来波动慢。微分时间应加长;
理想曲线两个波,前高后低4比1;
一看二调多分析,调节质量不会低;
若要反应增快,增大P减小I;
若要反应减慢,减小P增大I;
如果比例太大,会引起系统振荡;
如果积分太大,会引起系统迟钝。

增量PID

u(t)=Kpe(t)+Kin=0te(t)+Kd(e(t)e(t1))u(t1)=Kpe(t1)+Kin=0t1e(t)+Kd(e(t1)e(t2))u(t)=K_p * e(t) + K_i * \sum_{n=0}^t e(t) + K_d * (e(t) - e(t-1))\\ u(t-1)=K_p * e(t-1) + K_i * \sum_{n=0}^{t-1} e(t) + K_d * (e(t-1) - e(t-2))\\

Δu=u(t)u(t1)=(Kpe(t)+Kin=0te(t)+Kd(e(t)e(t1)))(Kpe(t1)+Kin=0t1e(t)+Kd(e(t1)e(t2)))=Kp(e(t)e(t1))+Kie(t)+Kd(e(t)+e(t2)2e(t1))=(Kp+Ki+Kd)e(t)+(Kp2Kd)e(t1)+Kde(t2)=Ae(t)+Be(t1)+Ce(t2)(1)\begin{aligned} \Delta u &=u(t)-u(t-1)\\ &=\bigg(K_p * e(t) + K_i * \sum_{n=0}^t e(t) + K_d * (e(t) - e(t-1))\bigg)-\bigg(K_p * e(t-1) + K_i * \sum_{n=0}^{t-1} e(t) + K_d * (e(t-1) - e(t-2))\bigg)\\ &=K_p\big(e(t)-e(t-1)\big) + K_i * e(t)+K_d*\big(e(t)+e(t-2)-2*e(t-1)\big)\\ &=\big(K_p+K_i+K_d)*e(t)+(-K_p-2*K_d)*e(t-1)+K_d*e(t-2)\\ &=A*e(t)+B*e(t-1)+C*e(t-2) \end{aligned}\tag1

其中 Ki=KpTTiK_i=K_p*\dfrac{T}{T_i}Kd=KpTdTK_d=K_p*\dfrac{T_d}{T} ,故:

A=Kp+Ki+Kd=Kp(1+TTi+TdT)B=Kp2Kd=Kp(1+2TdT)C=KpTdT\begin{aligned} A &=K_p+K_i+K_d\\ &=K_p(1+\dfrac{T}{T_i}+\dfrac{T_d}{T})\\ B &=-K_p-2*K_d\\ &=-K_p(1+\dfrac{2T_d}{T})\\ C &=K_p*\dfrac{T_d}{T} \end{aligned}

由(式 1)可以看出,如果计算机控制系统采用恒定的采样周期 T ,一旦确定 A、 B、 C,只要使用前后三次测量的偏差值,就可以由(式 1)求出控制量。

香农(Shannon) 采样定律 :为不失真地复现信号的变化, 采样频率至少应大于或等于连续信号最高频率分量的二倍。根据采样定律可以确定采样周期的上限值。实际采样周期的选择还要受到多方面因素的影响,不同的系统采样周期应根据具体情况来选择。

采样周期的选择,通常按照过程特性与干扰大小适当来选取采样周期:即对于响应快、(如流量、压力) 波动大、易受干扰的过程,应选取较短的采样周期;反之,当过程响应慢(如温度、 成份)、滞后大时,可选取较长的采样周期。

采样周期的选取应与 PID 参数的整定进行综合考虑, 采样周期应远小于过程的扰动信号的周期,在执行器的响应速度比较慢时,过小的采样周期将失去意义,因此可适当选大一点;在计算机运算速度允许的条件下,采样周期短, 则控制品质好;当过程的纯滞后时间较长时, 一般选取采样周期为纯滞后时间的 1/4~1/8。

参考

https://blog.csdn.net/bitcarmanlee/article/details/124747263

https://mp.weixin.qq.com/s?__biz=MzI4MDI4MDE5Ng==&mid=2247488157&idx=2&sn=3b214c5ee27da1a0075b51d886b9f580&chksm=ebbbbf76dccc36603e441e89aca2f61ad22858c49756e51c601d213acd4778c1ff5b2b56fb0f&scene=21#wechat_redirect

https://segmentfault.com/a/1190000041819928