基于 BP 神经网络整定的 PID 控制

news/2024/11/22 17:45:29/

基于 BP 神经网络整定的 PID 控制 是一种结合了经典 PID 控制和 BP(反向传播)神经网络的自适应控制方法。在这种方法中,神经网络用于在线调整 PID 控制器的参数(比例增益 KpK_pKp​,积分增益 KiK_iKi​ 和微分增益 KdK_dKd​)。神经网络通过学习系统的误差信号,自动调节 PID 参数,从而优化控制性能,尤其是在面对非线性、时变或复杂系统时。

1. 基本原理

(1) PID 控制器概述

PID 控制器是根据误差和误差的变化量调整控制信号,以实现系统的稳定和快速响应。PID 控制器的控制信号计算公式为:

(2) BP 神经网络概述

BP 神经网络是一种常见的前馈神经网络,通过反向传播算法进行训练,逐步调整网络的权重。BP 神经网络通常包括输入层、隐层和输出层。网络的目标是通过最小化误差函数,学习输入和输出之间的映射关系。

在基于 BP 神经网络整定的 PID 控制中,神经网络的输入是系统的误差信号和误差变化量,输出是 PID 控制器的三个增益(KpK_pKp​,KiK_iKi​,KdK_dKd​)的调整量。神经网络通过优化这些增益,使得控制系统的误差最小化。

3. C++实现基于 BP 神经网络整定的 PID 控制

以下是一个简化版的基于 BP 神经网络整定的 PID 控制的 C++ 实现:

#include <iostream>
#include <vector>
#include <cmath>class BPNeuralNetwork {
private:int input_size, hidden_size, output_size;double learning_rate;std::vector<std::vector<double>> input_to_hidden_weights;  // 输入到隐藏层的权重std::vector<std::vector<double>> hidden_to_output_weights; // 隐藏层到输出层的权重std::vector<double> hidden_bias, output_bias;std::vector<double> hidden_output, network_output;public:BPNeuralNetwork(int input_size, int hidden_size, int output_size, double learning_rate = 0.1): input_size(input_size), hidden_size(hidden_size), output_size(output_size), learning_rate(learning_rate) {// 初始化权重和偏置input_to_hidden_weights = std::vector<std::vector<double>>(input_size, std::vector<double>(hidden_size));hidden_to_output_weights = std::vector<std::vector<double>>(hidden_size, std::vector<double>(output_size));hidden_bias = std::vector<double>(hidden_size, 0.0);output_bias = std::vector<double>(output_size, 0.0);hidden_output = std::vector<double>(hidden_size, 0.0);network_output = std::vector<double>(output_size, 0.0);// 随机初始化权重for (int i = 0; i < input_size; ++i)for (int j = 0; j < hidden_size; ++j)input_to_hidden_weights[i][j] = (rand() % 1000) / 1000.0;  // 初始化为 [0, 1] 区间的随机数for (int i = 0; i < hidden_size; ++i)for (int j = 0; j < output_size; ++j)hidden_to_output_weights[i][j] = (rand() % 1000) / 1000.0;  // 初始化为 [0, 1] 区间的随机数}// 激活函数(sigmoid)double sigmoid(double x) {return 1.0 / (1.0 + exp(-x));}// 激活函数的导数(sigmoid的导数)double sigmoid_derivative(double x) {return x * (1.0 - x);}// 前向传播std::vector<double> forward(const std::vector<double>& input) {// 输入到隐藏层for (int i = 0; i < hidden_size; ++i) {hidden_output[i] = 0.0;for (int j = 0; j < input_size; ++j)hidden_output[i] += input[j] * input_to_hidden_weights[j][i];hidden_output[i] += hidden_bias[i];hidden_output[i] = sigmoid(hidden_output[i]);}// 隐藏层到输出层for (int i = 0; i < output_size; ++i) {network_output[i] = 0.0;for (int j = 0; j < hidden_size; ++j)network_output[i] += hidden_output[j] * hidden_to_output_weights[j][i];network_output[i] += output_bias[i];network_output[i] = sigmoid(network_output[i]);}return network_output;}// 反向传播void backward(const std::vector<double>& input, const std::vector<double>& target) {// 输出层误差std::vector<double> output_errors(output_size);for (int i = 0; i < output_size; ++i)output_errors[i] = target[i] - network_output[i];// 隐藏层误差std::vector<double> hidden_errors(hidden_size);for (int i = 0; i < hidden_size; ++i) {hidden_errors[i] = 0.0;for (int j = 0; j < output_size; ++j)hidden_errors[i] += output_errors[j] * hidden_to_output_weights[i][j];hidden_errors[i] *= sigmoid_derivative(hidden_output[i]);}// 更新输出层权重for (int i = 0; i < output_size; ++i) {for (int j = 0; j < hidden_size; ++j) {hidden_to_output_weights[j][i] += learning_rate * output_errors[i] * hidden_output[j];}output_bias[i] += learning_rate * output_errors[i];}// 更新隐藏层权重for (int i = 0; i < hidden_size; ++i) {for (int j = 0; j < input_size; ++j) {input_to_hidden_weights[j][i] += learning_rate * hidden_errors[i] * input[j];}hidden_bias[i] += learning_rate * hidden_errors[i];}}
};class BPNeuralNetworkPIDController {
private:double Kp, Ki, Kd;BPNeuralNetwork nn;public:BPNeuralNetworkPIDController(double Kp_init, double Ki_init, double Kd_init): Kp(Kp_init), Ki(Ki_init), Kd(Kd_init), nn(3, 5, 3) {}double compute(double setpoint, double actual) {double error = setpoint - actual;double delta_error = error;  // 假设每次误差变化为当前误差// 神经网络的输入为误差和误差变化量std::vector<double> input = { error, delta_error, Ki };std::vector<double> output = nn.forward(input);// 使用神经网络输出调整PID增益Kp += output[0];Ki += output[1];Kd += output[2];// 计算控制信号double control_signal = Kp * error + Ki * error + Kd * delta_error;return control_signal;}
};int main() {BPNeuralNetworkPIDController pid_controller(1.0, 0.1, 0.01);double setpoint = 10.0;double actual = 0.0;for (int step = 0; step < 50; ++step) {double control_signal = pid_controller.compute(setpoint, actual);actual += control_signal * 0.1;  // 假设控制信号对系统的影响std::cout << "Step: " << step << ", Control Signal: " << control_signal << ", Actual Output: " << actual << std::endl;}return 0;
}

4. 解释代码

  • BPNeuralNetwork 类:该类实现了一个简单的三层BP神经网络。输入层有3个输入节点(误差、误差变化量和Ki),输出层有3个节点(分别对应 KpK_pKp​、KiK_iKi​ 和 KdK_dKd​ 的调整量)。网络使用反向传播算法更新权重和偏置。
  • BPNeuralNetworkPIDController 类:这个类实现了基于 BP 神经网络整定的 PID 控制。它根据误差和误差变化量通过神经网络计算 PID 控制器的增益,并计算控制信号。

5. 总结

基于 BP 神经网络整定的 PID 控制方法,通过神经网络自适应地调整 PID 参数,从而优化控制性能。这种方法尤其适用于动态和非线性系统,在系统的特性发生变化时,神经网络能够自我调整 PID 参数,保持系统的稳定性和快速响应。


http://www.ppmy.cn/news/1549088.html

相关文章

window系统改为Linux系统

window系统改为Linux系统 一、制作启动盘 需要东西&#xff1a;ultraiso软件&#xff0c;centos镜像&#xff0c;U盘(16G) 1.下载和安装所需文件 UltraISO下载地址&#xff1a;https://cn.ultraiso.net/uiso9_cn.exe centos镜像下载地址&#xff1a;https://vault.centos.…

前端反向代理的配置和實現

反向代理是位於客戶端和服務器之間的一個中間層&#xff0c;它代表客戶端向伺服器發起請求&#xff0c;然後將伺服器的回應返回給客戶端。與傳統的正向代理不同&#xff0c;反向代理是由伺服器端配置的&#xff0c;客戶端通常不知道它的存在。在前端開發中&#xff0c;反向代理…

操作系统实验 C++实现死锁检测算法

实验目的 模拟实现死锁检测算法 实验内容 1、 输入&#xff1a; “资源分配表”文件&#xff0c;每一行包含资源编号、进程编号两项&#xff08;均用整数表示&#xff0c;并用空格分隔开&#xff09;&#xff0c;记录资源分配给了哪个进程。 “进程等待表”文件&…

机器学习问题之一:协变量偏移(Covariate Shift)

协变量偏移&#xff08;Covariate Shift&#xff09;是机器学习和深度学习中的一个重要概念&#xff0c;指的是在模型训练和应用时&#xff0c;输入数据&#xff08;特征&#xff09;的分布发生了变化&#xff0c;但输出标签的分布保持不变。这会导致模型在训练集上表现良好&am…

【LeetCode】每日一题 2024_11_21 矩阵中的蛇(模拟)

前言 每天和你一起刷 LeetCode 每日一题~ 最近有些课程期中考试所以停更了几天&#xff0c;现在我又回来啦 本期看点&#xff1a;普通简单题 LeetCode 启动&#xff01; 题目&#xff1a;矩阵中的蛇 代码与解题思路 题目让我从矩阵左上角的 0 元素开始&#xff0c;根据他给…

Gazebo仿真实现无人机+Apriltag码动态跟踪

目录 演示 一、环境 二、配置 创建模型 首先相机创建 添加相机 Apriltag创建 地图添加apriltag码 Apriltag_ros配置 三、代码运行 四、问题 修改相机模型的参数 演示 一、环境 ROSgazebo配置 Px4Mavros Apriltag_ros编译 二、配置 在默认的mavros_posix_sitl.l…

Go语言里简短声明语句词法域问题

Go语言里简短声明语句词法域问题 简短变量声明语句只有对已经在同级词法域声明过的变量才和赋值操作语句等价&#xff0c;如果变量是在外部词法域声明的&#xff0c;那么简短变量声明语句将会在当前词法域重新声明一个新的变量。 第一个程序 在第一个程序中&#xff0c;for循…

用java和redis实现考试成绩排行榜

一、引言 在各类考试场景中&#xff0c;无论是学校里的学业测试&#xff0c;还是线上培训课程的考核&#xff0c;亦或是各类竞赛的选拔&#xff0c;成绩排行榜都是大家颇为关注的一个元素。它不仅能直观地展示考生之间的成绩差异&#xff0c;激发大家的竞争意识&#xff0c;还能…