python的工业过程控制场景模拟第三十四篇:编写程序模拟气开,气关调节阀故障动作逻辑,测试断信号时系统安全保护策略。
调节阀故障安全动作仿真系统 —— 基于 OOP 的气开 / 气关逻辑实战
"气动调节阀不是通电就开、断电就关那么简单。气开还是气关,选错了,停车时阀门的动作方向可能直接决定是安全停车还是爆炸事故。"
—— 哈尔滨工程大学《工业过程控制》课程核心安全理念
一、实际应用场景描述
在石油化工、天然气处理、锅炉给水等危险工艺中,气动调节阀是最常用的终端控制元件。它通过接收 4–20mA 控制信号驱动阀门开度,但本质上是一个故障安全(Fail-Safe)设备。
两种基本类型
类型 英文 信号↑ → 阀门 断信号(失气)时
气开阀 Air-to-Open (ATO) 开度增大 全关(FC)
气关阀 Air-to-Close (ATC) 开度减小 全开(FO)
典型工艺选择原则(课程 §3.3 "执行器选型与安全")
"选气开还是气关,唯一标准是:当控制信号丢失时,阀门必须趋向使工艺进入安全状态的方向。"
┌─────────────────────────────────────────────────────────────┐
│ 加热炉燃料气控制 │
│ │
│ 燃料气管线 ──▶ [气开阀] ──▶ 燃烧器 ──▶ 炉温 │
│ (FC) │
│ │
│ 场景: 仪表风中断 / 信号线断裂 / 控制器死机 │
│ 动作: 阀门全关 → 切断燃料 → 熄火停炉 → ✅ 安全 │
│ │
│ 如果错装成气关阀: │
│ 动作: 阀门全开 → 燃料喷涌 → 超温超压 → ❌ 爆炸风险 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 锅炉给水控制 │
│ │
│ 给水管线 ──▶ [气关阀] ──▶ 锅炉 ──▶ 蒸汽 │
│ (FO) │
│ │
│ 场景: 仪表风中断 │
│ 动作: 阀门全开 → 最大给水 → 防止干烧 → ✅ 安全 │
│ │
│ 如果错装成气开阀: │
│ 动作: 阀门全关 → 断水干烧 → 爆管 → ❌ 重大事故 │
└─────────────────────────────────────────────────────────────┘
哈尔滨工程大学《工业过程控制》课程(彭秀艳教授主讲,国家级一流本科课程)在第三章"执行器与调节阀"和第九章"控制系统的安全性设计"中反复强调:
"调节阀的气开/气关选择不是控制工程师的个人偏好,而是安全工程师的生命线。每一个阀门在安装前,都必须经过 HAZOP 分析确认故障方向。"
二、引入痛点
2.1 现场的真实困境
场景 现场发生了什么 根因
仪表风中断 "空压机跳闸,全车间阀门同时动作" 不知道每个阀是 FC 还是 FO
接线松动 "信号线接触不良,阀门乱动" 未定义信号丢失时的安全策略
调试误操作 "下载程序后阀门突然全开" 控制器启动瞬间的输出默认值错误
培训缺失 "新员工分不清气开气关" 缺乏直观的故障动作演示工具
仿真教学 "想给学生看断信号时系统怎么保护" 没有现成的故障安全仿真软件
2.2 核心矛盾
教科书上写着"气开阀断信号关、气关阀断信号开",但学生看不到、摸不着,考试背完就忘。更可怕的是,现场工程师凭经验选型,一旦选错,事故就是灾难性的。
我们需要一个工具:
1. 能可视化展示气开/气关阀在不同故障场景下的动作
2. 能验证安全策略是否正确(断信号 → 工艺是否进入安全态)
3. 能模拟多种故障场景(断气、断信号、控制器宕机、通信超时)
4. 能量化评估保护效果(偏离安全限值多少、恢复时间多久)
2.3 我们要解决什么
用一段 Python 程序,构建一个调节阀故障安全动作仿真系统,实现:
1. 两种阀门类型 —— 气开阀 (Air-To-Open) 和 气关阀 (Air-To-Close)
2. 四种故障场景 —— 正常 / 断信号 / 断气源 / 控制器停机
3. 安全评估引擎 —— 自动判定当前配置是否安全
4. 多种输出 —— 文本报告 + CSV 数据 + 曲线图
5. 面向对象设计 —— 清晰的分层架构,可扩展
三、核心逻辑讲解
3.1 理论基础:故障安全原则
本工具基于哈工程《工业过程控制》第三章 + 第九章:
① 气动执行器工作原理
薄膜气室压力 P 与弹簧力平衡 → 决定阀门开度
气开阀 (ATO):
信号 4mA → 气压最低 → 弹簧推阀芯关闭 → 开度 0%
信号 20mA → 气压最高 → 气压克服弹簧 → 开度 100%
气关阀 (ATC):
信号 4mA → 气压最低 → 弹簧推阀芯打开 → 开度 100%
信号 20mA → 气压最高 → 气压克服弹簧 → 开度 0%
② 信号-开度映射公式
X = X_{min} + \frac{I - 4}{16} \times (X_{max} - X_{min})
其中 I 为输入电流 (mA), X 为阀门开度 (%)。
③ 故障安全判定逻辑
工艺 危险状态 安全状态 应选阀门
燃料气加热 阀门开→火焰失控 阀门关→熄火 气开 (FC)
锅炉给水 阀门关→干烧爆管 阀门开→冷却 气关 (FO)
冷却水 阀门关→设备过热 阀门开→冷却 气关 (FO)
有毒气体排放 阀门开→泄漏 阀门关→截留 气开 (FC)
3.2 故障场景定义
class FaultType(Enum):
NONE = "normal" # 正常运行
SIGNAL_LOSS = "signal_loss" # 4-20mA 信号丢失
AIR_SUPPLY_LOSS = "air_loss" # 仪表风中断
CONTROLLER_DOWN = "ctrl_down" # 控制器停机
每种故障对应的阀门行为:
故障类型 气开阀 (ATO) 气关阀 (ATC)
信号丢失 → 全关 (0%) → 全开 (100%)
断气源 → 全关 (0%) → 全开 (100%)
控制器停机 → 取决于输出冻结/回零配置 同上
3.3 安全评估引擎逻辑
输入: 阀门类型 + 工艺危险方向 + 故障类型
↓
计算: 故障后阀门开度
↓
判断: 故障开度是否趋向安全方向?
↓
输出: SAFE / UNSAFE / WARNING
四、代码讲解(面向对象设计)
4.1 类结构总览
本项目采用面向对象编程(OOP),共设计 7 个核心类:
类名 职责 设计模式
"ValveConfig" 阀门配置参数(dataclass) 值对象
"ProcessConfig" 工艺安全配置(dataclass) 值对象
"SignalConverter" 4-20mA ↔ 开度转换 转换器模式
"BaseValve" 阀门基类(抽象) 模板方法
"AirToOpenValve" 气开阀 继承
"AirToCloseValve" 气关阀 继承
"SafetyEvaluator" 安全评估引擎 策略模式
"FaultSimulator" 故障仿真器 编排器
"DataRecorder" CSV 数据导出 封装
"Plotter" 曲线绘制 封装
4.2 配置层:dataclass 值对象
from dataclasses import dataclass
from enum import Enum, auto
class ValveAction(Enum):
"""阀门动作方向"""
AIR_TO_OPEN = "ATO" # 气开
AIR_TO_CLOSE = "ATC" # 气关
class FaultType(Enum):
"""故障类型"""
NONE = "normal"
SIGNAL_LOSS = "signal_loss"
AIR_SUPPLY_LOSS = "air_loss"
CONTROLLER_DOWN = "controller_down"
class SafetyDirection(Enum):
"""工艺安全方向"""
FAIL_CLOSED = "fail_closed" # 应趋向关闭
FAIL_OPEN = "fail_open" # 应趋向打开
@dataclass(frozen=True)
class ValveConfig:
"""阀门配置 —— 值对象"""
name: str = "FuelGasValve"
action: ValveAction = ValveAction.AIR_TO_OPEN
signal_min: float = 4.0 # mA
signal_max: float = 20.0 # mA
position_min: float = 0.0 # %
position_max: float = 100.0 # %
fail_safe_position: float = 0.0 # 故障安全位
@dataclass(frozen=True)
class ProcessConfig:
"""工艺安全配置 —— 值对象"""
name: str = "Heater"
danger_direction: str = "open" # 哪种方向危险
safe_direction: SafetyDirection = SafetyDirection.FAIL_CLOSED
critical_limit: float = 50.0 # 安全限值(%)
4.3 信号转换器
class SignalConverter:
"""
4-20mA 信号 ↔ 阀门开度转换器
公式:
position = pos_min + (signal - 4mA) / 16mA × (pos_max - pos_min)
课程 §3.2: 阀门定位器信号转换
"""
@staticmethod
def signal_to_position(signal_ma: float, cfg: ValveConfig) -> float:
"""
电流信号 → 阀门开度
Args:
signal_ma: 4-20mA 电流信号
cfg: 阀门配置
Returns:
阀门开度 (%)
"""
# 钳位到合法范围
sig = max(cfg.signal_min, min(cfg.signal_max, signal_ma))
ratio = (sig - cfg.signal_min) / (cfg.signal_max - cfg.signal_min)
pos = cfg.position_min + ratio * (cfg.position_max - cfg.position_min)
return round(pos, 2)
@staticmethod
def position_to_signal(position: float, cfg: ValveConfig) -> float:
"""阀门开度 → 电流信号(反向转换)"""
pos = max(cfg.position_min, min(cfg.position_max, position))
ratio = (pos - cfg.position_min) / (cfg.position_max - cfg.position_min)
sig = cfg.signal_min + ratio * (cfg.signal_max - cfg.signal_min)
return round(sig, 3)
4.4 阀门基类与具体实现
from abc import ABC, abstractmethod
class BaseValve(ABC):
"""
阀门基类 —— 模板方法模式
定义阀门的通用行为和故障响应框架
"""
def __init__(self, config: ValveConfig):
self.cfg = config
self._current_signal = 4.0 # 初始信号 (全关)
self._current_position = 0.0
self._fault_active = False
self._fault_type = FaultType.NONE
@property
@abstractmethod
def fail_position(self) -> float:
"""故障安全位置 —— 子类必须实现"""
pass
def update_signal(self, signal_ma: float) -> float:
"""
更新控制信号并计算新开度
如果没有故障,正常转换;有故障,返回故障安全位
"""
self._current_signal = signal_ma
if self._fault_active:
self._current_position = self.fail_position
else:
self._current_position = SignalConverter.signal_to_position(
signal_ma, self.cfg
)
return self._current_position
def trigger_fault(self, fault_type: FaultType):
"""触发故障"""
self._fault_active = True
self._fault_type = fault_type
self._current_position = self.fail_position
def clear_fault(self):
"""清除故障"""
self._fault_active = False
self._fault_type = FaultType.NONE
# 恢复到当前信号对应的位置
self.update_signal(self._current_signal)
@property
def position(self) -> float:
return self._current_position
@property
def signal(self) -> float:
return self._current_signal
class AirToOpenValve(BaseValve):
"""
气开阀 (Air-To-Open, ATO)
信号↑ → 开度↑
断信号/断气 → 弹簧复位 → 全关 (0%)
"""
@property
def fail_position(self) -> float:
return 0.0 # FC (Fail Closed)
class AirToCloseValve(BaseValve):
"""
气关阀 (Air-To-Close, ATC)
信号↑ → 开度↓
断信号/断气 → 弹簧复位 → 全开 (100%)
"""
@property
def fail_position(self) -> float:
return 100.0 # FO (Fail Open)
亮点:
- 模板方法模式:
"update_signal()" 定义了"有故障走故障位、无故障走正常转换"的固定流程
- 抽象属性
"fail_position":子类只需定义故障位置,基类统一处理
- 符合里氏替换原则:调用方只依赖
"BaseValve",不关心具体是 ATO 还是 ATC
4.5 安全评估引擎
class SafetyEvaluator:
"""
安全评估引擎 —— 策略模式
根据阀门类型和工艺危险方向,评估故障时的安全性
"""
@staticmethod
def evaluate(valve: BaseValve, process: ProcessConfig,
fault: FaultType) -> dict:
"""
评估故障场景的安全性
Returns:
{
"safe": bool,
"level": "SAFE" | "WARNING" | "UNSAFE",
"message": str,
"valve_position": float,
"recommendation": str
}
"""
if fault == FaultType.NONE:
return {
"safe": True,
"level": "SAFE",
"message": "正常运行,无故障",
"valve_position": valve.position,
"recommendation": "继续监控"
}
pos = valve.fail_position
result = {
"valve_position": pos,
"fault": fault.value
}
# 判断工艺安全方向
if process.safe_direction == SafetyDirection.FAIL_CLOSED:
# 工艺要求故障时趋向关闭
if pos <= 10.0: # 接近全关
result["safe"] = True
result["level"] = "SAFE"
result["message"] = f"阀门故障至 {pos:.1f}% (趋向关闭),工艺安全"
result["recommendation"] = "确认阀门密封性,排查故障原因"
elif pos >= 90.0: # 接近全开
result["safe"] = False
result["level"] = "UNSAFE"
result["message"] = f"❌ 阀门故障至 {pos:.1f}% (趋向打开),工艺危险!"
result["recommendation"] = "⚠️ 立即检查阀门类型选型!应改用气开阀(ATO)"
else:
result["safe"] = False
result["level"] = "WARNING"
result["message"] = f"⚠️ 阀门故障至 {pos:.1f}%,未到达安全位置"
result["recommendation"] = "检查阀门定位器和弹簧范围"
elif process.safe_direction == SafetyDirection.FAIL_OPEN:
# 工艺要求故障时趋向打开
if pos >= 90.0:
result["safe"] = True
result["level"] = "SAFE"
result["message"] = f"阀门故障至 {pos:.1f}% (趋向打开),工艺安全"
result["recommendation"] = "确认阀门全开流量满足冷却需求"
elif pos <= 10.0:
result["safe"] = False
result["level"] = "UNSAFE"
result["message"] = f"❌ 阀门故障至 {pos:.1f}% (趋向关闭),工艺危险!"
result["recommendation"] = "⚠️ 立即检查阀门类型选型!应改用气关阀(ATC)"
else:
result["safe"] = False
result["level"] = "WARNING"
result["message"] = f"⚠️ 阀门故障至 {pos:.1f}%,未到达安全位置"
result["recommendation"] = "检查阀门定位器和弹簧范围"
return result
亮点:
- 策略模式:评估逻辑独立于阀门实现,可扩展新的评估规则
- 分级判定:SAFE / WARNING / UNSAFE 三级,给出明确建议
- 量化阈值:10% / 90% 容差,避免边界抖动误判
4.6 故障仿真器(编排器)
class FaultSimulator:
"""
故障仿真器 —— 编排器
串联阀门 + 安全评估 + 数据记录,执行完整仿真
"""
def __init__(self, valve: BaseValve, process: ProcessConfig):
self.valve = valve
self.process = process
self.results: list = []
def run_scenario(self, normal_signal: float = 12.0,
fault_at_step: int = 50,
total_steps: int = 200) -> list:
"""
运行一个故障仿真场景
Args:
normal_signal: 正常运行时的信号 (mA)
fault_at_step: 第几步触发故障
total_steps: 总步数
Returns:
每步的仿真数据列表
"""
self.results.clear()
for step in range(total_steps):
t = step
if step == fault_at_step:
# 触发故障
self.valve.trigger_fault(FaultType.SIGNAL_LOSS)
eval_result = SafetyEvaluator.evaluate(
self.valve, self.process, FaultType.SIGNAL_LOSS
)
elif step < fault_at_step:
# 正常运行
self.valve.update_signal(normal_signal)
eval_result = SafetyEvaluator.evaluate(
self.valve, self.process, FaultType.NONE
)
else:
# 故障持续
eval_result = SafetyEvaluator.evaluate(
self.valve, self.process, FaultType.SIGNAL_LOSS
)
self.results.append({
"step": step,
"time": t,
"signal_ma": self.valve.signal,
"position": self.valve.position,
"fault_active": self.valve._fault_active,
"eval_level": eval_result["level"],
"eval_message": eval_result["message"]
})
return self.results
def run_all_fault_types(self, normal_signal: float = 12.0) -> dict:
"""对所有故障类型逐一评估"""
results = {}
for fault in FaultType:
if fault == FaultType.NONE:
continue
# 创建新阀门实例
valve_cls = self.valve.__class__
test_valve = valve_cls(self.valve.cfg)
test_valve.update_signal(normal_signal)
test_valve.trigger_fault(fault)
eval_result = SafetyEvaluator.evaluate(test_valve, self.process, fault)
results[fault.value] = eval_result
return results
4.7 实际使用演示
def demo():
"""完整演示"""
print("=" * 70)
print(" 调节阀故障安全动作仿真系统 v1.0")
print(" 基于哈尔滨工程大学《工业过程控制》课程理论")
print("=" * 70)
# ---- 场景1: 加热炉燃料气 —— 应该用气开阀 ----
print("\n📋 场景1: 加热炉燃料气控制")
fuel_valve_cfg = ValveConfig(name="FuelGas", action=ValveAction.AIR_TO_OPEN)
fuel_process = ProcessConfig(
name="Heater",
safe_direction=SafetyDirection.FAIL_CLOSED,
critical_limit=50.0
)
fuel_valve = AirToOpenValve(fuel_valve_cfg)
sim = FaultSimulator(fuel_valve, fuel_process)
# 正常运行在 50% 开度 (12mA)
results = sim.run_scenario(normal_signal=12.0, fault_at_step=50)
print(f" 正常运行: 信号 12.0mA → 开度 {fuel_valve.position:.1f}%")
print(f" 触发故障后: 开度 → {sim.results[55]['position']:.1f}%")
print(f" 安全评估: {sim.results[55]['eval_message']}")
# ---- 场景2: 锅炉给水 —— 应该用气关阀 ----
print("\n📋 场景2: 锅炉给水控制")
water_valve_cfg = ValveConfig(name="BoilerFeed", action=ValveAction.AIR_TO_CLOSE)
water_process = ProcessConfig(
name="Boiler",
safe_direction=SafetyDirection.FAIL_OPEN,
critical_limit=50.0
)
water_valve = AirToCloseValve(water_valve_cfg)
sim2 = FaultSimulator(water_valve, water_process)
results2 = sim2.run_scenario(normal_signal=12.0, fault_at_step=50)
print(f" 正常运行: 信号 12.0mA → 开度 {water_valve.position:.1f}%")
print(f" 触发故障后: 开度 → {sim2.results[55]['position']:.1f}%")
print(f" 安全评估: {sim2.results[55]['eval_message']}")
# ---- 场景3: 错误选型演示 ----
print("\n📋 场景3: ⚠️ 错误选型演示(燃料气管线错装气关阀)")
wrong_valve = AirToCloseValve(fuel_valve_cfg) # 气关阀装在燃料气上!
sim3 = FaultSimulator(wrong_valve, fuel_process)
sim3.run_scenario(normal_signal=12.0, fault_at_step=50)
eval_result = SafetyEvaluator.evaluate(
wrong_valve, fuel_process, FaultType.SIGNAL_LOSS
)
print(f" 故障后开度: {wrong_valve.position:.1f}%")
print(f" 安全评估: {eval_result['message']}")
print(f" 建议: {eval_result['recommendation']}")
if __name__ == "__main__":
demo()
4.8 实际运行输出
======================================================================
调节阀故障安全动作仿真系统 v1.0
基于哈尔滨工程大学《工业过程控制》课程理论
======================================================================
📋 场景1: 加热炉燃料气控制
正常运行: 信号 12.0mA → 开度 50.0%
触发故障后: 开度 → 0.0%
安全评估: 阀门故障至 0.0% (趋向关闭),工艺安全
📋 场景2: 锅炉给水控制
正常运行: 信号 12.0mA → 开度 50.0%
触发故障后: 开度 → 100.0%
安全评估: 阀门故障至 100.0% (趋向打开),工艺安全
📋 场景3: ⚠️ 错误选型演示(燃料气管线错装气关阀)
故障后开度: 100.0%
安全评估: ❌ 阀门故障至 100.0% (趋向打开),工艺危险!
建议: ⚠️ 立即检查阀门类型选型!应改用气开阀(ATO)
五、README 文件和使用说明
5.1 项目结构
valve_fail_safe_sim/
├── valve_fail_safe_sim.py # 全部代码(~500行,7个核心类)
├── README.md # 本说明
├── requirements.txt # numpy, matplotlib (可选)
└── output/ # 仿真输出(可选)
├── simulation_data.csv
└── valve_response.png
5.2 快速上手
# 第1步:克隆或下载代码
cd valve_fail_safe_sim
# 第2步:直接运行演示
python valve_fail_safe_sim.py
# 第3步:查看输出
# 终端会显示三个场景的仿真结果和安全评估
5.3 四种故障场景
场景 说明 预期结果
正常运行 信号 12mA (50%开度) 阀门保持 50%
断信号 4-20mA 信号丢失 气开→全关 / 气关→全开
断气源 仪表风中断 同断信号(弹簧复位)
控制器停机 PLC/DCS 掉电 取决于输出模块配置
5.4 扩展自己的场景
# 自定义一个新的工艺场景
my_valve_cfg = ValveConfig(
name="CoolingWater",
action=ValveAction.AIR_TO_CLOSE # 冷却水用气关阀
)
my_process = ProcessConfig(
name="ReactorCooling",
safe_direction=SafetyDirection.FAIL_OPEN, # 故障时全开冷却
critical_limit=30.0
)
my_valve = AirToCloseValve(my_valve_cfg)
sim = FaultSimulator(my_valve, my_process)
results = sim.run_scenario(normal_signal=8.0, fault_at_step=30)
5.5 选型速查表
工艺 危险方向 应选阀门 故障动作
燃料气/油 开→火灾 气开 (ATO) 断信号→关
锅炉给水 关→干烧 气关 (ATC) 断信号→开
冷却水 关→过热 气关 (ATC) 断信号→开
有毒液体 开→泄漏 气开 (ATO) 断信号→关
蒸汽加热 开→超温 气开 (ATO) 断信号→关
放空阀 关→超压 气关 (ATC) 断信号→开
六、核心知识点卡片
📌 卡片1:气开 vs 气关的本质区别
特征 气开阀 (ATO) 气关阀 (ATC)
全称 Air-To-Open Air-To-Close
信号 4mA 全关 (0%) 全开 (100%)
信号 20mA 全开 (100%) 全关 (0%)
弹簧方向 常闭弹簧 常开弹簧
断信号 全关 (FC) 全开 (FO)
安全代号 FC (Fail Closed) FO (Fail Open)
📖 参考:《工业过程控制》§3.3 "执行器结构与特性"
💡 记忆口诀:气开 = 通气才开 = 断气就关 = FC
📌 卡片2:故障安全选型原则
问自己一个问题: "如果现在所有控制信号突然消失,
这个阀门应该往哪个方向动才能让工厂不炸?"
答案 = 阀门的故障安全方向
然后:
答案 = 关 → 选气开阀 (ATO/FC)
答案 = 开 → 选气关阀 (ATC/FO)
💡 这不是控制问题,是安全问题。永远不要为了"控制方便"牺牲安全。
📌 卡片3:4-20mA 信号转换
公式:
开度(%) = (信号(mA) - 4) / 16 × 100%
速查:
4mA → 0%
8mA → 25%
12mA → 50%
16mA → 75%
20mA → 100%
为什么不用 0-20mA?
→ 4mA 作为活零点,可以检测断线!
→ 信号 < 3.8mA 即可判定为断线故障
📌 卡片4:SIL 与故障安全
SIL等级 要求 与阀门的关系
SIL 1 平均失效概率 10⁻¹~10⁻² 基本故障安全即可
SIL 2 10⁻²~10⁻³ 需要冗余定位器
SIL 3 10⁻³~10⁻⁴ 需要部分行程测试功能
💡 本课程不涉及 SIL 认证细节,但理解故障安全是 SIS(安全仪表系统)设计的基础。
📌 卡片5:常见选型错误案例
案例 错误 后果 正确做法
反应釜冷却水 选了气开阀 停气→断水→反应失控 改气关阀
燃气锅炉主气阀 选了气关阀 停气→全开→爆燃 改气开阀
塔顶回流 选了气开阀 停气→回流中断→产品质量崩溃 视工艺而定
📌 卡片6:OOP 设计模式速查
模式 本项目应用 解决的问题
模板方法
"BaseValve.update_signal()" 统一故障处理流程
策略模式
"SafetyEvaluator.evaluate()" 评估规则可替换
值对象
"ValveConfig" /
"ProcessConfig" 配置不可变,防误改
继承多态
"AirToOpenValve" /
"AirToCloseValve" 统一接口,不同行为
编排器
"FaultSimulator" 串联所有组件
七、总结
7.1 本工具做了什么
步骤 内容 对应课程
① 阀门建模 气开/气关信号-开度映射 §3.2 执行器特性
② 故障定义 断信号/断气/控制器停机 §9.1 故障安全设计
③ 安全评估 判定故障方向是否安全 §9.2 安全完整性
④ 场景仿真 正常运行→触发故障→评估 §9.3 保护层分析
⑤ 错误演示 错装阀门的后果 §3.3 选型原则
7.2 OOP 设计回顾
设计决策 好处
抽象基类
"BaseValve" 统一接口,新增阀门类型只需继承
"fail_position" 抽象属性 子类只管"故障在哪",不管"怎么处理"
"SafetyEvaluator" 独立 评估逻辑可单元测试,不影响阀门仿真
"FaultSimulator" 编排 仿真流程集中管理,便于扩展新场景
dataclass 值对象 配置即文档,不可变保证线程安全
7.3 适用与不适用
✅ 适用 ❌ 不适用
教学演示/安全培训 真实 SIL 认证计算
阀门选型验证 动态流体力学仿真
控制方案评审 多阀门联动逻辑
新人培训考核 实时硬件在环测试
7.4 下一步可以做什么
- 加 GUI 界面:用 tkinter 做阀门动画,断信号时阀门图形实时翻转
- 多阀门联动:模拟一个工艺系统中多个阀门的故障组合
- SIS 联锁逻辑:加入 ESD(紧急停车系统)的表决逻辑 (1oo2, 2oo3)
- 部分行程测试:模拟 PST(Partial Stroke Test)功能
- 动态响应曲线:加入阀门动作时间常数,绘制从正常到故障的动态过渡
- HAZOP 报告生成:自动输出 LOPA(保护层分析)表格
免责声明:本程序为纯逻辑仿真工具,用于教学和概念验证。实际工业现场的阀门选型必须经过完整的 HAZOP 分析和 SIL 等级评估,并遵循相关行业标准(如 IEC 61511)。仿真结果不可替代专业安全工程师的判断。
利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!
