实现流量控制前馈 + 增益调度(MFC 结构)
按 plan.md 新增三个交付物,全部默认关闭以保持与纯 PID 的 A/B 兼容: - valve_model.py:阀特性模型 Q_ss = A_eff(x)·P1_abs·F(r),含 ISO 6358 椭圆 F(r)、行程/面积互逆插值、单调性校验、JSON 存取。 - identify_valve.py:从 open_loop.py 扫点 CSV 拟合 A_eff 表并输出 JSON。 - 控制器集成:config/flow_control/main/data_logger 新增阀前压读取 (channel 2)、前馈打底 + PI 修残差、按 P1 增益调度,并记录/绘制前馈项。 新增配置 FEEDFORWARD_ENABLED / GAIN_SCHEDULE_ENABLED 默认 False, VALVE_MODEL_PATH 默认空,未加载模型时行为与原先纯 PID 完全一致。
This commit is contained in:
@@ -13,8 +13,12 @@ CSV_FIELDS = (
|
||||
"measured_flow_slm",
|
||||
"opening_pct",
|
||||
"pressure_kpa",
|
||||
"pressure_before_kpa",
|
||||
"error_slm",
|
||||
"motor_position",
|
||||
"feedforward_pct",
|
||||
"correction_pct",
|
||||
"gain_scale",
|
||||
"actual_dt_s",
|
||||
"status",
|
||||
)
|
||||
@@ -59,8 +63,14 @@ class FlowRunRecorder:
|
||||
),
|
||||
"opening_pct": self._format_value(result.opening_pct),
|
||||
"pressure_kpa": self._format_value(result.pressure_kpa),
|
||||
"pressure_before_kpa": self._format_value(
|
||||
result.pressure_before_kpa
|
||||
),
|
||||
"error_slm": self._format_value(result.error_slm),
|
||||
"motor_position": self._format_value(result.motor_position),
|
||||
"feedforward_pct": self._format_value(result.feedforward_pct),
|
||||
"correction_pct": self._format_value(result.correction_pct),
|
||||
"gain_scale": self._format_value(result.gain_scale),
|
||||
"actual_dt_s": self._format_value(result.actual_dt_s),
|
||||
"status": result.status,
|
||||
}
|
||||
@@ -93,6 +103,7 @@ class FlowRunRecorder:
|
||||
target_flow = []
|
||||
measured_flow = []
|
||||
opening = []
|
||||
feedforward = []
|
||||
pressure = []
|
||||
|
||||
with self.csv_path.open("r", newline="", encoding="utf-8-sig") as file:
|
||||
@@ -103,6 +114,9 @@ class FlowRunRecorder:
|
||||
self._float_or_nan(row["measured_flow_slm"])
|
||||
)
|
||||
opening.append(self._float_or_nan(row["opening_pct"]))
|
||||
feedforward.append(
|
||||
self._float_or_nan(row.get("feedforward_pct"))
|
||||
)
|
||||
pressure.append(self._float_or_nan(row["pressure_kpa"]))
|
||||
|
||||
figure, axes = plt.subplots(
|
||||
@@ -138,7 +152,18 @@ class FlowRunRecorder:
|
||||
opening,
|
||||
color="#2E7D32",
|
||||
linewidth=1.4,
|
||||
label="Opening",
|
||||
)
|
||||
if any(math.isfinite(value) for value in feedforward):
|
||||
axes[1].plot(
|
||||
time_s,
|
||||
feedforward,
|
||||
color="#EF6C00",
|
||||
linewidth=1.2,
|
||||
linestyle="--",
|
||||
label="Feedforward",
|
||||
)
|
||||
axes[1].legend(loc="best")
|
||||
axes[1].set_ylabel("Opening (%)")
|
||||
axes[1].set_title("Valve opening")
|
||||
axes[1].set_ylim(-2, 102)
|
||||
|
||||
Reference in New Issue
Block a user