我对『PID算法』的理解 —— 原理介绍

2016-05-057.8万
AI 快速预览详细 收起
本文介绍了PID算法的基本原理及其在控制系统中的应用。通过生动的例子,如加热器控制水温和汽车定速巡航,解释了比例(P)、积分(I)和微分(D)的作用。文章详细说明了如何通过调整kP、kI、kD参数来实现精确控制,并通过弹簧在水中震荡的例子形象地解释了D(微分)的阻尼效果。无论是初学者还是有一定基础的工程师,都能从中获得启发。

LZ以前有个小小的理想,就是让手边的MCU自己“思考”起来,写出真正带算法的程序。
前段时间做一个比赛项目的过程中,对经典、实用的PID算法有了一点点自己的理解,就写了这些,与大家分享
因为LZ想尽办法,试着用最易于理解的语言说清楚原理,不做太多的理论分析。(LZ文学功底不行),
所以下面的内容会有不严谨的地方,或者有解释错误的地方。大神们发现了,一定要帮我补充,或者给予批评~~~谢谢你们:P

好啦,正文开始



啥是PID?   PID可以吃吗?
PID,就是“比例(proportional)、积分(integral)、微分(derivative)”,是一种很常见的控制算法。算法是不可以吃的。
到LZ发帖的这一天,PID已经有105年的历史了

它并不是什么很神圣的东西,大家一定都见过PID的实际应用

——比如四轴飞行器,再比如平衡小车......还有汽车的定速巡航、3D打印机上的温度控制器....
再比如动物园里的海狮,将一根杆子直立着顶在头上(OOPS,这个也算..)

就是类似于这种:需要将某一个物理量“保持稳定”的场合(比如维持平衡,稳定温度、转速等),PID都会派上大用场。



那么问题来了:
  比如,我想控制一个“热得快”,让一锅水的温度保持在50℃  
这么简单的任务,为啥要用到微积分的理论呢你一定在想:
这不是so easy嘛~  小于50度就让它加热,大于50度就断电,不就行了?几行代码用Arduino分分钟写出来:victory:

没错~在要求不高的情况下,确实可以这么干~  But!  如果LZ换一种说法,你就知道问题出在哪里了:

如果我的控制对象是一辆汽车呢?
要是希望汽车的车速保持在50km/h不动,你还敢这样干么

设想一下,假如汽车的定速巡航电脑在某一时间测到车速是45km/h。它立刻命令发动机:加速!
结果,发动机那边突然来了个100%全油门,嗡的一下,汽车急加速到了60km/h。这时电脑又发出命令:刹车!
结果,吱...............哇............(乘客吐)

所以,在大多数场合中,用“开关量”来控制一个物理量,就显得比较简单粗暴了。有时候,是无法保持稳定的。因为单片机、传感器不是无限快的,采集、控制需要时间。
而且,控制对象具有惯性。比如你将一个加热器拔掉,它的“余热”(即热惯性)可能还会使水温继续升高一小会。

这时,就需要一种『算法』:


  • 它可以将需要控制的物理量带到目标附近
  • 它可以“预见”这个量的变化趋势
  • 它也可以消除因为散热、阻力等因素造成的静态误差
  • ....

于是,当时的数学家们发明了这一历久不衰的算法——这就是PID。

你应该已经知道了,P,I,D是三种不同的调节作用,既可以单独使用(P,I,D),也可以两个两个用(PI,PD),也可以三个一起用(PID)。
这三种作用有什么区别呢?客官别急,听我慢慢道来


我对『PID算法』的理解 —— 原理介绍图1
我们先只说PID控制器的三个最基本的参数:kP,kI,kD。

kP
P就是比例的意思。它的作用最明显,原理也最简单。我们先说这个:

需要控制的量,比如水温,有它现在的『当前值』,也有我们期望的『目标值』。

  • 当两者差距不大时,就让加热器“轻轻地”加热一下。
  • 要是因为某些原因,温度降低了很多,就让加热器“稍稍用力”加热一下。
  • 要是当前温度比目标温度低得多,就让加热器“开足马力”加热,尽快让水温到达目标附近。

这就是P的作用,跟开关控制方法相比,是不是“温文尔雅”了很多

实际写程序时,就让偏差(目标减去当前)与调节装置的“调节力度”,建立一个一次函数的关系,就可以实现最基本的“比例”控制了~
kP越大,调节作用越激进,kP调小会让调节作用更保守。

要是你正在制作一个平衡车,有了P的作用,你会发现,平衡车在平衡角度附近来回“狂抖”,比较难稳住。
如果已经到了这一步——恭喜你!离成功只差一小步了~

kD
D的作用更好理解一些,所以先说说D,最后说I。

刚才我们有了P的作用。你不难发现,只有P好像不能让平衡车站起来,水温也控制得晃晃悠悠,好像整个系统不是特别稳定,总是在“抖动”。
我对『PID算法』的理解 —— 原理介绍图2
你心里设想一个弹簧:现在在平衡位置上。拉它一下,然后松手。这时它会震荡起来。因为阻力很小,它可能会震荡很长时间,才会重新停在平衡位置。
请想象一下:要是把上图所示的系统浸没在水里,同样拉它一下 :这种情况下,重新停在平衡位置的时间就短得多。

我们需要一个控制作用,让被控制的物理量的“变化速度”趋于0,即类似于“阻尼”的作用。

因为当比较接近目标时,P的控制作用就比较小了。越接近目标,P的作用越温柔。有很多内在的或者外部的因素,使控制量发生小范围的摆动。D的作用就是让物理量的速度趋于0,
只要什么时候,这个量具有了速度,D就向相反的方向用力,尽力刹住这个变化。

kD参数越大,向速度相反方向刹车的力道就越强。

如果是平衡小车,加上P和D两种控制作用,如果参数调节合适,它应该可以站起来了~欢呼吧


等等,PID三兄弟好想还有一位。看起来PD就可以让物理量保持稳定,那还要I干嘛?
因为我们忽视了一种重要的情况:

kI
还是以热水为例。假如有个人把我们的加热装置带到了非常冷的地方,开始烧水了。需要烧到50℃。

在P的作用下,水温慢慢升高。直到升高到45℃时,他发现了一个不好的事情:天气太冷,水散热的速度,和P控制的加热的速度相等了。
这可怎么办?

  • P兄这样想:我和目标已经很近了,只需要轻轻加热就可以了。
  • D兄这样想:加热和散热相等,温度没有波动,我好像不用调整什么。

于是,水温永远地停留在45℃,永远到不了50℃。


作为一个人,根据常识,我们知道,应该进一步增加加热的功率。可是增加多少该如何计算呢?
前辈科学家们想到的方法是真的巧妙。

设置一个积分量。只要偏差存在,就不断地对偏差进行积分(累加),并反应在调节力度上。

这样一来,即使45℃和50℃相差不太大,但是随着时间的推移,只要没达到目标温度,这个积分量就不断增加。系统就会慢慢意识到:还没有到达目标温度,该增加功率啦!
到了目标温度后,假设温度没有波动,积分值就不会再变动。这时,加热功率仍然等于散热功率。但是,温度是稳稳的50℃。
kI的值越大,积分时乘的系数就越大,积分效果越明显。

所以,I的作用就是,减小静态情况下的误差,让受控物理量尽可能接近目标值。

I在使用时还有个问题:需要设定积分限制。防止在刚开始加热时,就把积分量积得太大,难以控制。




这篇就写到这里。要想直观地体验PID的控制作用,需要一个具体的东西来调试。
LZ以后完成倒立摆项目后,会用一些视频来演示PID参数的整定方法。


本文是原创内容,欢迎大家转载。请注明,来自DF创客社区

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(21)
起飞4D
起飞4D
可不可以理解成P十调整,D是补偿,I是修正,如果差不多我就有点明白了。。。
JOVI
JOVI
学习学习
三春牛-创客
三春牛-创客
厉害啊!赞赞赞!
小朋友堆雪茄
小朋友堆雪茄
这么好的文章,让我产生一种相见恨晚的感觉
DF1001
DF1001
好文,值得推荐
面包板
面包板
跪求点拨那个PID动图(改变参数曲线变化那个)的做法
面包板
面包板回复1678064001
别逗我,那么严肃的数学建模软件
1678064001
1678064001回复面包板
matlab欢迎入坑
Star
Star
大家谁知道他那个仿真图怎么画的,就是那个动图
小米的爸
小米的爸
请问还有进一步的通俗易懂的教程吗?如程序编写?参数调节?
喵喵99
喵喵99
赞赞赞!
鲍sir
鲍sir
32个赞!
乐字当头
乐字当头
通俗易懂,6666
gada888
gada888
非常好
redx
redx
厉害了,通俗易懂
lilinfei
lilinfei
赞赞赞!!!对PID更加了解一点了
gray6666
gray6666
大赞一个
DDIsKII
DDIsKII
赞!!!讲得很好,通俗易懂。学到很多。
jiayinglong
jiayinglong
写的很科学,而且通俗易懂
Grey
Grey
不科学啊,这么好的文章竟然只有那么点评论!
virtualwiz
virtualwiz
作者
回复Grey
多谢支持:lol
凌风清羽
凌风清羽
好贴,顶起来~~被自控原理折磨的要死要死的
svw
svw
好赞,好清楚!
virtualwiz
virtualwiz
作者
回复svw
评论内容