【PID系列】一文理解PID原理

【PID系列目录】
[1、一文理解PID原理]
2、PID代码设计

1、引出

   各位朋友大家好,进入嵌入式行业已有10年多光景。从最初的一无所知,到现在自认为嵌入式入了门。一路都是自己自学,没有一个领路人带领,磕磕绊绊,走了不少弯路。头已白,发渐少,可才感觉找到嵌入式之门。但也算比较幸运,遇到一个技术管理比较严格、比较正规的公司。自己的自学加上公司的实践,总算对嵌入式有了一个系统的认识。在此,非常感谢公司这个大平台,正是因为有了这个平台,才有了今天的我。也非常感谢一起共事的小伙伴们,三人行,必有我师,我从你们那里学到了很多有用的东西。

   从今天(2024年8月29日)开始,我打算以系列的方式,把我这几年学到的,常用到的东西,以笔记的形式记录下来,给入门嵌入式的朋友们点亮一盏灯,希望你们少踩一些坑,少走一些弯路。一些可以进行模块化的代码,我也会进行梳理整理,以开源的形式开放出来,提供给大家使用。

   今天呢,我打算记录一下PID控制以及PID整定。PID是在工程领域使用最多的控制算法,应该没有之一。从温度,气压、流量、电机等各个可变的控制对象到小到小朋友的玩具,家用电器,精密设备,大到工程机械、钢铁熔炉各个领域都用到了PID控制。可以说PID控制无处不在。PID可是一把神器,有了这把神器,我们可以完全解决控制领域大多数最基本的问题。如果一个PID解决不了问题,那我们就用2个PID。很多人经常使用PID,但是PID这东西说简单非常简单,就一个公式,说难,也真是难以上青天,在实际使用中,经常整定不到合适的PID。所以,接下来,我会从PID的原理,PID代码的实现,PID代码工程化优化,PID自整定几个方面来记录PID的相关知识点,最终形成一个易于阅读、容易移植,便于控制的PID代码,提供给大家使用。

2、 PID概念

   我们现在开始记录本系列的第一篇文章,PID原理。

   所谓PID算法就是将偏差的比例(Proportion)、积分(Integral) 和 微分(Differential)通过线性组合构成控制量,用这一控制量对被控对象进行控制,这样的控制器称PID控制器。

在这里插入图片描述

   我们来理解一下上面这段话。

2.1 首先,什么是偏差呢?

   假如我们目前有一个需求,要把水烧到50±1℃。那这个需求我们就可以用PID进行控制。在这个系统中,我们的控制对象就是水温,我们的PID执行机构就是加热器,我们可以通过加热器的电流大小来控制加热器的加热快慢,即PID的输出量(output)即为电流大小。那我们要把水加热到指定的温度,我们必须还得有一个温度传感器,来获取实时水温。我们想要的水温的期望值是50±1℃,这个期望值我们叫做设定值(setpoint),温度传感器返回的实时温度值我们叫做反馈值(feedbackVal),那么所谓的偏差(error)就是反馈值偏离设定值的大小,即为error = setpoint - feedbackVal。

2.2 其次,什么是PID比例项?

   什么是偏差的比例?

   通常情况下,我们加热,都会采用恒定的电流加热,等水温达到设定值后,立即断电,水温低于设定值后,又立即启动加热,以此循环往复,这样进行控制(这种控制方式在工程上叫做乒乓控制)。对控制精度要求不高的场合,这样的控制方式完全够用,但如果控制精度比较高的情况下,水温要么就过了,要么达不到。这是因为大多数控制对象都有惯性,在惯性作用下,无法通过这种方式进行完美的控制。比如,我们的加热器,断电之后,它还有余热可以继续对水进行加热。比如电机,停止之后,由于惯性,它还会继续旋转。比如,关闭阀门,下达关闭指令后,它需要一定的时间才能完全关闭。

   另外很多场合,我们的控制对象还受其他的因素的影响。比如,加热水,水在加热的同时,也在散热,而这个散热在夏天和冬天完全不一样,所以在冬天和夏天,将同样的水加热升温一定的温度所需要的功耗完全不一样。散热的这个因素也在影响着我们的水温。又比如,往水缸里注水,我们需要控制水缸的水位,但是同时这个水缸也在放水,那这个放水量就会影响水缸的水位。

   那有没有一种方法可以在惯性以及其他因素的影响下,能够精确的控制呢?有的,方法肯定有很多,PID就是其中一种。PID的比例项是这样的。我们先求出偏差(error),根据偏差(error)的概念我们知道,如果反馈值偏离实际值很大,则偏差(error)也很大,如果反馈值距离实际值很小,则偏差(error)也很小。而我们控制一个对象,最理想的控制方式也是这样的,如果反馈值与设定值相差很大(即偏差(error)很大),我们可以输出(output)全功率,随着偏差(error)减小,我们也可以减少输出(output)功率,直到偏差(error)为0,我们的输出功率也为0。我们发现偏差的变化趋势和理想的控制方式是一样的。那我们使用偏差的概念来进行PID控制是非常完美的。

   我们可以直接把偏差作为output来控制执行机构,是很理想的情况,但是一般情况下,偏差的单位和输出值的单位不一致。比如我们控制水温时,偏差的单位是摄氏度,而我们的输出值的单位是电流的单位A,这两个数往往不在一个数量级。所以我们直接将偏差作为输出值,进行控制不合适。为了能够通过偏差值对电流进行控制,我们在偏差值上乘以一个系数,这样我们就可以得到一个合理的值。我们把偏差乘以系数的这个项叫做比例项(proportion),即:

p r o p o r t i o n = K p ∗ e r r o r     − − − − − − − − − − − − − − ( 1 ) proportion = Kp * error \space\space\space -------------- (1) proportion=Kperror   (1)

其中:
e r r o r = o u t p u t − s e t p o i n t     − − − − − − − − − − − − − − ( 2 ) error = output - setpoint \space\space\space -------------- (2) error=outputsetpoint   (2)
用一个式子表示就是:
p r o p o r t i o n = K p ∗ ( o u t p u t − s e t p o i n t )     − − − − − − − − − − − − − − ( 3 ) proportion = Kp * (output - setpoint) \space\space\space -------------- (3) proportion=Kp(outputsetpoint)   (3)

   上式中,Kp就是我们引入的偏差所乘的比例,我们一般称之为比例常数。那一般怎么选择Kp呢,这个就需要我们在实际中不断的去试,而这个找合适的Kp的过程,我们就叫做手动PID整定。PID整定是PID控制中最难的部分,需要不断的积累经验,才能快速的找到合适的Kp值。 我这个系列不打算讲解如何去手动整定参数,我会讲解一种自整定方法,通过这种自整定方法,我们就可以得到合理的比例常数。当你看完我这个系列后,相信你对PID的理解已经足够了。你也可以不用看我这个系列,而是直接使用我后面开源的PID代码去做PID控制,PID整定,相信也一定控制的非常好。

   这就是偏差的比例(proportion)。
K p ∗ ( o u t p u t − s e t p o i n t )     − − − − − − − − − − − − − − ( 4 ) Kp * (output - setpoint) \space\space\space -------------- (4) Kp(outputsetpoint)   (4)
叫做PID的比例项。

在这里插入图片描述

   如上图所示,是在不同kp系数下,PID的不同控制效果。当给定一个很小的Kp(例如图中的Kp=0.5),则此时待PID稳定后,我们发现反馈值达不到目标值,与目标值相差甚远。我们不断增加Kp的值,发现稳定后的反馈值距离设定值越来越近。同时,随着Kp越来越大,我们发现反馈值开始振荡,振荡也越来越大。这是因为我们控制的系统存在惯性以及受其他因素的影响的原因。由于以上因素的影响,在只用比例项的控制的情况下,系统稳定后,反馈值与设定值之间总是存在一定的偏差,这个偏差我们叫做稳态误差。

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=image-1.png&pos_id=img-VHhq7fU0-
1725191328368)
在这里插入图片描述

2.3 积分————解决稳态误差的利器

   怎么解决稳态误差?

   所谓稳态误差,就是反馈值和设定值之间总是存在一定的偏差。解决稳态误差的办法就是对偏差进行积分(intergration)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

   如上图所示,图中的曲线是偏差值(error = feedbackVal - setpoint),则偏差的积分(intergration)就是图中阴影部分的面积。我们从图中看到,面积的大小和两个变量有关:偏差大小和时间长久,只要偏差不为0,则积分(intergration)随着时间的增加也会一直增加下去。所以偏差更多的是影响积分(intergration)的速率,偏差大,则积分(intergration)增加的快,偏差小则积分(intergration)增加的慢。所以只要偏差存在,则在时间的加持下,最终我们的输出值就会越来越大,最终会消除存在的稳态误差。

   PID积分项(intergration)我们表示如下:
i n t e r g r a t i o n = ∫ 0 t d ( e r r o r ( t ) ) d t     − − − − − − − − − − − − − − ( 5 ) intergration = \int_0^t{d(error(t))dt} \space\space\space -------------- (5) intergration=0td(error(t))dt   (5)

   PID控制程序是周期性执行的,执行的周期称为采样周期(Ts)。上图中曲线为连续的实际的偏差值,但是我们通过计算机采集到的反馈值是离散的。我们一般都是每隔一个固定的时间去采集一个反馈值,并进行偏差计算,这个固定的时间间隔就是采样周期。就是上图中长方形的宽Ts了。每次PID运算时,偏差的积分就是在上一次积分的基础上,增加一个偏差(error)与采样周期(Ts)的乘积,即会增加一个图中的长方形的面积。偏差为正时,积分的增量为正,偏差为负时,积分的增量为负。

   我们知道,偏差的积分的单位是时间单位和偏差单位的乘积,它的单位和比例项的单位不一样,为了单位换算一致,那我们一般需要给积分项除以一个时间系数,这个时间系数叫做积分时间常数,一般用Ti表示。引入积分时间常数后,积分项公式变为:

i n t e r g r a t i o n = 1 T i ∫ 0 t d ( e r r o r ) d t     − − − − − − − − − − − − − − ( 6 ) intergration = {1\over{Ti}}\int_0^t{d(error)dt} \space\space\space -------------- (6) intergration=Ti10td(error)dt   (6)

   那怎么求这个Ti的值呢,方法也是一样,需要通过整定求得,本篇文章我们不涉及整定,后面会专门讲解自整定。

   引入积分项后,PID公式就变成了比例项和积分项的和。PID公式变为如下:

o u t p u t ( t ) = K p ∗ ( e r r o r ( t ) + 1 T i ∫ 0 t d ( e r r o r ) d t )     − − − − − − − − − − − − − − ( 7 ) output(t) = Kp * (error(t) + {1\over{Ti}}\int_0^t{d(error)dt}) \space\space\space -------------- (7) output(t)=Kp(error(t)+Ti10td(error)dt)   (7)
其中:
e r r o r = o u t p u t − s e t p o i n t     − − − − − − − − − − − − − − ( 8 ) error = output - setpoint \space\space\space -------------- (8) error=outputsetpoint   (8)

   上式中,我们看到,比例常数不仅作用到比例项上,还作用到积分项上,为什么要这么做呢?它和作用在比例系数上的作用一样,在Kp和Ti共同的作用下,将输出值(output)转化为合理的执行单元(执行输出值的器件或设备)可执行的的范围内的值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图为纯比例作用下的PID控制展示。

2.4  微分————改善动态响应,解决超调现象

   我们已经得到比例项和积分项组成的PID公式了,那这样PID公式是不是完美了呢?我们还没有讲解PID中的D,所以这个公式并不完美,它还是有缺陷的。但是在一般情况下,其实有了P和I也就够了,在P和I的作用下,一般都能达到我们想要的平衡值。

   虽然只有PI作用,也可以使系统稳定,但是往往有一些副作用。比如系统响应变化过快,系统不稳定,比如在快要达到目标值阶段,往往会出现超调现象(反馈值达到目标值,并超过目标值,然后再慢慢返回来,在目标值周围振荡若干次,才逐渐平稳)。而我们加入微分项后,就可以来改善这种情况。

   微分公式如下:

d i f f e r e n t i a l = d e r r o r ( t ) d t     − − − − − − − − − − − − − − ( 9 ) differential = {derror(t)\over{dt}} \space\space\space -------------- (9) differential=dtderror(t)   (9)

   error(t)表示t时刻的偏差,即setpoint – feedbackVal。所以上述公式我们就可以看成是单位时间内偏差的变化,即偏差变化率。

在这里插入图片描述

如上图,绿色线为设定值,红色线为实时反馈值,则图中的蓝色线可表示偏差值,从图中可以看出来,随着反馈值不断的接近设定值,蓝色线越来越短,即偏差越来越小。偏差的微分对图中来说,就是右边的蓝色线减去左边的蓝色线,所以其值是负的。

   那我们总结一下上述现象,就是偏差减小的过程中,微分值永远是负的,偏差增大的过程中,微分值永远是正的。偏差变化越快,此时红色的线越陡,则偏差的微分的绝对值越大。    从上述描述中,我们不难看到,微分在起一个阻力作用。上图中,偏差在减小的过程中,比例项和积分项是正的,但是微分是负的,它在阻碍偏差的减小,偏差变化越快的时候,微分的值越大,阻碍作用越大。

在这里插入图片描述

   上图是,偏差增大的过程中,上图中比例项和微分是负的,但微分项刚好是正的。所以由此可以看出,微分项的符号和比例项与积分项的符号是反的,它始终起一个阻力的作用。

在这里插入图片描述

   就像这个弹簧一样,不管你把它拉的多长,它最终会在阻尼作用下,停止运动,即达到平衡。

   微分的单位是偏差值的单位/时间单位,所以为了能够将微分项的单位与比例项和积分项单位统一,微分项还包含一个微分时间常数Td。我们在微分项上乘以这个微分时间常数后,单位统一,则乘以微分时间常数Td以后微分项公式如下:

d i f f e r e n t i a l = T d d e r r o r ( t ) d t     − − − − − − − − − − − − − − ( 10 ) differential = Td{derror(t)\over{dt}} \space\space\space -------------- (10) differential=Tddtderror(t)   (10)

   微分项对噪声特别敏感,如传感器反馈信号中有噪声或控制循环速率太低,微分项会使控制变的不稳定。噪声信号意味着反馈值突变,突变值的为微分值非常大,理论上可达到无穷大,所有其对噪声特别敏感。

在这里插入图片描述

上图表示微分作用。

2.5 最终的PID公式

经过上述讲解,我们已经清楚了PID公式,下面我们把最终的PID公式表示出来:

o u t p u t ( t ) = K p [ e r r o r ( t ) + 1 T i ∫ 0 t d ( e r r o r ( t ) ) d t + T d d e r r o r ( t ) d t ]     − − − ( 11 ) output(t) = Kp[error(t) + {1\over{Ti}}\int_0^t{d(error(t))dt} + Td{derror(t)\over{dt}}] \space\space\space --- (11) output(t)=Kp[error(t)+Ti10td(error(t))dt+Tddtderror(t)]   (11)

   上式中,output(t) 表示t时刻的PID输出值,error(t)表示t时刻的偏差,即:t时刻的设定值setpoint与反馈值feedbackVal的差值。

e r r o r ( t ) = s e t p o i n t ( t ) − f e e d b a c k V a l ( t )     − − − − − − − − − − − − − − ( 12 ) error(t) = setpoint(t) - feedbackVal(t) \space\space\space -------------- (12) error(t)=setpoint(t)feedbackVal(t)   (12)

3、PID公式简化

   我们观察以上公式,发现Kp作用在比例、积分、微分每一项上,如果我们需要手动整定PID的话,对于积分项和微分项来说,各有两个未知量需要求解。所以为了手动整定方便,一般需要对上式进行化简。 令:

K i = K p ∗ 1 T i , K d = K p ∗ T d     − − − − − − − − − − − − − − ( 13 ) K_i = K_p*{{1}\over{T_i}} ,K_d= K_p*T_d \space\space\space -------------- (13) Ki=KpTi1Kd=KpTd   (13)

则可得到如下公式:

o u t p u t ( t ) = K p ∗ e r r o r ( t ) + K i ∫ 0 t d ( e r r o r ( t ) ) d t + K d d e r r o r ( t ) d t     − − − − ( 14 ) output(t) = Kp*error(t) + K_i\int_0^t{d(error(t))dt} + K_d{derror(t)\over{dt}} \space\space\space ---- (14) output(t)=Kperror(t)+Ki0td(error(t))dt+Kddtderror(t)   (14)

上式中,比例、积分和微分项相互独立,过上式手动整定PID就比较方便。

4、PID公式离散化

我们得到的PID公式是连续的,但在计算机的处理中,无法处理连续的函数,我们对其进行离散化。

4.1、采集时间

   假设,我们有一个控制系统,以固定的时间间隔通过传感器获取实时反馈值。这个时间间隔我们称之为采集时间,一般设为Ts。我们获取一次实时反馈值,计算一次偏差,然后通过偏差进行一次PID控制,所以PID的控制时间也等于采集时间。 假设k为采样序号,K = 0,1,2,3,4,5...

第一次采样,则k=1,

第二次采样,则k=2,

第三次采样,则k=3,

第四次采样,则k=4,

第五次采样,则k=3,

.
.
.
第n-1才采样,k = n-1

第n次采样,则k= n,

第n+1次采样,则k= n+1,
.
.
.

4.2、求偏差

   假设,第k次采样,实时反馈值为feedbackVal(k),设置值为setpoint(k),则偏差就可以表示为:

e r r o r ( k ) = s e t p o i n t ( k ) − f e e d b a c k V a l ( k )     − − − − − − − − − − − − − − ( 15 ) error(k) = setpoint(k) - feedbackVal(k) \space\space\space -------------- (15) error(k)=setpoint(k)feedbackVal(k)   (15)

4.3、积分离散化

在这里插入图片描述

   如上图中,长方形的宽为采样时间Ts,假设每个采集时刻计算处的偏差值为error(k),即为长方形的长。那么积分就是各个长方形面积的和。 用公式表示就是:

e r r o r ( 0 ) ∗ T t + e r r o r ( 1 ) ∗ T t + e r r o r ( 2 ) ∗ T t + e r r o r ( 3 ) ∗ T t + error(0)*T_t + error(1)*T_t + error(2)*T_t + error(3)*T_t + error(0)Tt+error(1)Tt+error(2)Tt+error(3)Tt+
. . . + e r r o r ( k − 1 ) ∗ T t + e r r o r ( k ) ∗ T t + + e r r o r ( k + 1 ) ∗ T t + . . .     − − − ( 16 ) ... +error(k-1)*T_t + error(k)*T_t + +error(k+1)*T_t + ... \space\space\space --- (16) ...+error(k1)Tt+error(k)Tt++error(k+1)Tt+...   (16)

我们对上式进行化简,则可表示为:

T t [ e r r o r ( 0 ) + e r r o r ( 1 ) + e r r o r ( 2 ) + e r r o r ( 3 ) + T_t [error(0) + error(1) + error(2) + error(3) + Tt[error(0)+error(1)+error(2)+error(3)+
. . . + e r r o r ( k − 1 ) + e r r o r ( k ) + e r r o r ( k + 1 ) + . . . ]     − − − ( 17 ) ... +error(k-1) + error(k) + error(k+1)+...] \space\space\space ---(17) ...+error(k1)+error(k)+error(k+1)+...]   (17)

我们继续使用求和公式来表述上述公式,则可以写为:

T t ∑ i = 0 k e r r o r ( i )     − − − − − − − − − − − − − − ( 18 ) T_t\sum_{i=0}^kerror(i) \space\space\space -------------- (18) Tti=0kerror(i)   (18)

4.4、微分离散化

在这里插入图片描述

   假设第k次求得的偏差为error(k),第k-1次求得的偏差为error(k-1),如上图中的曲线和长方形长交叉点的Y轴的值,即为各个采集点的偏差值。那么微分就相当于两个交叉点处Y轴的值的差除以采集时间Ts,就是偏差曲线的斜率。 用公式表示就是:

[ e r r o r ( k ) − e r r o r ( k − 1 ) ] / T t     − − − − − − − − − − − − − − ( 19 ) [error(k) - error(k-1)]/T_t \space\space\space -------------- (19) [error(k)error(k1)]/Tt   (19)

4.5、PID公式离散化

   综上所述,我们把比例、积分和微分组合起来就可以得到离散化后的PID公式如下:

o u t p u t ( k ) = k p [ e r r o r ( k ) + T t ∑ i = 0 k e r r o r ( i ) T i + T d [ e r r o r ( k ) − e r r o r ( k − 1 ) ] T t ]     − − − ( 20 ) output(k) = k_p [error(k) + {T_t\sum_{i=0}^kerror(i)\over{T_i}} + {Td{[error(k) - error(k-1)]}\over{T_t}}] \space\space\space --- (20) output(k)=kp[error(k)+TiTti=0kerror(i)+TtTd[error(k)error(k1)]]   (20)
上式为公式(11)的离散化表示。

o u t p u t ( k ) = K p ∗ e r r o r ( k ) + K i ∗ T t ∑ i = 0 k e r r o r ( i ) + K d ∗ [ e r r o r ( k ) − e r r o r ( k − 1 ) ] T t     − − − ( 21 ) output(k) = K_p*error(k) + Ki*{T_t\sum_{i=0}^kerror(i)} + K_d*{{[error(k) - error(k-1)]}\over{T_t}} \space\space\space ---(21) output(k)=Kperror(k)+KiTti=0kerror(i)+KdTt[error(k)error(k1)]   (21)
上式为公式14的离散化表示。

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值