欢迎光临
我们一直在努力

《PID控制算法原理与工程实践》二、位置式、增量式 PID 与抗积分饱和(Anti-Windup)深度全景指南

在控制工程领域,PID(比例-积分-微分)算法被誉为工业控制的“心脏”。无论是在工业高精度恒温炉、伺服电机驱动器,还是现代四旋翼无人机的姿态控制中,PID 都凭借其简单的结构和极高的稳定性得到了大量技术人员的青睐。

本文将从PID连续公式的离散化出发,讲解位置式 PID 与 增量式 PID 这种算法,以及一些常用的抗积分饱和的一些策略。


一、 PID的离散化

在连续时间系统中,理想的 PID 控制器输出 u(t)u(t)u(t) 是由当前误差的比例、误差的历史积分以及误差的当前变化率线性加权组合而成的:

u(t)=Kpe(t)+Ki∫0te(τ)dτ+Kdde(t)dtu(t) = K_p e(t) + K_i \\int_{0}^{t} e(\\tau) d\\tau + K_d \\frac{de(t)}{dt}u(t)=Kpe(t)+Ki0te(τ)dτ+Kddtde(t)

然而,现代嵌入式芯片或数字信号处理器(DSP)是无法直接处理连续时间信号的。芯片只能在一个固定时间间隔 TsT_sTs(被称为采样周期)内,通过 ADC 采集当前物理量,并计算出当前的控制量。因此,必须将连续的微分和积分转换为计算机能够理解的离散数学加减法。

假设当前的采样时刻为 kkk,前一采样时刻为 k−1k-1k1,对应的误差分别为 e(k)e(k)e(k)e(k−1)e(k-1)e(k1)

  • 比例项(Proportional):直接数字化,只与当前误差挂钩:P(k)=Kp⋅e(k)P(k) = K_p \\cdot e(k)P(k)=Kpe(k)

  • 积分项(Integral):在数字离散系统中,连续积分演变为累加。
    ∫0te(τ)dτ≈∑j=0ke(j)⋅Ts\\int_{0}^{t} e(\\tau) d\\tau \\approx \\sum_{j=0}^{k} e(j) \\cdot T_s0te(τ)dτj=0ke(j)Ts

  • 微分项(Derivative):连续系统中的导数是切线斜率,在离散系统中,我们采用后向差分法,用相邻两次采样点的割线斜率来代替:

  • de(t)dt≈e(k)−e(k−1)Ts\\frac{de(t)}{dt} \\approx \\frac{e(k) – e(k-1)}{T_s}dtde(t)Tse(k)e(k1)

    通过上述方法,我们实现了PID算法的离散化。


    二、 位置式 PID

    2.1 数学模型

    将上述离散项直接代入连续 PID 公式,就可以得到位置式 PID(Positional PID)的经典离散表达式:

    u(k)=Kpe(k)+Ki∑j=0ke(j)⋅Ts+Kde(k)−e(k−1)Tsu(k) = K_p e(k) + K_i \\sum_{j=0}^{k} e(j) \\cdot T_s + K_d \\frac{e(k) – e(k-1)}{T_s}u(k)=Kpe(k)+Kij=0ke(j)Ts+KdTse(k)e(k1)

    从公式可以看出,位置式 PID 的当前输出 u(k)u(k)u(k) 对应的是执行机构的绝对位置或绝对状态(例如:加热器的绝对功率、节气门的绝对开度、伺服电机的绝对目标转矩)。

    比例项提供了瞬时反馈,微分项捕捉了未来的趋势,积分项 ∑e(j)\\sum e(j)e(j) 记录了历史误差和。

    2.2 位置PID的积分饱和(Integral Windup)现象

    在理想数学模型中,控制输出 u(k)u(k)u(k) 可以是无限大的。但在现实世界中,任何执行机构都有其物理极限。例如,一个阀门的开度只能在 0%∼100%0\\% \\sim 100\\%0%100% 之间,一个电压放大器的输出只能在 −12V∼+12V-12\\text{V} \\sim +12\\text{V}12V+12V 之间。

    当系统遭遇高载荷或设定值大幅度阶跃时,系统在短期内无法立刻消除误差。

    我们以一个工业恒温高压水箱为例,设定目标水温 rrr20∘C20^\\circ\\text{C}20C 突变到 100∘C100^\\circ\\text{C}100C(阶跃幅度 Δr=80∘C\\Delta r = 80^\\circ\\text{C}Δr=80C)。假设该加热器的物理极限最大功率输出为 umax⁡=100%u_{\\max} = 100\\%umax=100%(满功率加热),控制器的参数为 Kp=5,Ki=0.5K_p = 5, K_i = 0.5Kp=5,Ki=0.5,采样周期 Ts=0.1sT_s = 0.1\\text{s}Ts=0.1s。整个过程拆解为以下四个阶段:

  • t=0st = 0\\text{s}t=0s时刻目标跳变,当时当前实际水温仍是 20∘C20^\\circ\\text{C}20C,此时瞬间误差 e(0)=100−20=80∘Ce(0) = 100 – 20 = 80^\\circ\\text{C}e(0)=10020=80C
    根据公式,仅仅是比例项的计算结果就达到了 P=Kp⋅e=5×80=400%P = K_p \\cdot e = 5 \\times 80 = 400\\%P=Kpe=5×80=400%。此时理想未饱和输出 uunsat(0)≈400%u_{unsat}(0) \\approx 400\\%uunsat(0)400%,远远超过了物理上限。执行器由于硬限幅限制,被死死卡在输出最大物理值 usat=100%u_{sat} = 100\\%usat=100% 上。

  • t=0s∼60st = 0\\text{s} \\sim 60\\text{s}t=0s60s这段时间,大容量水箱的温度受制于热惯性,只能缓慢爬升。从 20∘C20^\\circ\\text{C}20C 升到 100∘C100^\\circ\\text{C}100C 统共耗时 60s60\\text{s}60s。在这长达 60 秒(即 600 个采样周期)的加热过程中,误差 eee 虽然在减小,但一直都是正数。位置式 PID 的积分器在每一个周期(0.1s0.1\\text{s}0.1s)里都在累计误差:
    每步积分增量=e⋅Ts\\text{每步积分增量} = e \\cdot T_s每步积分增量=eTs
    在这 60 秒的时间里,积分将会累积出了一个极大的数值:
    ∑e⋅Ts≈3000\\sum e \\cdot T_s \\approx 3000eTs3000
    此时,积分项的单独输出就高达 I=Ki⋅∑eTs=0.5×3000=1500%I = K_i \\cdot \\sum e T_s = 0.5 \\times 3000 = 1500\\%I=KieTs=0.5×3000=1500%!这意味着,未饱和总输出 uunsatu_{unsat}uunsat 已经到了 1500%1500\\%1500%

  • t=60st = 60\\text{s}t=60s 时,水温达到了 100∘C100^\\circ\\text{C}100C,误差 eee 瞬间归零,并在随后的几毫秒内由于惯性冲到了 100.1∘C100.1^\\circ\\text{C}100.1C,误差 eee 变成负数(e=−0.1∘Ce = -0.1^\\circ\\text{C}e=0.1C)。
    此时,理想的控制器本该立刻切断加热功率(甚至开启制冷)。然而,此时的 PID 总输出:
    uunsat=P+I=(5×(−0.1))+1500%=−0.5%+1500%=1499.5%u_{unsat} = P + I = \\big(5 \\times (-0.1)\\big) + 1500\\% = -0.5\\% + 1500\\% = 1499.5\\%uunsat=P+I=(5×(0.1))+1500%=0.5%+1500%=1499.5%
    因为 1499.5%1499.5\\%1499.5% 依然远远大于物理上限 100%100\\%100%,最终执行器的实际输出仍旧是:usat=100%u_{sat} = 100\\%usat=100%(满功率加热)!

  • 最终将会出现一个不好的现象:即便水温已经烧开、已经超调,但是由于积分器累计了大量的历史误差,即积分器处于过饱和状态,所以加热器依旧继续满功率输出,水温持续上升。直到将积分器里面的历史误差消耗结束,控制器才会输出一个降温的控制信号,但是此时水温已经严重超调(如升到 130∘C130^\\circ\\text{C}130C

    而在真实的工程实践中,水温严重超调,可能导致高压水箱内部压力过载爆炸,或者温控系统、电机驱动级因高温而彻底烧毁。


    三、 增量式 PID

    为了从根本上削弱积分饱和对位置控制造成的冲击,控制工程师提出了一种完全不同的视角:为什么不取消计算绝对输出,而是去计算当前输出应该比上一时刻输出改变多少呢?基于这种思路的PDI算法就是增量式 PID(Incremental PID)。

    3.1 数学模型

    增量式 PID 的核心思想是计算第 kkk 步输出与第 k−1k-1k1 步输出的差值,即控制增量 Δu(k)=u(k)−u(k−1)\\Delta u(k) = u(k) – u(k-1)Δu(k)=u(k)u(k1)

    首先写出第 kkk 步的位置式表达式:

    u(k)=Kpe(k)+KiTs∑j=0ke(j)+KdTs[e(k)−e(k−1)]u(k) = K_p e(k) + K_i T_s \\sum_{j=0}^{k} e(j) + \\frac{K_d}{T_s} [e(k) – e(k-1)]u(k)=Kpe(k)+KiTsj=0ke(j)+TsKd[e(k)e(k1)]

    再写出上一时刻第 k−1k-1k1 步的位置式表达式:

    u(k−1)=Kpe(k−1)+KiTs∑j=0k−1e(j)+KdTs[e(k−1)−e(k−2)]u(k-1) = K_p e(k-1) + K_i T_s \\sum_{j=0}^{k-1} e(j) + \\frac{K_d}{T_s} [e(k-1) – e(k-2)]u(k1)=Kpe(k1)+KiTsj=0k1e(j)+TsKd[e(k1)e(k2)]

    两式相减,展开求差:

    Δu(k)=Kp[e(k)−e(k−1)]+KiTs(∑j=0ke(j)−∑j=0k−1e(j))+KdTs[e(k)−2e(k−1)+e(k−2)]\\Delta u(k) = K_p [e(k) – e(k-1)] + K_i T_s \\left( \\sum_{j=0}^{k} e(j) – \\sum_{j=0}^{k-1} e(j) \\right) + \\frac{K_d}{T_s} [e(k) – 2e(k-1) + e(k-2)]Δu(k)=Kp[e(k)e(k1)]+KiTs(j=0ke(j)j=0k1e(j))+TsKd[e(k)2e(k1)+e(k2)]

    注意到积分求和项相减后,过去所有的历史误差全部互相抵消,只剩下了当前时刻的误差 e(k)e(k)e(k)。于是,我们得到增量式 PID 核心公式:

    Δu(k)=Kp[e(k)−e(k−1)]+KiTse(k)+KdTs[e(k)−2e(k−1)+e(k−2)]\\Delta u(k) = K_p [e(k) – e(k-1)] + K_i T_s e(k) + \\frac{K_d}{T_s} [e(k) – 2e(k-1) + e(k-2)]Δu(k)=Kp[e(k)e(k1)]+KiTse(k)+TsKd[e(k)2e(k1)+e(k2)]

    最终控制器的绝对输出则是增量的累加:u(k)=u(k−1)+Δu(k)u(k) = u(k-1) + \\Delta u(k)u(k)=u(k1)+Δu(k)

    3.2 增量式 PID 的优势

  • 天然抗积分饱和:由于公式中去掉了 ∑e(j)\\sum e(j)e(j) 这一大项,积分作用被完全转化为了当下的调节量。一旦执行器达到饱和边界,控制增量只要反向,输出就能瞬间退出饱和区,绝无位置式的历史滞后问题。
  • 系统安全性:位置式 PID 每次计算都需要全局积分,如果单片机复位或内存受到外界高频电磁干扰导致某个变量突变,绝对输出会瞬间跳变到极大值,引发事故。而增量式 PID 算出来的只是微调量,即使单次计算出错,在采样周期极短的系统中也绝不会引发系统恶性突变。
  • 状态切换平滑:当系统从“手动控制”平滑过渡到“自动控制(Auto Mode)”时,增量式 PID 只需要把上一时刻的手动输出作为 u(k−1)u(k-1)u(k1) 基准即可,实现了真正意义上的无扰切换(Bumpeless Transfer)。

  • 四、 抗积分饱和技术

    虽然增量式 PID 在很多方面由于增量式PID,但在大量位置型执行器(如纯电压驱动的 DC 电机、液压推杆)中,位置式 PID 的物理直观性依然不可替代。为了让解决位置式 PID 的积分饱和问题,以下几种抗积分饱和技术被提出。

    4.1 积分饱和(Integral Windup)

    在理想的线性控制系统中,控制器的计算输出 uunsat(t)u_{\\text{unsat}}(t)uunsat(t) 是无界的。然而,现实中的物理执行机构(如调节阀门的开度 0%∼100%0\\% \\sim 100\\%0%100%、驱动器的供电电压 −12V∼+12V-12\\text{V} \\sim +12\\text{V}12V+12V、加热器的功率极限)都存在物理上限 umax⁡u_{\\max}umax 与下限 umin⁡u_{\\min}umin。这类非线性硬限幅可以用 sat(·) 表示:

    usat(k)=sat(uunsat(k))={umax⁡,if uunsat(k)>umax⁡uunsat(k),if umin⁡≤uunsat(k)≤umax⁡umin⁡,if uunsat(k)<umin⁡u_{\\text{sat}}(k) = \\text{sat}\\big(u_{\\text{unsat}}(k)\\big) = \\begin{cases} u_{\\max}, & \\text{if } u_{\\text{unsat}}(k) > u_{\\max} \\\\ u_{\\text{unsat}}(k), & \\text{if } u_{\\min} \\le u_{\\text{unsat}}(k) \\le u_{\\max} \\\\ u_{\\min}, & \\text{if } u_{\\text{unsat}}(k) < u_{\\min} \\end{cases}usat(k)=sat(uunsat(k))=umax,uunsat(k),umin,if uunsat(k)>umaxif uminuunsat(k)umaxif uunsat(k)<umin

    当系统发生大幅度指令阶跃或遭遇强外部非线性负载扰动时,由于受控对象自身存在大惯性或时滞效应,状态反馈无法立即消除跟踪误差 e(k)e(k)e(k)。此时:

  • 执行器卡死:PID输出控制量迅速超越物理边界(uunsat>umax⁡u_{\\text{unsat}} > u_{\\max}uunsat>umax),执行机构被强行锁定在物理极限输出(usat=umax⁡u_{\\text{sat}} = u_{\\max}usat=umax),系统实质上退化为处于开环全功率驱动状态。
  • 积分器累积:由于标准位置式 PID 的积分器无对外界饱和状态的感知,在随后的动态过渡区间内,只要误差 e(k)e(k)e(k) 朝一个方向(一直为正数),离散积分更新项就会不停的执行累加:
  • I(k)=I(k−1)+e(k)⋅TsI(k) = I(k-1) + e(k) \\cdot T_sI(k)=I(k1)+e(k)Ts

  • 反向死区延迟:当反馈状态跨越平衡点(误差逆转为负值 e(k)<0e(k) < 0e(k)<0)时,系统本应立即施加反向控制力。然而,此时积分器内已经累计了庞大的数值(I(k)≫umax⁡I(k) \\gg u_{\\max}I(k)umax),导致总控制量 uunsatu_{\\text{unsat}}uunsat 依然在全力正向输出。
  • 积分饱和导致在系统已经超调的状态下,依然被迫维持满功率正向驱动。控制器必须依赖长时间的、大幅度的反向负误差去消耗历史积压的积分值。这种控制相位的严重滞后,轻则引发系统长时间的极限环震荡与巨幅超调,重则导致机械结构损坏或电控级热崩溃烧毁。

    4.2 反向计算法(Back Calculation)

    1. 核心思想

    反向计算法(后向相消法)的核心是在控制器内部引入一个基于控制量饱和残差的动态闭环负反馈回路。

    当控制器的理想未饱和输出 uunsat(k)u_{\\text{unsat}}(k)uunsat(k) 超过执行器的物理限制边界时,算法计算实际饱和输出 usat(k)u_{\\text{sat}}(k)usat(k) 与未饱和输出之间的代数差值,并通过一个特定的抗饱和反馈增益 KawK_{\\text{aw}}Kaw 反向叠加回积分器的输入端。

    2. 计算方法

    反向计算法下的离散积分状态差分方程为:

    I(k)=I(k−1)+e(k)⋅Ts+Kaw⋅(usat(k)−uunsat(k))⋅TsI(k) = I(k-1) + e(k) \\cdot T_s + K_{\\text{aw}} \\cdot \\big(u_{\\text{sat}}(k) – u_{\\text{unsat}}(k)\\big) \\cdot T_sI(k)=I(k1)+e(k)Ts+Kaw(usat(k)uunsat(k))Ts

    该方程在常规的积分器基础上增加了 Kaw⋅(usat(k)−uunsat(k))⋅TsK_{\\text{aw}} \\cdot \\big(u_{\\text{sat}}(k) – u_{\\text{unsat}}(k)\\big) \\cdot T_sKaw(usat(k)uunsat(k))Ts 项,当控制器的理想未饱和输出 uunsat(k)u_{\\text{unsat}}(k)uunsat(k) 没有超过执行器的物理限制边界时,该项为零,与传统位置PID算法一致;当当控制器的理想未饱和输出 uunsat(k)u_{\\text{unsat}}(k)uunsat(k) 超过执行器的物理限制边界时,Kaw⋅(usat(k)−uunsat(k))⋅TsK_{\\text{aw}} \\cdot \\big(u_{\\text{sat}}(k) – u_{\\text{unsat}}(k)\\big) \\cdot T_sKaw(usat(k)uunsat(k))Ts 会产生一个与 e(k)⋅Tse(k) \\cdot T_se(k)Ts 符号相反的数值抑制积分累加,从而实现抗积分饱和。

    在大误差导致的深度饱和期,积分项将会收敛至某一稳态平衡点 IssI_{\\text{ss}}Iss(即 I(k)=I(k−1)=IssI(k) = I(k-1) = I_{\\text{ss}}I(k)=I(k1)=Iss),积分器的净步进增量被强行清零。将该稳态判据带入上式:

    e(k)⋅Ts+Kaw⋅(usat(k)−uunsat(k))⋅Ts=0e(k) \\cdot T_s + K_{\\text{aw}} \\cdot \\big(u_{\\text{sat}}(k) – u_{\\text{unsat}}(k)\\big) \\cdot T_s = 0e(k)Ts+Kaw(usat(k)uunsat(k))Ts=0

    除去非零采样周期 TsT_sTs,将 uunsat(k)=Kp⋅e(k)+Ki⋅Iss+D(k)u_{\\text{unsat}}(k) = K_p \\cdot e(k) + K_i \\cdot I_{\\text{ss}} + D(k)uunsat(k)=Kpe(k)+KiIss+D(k)(此处因系统卡死在饱和平台,微分项 D(k)≈0D(k) \\approx 0D(k)0)及理论优化整定系数 Kaw=KiKpK_{\\text{aw}} = \\frac{K_i}{K_p}Kaw=KpKi (工程常用取值)代入方程:

    e(k)+KiKp⋅(usat(k)−(Kp⋅e(k)+Ki⋅Iss))=0e(k) + \\frac{K_i}{K_p} \\cdot \\Big( u_{\\text{sat}}(k) – \\big( K_p \\cdot e(k) + K_i \\cdot I_{\\text{ss}} \\big) \\Big) = 0e(k)+KpKi(usat(k)(Kpe(k)+KiIss))=0

    展开整理可得深度饱和期的积分值,该值是一个常数

    Iss=Kp(1−Ki)Ki2⋅e(k)+1Ki⋅usat(k)I_{\\text{ss}} = \\frac{K_p(1 – K_i)}{K_i^2} \\cdot e(k) + \\frac{1}{K_i} \\cdot u_{\\text{sat}}(k)Iss=Ki2Kp(1Ki)e(k)+Ki1usat(k)

    3. 特点

    该方法通过内部闭环使得饱和期间的积分器状态形成了一个关于当前残余误差 e(k)e(k)e(k) 和硬限幅边界 usatu_{\\text{sat}}usat 的自适应动态平衡守恒点。这使得控制相位在误差翻转的瞬时能够零延迟退出饱和限制区,在热力学长时滞过程控制中具有极高的价值。

    4.3 条件积分法

    1. 核心思想

    条件积分法的核心是通过条件判断是否进行积分。

    控制器实时监测执行机构是否已达物理硬饱和边界,并同时评估当前跟踪误差 e(k)e(k)e(k) 的代数方向。若执行器已触发正向饱和限制(u=umax⁡u = u_{\\max}u=umax),且当前误差依然为正(e>0e > 0e>0,意味着控制律仍试图驱使执行器增大输出,加剧饱和),则立刻冻结积分器;反之,若误差代数符号相反,指示控制量正在向退出饱和区的方向演进,则解除冻结,允许积分正常更新。

    2. 计算方法

    其离散积分项更新机制可以通过引入选择因子 σ(k)\\sigma(k)σ(k) 来表述:

    I(k)=I(k−1)+σ(k)⋅e(k)⋅TsI(k) = I(k-1) + \\sigma(k) \\cdot e(k) \\cdot T_sI(k)=I(k1)+σ(k)e(k)Ts

    其中,σ(k)\\sigma(k)σ(k) 的定义为:

    σ(k)={0,if (uunsat(k−1)≥umax⁡ AND e(k)>0) OR (uunsat(k−1)≤umin⁡ AND e(k)<0)1,otherwise\\sigma(k) = \\begin{cases} 0, & \\text{if } \\big( u_{\\text{unsat}}(k-1) \\ge u_{\\max} \\text{ AND } e(k) > 0 \\big) \\text{ OR } \\big( u_{\\text{unsat}}(k-1) \\le u_{\\min} \\text{ AND } e(k) < 0 \\big) \\\\ 1, & \\text{otherwise} \\end{cases}σ(k)={0,1,if (uunsat(k1)umax AND e(k)>0) OR (uunsat(k1)umin AND e(k)<0)otherwise

    3. 特点

    条件积分法逻辑严密,且不引入任何额外的现场调参自由度。其核心优势在于响应的瞬时切断特性,能够确保在饱和边际处积分状态绝对静止,从而消除了过冲隐患。常用于执行机构上下限高度不对称、非线性特强的高精密伺服动力学系统。

    4.4 积分分离法(Integral Separation)

    1. 核心思想

    在控制系统刚发生大幅度设定值阶跃的初期,由于跟踪误差幅值极大,积分算子此时参与计算不仅无助于加快响应,反而会累积出大量的恶性饱和动态能量。因此,该算法引入一个人工设定的误差边界(门限宽度) γ\\gammaγ。当大误差处于门限之外时,完全关闭积分器,仅靠比例与微分环节提供全局最大调节动力;当系统输出渐进收敛至线性过渡区、误差幅值收缩至门限以内时,再重新并入积分器,消除系统的稳态静差。

    2. 计算方法

    通过引入逻辑开关变量 α(k)\\alpha(k)α(k) 来改写离散积分公式:

    I(k)=I(k−1)+α(k)⋅e(k)⋅TsI(k) = I(k-1) + \\alpha(k) \\cdot e(k) \\cdot T_sI(k)=I(k1)+α(k)e(k)Ts

    α(k)={1,if ∣e(k)∣≤γ0,if ∣e(k)∣>γ\\alpha(k) = \\begin{cases} 1, & \\text{if } |e(k)| \\le \\gamma \\\\ 0, & \\text{if } |e(k)| > \\gamma \\end{cases}α(k)={1,0,if e(k)γif e(k)>γ

    3. 特点

    该方法在频繁大范围切换设定值的运动控制系统(如数控机床进给轴、CNC 刀闸位置环)中应用极广,能直接压制阶跃初始阶段的饱和风险。但该方法的缺点在于硬门限 γ\\gammaγ 的选择高度依赖人工工程经验:若 γ\\gammaγ 整定过大,抗饱和收效甚微;若 γ\\gammaγ 设定过小,系统在硬切换点附近可能退化为纯 PD 控制,导致进入稳态的过程极其缓慢,甚至在门限边缘触发非线性极限环震荡。


    4.5 总结

    在工程实际中落地防饱和算法时,应结合受控对象的物理边际和控制指标进行选择:

    抗饱和技术方案数学本质机理控制律连续性调参复杂度典型工程适用场景
    反向计算法 (Back Calculation) 利用限幅残差通过内部负反馈回路闭环冲刷积分发散量 优异 (动态自适应过渡) 中等 (需增设反馈增益 KawK_{\\text{aw}}Kaw) 高能重载伺服驱动器、复杂过程热力学温控核心回路
    条件积分法 (Conditional Integration) 实时诊断执行器状态与误差方向符号的合力代数方向 良好 (存在逻辑切换点) 极低 (无需增加任何额外参数) 多变量耦合系统、上下限非对称的非线性气动/液压推杆
    积分分离法 (Integral Separation) 空间域硬门限分段切离积分算子 较差 (在切换面存在硬阶跃) 中等 (需整定解耦宽度 γ\\gammaγ) 频繁遭遇大范围目标阶跃的机械臂关节位置环控制

    五、MATLAB 仿真

    5.1 仿真设置

    为了验证上述推导的严谨性,我们在 MATLAB 中搭建了一个二阶带有惯性和震荡特性的物理受控对象(传递函数为 G(s)=25s2+4s+25G(s) = \\frac{25}{s^2 + 4s + 25}G(s)=s2+4s+2525)。

    以下为完整的离散时间闭环仿真脚本。代码在 t=15st = 15\\text{s}t=15s 时发出了阶跃信号(目标值从 +1.5+1.5+1.5 骤降至 −2.5-2.52.5),故意将执行器逼入长达 15 秒的严重极限饱和区,而后目标值再回到正常的目标值 −1.5-1.51.5,由此来观察位置 PID 、 Anti-Windup PID 与 增量PID区别。

    5.2 代码与图像

    clc;
    clear;
    close all;

    %% ============================================================
    % Simulation Parameters
    %% ============================================================

    Ts = 0.01;
    Tend = 55;

    t = 0:Ts:Tend;
    N = length(t);

    %% ============================================================
    % Controlled Object (Plant)
    %
    % 25
    % G(s) = ——–
    % s²+4s+25
    %
    %% ============================================================

    sys = tf(25,[1 4 25]);

    sysd = c2d(sys,Ts);

    [num,den] = tfdata(sysd,'v');

    %% ============================================================
    % PID Parameters
    %% ============================================================

    Kp = 10;
    Ki = 4;
    Kd = 0.5;

    %% ============================================================
    % Anti-Windup Parameters
    %% ============================================================

    Kaw = Ki/Kp;

    %% ============================================================
    % Output Saturation Limits
    %% ============================================================

    u_max = 2;
    u_min = 2;

    %% ============================================================
    % Integrator Limits
    %% ============================================================

    Imax = 5;
    Imin = 5;

    %% ============================================================
    % Reference (Setpoint Profile)
    %
    % 0 ~ 15s : 1.5
    % 15 ~ 30s : -2.5
    % 30 ~ 55s : -1.5
    %
    %% ============================================================

    r = ones(1,N)*1.5;

    r(t>=15) = 2.5;

    r(t>=30) = 1.5;

    %% ============================================================
    % 1. Standard PID Simulation Loop
    %% ============================================================

    y1 = zeros(1,N);
    u1 = zeros(1,N);

    Istate1 = zeros(1,N);

    integral = 0;
    e_old = 0;

    for k = 3:N

    e = r(k) y1(k1);

    %% Integrator Accumulation
    integral = integral + e*Ts;
    integral = min(max(integral,Imin),Imax);

    %% PID Control Law
    P = Kp*e;
    I = Ki*integral;
    D = Kd*(ee_old)/Ts;

    u_unsat = P + I + D;

    %% Actuator Saturation Limit
    u1(k) = min(max(u_unsat,u_min),u_max);

    %% Plant Dynamics Update
    yplant =
    den(2)*y1(k1)
    den(3)*y1(k2)
    +num(2)*u1(k1)
    +num(3)*u1(k2);

    y1(k)=yplant;

    %% State Recording
    Istate1(k)=integral;
    e_old=e;

    end

    %% ============================================================
    % 2. Back Calculation PID Simulation Loop
    %% ============================================================

    y2 = zeros(1,N);
    u2 = zeros(1,N);

    Istate2 = zeros(1,N);

    integral = 0;
    e_old = 0;

    for k = 3:N

    e = r(k) y2(k1);

    %% Proportional Term (P)
    P = Kp*e;

    %% Derivative Term (D)
    D = Kd*(ee_old)/Ts;

    %% Unsaturated Control Output
    u_unsat = P + Ki*integral + D;

    %% Saturated Control Output
    u_sat = min(max(u_unsat,u_min),u_max);

    %% Back Calculation Dynamic Update
    integral = integral
    + e*Ts
    + Kaw*(u_satu_unsat)*Ts;

    %% Integrator Saturation Limit
    integral = min(max(integral,Imin),Imax);

    %% Final Control Signal Assignment
    u2(k)=u_sat;

    %% Plant Dynamics Update
    yplant =
    den(2)*y2(k1)
    den(3)*y2(k2)
    +num(2)*u2(k1)
    +num(3)*u2(k2);

    y2(k)=yplant;

    %% State Recording
    Istate2(k)=integral;
    e_old=e;

    end

    %% ============================================================
    % 3. Incremental PID Simulation Loop
    %% ============================================================

    y3 = zeros(1,N);
    u3 = zeros(1,N);

    Istate3 = zeros(1,N);

    e_old = 0;
    e_older = 0;

    for k = 3:N

    e = r(k) y3(k1);

    %% Calculate Incremental Terms
    dP = Kp * (e e_old);
    dI = Ki * e * Ts;
    dD = Kd * (e 2*e_old + e_older) / Ts;

    du = dP + dI + dD;

    %% Accumulate from PREVIOUS SATURATED Output (Inherent Anti-Windup)
    u_unsat = u3(k1) + du;

    %% Saturated Control Output
    u3(k) = min(max(u_unsat, u_min), u_max);

    %% Plant Dynamics Update
    yplant =
    den(2)*y3(k1)
    den(3)*y3(k2)
    +num(2)*u3(k1)
    +num(3)*u3(k2);

    y3(k) = yplant;

    %% Equivalent Integrator State Recording
    % Derived from: u = P + I + D -> I_equiv = (u – P – D) / Ki
    Istate3(k) = (u3(k) Kp*e Kd*(ee_old)/Ts) / Ki;

    %% Update Error History
    e_older = e_old;
    e_old = e;

    end

    %% ============================================================
    % Tracking Error Calculation
    %% ============================================================

    e1 = r y1;
    e2 = r y2;
    e3 = r y3;

    %% ============================================================
    % Data Visualization (Plotting)
    %% ============================================================

    figure(
    'Color','w',
    'Position',[100 100 1500 900]);

    %% ============================================================
    % System Output Plot
    %% ============================================================

    subplot(2,2,1)

    plot(t,r,
    'k–',
    'LineWidth',2)

    hold on

    plot(t,y1,
    'b',
    'LineWidth',2)

    plot(t,y2,
    'r',
    'LineWidth',2)

    plot(t,y3,
    'g',
    'LineWidth',2)

    grid on

    title('System Output')

    xlabel('Time (s)')
    ylabel('Output')

    legend('Reference',
    'Normal PID',
    'Anti-Windup PID',
    'Incremental PID',
    'Location','best')

    %% ============================================================
    % Controller Output Plot
    %% ============================================================

    subplot(2,2,2)

    plot(t,u1,
    'b',
    'LineWidth',2)

    hold on

    plot(t,u2,
    'r',
    'LineWidth',2)

    plot(t,u3,
    'g',
    'LineWidth',2)

    yline(u_max,'k–','Upper Limit')
    yline(u_min,'k–','Lower Limit')

    grid on

    title('Controller Output')

    xlabel('Time (s)')
    ylabel('Control Signal')

    legend('Normal PID',
    'Anti-Windup PID',
    'Incremental PID',
    'Location','best')

    %% ============================================================
    % Integrator State Plot
    %% ============================================================

    subplot(2,2,3)

    plot(t,Istate1,
    'b',
    'LineWidth',2)

    hold on

    plot(t,Istate2,
    'r',
    'LineWidth',2)

    plot(t,Istate3,
    'g',
    'LineWidth',2)

    yline(Imax,'k–','Upper Limit')
    yline(Imin,'k–','Lower Limit')

    grid on

    title('Integrator State')

    xlabel('Time (s)')
    ylabel('Integral State')

    legend('Normal PID',
    'Anti-Windup PID',
    'Incremental PID',
    'Location','best')

    %% ============================================================
    % Tracking Error Plot
    %% ============================================================

    subplot(2,2,4)

    plot(t,e1,
    'b',
    'LineWidth',2)

    hold on

    plot(t,e2,
    'r',
    'LineWidth',2)

    plot(t,e3,
    'g',
    'LineWidth',2)

    yline(0,'k–','Zero Error')

    grid on

    title('Tracking Error')

    xlabel('Time (s)')
    ylabel('e = r – y')

    legend('Normal PID',
    'Anti-Windup PID',
    'Incremental PID',
    'Location','best')

    %% ============================================================
    % Overall Super Title
    %% ============================================================

    sgtitle('PID vs Anti-Windup PID vs Incremental PID',
    'FontSize',14,
    'FontWeight','bold')

    5.3 结果分析

    从仿真结果可以看出,普通位置式PID、抗积分饱和PID以及增量式PID在执行器存在饱和限制时表现出明显差异。系统在 t=15st=15\\text{s}t=15s 时设定值由 1.51.51.5 跃变至 −2.5-2.52.5,控制器输出迅速达到下限 −2-22;随后在 t=30st=30\\text{s}t=30s 时设定值调整为 −1.5-1.51.5,此时能够直观地观察各类PID算法在饱和工况下的动态性能差异。

    • 普通位置式PID
      普通PID在进入饱和区后,控制器输出被限制在下限,但积分器仍然持续对误差进行累加,产生典型的积分饱和(Windup)现象。从左下角的积分状态图可以看到,蓝色曲线逐渐积累到较大的负值。当 =30s=30\\text{s}=30s 时设定值回升至 −1.5-1.51.5,系统误差已经转为正值,但控制器内部仍保存着大量负积分量。
      这种现象直接导致控制器理想输出 uunsatu_{\\text{unsat}}uunsat 长时间低于执行器下限,因此实际控制输出仍被限制在 −2-22。从控制器输出图和系统输出图可以看到,蓝色曲线在约 7s7\\text{s}7s 内几乎没有响应,系统表现出明显的“动力迟滞”现象。直到积分器逐渐释放掉此前积累的误差后,控制器才脱离饱和状态,系统开始向新的设定值收敛。这也是普通PID在存在执行器限幅时最典型的问题。

    • 抗积分饱和(反向计算法)位置PID
      抗积分饱和PID通过反向计算(Back Calculation)机制抑制积分器持续累积。当控制器输出达到饱和边界后,反馈项
      Kaw(usat−uunsat)K_{aw}(u_{sat}-u_{unsat})Kaw(usatuunsat)
      会自动修正积分状态,使积分器保持在合理范围内。
      从积分状态图可以看到,红色曲线在 t=15st=15\\text{s}t=15s 发生短暂波动后迅速稳定在约 0.43750.43750.4375 附近,并未继续向负方向发散。这说明误差驱动的积分作用与反向计算产生的补偿作用达到了平衡。根据系统参数:
      Kp=10,Ki=4,e=−0.5,usat=−2K_p=10,\\quad K_i=4,\\quad e=-0.5,\\quad u_{sat}=-2Kp=10,Ki=4,e=0.5,usat=2
      其稳态积分值为:
      Iss=Kp(1−Ki)Ki2e+1Kiusat=0.4375I_{ss}=\\frac{K_p(1-K_i)}{K_i^2}e+\\frac{1}{K_i}u_{sat}=0.4375Iss=Ki2Kp(1Ki)e+Ki1usat=0.4375
      因此积分器被稳定限制在一个合理范围内,而不会像普通PID那样持续累积。
      t=30st=30\\text{s}t=30s 设定值发生变化时,由于积分器内部不存在巨大的历史积累量,控制器理想输出立即回到线性工作区。从控制器输出图可以看到,红色曲线几乎瞬间脱离 −2-22 的饱和边界;系统输出也立即向新的目标值运动,没有出现明显的迟滞现象。相比普通PID,其超调更小、恢复速度更快,体现出了抗积分饱和策略的优势。

    • 增量式PID
      增量PID采用控制量增量作为输出:
      u(k)=u(k−1)+Δu(k)u(k)=u(k-1)+\\Delta u(k)u(k)=u(k1)+Δu(k)
      因此不会像位置式PID那样直接累积一个巨大的积分项,对积分饱和天然具有较好的抑制能力。
      从系统输出图可以看到,整个过程中几乎没有明显超调,且能够平稳地跟踪目标值变化。当设定值在 t=15st=15\\text{s}t=15st=30st=30\\text{s}t=30s 发生阶跃变化时,系统均能及时响应并最终稳定收敛。
      需要注意的是,左下角积分状态图中的绿色曲线在两个阶跃时刻出现了较大的尖峰,这并不意味着增量PID内部真的存在如此巨大的积分量。由于增量PID本身并不保存独立积分状态,图中显示的是根据控制输出反推得到的“等效积分状态”:Istate=usat−Kpe−KdΔeTsKiI_{\\text{state}}=\\frac{u_{sat}-K_p e-K_d \\dfrac{\\Delta e}{T_s}}{K_i}Istate=KiusatKpeKdTsΔe
      t=15st=15\\text{s}t=15s 阶跃发生时,误差瞬间由接近零变为约 −4-44,比例项和微分项同时急剧增大。其中微分项由于误差变化率极高,会产生较大的瞬时冲击。虽然执行器输出被限制在 −2-22,但反推公式中的分子项却会出现很大的数值,因此计算出的等效积分状态瞬间升高至约 60。随着阶跃冲击结束、误差变化率恢复正常,该数值迅速回落至零附近。因此绿色曲线的尖峰主要是数学计算结果,并不代表真实的积分累积现象。

    综合比较三种算法可以发现:

    • 普通位置PID结构简单,但在执行器饱和时容易产生严重积分饱和,导致大超调和长时间响应迟滞;
    • 抗积分饱和PID通过限制积分器累积,有效消除了Windup问题,在响应速度、超调量和恢复能力之间取得了最佳平衡;
    • 增量PID天然具备较强的抗饱和能力,控制输出平滑、稳定性好。

    从本次仿真结果来看,抗积分饱和PID、增量PID都表现出抗积分饱和的能力,两者都显著优于未采取任何抗饱和措施的普通位置式PID。


    七、 总结

    PID控制器作为工业控制领域应用最广泛的经典算法,其核心思想虽然简单,但在实际工程中仍面临执行器饱和、系统惯性以及外部扰动等诸多挑战。本文从PID离散化原理出发,介绍了位置式PID与增量式PID两种典型实现方式,并深入分析了积分饱和产生的原因及其对系统性能的影响。

    通过理论分析与MATLAB仿真可以发现,普通位置式PID在执行器达到限幅后容易产生严重的积分累积,导致系统出现超调大、恢复慢以及长时间响应迟滞等问题。增量式PID由于采用控制量增量形式进行计算,天然具备较好的抗积分饱和能力,控制过程更加平滑稳定。而引入反向计算等抗积分饱和策略后,位置式PID能够有效抑制积分器发散,在保证快速响应的同时显著改善系统动态性能。

    欢迎大家评论

    赞(0)
    未经允许不得转载:171主机测评 » 《PID控制算法原理与工程实践》二、位置式、增量式 PID 与抗积分饱和(Anti-Windup)深度全景指南
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址