PID - 模拟
先看一下效果
dai
代码实现:
import matplotlib.pyplot as plt# PID 控制器类
class PID:def __init__(self, kp, ki, kd):self.kp = kpself.ki = kiself.kd = kdself.integral = 0self.prev_error = 0def compute(self, setpoint, measured, dt):error = setpoint - measuredself.integral += error * dtderivative = (error - self.prev_error) / dtoutput = self.kp * error + self.ki * self.integral + self.kd * derivativeself.prev_error = errorreturn output# 模拟环境参数
set_temp = 25 # 设定温度
current_temp = 20 # 初始温度
dt = 1 # 时间间隔 (秒)
pid = PID(kp=1.2, ki=0.1, kd=0.05)temps = []
times = []# 模拟控制过程
for t in range(100):control = pid.compute(set_temp, current_temp, dt)# 简单模拟加热效果:控制量越大温度升得越快current_temp += control * 0.1temps.append(current_temp)times.append(t)# 绘图
plt.plot(times, temps, label="Room Temperature")
plt.axhline(set_temp, color='r', linestyle='--', label="Target Temperature")
plt.xlabel("Time (s)")
plt.ylabel("Temperature (°C)")
plt.legend()
plt.title("PID 控制温度变化示意图")
plt.grid()
plt.show()
超调(Overshoot)/震荡(Oscillation)
这属于典型的 PID 控制系统初期震荡现象。在模拟 PID 控制系统中,初始时刻(0~20秒左右)温度曲线出现如下特征:
-
温度快速上升并超过设定目标温度(超调)
-
然后又迅速下降,甚至低于目标值
-
来回几次震荡后才趋于稳定
原因分析
- 比例项过大 (kp)
- kp = 1.2,这个值在初始误差较大时产生的控制量会非常大
- 导致系统一次升温过头(超调)
- 之后又因误差变为负,迅速反向调整,造成震荡
积分方式
self.integral += error * dt
这种积分方式是矩形积分法(也称为欧拉积分法或左矩形法),即用当前时刻的误差 error 乘以时间步长 dt,累加到积分项上。这是离散PID算法中最常见、最简单的积分近似方法。
其他积分方法:
微分
derivative = (error - self.prev_error) / dt
前向差分(Forward Difference)是一种数值微分方法,用来近似计算函数在某一点的导数(变化率)。它是最简单的差分法,广泛用于实现 数值导数、PID 控制器的微分项、实时控制系统中的变化检测等。
优点
-
实现简单:只需当前值与前一个值
-
计算代价低:适合嵌入式、微控制器等系统
-
实时性好:适用于快速采样的系统
缺点
如果对 PID 微分项过于敏感,还可以考虑加入 噪声滤波(如低通滤波) 或 带限微分器(filtered derivative)
如果将Ki, Kd设置为0
在没有积分项的前提下,系统只能根据当前误差输出控制量,当系统逐渐接近目标值时,误差变小,控制量也减弱,所以最终可能无法完全达到目标值,而是在目标值以下稳定。而且系统的响应变慢了。
Other
稳态误差(Steady-State Error) 是指控制系统在输入信号保持恒定(通常是阶跃输入)一段时间后,系统输出与期望值之间的持续偏差。
简单定义
稳态误差 = 设定值(Setpoint) - 系统最终稳定的输出值
当系统运行足够长时间后,如果输出仍然和设定值之间存在恒定差距,这个差距就是稳态误差。
举例
假设你的设定温度是 25°C,但系统最终只升到 24°C 就不再变化了,那么稳态误差是:
稳态误差 = 25 - 24 = 1°C
图示
设定值(阶跃输入)|
25 -|------------------------------>| _______| /| /| /|_____________________/ ← 输出稳定后达不到设定值,产生稳态误差时间 →
为什么会有稳态误差?
-
只有 P 控制器 时,输出趋近目标后,误差变小,控制力变弱,导致无法再推进输出。
-
没有积分作用,就无法“逼近”到完全一致的目标值。
怎么消除稳态误差?
要使用带 积分(Integral) 项的控制器:
-
PI 控制器(Kp + Ki)
-
PID 控制器(Kp + Ki + Kd)
积分项会累计误差,即使误差很小也会累加并产生持续控制作用,最终让输出逼近设定值,稳态误差趋近于 0。
Reference
PID 比例-积分-微分控制器(Proportional-Integral-Derivative Controller)