本文基于 rm_pid_tuner 项目的实际开发经验。与大多数讲 PID 的文章不同,这里不满足于”知道三个环节的作用”,而是从数学模型 → 离散化 → 工程实现 → 性能评估 → 自动调参完整链路展开,让你看完能自己写一个带自动调参功能的 PID 控制器。
从传递函数说起:PID 到底在补偿什么
几乎所有”PID 入门”文章都会从三个环节的作用讲起,但很少有人问:为什么这三个环节是完备的?
考虑一个典型的直流电机速度环。忽略电感(电气时间常数远小于机械时间常数),电机模型为:
$$E = IR + K_e\omega$$
$$T = K_t I$$
合并得:
$$T = \frac{K_t(E - K_e\omega)}{R} = \frac{K_t}{R}E - \frac{K_t K_e}{R}\omega$$
注意这里的结构:**输入 E(电压)与输出 ω(转速)之间存在一个负反馈项 $\frac{K_t K_e}{R}\omega$**——电机本身就是一个天然的被控对象加内环反馈。加上负载惯量 J 和粘性阻尼 B:
$$J\frac{d\omega}{dt} + B\omega = T$$
得到从电压到转速的传递函数(一阶惯性环节):
$$G(s) = \frac{\Omega(s)}{E(s)} = \frac{\frac{K_t}{JR}}{s + \frac{B + K_tK_e/R}{J}} = \frac{K}{\tau s + 1}$$
关键结论:电机速度环是一阶系统。 这意味着:
- 纯 P 控制下,稳态误差 $e_{ss} = \frac{1}{1+KK_p}$——永远不为零,这正是”只有 P 会留静差”的数学根源
- 加入积分环节后,开环传递函数在原点增加一个极点,系统变为 I 型系统,阶跃响应稳态误差严格为零
- D 环节不改变系统型别,但改变闭环极点位置,可以增大阻尼比
所以 PID 三个环节的”完备性”在于:P 提供响应速度,I 消除稳态误差(提升系统型别),D 提供阻尼(抑制超调)。三者在频域上分别对应增益、低频整形、高频整形。
离散化:连续 PID 到单片机上的形式
连续 PID:
$$u(t) = K_p e(t) + K_i\int_0^t e(\tau)d\tau + K_d\frac{de(t)}{dt}$$
在 MCU 上必须以固定周期 T 采样离散化。用一阶向后差分近似积分和微分:
$$\int_0^t e(\tau)d\tau \approx T\sum_{k=0}^{n} e(k), \quad \frac{de(t)}{dt} \approx \frac{e(n) - e(n-1)}{T}$$
得到位置式 PID:
$$u(n) = K_p e(n) + K_i T\sum_{k=0}^{n} e(k) + \frac{K_d}{T}[e(n) - e(n-1)]$$
实际工程中通常把 $K_i T$ 合并为一个系数 $K_i’$,$\frac{K_d}{T}$ 合并为 $K_d’$,写代码时就不用关心采样周期了(但注意:换采样频率必须重新整定参数,这是新手最常踩的坑)。
增量式 PID 是位置式的差分:
$$\Delta u(n) = u(n) - u(n-1) = K_p[e(n)-e(n-1)] + K_i’ e(n) + K_d’[e(n) - 2e(n-1) + e(n-2)]$$
增量式最大的工程优势不是”计算量小”(现代 MCU 无所谓),而是:
- 故障安全:输出的是增量,执行机构(如步进电机驱动器)保持上一步位置,不会因计算异常跳变
- 无扰动切换:手动/自动切换时只需把 $\Delta u$ 清零,不会产生输出突变
- 天然抗积分饱和:u 被限幅时增量累积效应弱
RoboMaster 的电机速度环普遍用增量式,因为裁判系统掉线/串口异常时,增量输出不会让电机飞车。
工程实现:一个生产级的位置式 PID
结合 rm_pid_tuner 的实现,一个生产级 PID 至少要处理:积分分离、抗积分饱和、微分滤波、输出限幅。
1 | namespace rm_pid_tuner { |
几个容易被忽略的细节:
微分滤波为什么必须? 离散微分 $\frac{e(n)-e(n-1)}{T}$ 本质是一个高通滤波器,而传感器噪声正是高频成分。若 D 系数稍大,噪声被放大后会在输出端产生剧烈抖动,听起来就像”电机在发抖”。低通滤波后的微分才是”看趋势”,而不是”看噪声”。
积分限幅和输出限幅的区别? 输出限幅是物理约束(PWM 最大 100%),积分限幅是逻辑约束。如果不单独限幅积分,会发生:误差持续存在 → 积分持续累加 → 输出到顶 → 误差反向 → 积分需要很长时间才能”消化”掉累积值 → 系统在反向时迟钝,这就是积分饱和的典型症状。
性能评估:怎么量化”调得好不好”
手动调参时”感觉差不多了”很容易,但自动化调参必须把”好不好”变成数字。rm_pid_tuner 中定义了几个核心指标:
1 | struct Metrics { |
MAE 衡量稳态精度,标准差衡量振荡,max_error 衡量超调,ITAE 则是一个”既要快又要稳”的综合指标——它对后期的小误差惩罚轻、对早期的持续误差惩罚重,因此在工程上比 ISE(平方误差积分)更受青睐:ISE 会放大早期大误差,导致整定结果偏向”压超调”而牺牲响应速度。
评分函数:
1 | double calculatePerformanceScore(const Metrics& m) { |
各指标设了扣分上限(30/30/20/20),保证任何单一指标不会主导评分,这样”某一方面极差但其他方面很好”的系统不会被误判为优良。
规则式自动调参:把试凑法变成状态机
rm_pid_tuner 的核心是一个规则分析器:根据指标组合,决定参数往哪个方向调、调多少。
1 | AnalysisResult analyze(const Metrics& metrics, |
这套规则的本质,是把人类调参的经验抽象成可执行逻辑:
| 症状 | 处方 | 背后的控制理论 |
|---|---|---|
| 振荡(stddev 大) | 降 Kp、升 Kd | 增大阻尼比,压低谐振峰 |
| 响应慢(MAE 大) | 升 Kp | 提高穿越频率 |
| 稳态误差(MAE 中等) | 升 Ki | 提高低频增益,压静差 |
| 超调(max_error 大) | 降 Kp、升 Kd | 减小闭环峰值 |
自动调参的完整流程是一个状态机:
1 | 监听误差数据 → 缓存200个采样点 → 计算指标 |
注意冷却时间的工程意义:参数调整后系统需要时间过渡,如果立即采样会读到”调整过程中的瞬态”,导致误判。冷却期本质上是给闭环系统留出 3~5 个过渡过程时间。
从 PWM 到扭矩:PID 输出之后的最后一公里
PID 输出的是”控制量”,但对电机而言最终指令是 PWM 占空比 m。反解过程:
$$E = V_d \times m, \quad T = \frac{K_t(E - K_e\omega)}{R}$$
$$m = \frac{T \cdot R + K_e\omega}{K_t \cdot V_d}$$
其中关键参数获取:
- R(相电阻):万用表测任意两相电阻,一半为每相电阻
- K_e(反电动势系数):示波器测手拨电机产生的正弦波,$K_e = \frac{V_{peak}}{\omega}$
- K_t(转矩系数):$K_t = \frac{60}{2\pi \cdot PP} K_e$,PP 为极对数
实际工程中 PWM 频率、死区、续流二极管压降都会造成偏差,所以多数 RoboMaster 队直接做电流环闭环:用电流传感器(如 INA240 + 采样电阻)测实际电流,电流环 PID 输出直接给 PWM,速度环 PID 输出作为电流环目标——两级串联。这样 PWM 非线性被电流环”消化”掉了,速度环面对的是一个近似线性的对象,调参更容易。
总结:工程 PID 的六个认知
- 先建模再调参:知道对象是一阶还是二阶,才能预测 P/I/D 的效果
- 增量式 ≠ 更高级:位置式和增量式是应用场景的选择,不是水平高低的区别
- 微分必须滤波:不滤波的 D 在真实传感器噪声面前是灾难
- 积分要限幅:抗饱和不是可选项,是必须项
- 用数字说话:MAE / 标准差 / 超调 / ITAE 四个指标,让调参从玄学变科学
- 给系统留冷却时间:调参节奏比参数本身更重要