简介:这份PDF文档是发表于《燃料与化工》的焦炉多集气管压力智能控制研究论文,面向焦化工业自动化、智能控制方向的工程师与研究者,以及需要工业过程控制参考文献的高校师生。全文围绕集气管压力强耦合、非线性、时变且扰动剧烈等难点,提出智能混合解耦控制算法,将多变量系统分解为独立单变量回路,并结合高压氨水泵变频曲线调节、托板行程联锁与参数校正技术,实现压力稳定在130±20 Pa。资源包仅含1个PDF文件,约566KB,下载后可直接查阅论文的理论推导、耦合关系分析、装煤与换向工况的控制策略及现场应用效果。目前已有102人学习,可作为智能控制系统开发、自动化改造或学术写作的参考资料,帮助读者理解工业多变量解耦控制的工程实现路径。
1. 集气管压力为什么难控:多集气管耦合与智能控制系统的边界
焦炉正常生产时,炭化室逸出的荒煤气经上升管进入集气管,再由吸气管送往初冷器和鼓风机。集气管压力偏高会冒烟、损坏炉门密封;偏低则吸入空气,荒煤气含氧超标、焦炭烧损。麻烦在于,一座焦炉常有两条甚至多条集气管并列运行,通过煤气总管与鼓风机入口联通,阀门一动,邻管压力跟着变。现场最典型的反直觉现象是:单管PID整定得很漂亮,双管一投自动就来回打架,压力在±300Pa间摆动。焦炉多集气管压力智能控制系统要处理的,不是把一个压力值压到设定值,而是在多变量耦合、执行机构非线性和工况频繁切换下,让各管压力同时稳在工艺窗口内。适合焦化厂仪表与自动化工程师、DCS组态人员和接手老PID系统改造的技术负责人。
2. 集气管压力对象建模与多回路耦合分析
2.1 从工艺管路到传递函数:集气管压力对象的简化
集气管压力控制的执行手段主要有两类:吸气管上的调节蝶阀,以及鼓风机入口大循环阀或回流阀。日常投自动用的是各管吸气管蝶阀,鼓风机负责维持总管吸力。对这个对象做机理建模意义不大,实际工程里我一般按“一阶惯性加纯滞后”来近似:阀位变化后,压力先滞后几秒,再按指数规律趋近新稳态。
设第 i 条集气管的压力为 p_i,第 j 个阀位为 u_j,则通道可以写成 p_i(s)/u_j(s) = K_ij·e^(-τ_ij·s)/(T_ij·s+1)。当 i=j 时是主通道,K 通常较大、τ 较小;当 i≠j 时是耦合通道,K 较小但滞后更长。辨识的任务就是把 K、T、τ 这三个数从现场数据里抠出来。
采样周期要和执行机构匹配。蝶阀执行器全行程一般十几秒到几十秒,压力变送器响应在秒级,取 1s 采样足够。数据里混有装煤、推焦、换向带来的周期性扰动,辨识前要先剔除装煤段和推焦段,只保留结焦中期的平稳数据,否则辨识出的增益会被扰动带偏。
2.2 多集气管耦合通道的阶跃辨识与数据采集
现场做辨识的步骤我通常这么做:
- 把各管阀位切手动,稳定运行至少 20 分钟,记录压力、阀位、鼓风机前吸力,存成趋势或导出 CSV。
- 对 1# 阀做 3%~5% 的阀位阶跃,其余阀保持不动,观察 1#、2# 压力的响应曲线,持续到压力重新稳定,一般 5~10 分钟。
- 等压力回到原稳态后再对 2# 阀重复一次。
- 每次阶跃只动一个阀,这是拿到干净耦合通道数据的前提。
拿到数据后,我习惯用 ARX 模型做最小二乘辨识,代码量小、对现场工程师友好:
import numpy as np from numpy.linalg import lstsq # ARX 辨识:y(k) = a1*y(k-1) + a2*y(k-2) + b1*u(k-d) + b2*u(k-d-1) # y 为压力序列,u 为阀位序列,二者都已去均值 def arx_fit(y, u, na=2, nb=2, delay=3): n = len(y) start = max(na, delay + nb) rows, target = [], [] for k in range(start, n): row = [y[k - i] for i in range(1, na + 1)] row += [u[k - delay - i + 1] for i in range(1, nb + 1)] rows.append(row) target.append(y[k]) theta, *_ = lstsq(np.array(rows), np.array(target), rcond=None) return theta # [a1, a2, b1, b2] # 去均值 y = y - np.mean(y) u = u - np.mean(u) theta = arx_fit(y, u)这段代码里,a1、a2 描述对象自身的惯性和阻尼,b1、b2 描述阀位到压力的动态增益,delay 是纯滞后步数,单位是采样周期。辨识完把静态增益算成 (b1+b2)/(1-a1-a2),时间常数由极点位置反推,对比阶跃曲线目视校核,两者差太多说明 delay 没取准,改 delay 重跑。
一个双集气管系统的辨识结果常见形态如下,仅作量级参考,实际值必须以现场数据为准:
| 通道 | 静态增益 (Pa/%) | 时间常数 (s) | 纯滞后 (s) | 类型 |
|---|---|---|---|---|
| 1#阀 → 1#压力 | 42 | 55 | 8 | 主通道 |
| 1#阀 → 2#压力 | 13 | 70 | 12 | 耦合通道 |
| 2#阀 → 2#压力 | 39 | 58 | 9 | 主通道 |
| 2#阀 → 1#压力 | 11 | 68 | 11 | 耦合通道 |
2.3 用RGA判断阀门与压力的配对是否合理
耦合程度不能只看增益大小,要看相对增益阵列 RGA。它把增益矩阵 K 归一化,直接回答“这个阀到底该管哪条管”。计算只要两行:
import numpy as np # 行:阀(1#、2#),列:压力(1#、2#) K = np.array([[42, 11], [13, 39]]) RGA = K * np.linalg.inv(K).T # 逐元素相乘 print(np.round(RGA, 2))RGA 的对角元素接近 1、非对角接近 0,说明 1#阀配 1#压力、2#阀配 2#压力是合理的;如果对角元素是负数,或者明显大于 2,说明耦合已经强到不适合直接单回路控制。我遇到过一台焦炉因为两条吸气管共用一段总管,RGA 对角掉到 0.6 左右,此时要么加解耦补偿,要么把其中一条管改为压力随动、由另一条管统一调节,硬上双回路 PID 只会越调越乱。RGA 算完再决定控制结构,比先写算法后修修补补省事得多。
3. 智能控制算法落地:模糊PID与解耦补偿的最小实现
3.1 模糊PID的输入输出与规则表设计
集气管压力的工况变化慢,但装煤、推焦瞬间扰动大,固定参数 PID 很难两头兼顾:参数调硬了稳态抖,调软了扰动压不住。工程上用得最多的是模糊 PID,用偏差 e 和偏差变化率 ec 在线修正 ΔKp、ΔKi、ΔKd。
把 e 和 ec 归一化到 [-1,1],各分 NB、NS、ZE、PS、PB 五档,规则表以 ΔKp 为例:
| e \ ec | NB | NS | ZE | PS | PB |
|---|---|---|---|---|---|
| NB | PB | PB | PB | PS | ZE |
| NS | PB | PB | PS | ZE | NS |
| ZE | PB | PS | ZE | NS | NB |
| PS | PS | ZE | NS | NB | NB |
| PB | ZE | NS | NB | NB | NB |
规则背后的逻辑很直白:偏差大时加大比例作用,快速拉回;偏差接近零但变化率大时,加一点微分抑制超调;偏差和变化率都小,就往零靠,避免稳态抖动。ΔKi 和 ΔKd 用同样思路各做一张表,Ki 一般在偏差大时取零,防止积分饱和;Kd 在压力信号噪声大时整表乘一个 0.5 以下的系数。
3.2 前馈解耦补偿通道的工程化写法
解耦不必搞得很复杂。最实用的做法是把耦合通道当成可测扰动,从另一个阀的控制量里取前馈信号。以 1# 回路为例,最终阀位输出为:
u1 = u1_pid − k12·(p2 − sp2)
其中 u1_pid 是 1# 模糊 PID 的输出,p2 和 sp2 是 2# 管压力和设定值,k12 是补偿系数,按 K12/K11 估算,一般取 0.2~0.35,再在现场微调。符号很关键:当 2# 管压力高于设定、需要开大 2# 阀放气时,这个补偿量会让 1# 阀适当关小,抵消 2# 阀动作对 1# 管压力的拉低作用。
补偿系数不能一次取太大,否则等于人为制造了一个正反馈。调试时先取估算值的一半,观察双管压力在扰动下是收敛还是发散,再逐步加到合适位置。
3.3 用Python把双集气管回路跑一遍
投现场之前,先用离线仿真验证逻辑,能省掉很多上机调试时间:
import numpy as np dt = 1.0 N = 1200 # 简化一阶离散模型: p[k+1] = p[k] + dt/T * (-p[k] + K*u[k-delay]) K11, T11, d11 = 42.0, 55.0, 8 K21, T21, d21 = 13.0, 70.0, 12 K12, T12, d12 = 11.0, 68.0, 11 K22, T22, d22 = 39.0, 58.0, 9 p1 = np.zeros(N); p2 = np.zeros(N) u1 = np.zeros(N); u2 = np.zeros(N) sp1, sp2 = 0.0, 0.0 for k in range(1, N): # 阀位取上一时刻 PID 输出,这里用简单比例代替模糊推理 u1[k] = 50.0 - 0.6 * (p1[k-1] - sp1) - 0.3 * (p2[k-1] - sp2) u2[k] = 50.0 - 0.6 * (p2[k-1] - sp2) - 0.3 * (p1[k-1] - sp1) # 限幅 5%~95% u1[k] = min(95.0, max(5.0, u1[k])) u2[k] = min(95.0, max(5.0, u2[k])) # 两条管的压力动态叠加主通道与耦合通道 p1[k] = p1[k-1] + dt/T11 * (-p1[k-1] + K11 * u1[k-1]) p1[k] += dt/T21 * (K21 * u2[k-1]) p2[k] = p2[k-1] + dt/T22 * (-p2[k-1] + K22 * u2[k-1]) p2[k] += dt/T12 * (K12 * u1[k-1]) print("末段1#压力均值", np.mean(p1[-100:])) print("末段2#压力均值", np.mean(p2[-100:]))这段仿真里,T 和 K 来自 2.2 的辨识结果,delay 用缓存索引模拟更真实,为了代码简洁这里先省略。跑完看两个量:一是末段压力是否收敛到设定值附近,二是在 k=400 处给 2# 管加一个 100Pa 的外部扰动,看 1# 压力被拉起多少。如果解耦系数为 0 时 1# 压力被拉走 80Pa 以上,加上补偿后应压到 30Pa 以内,否则继续调 k12、k21。
4. PLC/DCS侧实现:多集气管压力回路组态、参数整定与联锁
4.1 回路组态与执行机构非线性处理
算法再好,落到 DCS 或 PLC 上都要面对阀门死区、回差和流量特性非线性。蝶阀在小开度段增益高、大开度段增益低,直接用线性 PID 会出现小开度时一调就过、大开度时调不动的现象。我一般先做两件事:一是标定阀位死区,把 0%~5% 和 95%~100% 这两段从调节区间里剔除,输出限幅在 5%~95%;二是如果 DCS 支持,给阀位输出加一个流量特性补偿函数,用分段折线把等百分比特性拉回近似线性。
回路组态时,每条集气管一个压力控制回路,PV 取对应压力变送器,OP 送对应蝶阀。鼓风机入口吸力做成前馈:总管吸力变化超过设定死区时,同时给各管回路一个同向的阀位偏置,避免每条管各自为战。手动自动切换必须无扰,切换瞬间把积分项预置成当前阀位,否则一切自动就跳。
4.2 关键参数整定表与限幅、速率限制
参数整定没有万能值,但可以给一个起调范围,现场在这个范围内微调:
| 参数 | 建议取值 | 说明 |
|---|---|---|
| 采样周期 | 1 s | 与阀门执行周期匹配,过快无收益 |
| 压力设定值 | 0~+50 Pa | 维持微正压,具体按炉型定 |
| 比例带 | 30%~60% | 耦合强的管取大一些 |
| 积分时间 | 60~120 s | 小于 60s 易与耦合通道共振 |
| 微分时间 | 0~15 s | 信号噪声大时直接置 0 |
| 阀位限幅 | 5%~95% | 防全关全开 |
| 速率限制 | 3%/s | 保护执行机构,也抑制耦合振荡 |
速率限制这一项经常被忽略,但在多集气管系统里很有用:它相当于给耦合通道加了一个低通,邻管来不及被“带飞”,双管互扰会明显减轻。
4.3 联锁与异常工况下的控制切换
异常工况下,智能控制必须让位于安全逻辑。我在项目里固定的联锁策略是:鼓风机跳车或总管吸力低于下限,所有压力回路立即切手动,同时开大放散阀;初冷器出口温度超高,压力回路保持自动但设定值上移,避免煤气倒吸;氧含量分析仪超限,切手动并报警,由操作工接管。
下面是一段结构化文本写法的回路输出处理,限幅、速率限制和手自动切换都放在里面:
FUNCTION_BLOCK FB_GasPressure VAR_INPUT PV : REAL; // 实测压力 Pa SP : REAL; // 设定压力 Pa MANUAL : BOOL; // 手动自动切换 MAN_OUT : REAL; // 手动阀位 % TRIP : BOOL; // 联锁信号 END_VAR VAR_OUTPUT OUT : REAL; // 阀位输出 % END_VAR VAR e, ec, last_e : REAL; out_raw, out_lim : REAL; END_VAR BEGIN e := SP - PV; ec := (e - last_e) / 1.0; // 采样周期 1 s last_e := e; IF TRIP OR MANUAL THEN OUT := MAN_OUT; // 联锁或手动时直接跟手动值 ELSE out_raw := FuzzyPID(e, ec); // 模糊 PID 推理输出 out_lim := LIMIT(5.0, out_raw, 95.0); // 速率限制:每个周期最多变化 3% IF ABS(out_lim - OUT) > 3.0 THEN IF out_lim > OUT THEN OUT := OUT + 3.0; ELSE OUT := OUT - 3.0; END_IF; ELSE OUT := out_lim; END_IF; END_IF; END_FUNCTION_BLOCKFuzzyPID 这个功能块负责查表推理,输入 e、ec,输出阀位。把限幅和速率限制放在它外面,好处是手动、联锁、自动三条路径共用同一套输出保护,不会出现某条路径绕过去把阀推到极限的情况。TRIP 信号优先于 MANUAL,联锁一来立刻跟手动值,操作工在画面上先把阀位摆到安全位置,再复位联锁。
5. 投运验证与排错:压力振荡、阀门饱和与工况漂移的处理
5.1 压力振荡先分清是自激还是耦合
投自动后压力来回摆,第一步是看振荡周期。周期在几十秒量级、幅度稳定,通常是本回路比例带太小或积分时间太短引起的自激,把比例带放大 20%、积分时间加长 30% 再试。周期在一两分钟、两条管此起彼伏,这是耦合振荡,单独改一条管的参数没用,要回头查解耦系数符号对不对、速率限制是不是放得太松。我一般用趋势对比法:把 1# 阀切手动,振荡消失说明问题出在 1# 回路;振荡照旧,问题在 2# 阀或耦合补偿上。
5.2 阀门饱和与死区的快速判断
阀位长时间贴在上限或下限,压力还是回不到设定值,就是饱和。常见原因有三个:蝶阀选型偏小、总管吸力不足、或者积分项被卡死。前两个是工艺问题,控制上救不了;第三个可以在 PID 里加积分分离,偏差大于阈值时停止积分。判断方法很简单,在画面上同时看阀位趋势和压力趋势,阀位到 95% 不动而压力还在往一个方向走,基本可以确定是饱和而不是参数问题。
阀门死区则表现为压力在设定值附近小幅游走,阀位输出在某个值附近反复微动但不产生实际动作。处理办法是给输出加一个 1%~2% 的死区补偿,或者接受这点静差,不要为了消掉它把增益调到振荡。
5.3 工况漂移时的参数自适应与验证记录
焦炉从装煤到推焦,煤气发生量在变化,辨识出的对象增益也会漂。固定一组模糊 PID 参数能覆盖大部分时段,但在结焦末期和装煤初期往往偏差较大。我的做法是按结焦周期分段:结焦中期用一组基准参数,装煤后 30 分钟内把比例带适当放大、积分时间加长,推焦前再切回基准。分段开关由推焦计划自动触发,避免操作工手动切来切去。
验证阶段建议做三类记录,每类至少三次:
| 验证项 | 方法 | 合格判据 |
|---|---|---|
| 设定值阶跃 | 设定值改 50Pa | 超调小于 30%,稳定时间小于 3 分钟 |
| 邻管扰动 | 手动动 2# 阀 5% | 1# 压力波动小于 50Pa |
| 异常联锁 | 模拟鼓风机跳车 | 3 秒内切手动并开大放散 |
三次记录里如果阶跃响应的稳定时间一次比一次长,说明阀门或管路有结焦堵塞,别急着改参数,先安排清焦。参数永远救不了机械问题,这条在多集气管系统里尤其明显。
本文还有配套的精品资源,点击获取