RBF神经网络PID-python代码

文章详细介绍了使用Python和C语言实现PID控制器的示例代码,以及RBF-PID算法的应用,通过动态调整参数以逼近设定的目标值。内容涉及PID参数计算、误差处理和神经网络权重更新。
摘要由CSDN通过智能技术生成

模拟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;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值