嵌入式控制笔记:PID 控制算法

🧠 嵌入式控制笔记:PID 控制算法与控制量 u(t) / u[k] 解析(WP Githuber MD 版)


一、PID 控制简介

PID(Proportional–Integral–Derivative)控制器 是最常用的反馈控制算法之一,广泛用于嵌入式控制系统中:

  • 电机转速控制
  • 温度控制
  • 压力 / 流量控制
  • 伺服控制系统

核心思想:
根据 目标值系统输出值 之间的误差,通过比例(P)、积分(I)、微分(D)三项调节,使输出逐步逼近目标。

核心结论:

PID 不直接控制目标状态(温度 / 水位),
而是计算“应该施加多大的控制作用”。

以温度控制示例(加热系统)

  1. 变量对应关系
名称 符号 含义
设定值 SP 目标温度
被控量 PV 实际温度
误差 e e = SP - PV
控制输出 u 加热功率 / PWM 占空比
  1. 物理因果链

PWM 占空比->加热功率->热量输入->温度变化(PV)

  1. 控制流程
    读取温度
    计算误差 e
    PID 计算输出 u
    u → PWM
    温度随时间变化

二、系统误差与控制量定义

系统误差定义为:

行内公式:e(t) = r(t) - y(t)

其中:

  • r(t):目标值(设定值)
  • y(t):系统输出(测量值)
  • e(t):误差(偏差量)

PID 控制器输出(控制量)为:

u(t) = K_p \cdot e(t) + K_i \cdot \int e(t)\,dt + K_d \cdot \frac{de(t)}{dt}

其中:

参数 含义
K_p 比例系数(Proportional Gain)
K_i 积分系数(Integral Gain)
K_d 微分系数(Derivative Gain)

三、各部分作用与直观理解

名称 公式 作用 直观理解 缺点
P(比例) U_P = K_p \cdot e 按误差比例输出,误差越大,输出越大 “踩油门力度正比于偏差” 稳态误差存在
I(积分) U_I = K_i \cdot \int e\,dt 消除稳态误差 “记住过去的所有偏差,慢慢补” 易引起超调
D(微分) U_D = K_d \cdot \frac{de}{dt} 根据误差变化率修正,抑制超调、震荡 “预判趋势,提前刹车” 对噪声敏感

关键:在嵌入式实现中,积分和微分都需要离散化,即用采样方式近似计算,积分用累加,微分用前后两次误差差,采样周期 T_s 必须固定。

四、控制量 u(t) / u[k] 的物理意义

在 PID 控制器中:

  • u(t)(连续时间)或 u[k](离散时间)
    控制器的输出信号,即“控制量”。

控制量的作用:
用于驱动执行机构,直接影响被控对象的输入。

应用场景 控制量 u(t) / u[k] 含义
电机转速控制 PWM 占空比(控制电压)
温度控制 加热功率或继电器占空比
压力 / 流量控制 阀门开度(0–100%)
伺服控制 电流或位置指令信号

📊 控制系统信号流向

     ┌──────────────┐
 r → │   PID控制器    │ → u → │ 被控对象(执行机构) │ → y
     └──────────────┘        └──────────────────┘
           ↑____________________________________|
                        反馈回路
  • r(t):目标输入(期望值)
  • y(t):系统输出(传感器反馈)
  • e(t):误差信号
  • u(t):控制器输出,用来“调节”系统

五、离散化 PID(嵌入式常用形式)

在实际嵌入式系统中,信号是离散采样的
令采样周期为 T,第 k 次采样时刻:

行内公式:e[k] = r[k] - y[k]

位置式 PID:

u[k] = K_p \cdot e[k] + K_i \cdot \sum_{i=0}^{k} e[i] \cdot T + K_d \cdot \frac{e[k] - e[k-1]}{T}

增量式 PID:

\Delta u[k] = K_p \cdot [e[k] - e[k-1]] + K_i \cdot e[k] \cdot T + K_d \cdot \frac{e[k] - 2e[k-1] + e[k-2]}{T}
u[k] = u[k-1] + \Delta u[k]

增量式 PID 优点:抗干扰性强、积分饱和风险低、适合数字控制器实现。


六、C 语言实现(位置式 PID)

typedef struct {
    float Kp;
    float Ki;
    float Kd;
    float setpoint;   // 目标值
    float integral;   // 积分累加
    float prev_error; // 上一次误差
} PID_t;

void PID_Init(PID_t *pid, float kp, float ki, float kd, float setpoint) {
    pid->Kp = kp;
    pid->Ki = ki;
    pid->Kd = kd;
    pid->setpoint = setpoint;
    pid->integral = 0.0f;
    pid->prev_error = 0.0f;
}

float PID_Compute(PID_t *pid, float feedback, float dt) {
    float error = pid->setpoint - feedback;
    pid->integral += error * dt;
    float derivative = (error - pid->prev_error) / dt;
    float output = pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative;
    pid->prev_error = error;
    return output;
}

Python

class PID:
    """
    PID控制器
    - P(比例): 误差越大,输出越大,响应快但可能超调
    - I(积分): 累积误差,消除稳态误差,但可能引起震荡
    - D(微分): 预测误差变化,抑制超调,但对噪声敏感
    """
    def __init__(self, kp, ki, kd):
        self.kp = kp  # 比例系数
        self.ki = ki  # 积分系数
        self.kd = kd  # 微分系数
        self.integral = 0      # 误差积分累积
        self.prev_error = 0    # 上一次误差(用于微分)

    def compute(self, target, current, dt):
        error = target - current                    # 当前误差
        self.integral += error * dt                 # 积分累加
        derivative = (error - self.prev_error) / dt # 误差变化率
        self.prev_error = error
        # 输出 = P项 + I项 + D项
        return self.kp * error + self.ki * self.integral + self.kd * derivative

pid = PID(kp=1.0, ki=0.1, kd=0.05)  # 参数先随便给
target_rps = 1.0  # 目标转速

while True:
    time.sleep(dt)
    # ... 你原来的编码器读取代码 ...
    current_rps = pulses_to_rps(filtered_speed * dt, dt)

    output = pid.compute(target_rps, current_rps, dt)
    motor.set_pwm(output)  # 输出给电机

七、实际应用:直流电机转速控制

目标: 保持电机转速 r[k] = 1000\,\text{RPM}

控制流程:

  1. 从编码器获取当前转速 y[k]
  2. 计算误差 e[k] = r[k] - y[k]
  3. 用 PID 算法计算控制量 u[k]
  4. u[k] 转换为 PWM 占空比并输出
  5. 形成闭环控制

伪代码:

float target_speed = 1000.0f;
float current_speed = get_speed_sensor();
float dt = 0.01f;

float pwm = PID_Compute(&pid, current_speed, dt);
set_motor_pwm(pwm);  // 控制输出 u[k]

八、PID 参数整定方法

方法 特点
经验法 手动调参,简单直观
Ziegler–Nichols 法 工程常用,通过振荡求参数
临界比例法 找到系统振荡点后换算 PID 参数
自动调参(MATLAB) 适合仿真和快速设计

调参顺序建议:

  1. K_p → 控制响应速度
  2. K_i → 消除稳态误差
  3. K_d → 抑制超调与振荡

九、控制模式对比

控制类型 优点 缺点 适用场景
P 控制 结构简单、响应快 稳态误差存在 简单系统
PI 控制 消除稳态误差 易超调 稳定对象
PID 控制 响应快、精度高 参数调节复杂 高精度系统

🔚 十、总结

  • u(t) / u[k] 是 PID 控制器的输出(控制量)
  • 它用于驱动执行机构(PWM、电压、电流、阀门开度等)。
  • 连续系统u(t)离散系统u[k]
  • PID 控制的本质是对误差的比例、积分、微分调节,使系统输出逐渐逼近目标值。
  • 在嵌入式系统中,PID 控制通常以离散形式实现,通过周期采样和 PWM 输出形成闭环控制。