PID控制原理概述

PID控制器由比例(P)、积分(I)、微分(D)三部分组成,通过误差信号的比例、积分和微分运算生成控制信号。其数学表达式为:

$$ u(t) = K_p e(t) + K_i \int_0^t e(\tau) d\tau + K_d \frac{de(t)}{dt} $$

其中:

  • $u(t)$为控制输出
  • $e(t)$为误差(设定值与实际值之差)
  • $K_p$、$K_i$、$K_d$分别为比例、积分、微分系数

基础PID实现(Python)

以下代码展示离散化PID算法的基本实现,适用于大多数嵌入式系统:

class PIDController:
    def __init__(self, Kp, Ki, Kd):
        self.Kp = Kp
        self.Ki = Ki
        self.Kd = Kd
        self.last_error = 0
        self.integral = 0
        
    def update(self, setpoint, measured_value, dt):
        error = setpoint - measured_value
        self.integral += error * dt
        derivative = (error - self.last_error) / dt
        output = self.Kp * error + self.Ki * self.integral + self.Kd * derivative
        self.last_error = error
        return output

使用示例:

pid = PIDController(Kp=1.0, Ki=0.1, Kd=0.01)
temperature = 25.0  # 当前测量值
target = 30.0       # 目标值
dt = 0.1            # 采样时间间隔

control_signal = pid.update(target, temperature, dt)

抗积分饱和处理

积分项可能导致输出饱和,需添加抗饱和机制:

def update_with_antiwindup(self, setpoint, measured_value, dt, max_output):
    error = setpoint - measured_value
    
    # 计算未受限的输出
    self.integral += error * dt
    derivative = (error - self.last_error) / dt
    output = self.Kp * error + self.Ki * self.integral + self.Kd * derivative
    
    # 抗饱和处理
    if abs(output) > max_output:
        output = max_output * (1 if output > 0 else -1)
        self.integral -= error * dt  # 回退积分项
    
    self.last_error = error
    return output

增量式PID算法

适用于执行机构带积分特性的场景(如步进电机):

class IncrementalPID:
    def __init__(self, Kp, Ki, Kd):
        self.Kp = Kp
        self.Ki = Ki
        self.Kd = Kd
        self.last_error = 0
        self.prev_error = 0
        
    def update(self, setpoint, measured_value):
        error = setpoint - measured_value
        delta = (self.Kp + self.Ki + self.Kd) * error \
                - (self.Kp + 2*self.Kd) * self.last_error \
                + self.Kd * self.prev_error
        self.prev_error = self.last_error
        self.last_error = error
        return delta

参数整定方法

Ziegler-Nichols整定步骤:

  1. 将$K_i$和$K_d$设为0,逐渐增大$K_p$直到系统出现等幅振荡
  2. 记录临界增益$K_u$和振荡周期$T_u$
  3. 根据下表设置参数:
控制器类型 $K_p$ $K_i$ $K_d$
P 0.5$K_u$ 0 0
PI 0.45$K_u$ 0.54$K_u$/T_u$ 0
PID 0.6$K_u$ 1.2$K_u$/T_u$ 0.075$K_u$T_u$

实际应用案例(温度控制)

Arduino平台上的PID控制示例:

#include <PID_v1.h>

double Setpoint, Input, Output;
PID myPID(&Input, &Output, &Setpoint, 2.0, 5.0, 1.0, DIRECT);

void setup() {
  Input = analogRead(A0);  // 读取温度传感器
  Setpoint = 80;           // 目标温度80°C
  myPID.SetMode(AUTOMATIC);
  myPID.SetSampleTime(100); // 100ms采样周期
}

void loop() {
  Input = analogRead(A0);
  myPID.Compute();
  analogWrite(3, Output);  // 输出PWM控制加热器
  delay(100);
}

数字低通滤波

对微分项添加滤波,避免高频噪声放大:

class FilteredPID(PIDController):
    def __init__(self, Kp, Ki, Kd, tau=0.1):
        super().__init__(Kp, Ki, Kd)
        self.tau = tau  # 滤波时间常数
        self.filtered_deriv = 0
        
    def update(self, setpoint, measured_value, dt):
        error = setpoint - measured_value
        self.integral += error * dt
        
        # 低通滤波的微分项
        raw_deriv = (error - self.last_error) / dt
        self.filtered_deriv += (raw_deriv - self.filtered_deriv) * dt / (self.tau + dt)
        
        output = self.Kp*error + self.Ki*self.integral + self.Kd*self.filtered_deriv
        self.last_error = error
        return output

多变量PID协调控制

对于耦合系统,需使用多个PID协调工作:

class MultiAxisController:
    def __init__(self, params_x, params_y):
        self.pid_x = PIDController(*params_x)
        self.pid_y = PIDController(*params_y)
        
    def update(self, setpoints, measurements, dt):
        x_out = self.pid_x.update(setpoints[0], measurements[0], dt)
        y_out = self.pid_y.update(setpoints[1], measurements[1], dt)
        
        # 添加耦合补偿
        y_out += 0.2 * x_out  # 示例耦合补偿系数
        return x_out, y_out

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐