用python实现PID控制器 (PyCharm)
文章目录
- 用python实现PID控制器 (PyCharm)
- PID框图
- python实现
- 控制器
- 被控对象
- 主函数
- 调参顺序建议
- 程序下载
PID框图
PID 的控制框图如下图所示:
python实现
控制器
PID的三个参数一般是我们自己设计的,而且一般是固定的,所以最好在初始化的时候设置一下。
在具体实现的时候,当前误差需要知道系统的输出和目标值,因此误差作为参数传入。dt是系统的步长,即调节周期,也将其作为参数传入
为了适应某些变参数算法(al,bp),设计一个函数仅用来改变三个参数
控制器代码如下:
class PID_Controller:
# 给pid的三个参数赋初值
def __init__(self, kp, ki, kd):
self.kp = kp
self.ki = ki
self.kd = kd
self.last_error = 0.0
self.integral = 0.0
def change_para(self, kp, ki, kd):
self.kp = kp
self.ki = ki
self.kd = kd
def control_action(self, error, dt):
"""
Args:
error: 当前误差
dt: 步长
Returns: pid的输出
"""
p = self.kp * error
self.integral += error
i = self.ki * self.integral
derivative = (error - self.last_error) / dt
d = self.kd * derivative
self.last_error = error
return p + i + d
被控对象
被控对象一般是用传递函数表示的,这边可以用欧拉公式实现
对传递函数为:
进行变换
import numpy as np
class levitationSys:
def __init__(self, ncount, x10, x20, y10, y20):
self.x10 = x10
self.x20 = x20
self.X1 = np.zeros(ncount)
self.y10 = y10
self.y20 = y20
self.Y1 = np.zeros(ncount)
self.Y2 = np.zeros(ncount)
def system_io(self, i, input, h, f):
y1 = self.y10 + h * self.y20
y2 = self.y20 + h * (-4900 * self.y10 + 3.1877 * input);
self.Y1[i] = self.y10
self.Y2[i] = self.y20
self.y10 = y1
self.y20 = y2
return y1
主函数
控制器和传递函数设计好之后,我们只需要建立一个主函数去调用它即可
from pid import PID_Controller
from system import levitationSys
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
wc = 50
kp = wc * wc / 3.2
ki = 15
kd = wc / 1.6
ncount = 200000 # 循环次数
h = 0.0002 #步长
ts = np.zeros(ncount)
# 被控对象
sys = levitationSys(ncount, 0, 0, 0, 0)
# 控制器
PID = PID_Controller(kp, ki, kd)
gap = 0.0
gap_last = 0.0
for i in range(ncount):
gap = sys.system_io(i, PID.control_action(0.004 - gap_last, h), h, 0)
ts[i] = i * h
print(gap)
gap_last = gap
# 图像输出
plt.plot(ts, sys.Y1)
plt.xlabel('x-axis')
plt.ylabel('y-axis')
plt.title('Simple Line Plot')
plt.show()
运行结果:
调参顺序建议
- 先调节比例系数 kp,使系统的响应能够快速达到稳定状态,并具有合理的超调量。因为它是最基本的参数,可以快速反应出控制效果。
- 然后调节积分时间常数 ki,使系统的静态误差消失或达到最小值。增加 ki 可以减小稳态误差,但过大的 ki 会引起系统的震荡和不稳定。
- 调节微分时间常数 kd,使系统的稳定性和动态响应之间取得平衡。增加 kd 可以使系统更加稳定,减小系统的超调和振荡,但过大的 kd 会引起系统的噪声和抖动。
- 最后综合进行微调
需要注意的是,这只是一种基本的调参顺序,实际情况可能因为不同系统的特点而有所不同