PID算法:就是“比例(proportional)、积分(integral)、微分(derivative)”,是一种常见的“保持稳定”控制算法。
import numpy as np
import matplotlib.pyplot as plt
import control.matlab as ctl
def ndT(num,den):
ret1 = (num[0])[0]
ret2 = (den[0])[0]
return ret1,ret2
ts = 0.001
sys = ctl.tf(5.235e005,[1,87.35,1.047e4,0])
dsys = ctl.c2d(sys,ts,'zoh')
num,den = ctl.tfdata(dsys)
num,den = ndT(num,den) #Matlab 和 python 的差别
#变量初始化
u_1, u_2,u_3 = 0, 0, 0
y_1, y_2,y_3 = 0, 0, 0
x = [0,0,0] # 3行1列 对应着课上的 当前偏差e(k),偏差增量 △e(k) 和 △e(k - 1)
x2_1 = 0
#比例 积分 微分 参数的初始值的设定
kp = 0.6
ki = 0.03
kd = 0.01
error_1 = 0
#控制算法的循环过程
i = 0
cycle = 500 #总周期为 500次的采样
r = [0 for i in range(cycle)]
u = [0 for i in range(cycle)]
y = [0 for i in range(cycle)]
error =[0 for i in range(cycle)]
time = np.linspace(0,2,cycle)
for k in range(500):
u[k] = kp * x[0] + kd * x[1] + ki * x[2] #PID控制器的输出
r[k] = 1
#专家控制部分
#规则1,效果为开环
if abs(x[0]) > 0.8:
u[k] = 0.45
elif abs(x[0]) > 0.4:
u[k] = 0.4
elif abs(x[0]) > 0.2:
u[k] = 0.12
elif abs(x[0]) > 0.01:
u[k] = 0.10
# 规则2 偏差往绝对值增大方向变化或为某一固定值,根据与中间值的关系进行判断
if x[0] * x[1] > 0 or (x[1] == 0):
if abs(x[0]) >= 0.05:
u[k] = u_1 + 2 * kp * x[0]
else:
u[k] = u_1 + 0.4 * kp * x[0]
# 规则3 偏差往绝对值减小方向变化,或已达到平衡,保存控制器输出维持不变
if (x[0] * x[1] < 0 and x[1] * x2_1 > 0) or x[0] == 0:
u[k] = u[k]
# 规则4 偏差处于极限状态,根据中间值进行判断
if x[0] * x[1] < 0 and x[1] * x2_1 < 0:
if abs(x[0]) >= 0.05:
u[k] = u_1+2*kp*error_1
else:
u[k] = u_1 + 0.6 * kp * error_1
# 规则5 偏差小于极小值
if abs(x[0]) <= 0.001:
u[k] = 0.5*x[0]+0.01*x[2]
#对控制器输出进行限制
if u[k] >= 10:
u[k] = 10
if u[k] <= -10:
u[k] = -10
y[k]= -den[1]*y_1-den[2]*y_2-den[3]*y_3+0*u[k]+num[0]*u_1+num[1]*u_2+num[2]*u_3;
error[k] = r[k] - y[k]
u_3 = u_2
u_2 = u_1
u_1 = u[k]
y_3 = y_2
y_2 = y_1
y_1 = y[k]
x[0] = error[k]
x2_1 = x[1]
x[1] = (error[k] - error_1) / ts
x[2] = x[2] + error[k] * ts
error_1 = error[k]
plt.figure('智能控制作业1 -- 专家控制PID')
plt.plot(time,y)
plt.plot(time,r)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import control.matlab as ctl
def ndT(num,den):
ret1 = (num[0])[0]
ret2 = (den[0])[0]
return ret1,ret2
ts = 0.001
sys = ctl.tf(5.235e005,[1,87.35,1.047e4,0])
dsys = ctl.c2d(sys,ts,'zoh')
num,den = ctl.tfdata(dsys)
num,den = ndT(num,den) #Matlab 和 python 的差别
#变量初始化
u_1, u_2,u_3 = 0, 0, 0
y_1, y_2,y_3 = 0, 0, 0
x = [0,0,0] # 3行1列 对应着课上的 当前偏差e(k),偏差增量 △e(k) 和 △e(k - 1)
x2_1 = 0
#比例 积分 微分 参数的初始值的设定
kp = 0.6
ki = 0.03
kd = 0.01
error_1 = 0
#控制算法的循环过程
i = 0
cycle = 500 #总周期为 500次的采样
r = [0 for i in range(cycle)]
u = [0 for i in range(cycle)]
y = [0 for i in range(cycle)]
error =[0 for i in range(cycle)]
time = np.linspace(0,2,cycle)
for k in range(500):
u[k] = kp * x[0] + kd * x[1] + ki * x[2] #PID控制器的输出
r[k] = 1
#对控制器输出进行限制
if u[k] >= 10:
u[k] = 10
if u[k] <= -10:
u[k] = -10
y[k]= -den[1]*y_1-den[2]*y_2-den[3]*y_3+0*u[k]+num[0]*u_1+num[1]*u_2+num[2]*u_3;
error[k] = r[k] - y[k]
u_3 = u_2
u_2 = u_1
u_1 = u[k]
y_3 = y_2
y_2 = y_1
y_1 = y[k]
x[0] = error[k]
x2_1 = x[1]
x[1] = (error[k] - error_1) / ts
x[2] = x[2] + error[k] * ts
error_1 = error[k]
plt.figure('智能控制作业1 -- 纯PID')
plt.plot(time,y)
plt.plot(time,r)
plt.show()
实验遇到的问题
Matlab
clc; ts=0.001; sys=tf(5.235e005,[1,87.35,1.047e4,0]); %Process TF dsys=c2d(sys,ts,'z'); [num, den]=tfdata(dsys,'v'); disp(num) disp(den)
num 的值在python中是比Matlab 里少一个,少的就是第一个的0。



