PID算法从入门到了解

PID算法详细解读

本文章借鉴网上多位大神的博客以及野火的教程,非原创,主要为按照自己的理解整理。

PID控制算法

基本讲解

PID即:Proportional(比例)、Integral(积分)、Differential(微分)的缩写。也就是说,PID算法是结合这三种环节在一起来实现一个闭环控制。PID控制应该算是应用非常广泛的控制算法了。小到控制一个元件的温度,大到控制无人机的飞行姿态和飞行速度等等,都可以使用PID控制。

PID控制框架

以上是一个pid的控制框图,不懂没有关系,只需要了解它的大概执行流程就好。

为什么需要PID三个环节的控制?

我们先说PID中最简单的比例控制,抛开其他两个不谈。还是用一个经典的例子吧。假设我有一个水缸,最终的控制目的是要保证水缸里的水位永远的维持在1米的高度。假设初始时刻,水缸里的水位是0.2米,那么当前时刻的水位和目标水位之间是存在一个误差的error,且error为0.8.这个时候,假设旁边站着一个人,这个人通过往缸里加水的方式来控制水位。如果单纯的用比例控制算法,就是指加入的水量u和误差error是成正比的。即 u=kp×error。
假设kp取0.5,那么t=1时(表示第1次加水,也就是第一次对系统施加控制),那么u=0.5×0.8=0.4,所以这一次加入的水量会使水位在0.2的基础上上升0.4,达到0.6。
接着,t=2时刻(第2次施加控制),当前水位是0.6,所以error是0.4。u=0.5×0.4=0.2,会使水位再次上升0.2,达到0.8。如此这么循环下去,就是比例控制算法的运行方法。可以看到,最终水位会达到我们需要的1米。
但是,单单的比例控制存在着一些不足,其中一点就是 –稳态误差
像上述的例子,根据kp取值不同,系统最后都会达到1米,只不过kp大了到达的快,kp小了到达的慢一些。不会有稳态误差。但是,考虑另外一种情况,假设这个水缸在加水的过程中,存在漏水的情况,假设每次加水的过程,都会漏掉0.1米高度的水。仍然假设kp取0.5,那么会存在着某种情况,假设经过几次加水,水缸中的水位到0.8时,水位将不会再变换!!!因为,水位为0.8,则误差error=0.2. 所以每次往水缸中加水的量为u=0.5*0.2=0.1.同时,每次加水,缸里又会流出去0.1米的水!!!加入的水和流出的水相抵消,水位将不再变化!!也就是说,我的目标是1米,但是最后系统达到0.8米的水位就不再变化了,且系统已经达到稳定。由此产生的误差就是稳态误差了。(在实际情况中,这种类似水缸漏水的情况往往更加常见,比如控制汽车运动,摩擦阻力就相当于是“漏水”,控制机械臂、无人机的飞行,各类阻力和消耗都可以理解为本例中的“漏水”)
所以,单独的比例控制,在很多时候并不能满足要求

P I D分别起什么作用

P(Proportional 比例环节)

比例控制算法,我感觉应该是PID算法中比较核心的部分,感觉他是整个PID中的主力,当kp值越大的时候,控制系统的响应速度就越快,但是同时也会带来更大的震荡。至于其他的像积分控制算法,和微分控制算法,是为了消除误差,减少震荡。P的具体作用见上一节介绍。

I(Integral 积分环节)

积分控制算法,就是为了消除稳态误差(在理解上可以参考积分的几何意义),由于积分是从0时刻一直积分到当前时刻 t,并且是对e(t)函数进行积分。

在只有P(比例)环节的时候,在上面我们可以看到,在理想状态下也是可以满足控制需求,但是在真实场景中无法达到。所以**引入I(积分)来消除静态误差。**在到达节点位置之前,e(t)始终是正的,也就是它的积分始终是大于0的,如果系统存在稳态误差的话,由于误差一直不变,但是积分变呀,积分会一直积下去,之前的稳态误差是中和了比例控制算法的值,现在有一个一直增长的积分,导致每次u(t)的输出也在一直的增大,从而稳态误差就被消除了。到最后,误差为零了,而此时的e(t)也为0了,积分也就固定在某一个值了。从而每次的稳态误差就都可以被消除掉。
如果到达节点位置之后了,也就是冲过了节点的指定位置,这时候误差就变为了负的,然后由于积分正负可以相减,同样可以很好的适应这种情况。

D(Differential 微分环节)

用了积分控制算法,现在可以消除稳定误差了,但是考虑下面几种情况:

1.现在的情况是不存在稳态误差,但是存在积分控制算法,那么问题就出现了,当到达了目的位置后,哪怕误差已经是0了,但是积分控制算法那里还是一个整数,导致下一次输出u(t)仍然为一个整数,而不是0,这样的话,就会越过目的位置,虽然之后误差就变成了负数,又会回落回目的位置,但是这样始终是震荡的,而不是一直稳定下去。
2.在初始状态下,如果Kp或者Ki设置的过大,则会导致u(t)的变化幅度过大。
综上,在上述情况下,加入微分控制就很有必要,其实微分控制的作用就是防止幅度过大(防止超调),导致震荡或者超调,微分就是为了在输出斜率变的太大之前,在系统中引入一个有效的早期修正信号。微分可以防止震荡,比如当控制无人机悬停到一定高度,kd的作用就是如何让他停稳。

当存在稳态误差的时候,由于微分对于常数的求导是0,故微分不能解决稳态误差的问题。单独使用意义不大,故需要与比例积分共同配合使用,构成PD或PID控制。

从时间的角度讲,比例作用是针对系统当前误差进行控制,积分作用则针对系统误差的历史,而微分作用则反映了系统误差的变化趋势,这三者的组合是“过去、现在、未来”的完美结合。同样这三个参数也不可以设置的过大,我们要找到一个平衡点(调参)。

PID的两种不同实现方式

数字 PID 控制算法因时间离散化不同,通常分为位置式 PID 控制算法和增量式 PID 控制算法。

位置式PID

位置式PID

也就是位置式PID是当前系统的实际位置,与你想要达到的预期位置的偏差,进行PID控制

因为有误差积分 ∑e(i),一直累加,也就是当前的输出u(k)与过去的所有状态都有关系,用到了误差的累加值;(误差e会有误差累加),输出的u(k)对应的是执行机构的实际位置,,一旦控制输出出错(控制对象的当前的状态值出现问题 ),u(k)的大幅变化会引起系统的大幅变化

并且位置式PID在积分项达到饱和时,误差仍然会在积分作用下继续累积,一旦误差开始反向变化,系统需要一定时间从饱和区退出,所以在u(k)达到最大和最小时,要停止积分作用,并且要有积分限幅和输出限幅。

而位置式 PID 适用于执行机构不带积分部件的对象,如舵机和平衡小车的直立和温控系统的控制。
缺点:

1)、由于全量输出,所以每次输出均与过去状态有关,计算时要对ek进行累加,工作量大;

2)、因为计算机输出的uk对应的是执行机构的实际位置,如果计算机出现故障,输出的uk将大幅度变化,会引起执行机构的大幅度变化,有可能因此造成严重的生产事故,这在实生产际中是不允许的

3)、如果偏差一直是正的或者负的,位置式PID在积分项会一直累积,因此必须对积分项进行限幅,同时也要对输出进行限幅。当偏差开始反向变化,位置式PID在积分项需要一段时间才能从最大值减下来,造成输出的滞后。

代码实现(C语言)
//相关值结构体
typedef struct
{
    int target_val;           //目标值
    int actual_val;        		//实际值
    int err;             			//定义偏差值
    int err_last;          		//定义上一个偏差值
    float Kp,Ki,Kd;          		//定义比例、积分、微分系数
    int erradd;          		//定义积分值
}_pid;
//位置式pid算法实现,可以结合位置式pid算式理解
int PID_realize(uint16_t temp_val,uint16_t speed)
{
	pid.target_val=temp_val;
  /*计算目标值与实际值的误差*/
  pid.err = pid.target_val - speed;
  pid.erradd += pid.err;
  /*PID算法实现*/
  pid.actual_val = pid.Kp * pid.err + 
                   pid.Ki * pid.erradd + 
                   pid.Kd * (pid.err - pid.err_last);
  /*误差传递*/
  pid.err_last = pid.err;

  /*返回当前实际值*/
  return pid.actual_val;
}

增量式PID

1、优点

1)、根据增量式PID的表达式可以很好地看出,一旦确定了 KP、TI 、TD,只要使用前后三次测量值的偏差, 即可由公式求出控制增量。而得出的控制量▲uk对应的是近几次位置误差的增量,而不是对应与实际位置的偏差,因此没有误差累加。

2)、增量式PID中不需要累加,计算量小。控制增量Δu(k)的确定仅与最近3次的采样值有关,容易通过加权处理获得比较好的控制效果,并且在系统发生问题时,增量式不会严重影响系统的工作。

2、缺点:

1)、积分截断效应大,有稳态误差;

2)、溢出的影响大。有的被控对象用增量式则不太好;

代码实现(C语言)
typedef struct
{
  float target_val;     //目标值
	float actual_val;     //实际值
	float err;            //定义当前偏差值
	float err_next;       //定义下一个偏差值
	float err_last;       //定义上一个偏差值
	float Kp, Ki, Kd;     //定义比例、积分、微分系数
}_pid;
//算法实现
float PID_realize(float temp_val) 
{
	/*传入实际值*/
	pid.actual_val = temp_val;
	/*计算目标值与实际值的误差*/
  pid.err=pid.target_val-pid.actual_val;
	/*PID算法实现*/
	float increment_val = pid.Kp*(pid.err - pid.err_next) + pid.Ki*pid.err + pid.Kd*(pid.err - 2 * pid.err_next + pid.err_last);
	/*传递误差*/
	pid.err_last = pid.err_next;
	pid.err_next = pid.err;
	/*返回增量值*/
	return increment_val;
}

位置式PID与增量式PID对比

  • 增量式算法不需要对积分项累加,控制量增量至于近几次误差有关,计算误差对控制量影响较小。而位置式算法要对近几次的偏差进行积分累加,容易产生较大的累加误差。
  • 增量式算法控制输出的是控制量增量,并无积分作用,因此该方法适合用于执行机构带积分作用的对象,如步进电机。而位置式算法适合用于执行机构不带积分不见的对象。
  • 增量式算法得出的是控制量的增量,例如在阀门控制中,只输出阀门开度的变化部分,误动作影响小,必要时还可通过逻辑判断限制或禁止本次输出,不会严重影响系统的工作;而位置式算法的输出直接对应对象的输出,因此对系统影响较大。
  • 在进行PID控制时,位置式PID需要有积分限幅和输出限幅,而增量式只需要输出限幅。

PID 参数选取方法

各个参数特点

  • 比例调节作用特点:调节作用快,系统一出现偏差,调节器立即将偏差放大输出;
  • 积分调节作用特点:积分调节作用的输出变化与输入偏差的积分成正比,积分调节作用的

输出不仅取决于偏差的大小,还取决于偏差存在的时间,只要有偏差存在, 尽管偏差可能很

小,但它存在的时间越长,输出信号就越大,只有消除偏差,输出才停止变化;

  • 微分调节作用特点:微分调节的输出是与被调量的变化率成正比,微分调节越大,越能提

前响应,但是也会将不必要的偏差放大;

试凑法

  • 要根据设计系统的具体情况,选择合适的采样周期,多次试凑,选择性能较好的一个作为最后采样周期。早整定参数时必须要认真观察系统的相应情况,根据响应情况来调整参数。

    具体方法
    • 先是比例,然后积分,最后微分;
    • 调试时,将PID参数置于影响最小的位置,即P最大,I最大,D最小;
    • 按纯比例系统整定比例度,使其得到比较理想的调节过程曲线,然后再把比例度放大 1.2倍左右,将积分时间从大到小改变,使其得到较好的调节过程曲线;
    • 最后在这个积分时间下重新改变比例度,再看调节过程曲线有无改善;
    • 如有改善,可将原整定的比例度减少,改变积分时间,这样多次的反复,就可得到合适的比例度和积分时间;
    • 如果在外界的干扰下系统稳定性不好,可把比例度和积分时间适当增加一些,使系统足够稳定;
    • 将整定好的比例度和积分时间适当减小,加入微分作用,以得到超调量最小、调节作用时间最短的调节过程。

临界比例法

临界比例法:适用于闭环控制系统里将调节器置于纯比例的作用下,从大到小逐渐改变调节器的比例度,并且得到等幅度的震荡过程就叫做临界比例度;

  • 1.将调节器的积分置于最大,微分置于 0,比例度系数适当即可平衡一段时间,把系统投放到自动运行中。
  • 2.然后将比例逐渐增大,增大到产生等幅现象,并记录下等幅时的临界比例系数(δk)和两个波峰的时间间隔(Tk 单位:min)。
  • 3.根据记下的比例系数和周期,采用经验公式,计算调节器的参数。
控制方法KpKiKd
P2×δk--------
PI2.2×δk0.85×Tk----
PD1.8×δk----0.1×Tk
PID1.7×δk0.5×Tk0.125×Tk

一般调节法

一般步骤为:

a. 确定比例增益 P :确定比例增益 P 时,首先去掉 PID 的积分项和微分项,一般是令 Ti=0、Td=0(具体见 PID 的参数设定说明),使 PID 为纯比例调节。输入设定为系统允许的最大值的 60%~70%,由 0 逐渐加大比例增益 P,直至系统出现振荡;再反过来,从此时的比例增益 P 逐渐减小,直至系统振荡消失,记录此时的比例增益 P,设定 PID 的比例增益 P为当前值的 60%~70%。比例增益 P 调试完成。

b. 确定积分时间常数 Ti 比例增益 P 确定后,设定一个较大的积分时间常数 Ti 的初值,然后逐渐减小 Ti,直至系统出现振荡,之后在反过来,逐渐加大 Ti,直至系统振荡消失。记录此时的 Ti,设定 PID 的积分时间常数 Ti 为当前值的 150%~180%。积分时间常数 Ti 调试完成。

c. 确定积分时间常数 Td 积分时间常数 Td 一般不用设定,为 0 即可。若要设定,与确定 P 和 Ti 的方法相同,取不振荡时的 30%。

d. 系统空载、带载联调,再对 PID 参数进行微调,直至满足要求:理想时间两个波,前高后低 4 比 1。

[参数调整方法参考来源,感兴趣的话可以进去下载]([野火]电机应用开发实战指南-基于STM32 — 野火产品资料下载中心 文档 (embedfire.com))


  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Max玮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值