更新了README.md
This commit is contained in:
@@ -1,120 +1,251 @@
|
|||||||
# 气体流量闭环控制系统
|
# 气体流量控制与阀门开环标定
|
||||||
|
|
||||||
基于 **MT2-AM8 模拟量采集/输出模块** 的单回路气体流量 PID 闭环控制程序。
|
本项目基于艾莫迅 **MT2-AM8 模拟量采集/输出模块**,提供两个可独立运行的入口:
|
||||||
程序以 10 Hz 周期读取流量(可选读取压力),经增量式 PID 计算阀门开度,
|
|
||||||
映射为电机行程后通过 Modbus TCP 下发给执行机构,并在每次运行结束后自动
|
|
||||||
保存逐周期数据、生成三联曲线图与一次性的控制性能报告。
|
|
||||||
|
|
||||||
## 硬件与通讯
|
- [main.py](main.py):以 10 Hz 周期运行单回路气体流量增量式 PID 闭环控制;
|
||||||
|
- [open_loop.py](open_loop.py):随机扫描阀门开度,采集阀前/阀后的压力与流量,用于开环标定、动态特性观察和临界压力比分析。
|
||||||
|
|
||||||
- 采集/输出模块:艾莫迅 **MT2-AM8**(Modbus TCP,默认 `192.168.1.12:502`,站号 1)
|
两个入口都会逐周期保存 CSV,并在运行结束时为有效采样数据生成 PNG 曲线图。闭环程序还会持续进行滑动窗口稳态判定,并在首次达到稳态时输出一次控制性能报告。
|
||||||
- 模拟量输入(AI):地址 `0x00~0x03`,0~4095 对应 0~10V / 0~20mA
|
|
||||||
- 模拟量输出(AO):保持寄存器 `0x00~0x03`
|
|
||||||
- 流量计量程默认 300 SLM,压力表量程默认 400 kPa
|
|
||||||
- 电机行程与开度**反向作用**:行程越大开度越小,
|
|
||||||
`opening=0% → MOTOR_CLOSED_POSITION`,`opening=100% → MOTOR_OPEN_POSITION`
|
|
||||||
|
|
||||||
> 所有地址、通道、量程、行程端值均在 [config.py](config.py) 中集中配置,
|
## 重要安全说明
|
||||||
> 首次连接真实设备前必须核对。
|
|
||||||
|
|
||||||
## 架构与模块职责
|
> 本项目会直接控制真实阀门。首次运行前必须核对 IP、站号、AI/AO 通道、传感器量程、阀门行程方向、压力上限和执行机构的断电/失驱位置,并准备独立的机械或电气急停手段。
|
||||||
|
|
||||||
| 文件 | 职责 |
|
闭环与开环程序当前采用不同的退出策略:
|
||||||
| --- | --- |
|
|
||||||
| [main.py](main.py) | 程序入口:解析参数、装配日志/控制器/记录器/报告器、主循环与安全退出 |
|
|
||||||
| [flow_control.py](flow_control.py) | 闭环控制层:`读取传感器 → PID → 开度/行程映射 → 下发电机位置`,含全部安全处理 |
|
|
||||||
| [controllers.py](controllers.py) | 通用增量式 PID 控制器 `IncrementalPID`(输出限幅 + 输出变化率限幅) |
|
|
||||||
| [config.py](config.py) | 集中配置与 `validate_config()` 启动前校验 |
|
|
||||||
| [data_logger.py](data_logger.py) | `FlowRunRecorder`:逐周期写 CSV,运行结束生成三联曲线图 |
|
|
||||||
| [performance_reporter.py](performance_reporter.py) | `PerformanceReporter`:滑窗稳态判定,输出一次性性能报告 |
|
|
||||||
| [PcControl.py](PcControl.py) | 硬件层:`MT2AM8Client` 等 Modbus 客户端(本项目实际使用 `MT2AM8Client`) |
|
|
||||||
|
|
||||||
### 控制回路流程
|
- **闭环 `main.py`**:启动时不再预先下发关闭位置,PID 内部输出由 `INITIAL_OPENING_PCT=100%` 开始;故障或退出时停止控制并断开 MT2-AM8,不主动下发关阀命令。当前系统按“执行机构失驱后回到全开”设计,现场必须确认实际硬件确实如此。
|
||||||
|
- **开环 `open_loop.py`**:连接成功后先主动设置 `0%` 开度,实验结束、异常或 `Ctrl+C` 时再次尝试设置 `0%` 开度,然后断开设备。
|
||||||
|
|
||||||
```
|
因此,README 中的“关闭”或“全开”均指当前代码定义的逻辑位置,不能代替现场对阀门真实动作方向的确认。
|
||||||
读取流量/压力 (MT2-AM8)
|
|
||||||
│
|
## 硬件与默认接线
|
||||||
▼
|
|
||||||
IncrementalPID.update() ──► 开度百分比 0~100%
|
- MT2-AM8:Modbus TCP,默认 `192.168.1.12:502`,站号 `1`;
|
||||||
│
|
- AI 输入寄存器:地址 `0x00~0x03`;
|
||||||
▼
|
- AO 保持寄存器:地址 `0x00~0x03`;
|
||||||
opening_to_motor_position() ──► 反向行程 0~1000
|
- 模拟量原始范围:`0~4095`,传感器物理量换算使用 `819~4095` 对应有效量程;
|
||||||
│
|
- 默认流量量程:`300 SLM`;默认压力量程:`400 kPa`;
|
||||||
▼
|
- 电机行程范围:`0~1000`,且行程与阀门开度反向作用。
|
||||||
hardware.set_motor_position() ──► Modbus TCP 写 AO
|
|
||||||
|
默认通道如下,通道编号均从 `0` 开始:
|
||||||
|
|
||||||
|
| 用途 | 通道 | 配置位置 |
|
||||||
|
| --- | ---: | --- |
|
||||||
|
| 闭环/阀后压力 | `AI0` | `config.PRESSURE_INPUT_CHANNEL` |
|
||||||
|
| 闭环/阀后流量 | `AI1` | `config.FLOW_INPUT_CHANNEL` |
|
||||||
|
| 开环阀前压力 | `AI2` | `open_loop.PRESSURE_BEFORE_CHANNEL` |
|
||||||
|
| 开环阀前流量 | `AI3` | `open_loop.FLOW_BEFORE_CHANNEL` |
|
||||||
|
| 电机位置指令 | `AO1` | `config.MOTOR_OUTPUT_CHANNEL` |
|
||||||
|
|
||||||
|
开度与行程的默认映射为:
|
||||||
|
|
||||||
|
```text
|
||||||
|
opening = 0% -> motor_position = 1000(关闭)
|
||||||
|
opening = 100% -> motor_position = 0(全开)
|
||||||
```
|
```
|
||||||
|
|
||||||
`error = setpoint - measurement`;PID 输出累加后统一映射为阀门开度百分比,
|
所有闭环通道、量程和行程端值集中在 [config.py](config.py);开环新增的阀前通道和实验参数位于 [open_loop.py](open_loop.py) 顶部。
|
||||||
再做行程换算,因此 PID 与执行机构解耦。
|
|
||||||
|
|
||||||
## 快速开始
|
## 环境与依赖
|
||||||
|
|
||||||
```bash
|
项目使用 Python 3,直接依赖:
|
||||||
|
|
||||||
|
- `pymodbus`:Modbus TCP/RTU 通讯;
|
||||||
|
- `matplotlib`:使用 `Agg` 后端生成 PNG,无显示器环境也可运行。
|
||||||
|
|
||||||
|
示例安装:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python -m venv .venv
|
||||||
|
.\.venv\Scripts\Activate.ps1
|
||||||
|
python -m pip install pymodbus matplotlib
|
||||||
|
```
|
||||||
|
|
||||||
|
仓库当前没有锁定依赖版本。若 `PcControl.py` 导入 `pymodbus.payload` 或调用 `slave=` 参数时报错,请使用与现有 [PcControl.py](PcControl.py) API 兼容的 `pymodbus` 版本。
|
||||||
|
|
||||||
|
## 闭环控制
|
||||||
|
|
||||||
|
### 运行
|
||||||
|
|
||||||
|
先在 [config.py](config.py) 中完成现场参数核对,再执行:
|
||||||
|
|
||||||
|
```powershell
|
||||||
python main.py --target 50
|
python main.py --target 50
|
||||||
```
|
```
|
||||||
|
|
||||||
- `--target`:目标流量(SLM),必须在 `[TARGET_FLOW_MIN_SLM, TARGET_FLOW_MAX_SLM]` 内。
|
`--target` 的单位为 SLM,必须位于 `TARGET_FLOW_MIN_SLM~TARGET_FLOW_MAX_SLM`(当前为 `0~300`)范围内。按 `Ctrl+C` 停止;默认 `AUTO_STOP_ON_STEADY=False`,所以达到稳态后仍会继续控制。如需首次达到稳态后自动结束,将该配置改为 `True`。
|
||||||
- 启动流程:连接 MT2-AM8 → 确认阀门关闭 → 读取初始流量 → 启动闭环。
|
|
||||||
- 停止:`Ctrl+C`;控制故障、未处理异常同样会触发安全关阀并断开设备。
|
|
||||||
|
|
||||||
## 运行输出
|
启动流程为:
|
||||||
|
|
||||||
1. **终端/日志**:周期状态行(状态、目标/实际流量、压力、开度、行程、实际 dt),
|
```text
|
||||||
日志同时写入 [logs/flow_control.log](logs/flow_control.log)。
|
校验配置 -> 连接 MT2-AM8 -> 读取一次初始流量
|
||||||
2. **逐周期数据**:每次运行生成 `data/flow_run_<时间戳>.csv`。
|
-> PID 输出初始化为 INITIAL_OPENING_PCT
|
||||||
3. **曲线图**:与 CSV 同名的 PNG 三联图(流量响应 / 阀门开度 / 压力)。
|
-> 进入周期控制(启动阶段不主动写入关闭位置)
|
||||||
4. **性能报告**:首次达到稳态时打印一次,包含:
|
```
|
||||||
|
|
||||||
- 本次 PID 参数(Kp / Ki / Kd)
|
单个控制周期为:
|
||||||
- 调节时间(至稳态,秒)
|
|
||||||
- 超调量(绝对 SLM + 相对目标百分比)
|
|
||||||
- 本次控制范围
|
|
||||||
|
|
||||||
稳态判定为两个条件**同时**满足:滑窗均值落在目标 ±`STEADY_STATE_BAND_PCT`% 误差带内,
|
```text
|
||||||
且滑窗标准差低于 `STEADY_STATE_STD_PCT`% 目标流量阈值。考虑采样时间戳抖动,
|
读取流量/压力
|
||||||
滑窗覆盖时长允许一个控制周期的余量。
|
|
|
||||||
|
v
|
||||||
|
IncrementalPID.update()
|
||||||
|
error = target - measurement
|
||||||
|
|
|
||||||
|
v
|
||||||
|
开度百分比 0~100%(输出限幅 + 变化率限幅)
|
||||||
|
|
|
||||||
|
v
|
||||||
|
opening_to_motor_position()
|
||||||
|
|
|
||||||
|
v
|
||||||
|
反向行程 1000~0 -> MT2-AM8 AO1
|
||||||
|
```
|
||||||
|
|
||||||
## 安全机制
|
增量 PID 的输出直接定义为阀门开度,因此控制器本身不包含电机行程或死区映射。目标流量不高于 `ZERO_FLOW_THRESHOLD_SLM`(当前 `0.5 SLM`)时,程序跳过常规 PID 更新并直接命令 `0%` 开度。
|
||||||
|
|
||||||
- **启动前安全关阀**:控制开始前先确认阀门已关闭。
|
### 运行输出
|
||||||
- **流量/压力越限关阀**:读数超出 `FLOW_VALID_*` 或超过 `MAX_PRESSURE_KPA` 立即关阀。
|
|
||||||
- **连续读取失败关阀**:短暂读取失败保持上一输出;连续达到阈值后关阀。
|
|
||||||
- **控制循环超时保护**:实际周期超过 `MAX_CONTROL_DT_S` 判定超时。
|
|
||||||
- **输出变化率限幅**:`MAX_OPENING_RATE_PCT_S` 限制开度变化速度,防止阀门阶跃冲击。
|
|
||||||
- **退出安全关阀**:任何退出路径(含异常)都会再次尝试关阀并断开设备。
|
|
||||||
|
|
||||||
## 关键配置项
|
每次闭环运行会产生:
|
||||||
|
|
||||||
见 [config.py](config.py),常用项:
|
1. **终端与日志**:约每秒输出一次状态;非 `OK` 状态立即输出。日志保存到 `logs/flow_control.log`。
|
||||||
|
2. **逐周期 CSV**:默认保存为 `data/flow_run_YYYYMMDD_HHMMSS.csv`,每行写入后立即刷新到磁盘。现有 `data/日期/实验说明/` 子目录是历史数据的人工归档方式,不是程序自动创建的层级。
|
||||||
|
3. **三联曲线图**:结束时保存同名 PNG,依次显示目标/实际流量、阀门开度和压力。
|
||||||
|
4. **性能报告**:首次达到稳态时写入终端和日志;若整个运行过程未达到稳态,只输出未达到稳态的提示。
|
||||||
|
|
||||||
| 配置 | 默认值 | 说明 |
|
闭环 CSV 字段:
|
||||||
|
|
||||||
|
| 字段 | 含义 |
|
||||||
|
| --- | --- |
|
||||||
|
| `time_s` / `timestamp` | 相对运行时间 / Unix 时间戳 |
|
||||||
|
| `target_flow_slm` / `measured_flow_slm` | 目标流量 / 实测流量 |
|
||||||
|
| `opening_pct` / `motor_position` | 阀门开度 / 电机行程 |
|
||||||
|
| `pressure_kpa` | 压力;未启用或读取失败时为空 |
|
||||||
|
| `error_slm` | `目标流量 - 实测流量` |
|
||||||
|
| `actual_dt_s` | 实际控制周期 |
|
||||||
|
| `status` | `OK` 或传感器读取重试状态 |
|
||||||
|
|
||||||
|
### 稳态判定与性能报告
|
||||||
|
|
||||||
|
判稳只使用状态为 `OK` 的有效流量样本。滑窗至少覆盖 `STEADY_STATE_WINDOW_S - CONTROL_PERIOD_S`,以容纳真实采样时间戳抖动,并要求下列条件同时成立:
|
||||||
|
|
||||||
|
```text
|
||||||
|
|窗口均值 - 目标流量| <= STEADY_STATE_BAND_PCT / 100 * 目标流量
|
||||||
|
窗口总体标准差 <= STEADY_STATE_STD_PCT / 100 * 目标流量
|
||||||
|
```
|
||||||
|
|
||||||
|
当前默认使用 10 秒窗口、±1% 均值误差带和 1% 标准差阈值。报告内容包括 PID 参数、目标与控制范围、调节时间、窗口均值、窗口标准差、稳态误差(目标减窗口均值)、初始流量,以及按初始变化方向计算的峰值/谷值超调量。
|
||||||
|
|
||||||
|
## 开环扫点实验
|
||||||
|
|
||||||
|
[open_loop.py](open_loop.py) 不参与闭环反馈,也不会被 `main.py` 导入。默认将 `0%~100%`、间隔 `10%` 的 11 个开度按固定随机种子 `42` 打乱,然后逐点执行:
|
||||||
|
|
||||||
|
```text
|
||||||
|
写入开度 -> 每 0.1 s 采集阀前/阀后压力与流量
|
||||||
|
-> 等待阀后流量稳定,或等待满 60 s
|
||||||
|
-> 切换到下一个开度
|
||||||
|
```
|
||||||
|
|
||||||
|
运行默认实验或自定义扫描范围:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python open_loop.py
|
||||||
|
python open_loop.py --seed 7
|
||||||
|
python open_loop.py --min 0 --max 100 --step 5
|
||||||
|
```
|
||||||
|
|
||||||
|
- `--min`、`--max`:扫描开度上下限,必须满足 `0 <= min < max <= 100`;
|
||||||
|
- `--step`:开度间隔,必须大于 `0`;不能整除区间时会额外包含 `max` 端点;
|
||||||
|
- `--seed`:打乱顺序的随机种子;相同参数和种子会得到相同顺序。
|
||||||
|
|
||||||
|
> 当前 `open_loop.py --help` 的帮助文本存在 `%` 格式化问题,会触发 `ValueError`;上面的正常运行命令及参数解析不受影响。
|
||||||
|
|
||||||
|
开环没有目标值,其稳态条件仅依据阀后流量的滑窗总体标准差:
|
||||||
|
|
||||||
|
```text
|
||||||
|
std <= max(STEADY_STATE_STD_PCT / 100 * |窗口均值|, MIN_ABS_STD_SLM)
|
||||||
|
```
|
||||||
|
|
||||||
|
默认窗口为 10 秒,绝对标准差下限为 `0.05 SLM`。阀后流量连续 5 次读取失败会中止实验;其他通道读取失败会在对应 CSV 字段中留空。
|
||||||
|
|
||||||
|
输出保存到 `open_loop_data/open_loop_YYYYMMDD_HHMMSS.csv/.png`,日志保存到 `logs/open_loop.log`。PNG 包含三张子图:阀前/阀后压力、阀前/阀后流量、阀后绝对压力与阀前绝对压力之比。
|
||||||
|
|
||||||
|
压力比按下式计算:
|
||||||
|
|
||||||
|
```text
|
||||||
|
P_abs_ratio = (阀后表压 + 101.325 kPa) / (阀前表压 + 101.325 kPa)
|
||||||
|
```
|
||||||
|
|
||||||
|
CSV 同时记录 `is_ratio_smaller_than_0.528`:压力比小于临界值 `0.528` 时为 `Y`,否则为 `N`;任一压力缺失或分母非法时两个压力比字段留空。图中会绘制 `0.528` 参考线,并标出各开度切换时刻。
|
||||||
|
|
||||||
|
## 安全与故障处理
|
||||||
|
|
||||||
|
### 闭环
|
||||||
|
|
||||||
|
- 配置在连接硬件前由 `validate_config()` 校验;
|
||||||
|
- 流量超出 `FLOW_VALID_MIN_SLM~FLOW_VALID_MAX_SLM` 或压力高于 `MAX_PRESSURE_KPA` 时停止控制并报故障;
|
||||||
|
- 短暂的流量/压力读取失败保持上一输出,不下发新位置;连续达到各自阈值后停止控制;
|
||||||
|
- 实际控制周期超过 `MAX_CONTROL_DT_S` 时停止控制;
|
||||||
|
- PID 输出限制在 `0~100%`,`MAX_OPENING_RATE_PCT_S` 限制每秒最大开度变化;
|
||||||
|
- 电机命令写入异常或返回失败时停止控制;
|
||||||
|
- 所有退出路径都会尝试断开设备,但当前闭环代码不会主动下发关阀命令。
|
||||||
|
|
||||||
|
### 开环
|
||||||
|
|
||||||
|
- 启动和收尾均主动下发 `0%` 开度;
|
||||||
|
- 任一有效流量读数越界、任一有效压力读数超过上限时中止;
|
||||||
|
- 阀后流量连续读取失败达到阈值时中止;
|
||||||
|
- 写入开度失败时中止;
|
||||||
|
- 中止后仍会尽力关阀、断开连接并保留已经写入的 CSV。
|
||||||
|
|
||||||
|
## 关键配置默认值
|
||||||
|
|
||||||
|
| 配置 | 当前默认值 | 说明 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `MT2AM8_HOST` / `MT2AM8_PORT` / `MT2AM8_SLAVE_ID` | `192.168.1.12` / `502` / `1` | 模块地址 |
|
| `MT2AM8_HOST` / `MT2AM8_PORT` / `MT2AM8_SLAVE_ID` | `192.168.1.12` / `502` / `1` | 通讯参数 |
|
||||||
| `FLOW_INPUT_CHANNEL` / `PRESSURE_INPUT_CHANNEL` / `MOTOR_OUTPUT_CHANNEL` | `1` / `0` / `0` | AI/AO 通道(0 起始) |
|
| `FLOW_INPUT_CHANNEL` / `PRESSURE_INPUT_CHANNEL` | `1` / `0` | 闭环 AI 通道;压力可设为 `None` |
|
||||||
| `FLOW_METER_RANGE_SLM` / `PRESSURE_RANGE_KPA` | `300` / `400` | 量程 |
|
| `MOTOR_OUTPUT_CHANNEL` | `1` | 电机 AO 通道 |
|
||||||
| `CONTROL_PERIOD_S` | `0.1` | 控制周期(100 ms,10 Hz) |
|
| `FLOW_METER_RANGE_SLM` / `PRESSURE_RANGE_KPA` | `300` / `400` | 传感器量程 |
|
||||||
| `PID_KP` / `PID_KI` / `PID_KD` | `0.5` / `0.1` / `0.0` | 安全起步 PI 参数,需现场整定 |
|
| `TARGET_FLOW_MIN_SLM` / `TARGET_FLOW_MAX_SLM` | `0` / `300` | 允许的目标范围 |
|
||||||
| `MOTOR_CLOSED_POSITION` / `MOTOR_OPEN_POSITION` | `1000` / `0` | 行程端值 |
|
| `CONTROL_PERIOD_S` / `MAX_CONTROL_DT_S` | `0.1` / `0.3` | 目标周期 / 超时阈值 |
|
||||||
| `MAX_PRESSURE_KPA` | `400` | 压力上限,须按管路额定压力确认 |
|
| `PID_KP` / `PID_KI` / `PID_KD` | `0.5` / `0.5` / `0.0` | 当前 PI 参数,需按现场继续整定 |
|
||||||
| `STEADY_STATE_WINDOW_S` / `STEADY_STATE_BAND_PCT` / `STEADY_STATE_STD_PCT` | `10.0` / `1.0` / `1.0` | 稳态判定参数 |
|
| `OPENING_MIN_PCT` / `OPENING_MAX_PCT` | `0` / `100` | PID 输出开度范围 |
|
||||||
|
| `MAX_OPENING_RATE_PCT_S` | `20` | 每秒最大开度变化百分比 |
|
||||||
|
| `MOTOR_CLOSED_POSITION` / `MOTOR_OPEN_POSITION` | `1000` / `0` | 反向行程端值 |
|
||||||
|
| `INITIAL_OPENING_PCT` | `100` | 闭环 PID 内部初始输出 |
|
||||||
|
| `FLOW_VALID_MIN_SLM` / `FLOW_VALID_MAX_SLM` | `0` / `300` | 流量安全范围 |
|
||||||
|
| `MAX_PRESSURE_KPA` | `400` | 压力上限,须按实际管路额定压力确认 |
|
||||||
|
| `MAX_CONSECUTIVE_FLOW_FAILURES` / `MAX_CONSECUTIVE_PRESSURE_FAILURES` | `3` / `3` | 闭环连续读取失败阈值 |
|
||||||
|
| `STEADY_STATE_WINDOW_S` / `STEADY_STATE_BAND_PCT` / `STEADY_STATE_STD_PCT` | `10` / `1` / `1` | 闭环稳态判定参数 |
|
||||||
|
| `AUTO_STOP_ON_STEADY` | `False` | 达到稳态后是否自动结束闭环 |
|
||||||
|
|
||||||
## 依赖
|
## 模块职责
|
||||||
|
|
||||||
- Python 3
|
| 文件 | 职责 |
|
||||||
- [pymodbus](https://pymodbus.readthedocs.io/)(`PcControl.py` 的 Modbus TCP 通讯)
|
| --- | --- |
|
||||||
- [matplotlib](https://matplotlib.org/)(曲线图生成,使用 `Agg` 后端,无显示器环境也可保存)
|
| [main.py](main.py) | 闭环入口:参数解析、日志、控制循环、记录器、性能报告与收尾 |
|
||||||
|
| [flow_control.py](flow_control.py) | 闭环控制层、传感器读取、开度/行程映射和故障处理 |
|
||||||
|
| [controllers.py](controllers.py) | 通用增量式 PID,含输出限幅和输出变化率限幅 |
|
||||||
|
| [config.py](config.py) | 闭环集中配置和启动前校验 |
|
||||||
|
| [data_logger.py](data_logger.py) | 闭环逐周期 CSV 与三联曲线图 |
|
||||||
|
| [performance_reporter.py](performance_reporter.py) | 闭环滑窗判稳和一次性性能报告 |
|
||||||
|
| [open_loop.py](open_loop.py) | 独立开环扫点、四传感器记录和压力比分析 |
|
||||||
|
| [PcControl.py](PcControl.py) | Modbus 硬件客户端;本项目两个入口实际使用 `MT2AM8Client` |
|
||||||
|
|
||||||
## 项目结构
|
## 项目结构
|
||||||
|
|
||||||
```
|
```text
|
||||||
flow_control/
|
flow_control/
|
||||||
├── main.py # 程序入口
|
├── main.py
|
||||||
├── flow_control.py # 闭环控制层
|
├── open_loop.py
|
||||||
├── controllers.py # 增量式 PID
|
├── flow_control.py
|
||||||
├── config.py # 集中配置与校验
|
├── controllers.py
|
||||||
├── data_logger.py # CSV 记录 + 曲线图
|
├── config.py
|
||||||
├── performance_reporter.py # 稳态判定 + 性能报告
|
├── data_logger.py
|
||||||
├── PcControl.py # Modbus 硬件客户端
|
├── performance_reporter.py
|
||||||
├── data/ # 每次运行的 CSV / PNG
|
├── PcControl.py
|
||||||
└── logs/ # 运行日志
|
├── README.md
|
||||||
|
├── data/ # 闭环 CSV / PNG;历史数据可能已人工分组
|
||||||
|
├── open_loop_data/ # 开环 CSV / PNG(首次运行时创建)
|
||||||
|
└── logs/ # flow_control.log / open_loop.log
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user