1018 字
5 分钟
PID控制算法详解:从数学原理到位置式与增量式C语言工程实现

引言#

PID控制器(Proportional-Integral-Derivative)是现代工业和嵌入式系统中使用最广泛的反馈控制算法。它结构简单、参数物理意义明确,几乎覆盖了从温度控制到无人机姿态的所有场景。

本文作为PID系列基础篇,将从数学原理讲到可直接上板的C语言实现,并与后续《PID控制算法的改进与实现》形成完美互补。读完即可上手调试硬件。


1. PID控制器的基本原理#

PID通过计算设定值(Setpoint)与实际值(Actual)之间的误差(Error),用比例、积分、微分三项线性组合得到控制量。

连续形式数学表达式

u(t)=Kpe(t)+Ki0te(τ)dτ+Kdde(t)dtu(t) = K_p e(t) + K_i \int_0^t e(\tau) \, d\tau + K_d \frac{de(t)}{dt}

三个环节的物理含义:#

  1. 比例(P):当下误差,快速响应,但会留下静差。
  2. 积分(I):历史误差累积,彻底消除静差,但易导致积分饱和。
  3. 微分(D):误差变化率,预测趋势,抑制超调。

2. 位置式PID(Position Form)#

适用于执行器没有记忆功能的系统(如电加热器、PWM占空比控制)。

2.1 基础完整实现#

typedef struct {
float Kp, Ki, Kd;
float integral;
float prev_error;
} PID;
float PID_Compute(PID *pid, float setpoint, float actual) {
float error = setpoint - actual;
pid->integral += error; // 积分累积
float derivative = error - pid->prev_error; // 微分
float output = pid->Kp * error +
pid->Ki * pid->integral +
pid->Kd * derivative;
pid->prev_error = error;
return output;
}

2.2 工程必备:抗饱和(Anti-Windup)#

// 在Compute函数中加入(推荐Back-calculation方式,效果最佳)
if (output > pid->out_max) {
output = pid->out_max;
pid->integral -= (output - pid->prev_output) / pid->Ki; // 反计算
} else if (output < pid->out_min) {
output = pid->out_min;
pid->integral -= (output - pid->prev_output) / pid->Ki;
}
pid->prev_output = output;

3. 增量式PID(Incremental Form)#

计算的是控制量的增量Δu,适用于步进电机、阀门位置等带记忆的执行器。

优点

  • 不需要累加积分,天然避免积分饱和。
  • 手动/自动切换冲击小。
  • 计算量更小,适合高实时性系统。

完整C语言实现#

typedef struct {
float Kp, Ki, Kd;
float error_n1; // 上一次误差 e(n-1)
float error_n2; // 上上一次误差 e(n-2)
} PID_Inc;
float PID_Inc_Compute(PID_Inc *pid, float setpoint, float actual) {
float error_n = setpoint - actual; // 当前误差 e(n)
// 增量公式:Δu(k) = Kp[e(k)-e(k-1)] + Ki e(k) + Kd[e(k)-2e(k-1)+e(k-2)]
float delta_output = pid->Kp * (error_n - pid->error_n1) +
pid->Ki * error_n +
pid->Kd * (error_n - 2*pid->error_n1 + pid->error_n2);
// 更新历史误差
pid->error_n2 = pid->error_n1;
pid->error_n1 = error_n;
return delta_output; // 返回本次增量,直接加到执行器当前值上
}

4. 参数整定实用流程(Ziegler-Nichols临界比例法)#

  1. 先调P:只保留P项,逐渐增大Kp直到系统出现等幅振荡(记下此时的Kp和振荡周期T)。
  2. 加入I:设置Ki = 0.45 Kp,观察是否消除静差。
  3. 加入D:设置Kd = 0.125 Kp × T,微调直到超调和响应达到最佳。

5. PID工程CheckList(调试必查)#

  1. 位置式还是增量式是否匹配执行器类型?
  2. 是否实现了输出限幅 + 抗饱和(Back-calculation)?
  3. 采样周期是否固定(推荐1~10ms)?
  4. 参数整定是否按P→I→D顺序进行?
  5. 是否在空载/满载/扰动三种工况下实测验证?

6. 常见避坑指南#

  • 积分项不限幅 → 严重超调,执行器长时间饱和。
  • 增量式误用在无记忆执行器上 → 系统漂移。
  • 采样周期不固定 → 微分项计算错误,控制发散。
  • 只看仿真不实测 → 噪声和非线性会让参数完全失效。
  • 参数调好后不固化 → 换硬件或温度变化后全部重调。

7. 总结#

位置式PID直观易懂,适合大多数连续执行器;增量式PID更安全,适合步进/位置控制。掌握这两套基础实现,再配合后续《PID控制算法的改进与实现》中的抗饱和、微分滤波、滑模等高级技巧,你就能应对90%以上的嵌入式控制项目。

工程铁律先选对形式(位置/增量)→ 再加抗饱和 → 最后实测整定

PID控制算法详解:从数学原理到位置式与增量式C语言工程实现
https://hw.rscclub.website/posts/pidjbsfsx/
作者
杨月昌
发布于
2018-03-23
许可协议
CC BY-NC-SA 4.0