3、Ziegler-Nichols整定法(时域法):基于阶跃响应的ZN法、临界比例度法、参数计算表

说到PID参数整定,Ziegler-Nichols法(简称ZN法)绝对是绕不开的经典。我入行那会儿,师父丢给我的第一本手册就是Ziegler和Nichols在1942年发表的论文。说实话,那时候觉得这方法有点老古董了。但后来在实际项目中吃了几次亏,才明白经典之所以是经典,是因为它真的能打。

ZN法说白了就两种思路:一种看系统的阶跃响应曲线,另一种找系统的临界振荡点。咱们一个一个聊。

3.1 基于阶跃响应的ZN法(开环整定)

这个方法适合那些开环稳定的对象。比如温度控制、液位控制,你给它一个阶跃信号,它慢慢悠悠地爬到稳态值。嗯,这时候就能用上这个办法了。

具体怎么做?我习惯分三步走:

  1. 做阶跃实验:系统开环,给一个幅度合适的阶跃输入。记录输出响应曲线。
  2. 找特征参数:从曲线上提取两个关键值——滞后时间L和上升时间T(或者叫时间常数τ)。
  3. 查表算参数:根据L和T的比值,套用ZN参数表。

这里有个细节要注意:阶跃幅度不能太大,否则系统可能进入非线性区;也不能太小,否则信噪比不够,曲线毛刺太多。我个人习惯取稳态值的10%~15%。

核心公式:

对于一阶惯性加纯滞后系统(FOPDT):G(s) = K * e^(-Ls) / (τs + 1)

其中:L = 滞后时间,τ = 时间常数,K = 稳态增益

拿到L和τ之后,直接套用ZN参数计算表:

控制器类型 Kp Ti Td
P τ / (K * L)
PI 0.9 * τ / (K * L) 3.33 * L
PID 1.2 * τ / (K * L) 2 * L 0.5 * L

你想想看,这个表其实挺有意思的。比例系数Kp跟τ/L成正比,说白了就是系统响应越慢(τ大),或者滞后越小(L小),Kp就可以给得越大。积分时间Ti跟滞后时间L直接挂钩,滞后越大,积分越慢,防止积分饱和。

我的经验:用这个方法整定出来的参数,通常系统会有10%~20%的超调。如果现场不允许超调,我建议把Kp打八折,Ti翻倍。我在一个化工反应釜的温度控制项目里就是这么干的,效果还不错。

3.2 临界比例度法(闭环整定)

这个方法适合那些开环不稳定的对象,或者你懒得做开环实验的场合。说白了就是让系统先振荡起来,找到临界点。

操作步骤也不复杂:

  1. 系统闭环,把积分和微分都关掉(Ti = ∞,Td = 0)。
  2. 慢慢增大比例增益Kp,直到系统输出出现等幅振荡。
  3. 记录此时的临界增益Ku和临界振荡周期Tu。

这里有个坑——我曾经遇到过,系统还没到等幅振荡就先发散掉了。为什么会这样?因为有些系统的非线性太强,或者执行机构有饱和限制。遇到这种情况,我建议把目标定为「出现明显的持续振荡」就行,不一定非要等幅。

拿到Ku和Tu之后,查另一张表:

控制器类型 Kp Ti Td
P 0.5 * Ku
PI 0.45 * Ku 0.83 * Tu
PID 0.6 * Ku 0.5 * Tu 0.125 * Tu

警告:临界比例度法会让系统进入振荡状态。对于某些不允许振荡的场合(比如精密位置控制、医疗设备),千万别用这个方法。我曾经在一个伺服电机项目里试过,结果电机嗡嗡响,差点把机械结构震散架了。

3.3 两种方法的对比与选择

说了这么多,到底该用哪个?我个人的选择原则是这样的:

  • 开环阶跃响应法:适合大多数工业过程控制,比如温度、压力、流量。安全,不会让系统振荡。但前提是你得能做开环实验。
  • 临界比例度法:适合那些开环实验不好做的系统,或者你赶时间。但风险就是系统会振荡,得悠着点。

其实吧,这两种方法整定出来的参数都只是「初始值」。真正好用的参数,还得在现场微调。我一般用ZN法算个大概,然后根据实际响应再调一调Kp、Ti、Td。说白了,ZN法就是个起点,不是终点。

3.4 代码实现示例

最后,给一段我常用的Python代码,用来计算ZN参数。你拿去改改就能用:

def zn_open_loop(L, tau, K, controller_type='PID'):
    """
    基于阶跃响应的ZN法参数计算
    L: 滞后时间
    tau: 时间常数
    K: 稳态增益
    """
    if controller_type == 'P':
        Kp = tau / (K * L)
        Ti = None
        Td = None
    elif controller_type == 'PI':
        Kp = 0.9 * tau / (K * L)
        Ti = 3.33 * L
        Td = None
    elif controller_type == 'PID':
        Kp = 1.2 * tau / (K * L)
        Ti = 2 * L
        Td = 0.5 * L
    return Kp, Ti, Td

def zn_closed_loop(Ku, Tu, controller_type='PID'):
    """
    临界比例度法参数计算
    Ku: 临界增益
    Tu: 临界振荡周期
    """
    if controller_type == 'P':
        Kp = 0.5 * Ku
        Ti = None
        Td = None
    elif controller_type == 'PI':
        Kp = 0.45 * Ku
        Ti = 0.83 * Tu
        Td = None
    elif controller_type == 'PID':
        Kp = 0.6 * Ku
        Ti = 0.5 * Tu
        Td = 0.125 * Tu
    return Kp, Ti, Td

嗯,代码不长,但够用。你拿到参数之后,记得先在仿真环境里跑一跑,别直接往现场怼。我在一个项目里就因为太自信,参数直接上机,结果系统超调了30%,差点把阀门给干废了。

好了,ZN法就聊到这儿。下一章咱们聊聊另一种经典方法——Cohen-Coon整定法,那个更适合大滞后系统。