模拟PID调参python代码
import matplotlib.pyplot as plt
# 设置PID控制器参数
Kp = 0.1
Ki = 0.2
Kd = 0.1
# 初始化变量
SetPoint = 10
dt = 0.1
error = 0
integral = 0
derivative = 0
last_error = 0
output = 0
# 数据记录
time = []
outputs = []
# 模拟PID调节过程
for t in range(100):
time.append(t)
error = SetPoint - output
integral += error * dt
derivative = (error - last_error) / dt
output = Kp * error + Ki * integral + Kd * derivative
outputs.append(output)
last_error = error
# 绘制图表
plt.plot(time, outputs, label='PID Output')
plt.axhline(y=SetPoint, color='r', linestyle='--', label='Set Point')
plt.xlabel('Time')
plt.ylabel('Output')
plt.legend()
plt.grid(True)
plt.show()
参考《先进pid控制matlab仿真.pdf》
RBF-PID python
'''实现可控的rbf,根据自己的输入动态调整逐渐逼近目标值'''
#RBF
import numpy as np
import matplotlib.pyplot as plt
lr = 0.1 #定义学习率
alfa=0.05
nn = 6 #六个隐含层节点
U_pid=0
feed_back_value=0
feed_back_value_1=0
x = np.array([U_pid, feed_back_value,feed_back_value_1])
#输入
#误差
error = 0
error_1=0
error_2=0
#计算参数
ci = 3 * np.ones((3, nn))
bi = 4 * np.ones(nn)
w = 1 * np.ones(nn)
h = np.zeros((nn,1))
ci_1=ci
ci_2=ci_1
bi_1=bi
bi_2= bi_1
w_1= w
w_2 = w_1
plot_y = []
#ec = np.array([0, 0, 0]).reshape(-1, 1)#列向量
kp0, ki0, kd0 = 0.2, 0.2, 0.000
kp, kd, ki = kp0, kd0, ki0
kp_lr, kd_lr, ki_lr = 0.00010, 0.00010, 0.00020
def RBF_pid(target, feed_back_value,ci,bi,w,kp,kd,ki):
global w_1,bi_1,ci_1,w_2,bi_2,ci_2,error,error_1,error_2,feed_back_value_1
for j in range(nn):
h[j] = np.exp(-np.linalg.norm(x - ci[:, j])**2 / (2 * bi[j]**2))
#隐含层到输出层
ymout= np.dot(w.T, h)
#修改权重
d_w = 0*w
for j in range(nn):
d_w[j] = lr * (feed_back_value - ymout) * h[j]
w = w_1 + d_w + alfa * (w_1 - w_2)
#修改高斯函数b y_2为经过pid计算后的输出
d_bi = np.zeros(nn)
for j in range(nn):
d_bi[j] = lr * (feed_back_value - ymout) * w[j] * h[j] * (bi[j]**-3) * np.linalg.norm(x - ci[:, j])**2
bi = bi_1 + d_bi + alfa * (bi_1 - bi_2)
#修改高斯函数C
d_ci = np.zeros((3, nn))
for j in range(nn):
for i in range(3):
d_ci[i, j] = lr * (feed_back_value - ymout) * w[j] * h[j] * (x[i] - ci[i, j]) * (bi[j]**-2)
ci = ci_1 + d_ci + alfa * (ci_1 - ci_2)
#灵敏度,计算dym/du
yu = 0
for j in range(nn):
yu += w[j] * h[j] * (-x[0] + ci[0, j]) / bi[j]**2
#误差,这一次计算与目标值
error = target-feed_back_value
xe1 = error - error_1
xe2 = error
xe3 = error - 2 * error_1 + error_2
U_pid = kp * xe1 + kd * xe3 + ki * xe2
feed_back_value = feed_back_value + U_pid
feed_back_value_1=feed_back_value
plot_y.append(feed_back_value)
print(feed_back_value)
dyout = yu
kp = kp + kp_lr * error * dyout * xe1
ki = ki + ki_lr * error* dyout * xe2
kd = kd + kd_lr * error* dyout * xe3
x[0] = U_pid
x[1] = feed_back_value
x[2] = feed_back_value_1
ci_2, ci_1 = ci_1, ci
bi_2, bi_1 = bi_1, bi
w_2, w_1 = w_1, w
error_2 = error_1#用于pid
error_1 = error
kp = kp
kd= kd
ki = ki
target = 20#目标值
def main():
for i in range(10):
feed_back_value = float(input("请输入反馈值:"))
RBF_pid(target, feed_back_value,ci,bi,w,kp,kd,ki)
main()
plt.plot(plot_y)
plt.show()
'''实现可控的rbf,根据自己的输入动态调整逐渐逼近目标值'''
#RBF
import numpy as np
import matplotlib.pyplot as plt
lr = 0.1 #定义学习率
alfa=0.05
nn = 6 #六个隐含层节点
U_pid=0.0
feed_back_value=0.0
feed_back_value_1=0.0
x = np.array([U_pid, feed_back_value,feed_back_value_1])
#输入
#误差
error = 0.0
error_1=0.0
error_2=0.0
#计算参数
ci = 100* np.ones((3, nn))
bi = 400 * np.ones(nn)
w = 1* np.ones(nn)
h = np.zeros((nn,1))
ci_1=ci
ci_2=ci_1
bi_1=bi
bi_2= bi_1
w_1= w
w_2 = w_1
plot_y = [0]
#ec = np.array([0, 0, 0]).reshape(-1, 1)#列向量
kp0, ki0, kd0 = 0.1, 0.5, 0.000
kp, kd, ki = kp0, kd0, ki0
kp_lr, kd_lr, ki_lr = 0.00010, 0.00000, 0.0001
def RBF_pid(target, feed_back_value,ci,bi,w,kp,kd,ki):
global w_1,bi_1,ci_1,w_2,bi_2,ci_2,error,error_1,error_2,feed_back_value_1
if feed_back_value>1000:
feed_back_value=800
for j in range(nn):
h[j] = np.exp(-np.linalg.norm(x - ci[:, j])**2 / (2 * bi[j]**2))
#隐含层到输出层
ymout= np.dot(w.T, h)
#修改权重
d_w = 0*w
for j in range(nn):
d_w[j] = lr * (feed_back_value - ymout) * h[j]
w = w_1 + d_w + alfa * (w_1 - w_2)
#修改高斯函数b y_2为经过pid计算后的输出
d_bi = np.zeros(nn)
for j in range(nn):
d_bi[j] = lr * (feed_back_value - ymout) * w[j] * h[j] * (bi[j]**-3) * np.linalg.norm(x - ci[:, j])**2
bi = bi_1 + d_bi + alfa * (bi_1 - bi_2)
#修改高斯函数C
d_ci = np.zeros((3, nn))
for j in range(nn):
for i in range(3):
d_ci[i, j] = lr * (feed_back_value - ymout) * w[j] * h[j] * (x[i] - ci[i, j]) * (bi[j]**-2)
ci = ci_1 + d_ci + alfa * (ci_1 - ci_2)
#灵敏度,计算dym/du
yu = 0
for j in range(nn):
yu += w[j] * h[j] * (-x[0] + ci[0, j]) / bi[j]**2
#误差,这一次计算与目标值
error = target-feed_back_value
xe1 = error - error_1
xe2 = error
xe3 = error - 2 * error_1 + error_2
U_pid = kp * xe1 + kd * xe3 + ki * xe2
feed_back_value = feed_back_value + U_pid
feed_back_value_1=feed_back_value
plot_y.append(float(feed_back_value))
dyout = yu
kp = kp + kp_lr * error * dyout * xe1
ki = ki + ki_lr * error* dyout * xe2
kd = kd + kd_lr * error* dyout * xe3
print('U_pid:',U_pid)
print('error:',error)
print('feed_back_value:',feed_back_value)
print("ci",ci,"\n","bi",bi,"\n","w",w,"\n","yu",yu,"\n","h",h)
print("kp",kp,"ki",ki,"kd",kd)
x[0] = U_pid
x[1] = feed_back_value
x[2] = feed_back_value_1
ci_2, ci_1 = ci_1, ci
bi_2, bi_1 = bi_1, bi
w_2, w_1 = w_1, w
error_2 = error_1#用于pid
error_1 = error
kp = kp
kd= kd
ki = ki
return feed_back_value
# global target = 1000#目标值
target_value=[70,90,150,180,300,500,400,300]
feed_back_value=0
def main():
for i in range(len(target_value)):
global feed_back_value
# target = float(input("请输入目标值:"))#目标值
target=target_value[i]
for i in range(10):
print("\n",i)
# feed_back_value = float(input("请输入反馈值:"))
give_value=RBF_pid(target, feed_back_value,ci,bi,w,kp,kd,ki)
feed_back_value=give_value+np.random.randint(-1, 1, size=1)# 生成1个范围在[-5,5]之间的随机整数
main()
plt.plot(plot_y)
for i in range(len(target_value)):
plt.axhline(target_value[i],color="green",lw=1,ls="--")
plt.show()
RBF_PID c语言
由于要控制单片机,我不得不又去写一个C语言的代码。
#include <stdio.h>
#include <math.h>
#define NN 6
void update(float *old, float *new, float *delta, float alpha) {
int i;
for (i = 0; i < NN; i++) {
old[i] = new[i] + delta[i] + alpha * (new[i] - old[i]);
}
}
float norm(float *x, float *y) {
int i;
float sum = 0;
for (i = 0; i < NN; i++) {
sum += pow(x[i] - y[i], 2);
}
return sqrt(sum);
}
int main() {
int i, j;
float lr = 0.001;
float alpha = 0.05;
float beta = 0.01;
float du = 0;
float u_1 = 0, y_2 = 800, y_1 = 0;
float x[3] = {du, y_2, y_1};
float error = 0, error_1 = 0, error_2 = 0;
float ci[3][NN], ci_1[3][NN], ci_2[3][NN];
float bi[NN], bi_1[NN], bi_2[NN];
float w[NN], w_1[NN], w_2[NN];
float h[NN];
//float kp0 = 0.2, ki0 = 0.2, kd0 = 0.000;
float kp0 = 0.001, ki0 = 0.0001, kd0 = 0.000;
float kp_1 = kp0, kd_1 = kd0, ki_1 = ki0;
float kp_lr = 0.00010, kd_lr = 0.00020, ki_lr = 0.00020;
for (i = 0; i < NN; i++) {
ci[0][i] = ci_1[0][i] = ci_2[0][i] = 10;
ci[1][i] = ci_1[1][i] = ci_2[1][i] = 10;
ci[2][i] = ci_1[2][i] = ci_2[2][i] = 10;
bi[i] = bi_1[i] = bi_2[i] = 4;
w[i] = w_1[i] = w_2[i] = 0.0001;
}
for (int time = 0; time < 50; time++) {
for (j = 0; j < NN; j++) {
h[j] = exp(-norm(x, ci[j]) / (2 * pow(bi[j], 2)));
}
float ymout = 0;
for (j = 0; j < NN; j++) {
ymout += w[j] * h[j];
}
float d_w[NN] = {0};
for (j = 0; j < NN; j++) {
d_w[j] = lr * (y_2 - ymout) * h[j];
}
update(w_2, w_1, d_w, alpha);
float d_bi[NN] = {0};
for (j = 0; j < NN; j++) {
d_bi[j] = lr * (y_2 - ymout) * w[j] * h[j] * pow(bi[j], -3) * norm(x, ci[j]);
}
update(bi_2, bi_1, d_bi, alpha);
float d_ci[3][NN] = {0};
for (j = 0; j < NN; j++) {
for (i = 0; i < 3; i++) {
d_ci[i][j] = lr * (y_2 - ymout) * w[j] * h[j] * (x[i] - ci[i][j]) * pow(bi[j], -2);
}
}
for (i = 0; i < 3; i++) {
update(ci_2[i], ci_1[i], d_ci[i], alpha);
}
float yu = 0;
for (j = 0; j < NN; j++) {
yu += w[j] * h[j] * (-x[0] + ci[0][j]) / pow(bi[j], 2);
}
float dyout = yu;
error = 70 - y_2;
float xe1 = error - error_1;
float xe2 = error;
float xe3 = error - 2 * error_1 + error_2;
float kp = kp_1 + kp_lr * error * dyout * xe1;
float kd = kd_1 + kd_lr * error * dyout * xe3;
float ki = ki_1 + ki_lr * error * dyout * xe2;
du = kp * xe1 + kd * xe3 + ki * xe2;
y_1 = y_2;
y_2 = y_2 + du;
printf("de_u:%f\n", du);
printf("Y_2:%f\n", y_2);
x[0] = du;
x[1] = y_2;
x[2] = y_1;
for (i = 0; i < 3; i++) {
for (j = 0; j < NN; j++) {
ci_2[i][j] = ci_1[i][j];
ci_1[i][j] = ci[i][j];
}
}
update(bi_2, bi_1, bi, 0);
update(w_2, w_1, w, 0);
error_2 = error_1;
error_1 = error;
printf("err:%f\n", error);
kp_1 = kp;
kd_1 = kd;
ki_1 = ki;
}
getchar();
return 0;
}