接着前面更过的三篇文章,今天我们继续来学习PID的算法改进。

一共包含一下这几种,后续文章我们将一起深入了解这些知识

积分限幅:限制积分的幅度,防止积分深度饱和

积分分离:误差小于一个限度才开始积分,反之则去掉积分部分

变速积分:根据误差的大小调整积分的速度

不完全微分:给微分项加入一节惯性单元(低通滤波器)

微分先行:将对误差的微分替换为对实际值的微分

输出偏移:在非0输出时,给输出值加一个固定偏移

输入死区:误差小于一个限度时不进行调控

积分限幅(抗积分饱和)

首先要明确只有当KI !=0时才会出现积分饱和的现象

所要解决的问题:问题的核心在于理论计算与物理现实之间的脱节,第一:理论上,只要有误差存在,积分项就会持续增大或减小,以期驱动系统消除误差。然而,在现实世界中,任何执行器都有其物理极限。例如,阀门的开度只能在0%到100%之间,电机的转速也不能无限提高。第二:如果执行器因为卡住,断电,损坏等原因不能消除误差,则误差积分会无限制的加大,进而达到深度饱和状态,此时PID调控器会持续输出最大的调控力,即使后续执行器恢复正常,PID控制器在短时间内也会维持最大的调控力,直到误差积分从深度饱和状态退出

举例:当系统遇到以下情况时,会引发一个严重的问题——积分饱和

1. 系统响应慢或执行器达到极限:当被控制的物理量(如电机转速、加热器温度)由于物理限制,无法跟上控制器发出的指令时。例如,你命令一个电机以3000 RPM转速运行,但它的物理极限是2000 RPM。

2. 大的阶跃设定或外部扰动:当你突然给出一个远超当前状态的设定值(比如,室温25°C,你突然将暖气目标设为80°C),或者系统受到一个巨大的外部干扰。
这些情况下 设定值与输出值会产生一个巨大且持久的误差,积分环节会忠实地将这个巨大的误差不断累积,其累加值会变得越来越大,远超系统实际需要的控制量。而积分饱和会导致巨大的超调,系统响应时间变长,调节时间延长,系统可能进入振荡或不稳定,控制器在饱和区对于微小误差失去了精细调节的能力。

解决的方法:

对误差积分或积分项输出进行判断,如果幅值超过指定阈值,则进行限制。

1. 如果积分累积值超过了预设的上限(I_max),就强制让它等于上限;如果低于了预设的下限(I_min),就强制让它等于下限。

# e: 当前误差
# dt: 时间间隔
# error_sum: 积分累积值
error_sum += e * dt
# --- 核心逻辑 ---
if error_sum > I_max:
    error_sum = I_max
elif error_sum < I_min:
    ierror_sum = I_min
# ------------------

那么如何确定这里的上下限呢 有两种方法

(1):实测法:观察一下正常工作时误差积分的变化范围,稍微留一个余量,确定一个上限和下限

(2):计算法:确定一下积分项输出占总输出的最大比例,最简单的就是积分项的输出最大和总输出保持一致就是积分项限幅和输出项限幅和输出限幅保持一致,那么单独的积分限幅=输出限幅÷Ki 

积分分离

控制类型 P (比例) I (积分) D (微分) 常用组合 核心原因
定位置控制 必须加(提供调节动力) 慎用 / 不加(易致超调与振荡) 必须加(提供阻尼,类似 “刹车”) PD 系统自带积分特性,额外添加 I 项会形成 “双积分”,极易破坏稳定性,导致定位过冲。
定速控制 必须加(提供基础调节力) 必须加(消除负载带来的静差) 可选 / 不加(对速度噪声敏感) PI 系统无积分特性,仅靠 P 项无法抵消负载扰动,必须依赖 I 项实现转速无静差稳定。

定位置控制时,当系统到达目标点,误差变为零时,I项累积的巨大数值无法立刻消失,会继续推动系统冲过目标点。那么对于定位置控制我们可以引出积分分离。

要解决的问题:积分项一般作用于调控后期,用来消除持续的误差,调控前期一般误差较大且不需要积分项作用,如果此时任然进行积分,则调控进行到后期时,积分项可能已经累积了过大的调控力,这会导致超调。

解决方法:对误差大小进行判断,如果误差绝对值小于指定阈值,则加入积分项作用,反之,则直接将误差积分清零或不加入积分项作用。

# e: 当前误差
# dt: 时间间隔
# error_sum: 积分累积值
if( abs( error_sum) > integral_threshold)
    # 当误差绝对值大于阈值时,进行积分累积
     {error_sum += error * dt;}
else
    # 当误差小于或等于阈值时,直接将积分项清零
     {error_sum = 0;}

那么如何来判断阈值呢——实测可通过波形观察

如果值过大,则积分分离就没有作用了,如果值过小,一旦误差超过阈值了,积分作用就会完全消失,失去了积分来对抗外力的作用,所以阈值可以取最终误差正常波动的范围,在留些余量.。

变速积分

要解决的问题:如果积分分离阈值没有设定好,被控对象正好在阈值之外停下来,则此时控制器完全没有积分作用,误差不能消除。

方法:变速积分需要设计一个函数值随误差绝对值增大而减小的函数,函数值作为调整系数,用于调整误差积分的速度或积分项作用的强度

# dt: 时间间隔
# error_sum: 积分累积值
/*定义一个系数C,表示积分的速度,C的值与误差绝对值大小呈反比,误差绝对值越大,积分速度越慢*/
float C = 1 / (0.2 * fabs(Error0) + 1);		//根据公式计算得到系数C
error_sum += error * dt * C ;

微分先行

要解决的问题:普通PID的微分项对误差进行微分,当目标值大幅度跳变时,误差也会大幅度跳变,这会导致微分项突然输出一个很大的调控力,如果系统的目标值频繁大幅度切换,则此时的微分项不利于系统稳定

微分项的初衷是预测其变化趋势。而对设定值的阶跃做出剧烈反应,完全违背了微分项的本来目的。微分先行的目标,就是消除这种由于设定值改变而产生的微分冲击,同时保留微分项对过程值变化的响应能力。

解决方法:将对误差的积分换为对于实际值的积分

标准PID的微分项输出:

dout(k)=Kd​∗(error(k)−error(k−1))

微分先行PID的微分项输出:

dout(k)=−Kd​∗(actual(k)−actual(k−1))

为什么是负号,微分本质求斜率,因为从上面曲线图可以看出实际值与误差切线的斜率相反,我们需要一个负的微分作用来抑制它,并且控制器只会在测量值真正开始变化时才施加微分作用,这正是“微分先行”这个名字的由来。

不完全微分

这幅图表述的是噪声对各分量的影响:

对 P 项 (比例项) 的影响:中等

机理: P项的输出与当前误差成正比。

表现: 传感器信号中的噪声会直接、实时地传递到控制器输出上,导致输出信号也带有同样的高频抖动。这会使执行机构(如阀门、电机)产生不必要的小范围高频动作。

对 I 项 (积分项) 的影响:微小

机理: I项是对误差进行长时间的累积(积分)。

表现: 高频噪声的特点是围绕真实值快速上下波动,其正负值在积分过程中会大部分相互抵消。因此,I项具有天然的平滑和滤波效果,对高频噪声不敏感,主要响应误差的长期趋势(稳态误差)

对 D 项 (微分项) 的影响:严重

机理: D项计算的是误差的变化率(斜率)

表现: 噪声信号的特点是包含大量瞬时的、剧烈的跳变,这导致其瞬时斜率极大。图中斜率会突然由正变为负因此,D项会急剧放大噪声信号,产生幅度巨大且毫无规律的尖峰脉冲输出。这是最具破坏性的影响,常常导致系统剧烈振荡、不稳定,并可能快速磨损或损坏执行机构。

所以就引出了不完全微分要解决的问题:传感器获取的实际值经常会受到噪声干扰,而PID控制器中的微分项对噪声最敏感,这些噪声干扰可能会导致微分项输出抖动,进而影响系统性能

解决办法:给微分项加入一阶惯性单元(低通滤波器)

普通PID的微分项输出:

d_{\text{out}}(k) = K_d \cdot (e(k) - e(k-1))

不完全微分PID的微分项输出:

d_{\text{out}}(k) = (1-\alpha) \cdot K_d \cdot (e(k) - e(k-1)) + \alpha \cdot d_{\text{out}}(k-1)

不完全微分 PID 的应用远比普通 PID 广泛,它能在保证控制性能的同时,显著提高系统的稳定性和可靠性。

输出偏移

要解决的问题:对于一些启动需要执行一定力度的执行器,若输出值较小,执行器可能完全无动作,这可能会引起调控调控误差,同时会降低系统响应速度

解决方法:若输出值为0,则正常输出0,不进行调控,若输出值非0,则给输出值加一个固定偏移,跳过执行器无动作的阶段

输出偏移的PID输出值:

/*输出偏移*/
				if (Out > 0)		//如果输出为正
				{
					Out += 6;		//则直接给输出值加上一个固定偏移
				}
				else if (Out < 0)	//如果输出为负
				{
					Out -= 6;		//则直接给输出值减去一个固定偏移
				}
				else				//输出为0
				{
					Out = 0;		//输出0
				}

那这里的偏移量为什么是6呢 其实是要根据实测来得出,比如驱动电机旋转,你单独给设置一个PWM占空比的函数,逐渐增大PWM值看在哪个值下电机开始旋转那么偏移量就在那个附件留点余量就行。

但是原本PID控制的目标是让误差尽可能趋近于零。但引入偏移后,控制器失去了进行“微调”的能力。牺牲了精细调节的能力来换取执行器的响应。系统无法稳定在“刚刚好”的位置,只能在设定值两侧“来回走动”。便引出下一个解决方法输入死区

输入死区

要解决的问题:在某些系统中,输入的目标值或实际值有微小的噪声波动,或者系统有一点的滞后,这些情况可能导致执行器在误差很小时进行频繁调控,不能最终稳定下来

解决方法:若误差的绝对值小于一个限度,则固定输出0,不进行调控。

输入死区来告诉控制器:“这点小事(噪声/微小误差)就别管了,省点力气。”

输出偏移来告诉执行器:“我知道你启动需要点力气,我帮你加一把,跳过你的‘懒惰’阶段。”

一般情况下这两种结合这使用效果会更好。

到这里,PID算法的改进措施讲解就到此结束了,其实有这么多改进的方法 在具体的项目中需要按需进行选用,一步步调试获得最适合自己项目的PID算法。如有错误麻烦指出

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐