完善流量控制前馈、稳态判定与阀门标定流程
- 前馈冻结改用可配置的 3 秒流量绝对误差滑窗,修复采样抖动造成的重复解冻,并保留下游扰动后的自动更新 - 支持非单调阀特性反解、最小可测面积以下直接全关,以及闭阀端精细扫点与辨识开关 - 调整双压力判稳、最长等待时间、在线入口全开收尾和闭环四联图 - 更新配置、README、阀模型及离线测试,归档本轮实验数据与诊断产物
This commit is contained in:
@@ -3,8 +3,8 @@
|
||||
示例:
|
||||
python main.py --target 50
|
||||
|
||||
程序启动后直接从当前阀门开度(默认全开)开始闭环。Ctrl+C、控制故障或
|
||||
其他异常会断开 PLC;阀门不被驱动时默认回到全开。
|
||||
程序连接 PLC 后先主动设置全开,再开始采样与闭环。Ctrl+C、控制故障或
|
||||
其他异常退出时会再次尝试设置全开,然后断开 PLC。
|
||||
"""
|
||||
|
||||
import argparse
|
||||
@@ -126,10 +126,12 @@ def build_control_loop(hardware, logger):
|
||||
opening_rate_far_pct_s=config.MAX_OPENING_RATE_FAR_PCT_S,
|
||||
opening_rate_near_pct_s=config.MAX_OPENING_RATE_NEAR_PCT_S,
|
||||
pid_near_error_min_slm=config.PID_NEAR_ERROR_MIN_SLM,
|
||||
pid_near_error_max_slm=config.PID_NEAR_ERROR_MAX_SLM,
|
||||
pid_near_error_target_ratio=(
|
||||
config.PID_NEAR_ERROR_TARGET_RATIO
|
||||
),
|
||||
pid_far_error_min_slm=config.PID_FAR_ERROR_MIN_SLM,
|
||||
pid_far_error_max_slm=config.PID_FAR_ERROR_MAX_SLM,
|
||||
pid_far_error_target_ratio=config.PID_FAR_ERROR_TARGET_RATIO,
|
||||
pid_mode_switch_confirm_cycles=(
|
||||
config.PID_MODE_SWITCH_CONFIRM_CYCLES
|
||||
@@ -137,6 +139,10 @@ def build_control_loop(hardware, logger):
|
||||
valve_model=valve_model,
|
||||
feedforward_enabled=config.FEEDFORWARD_ENABLED,
|
||||
feedforward_correction_band_pct=config.FEEDFORWARD_CORRECTION_BAND_PCT,
|
||||
feedforward_update_error_threshold_slm=(
|
||||
config.FEEDFORWARD_UPDATE_ERROR_THRESHOLD_SLM
|
||||
),
|
||||
feedforward_update_window_s=config.FEEDFORWARD_UPDATE_WINDOW_S,
|
||||
gain_schedule_enabled=config.GAIN_SCHEDULE_ENABLED,
|
||||
gain_schedule_ref_abs_kpa=config.GAIN_SCHEDULE_REF_ABS_KPA,
|
||||
gain_schedule_floor_abs_kpa=config.GAIN_SCHEDULE_FLOOR_ABS_KPA,
|
||||
@@ -246,6 +252,21 @@ def run(target_flow_slm):
|
||||
},
|
||||
)
|
||||
|
||||
# 连接后的全开动作发生在初始采样、报告计时和控制计时开始之前。
|
||||
if not hardware.set_motor_position(
|
||||
config.MOTOR_OPEN_POSITION,
|
||||
channel=config.MOTOR_OUTPUT_ADDR,
|
||||
):
|
||||
raise FlowControlFault(
|
||||
"STARTUP_FULL_OPEN_FAILED",
|
||||
"STARTUP",
|
||||
"连接后设置阀门 100% 开度失败",
|
||||
)
|
||||
logger.info(
|
||||
"PLC 已连接;阀门已设置为 100%% 开度(行程 %.1f),不计入控制计时",
|
||||
config.MOTOR_OPEN_POSITION,
|
||||
)
|
||||
|
||||
# 控制前读取一次当前流量,作为超调量方向的基准。
|
||||
try:
|
||||
initial_flow_slm = hardware.get_flow(config.FLOW_AFTER_ADDR)
|
||||
@@ -257,7 +278,7 @@ def run(target_flow_slm):
|
||||
window_s=config.STEADY_STATE_WINDOW_S,
|
||||
sample_period_s=config.CONTROL_PERIOD_S,
|
||||
band_pct=config.STEADY_STATE_BAND_PCT,
|
||||
std_pct=config.STEADY_STATE_STD_PCT,
|
||||
pressure_band_kpa=config.STEADY_STATE_PRESSURE_BAND_KPA,
|
||||
flow_range_min_slm=config.TARGET_FLOW_MIN_SLM,
|
||||
flow_range_max_slm=config.TARGET_FLOW_MAX_SLM,
|
||||
initial_flow_slm=initial_flow_slm,
|
||||
@@ -377,6 +398,21 @@ def run(target_flow_slm):
|
||||
finally:
|
||||
console_gate.blocked = False
|
||||
if connected:
|
||||
try:
|
||||
if hardware.set_motor_position(
|
||||
config.MOTOR_OPEN_POSITION,
|
||||
channel=config.MOTOR_OUTPUT_ADDR,
|
||||
):
|
||||
logger.info(
|
||||
"断开 PLC 前已设置阀门为 100%% 开度(行程 %.1f),不计入控制计时",
|
||||
config.MOTOR_OPEN_POSITION,
|
||||
)
|
||||
else:
|
||||
exit_code = max(exit_code, 4)
|
||||
logger.critical("断开 PLC 前设置阀门 100%% 开度失败")
|
||||
except Exception:
|
||||
exit_code = max(exit_code, 4)
|
||||
logger.exception("断开 PLC 前设置阀门 100%% 开度时发生异常")
|
||||
try:
|
||||
hardware.disconnect()
|
||||
except Exception:
|
||||
@@ -388,7 +424,7 @@ def run(target_flow_slm):
|
||||
image_path = recorder.finalize()
|
||||
logger.info("控制数据已保存:%s", recorder.csv_path)
|
||||
if image_path is not None:
|
||||
logger.info("三联曲线图已保存:%s", image_path)
|
||||
logger.info("四联曲线图已保存:%s", image_path)
|
||||
else:
|
||||
logger.warning("本次运行没有采样点,因此未生成曲线图")
|
||||
except Exception:
|
||||
|
||||
Reference in New Issue
Block a user