LLM PID Tuner
Codex 直接做 PID 迭代调参,无需外部 LLM API key。bridge 脚本封装了原工具的全部逻辑:收敛判定、 回滚检测、最佳参数跟踪、护栏裁剪、CSV 导出。
依赖
pip install pyserial textual numpy
python scripts/doctor.py # 检查环境
仿真调参工作流(精确步骤)
每轮操作
1. 运行: python scripts/tune.py sim --p <P> --i <I> --d <D>
[--round N] [--stable-rounds N]
[--best-pid '{"p":X,"i":Y,"d":Z}' --best-metrics '{...}' --best-round N]
[--history '[...]']
2. 读取 convergence 段:
- IF convergence.good_enough == true AND stable_rounds >= 3:
→ 输出 status: "DONE", 调参结束
- IF convergence.rollback_recommended == true:
→ 回复 rollback_target_pid 作为建议 PID, status: "TUNING"
- ELSE:
→ 按决策表分析 → 给新 PID → status: "TUNING"
3. 重复步骤 1, 传递 --round N+1, --stable-rounds 新值,
--best-pid/best-metrics 更新, --history 追加当前轮
决策表
| metrics.status | 典型症状 | 调参动作 | tuning_action |
|---|---|---|---|
| SLOW_RESPONSE | avg_error 大, overshoot=0 | 大步提 P (2-5x, 在护栏内)。I=0, D=0 | BOOST_RESPONSE |
| OVERSHOOTING | overshoot > 5% | 降 P (*0.7-0.85), 微降 I。考虑后续引入 D | REDUCE_OVERSHOOT |
| OSCILLATING | zero_crossings 多 | 大幅降 P (*0.5-0.7), 降 I (*0.7-0.85), 引入/增大 D | DAMP_OSCILLATION |
| STABLE + sse 大 | 稳态有残留误差 | 微增 I (*1.15-1.5), 保持 P/D | REDUCE_STEADY_ERROR |
| STABLE + 接近目标 | 各项指标接近 good_enough | 小步微调 (1.05-1.15x), 观察稳定轮数 | FINE_TUNE |
收敛判定
同时满足以下全部条件时输出 status: "DONE":
convergence.good_enough == trueconvergence.stable_rounds >= convergence.required_stable_rounds(默认 3)
收敛标准 (good_enough):
metrics.status == "STABLE"metrics.avg_error <= 0.1metrics.steady_state_error <= 0.2metrics.overshoot <= 1.0%
三阶段强制顺序
阶段检测: convergence.tuning_stage 自动判断当前阶段。遵守 convergence.stage_guidance 的指引。
| stage | 条件 | 规则 |
|---|---|---|
| p_exploration | I≈0, D=0, status≠STABLE | 只调 P。大步探索 2-5x, I/D 保持为 0。目标: 找到使响应速度满意且超调<5%的 P 区间 |
| i_introduction | I>0.5, ovs<5%, P 已有效 | 引入 I。从小值逐步增大消除稳态误差。若出现超调则减小 I。D 保持 0 |
| d_damping | D>0.1, 仍有超调/振荡 | 引入 D。从 0.1~1 开始逐步增大抑制振荡。过大 D 会导致过度阻尼 |
| converged | STABLE, sse<1, ovs<2% | 微调维持。满足 good_enough 后标 DONE |
严禁跳跃阶段。严禁在 p_exploration 阶段调整 I 或 D。
安全护栏
guardrail_limits 字段给出每轮的实际限制。选择 PID 时必须主动遵守:
p/i/d.min和.max: 绝对上下限max_increase_ratio: 相对当前值的最大单轮增幅倍数
验证建议: 在应用新 PID 前可运行:
python scripts/tune.py validate --current-pid '...' --suggested-pid '...'
此命令返回裁剪后的 safe_pid 和 guardrail_notes。
输出 JSON 格式
每轮分析后输出合法 JSON(与 response_parser.py 兼容):
{
"thought_process": "完整推理链: 当前处于哪个阶段? 数据相比历史如何变化? 为什么选择这个调整方向和幅度?",
"analysis_summary": "一句话总结。如: P 从 3→9(护栏 3x), 响应加速中, I/D 保持 0, 继续 P 探索。",
"tuning_action": "BOOST_RESPONSE | REDUCE_OVERSHOOT | DAMP_OSCILLATION | REDUCE_STEADY_ERROR | FINE_TUNE",
"p": 9.0, "i": 0.0, "d": 0.0,
"status": "TUNING | DONE"
}
详细规范: references/json-output-spec.md
硬件模式
python scripts/doctor.py # 环境检查
python scripts/system_id.py --mode live --port <PORT> # 系统辨识
python scripts/tune.py hw --port <PORT> [--duration 30] # 数据采集
硬件模式必须保守: 每次参数变化幅度要小。过大 P/I 可能损坏设备。
系统辨识
python scripts/system_id.py --mode demo # 演示数据
python scripts/system_id.py --mode live --port X # 串口实时
python scripts/system_id.py --mode file --file X # CSV 文件
输出 system_info (增益、时间常数、延迟) 和 pid_suggestion (Z-N 整定建议)。
CSV 导出
python scripts/tune.py export --history '[...]' --output path.csv
故障排查
| 症状 | 原因 | 解决 |
|---|---|---|
| 持续 SLOW_RESPONSE | P 提升不足 | 确认 P 每轮在护栏内最大幅度提升 |
| 收敛判定不触发 | good_enough 阈值太严 | 检查 convergence.failed_rules 逐条 |
| 硬件无数据 | 串口问题 | doctor.py 检查, 确认波特率和端口 |
| best_updated 始终 false | 非 STABLE 状态不记录最佳 | 正常行为, 先让系统进入 STABLE |