模糊PID控制算法实战讲解-案例温度控制(附C语言实现)

 可结合之前的文章一起理解:

控制算法-PID算法总结-从公式原理到参数整定解析(附C源码)_pid自整定算法-CSDN博客

模糊控制算法实战讲解-案例温度控制(附C语言实现)-CSDN博客 

 

目录

一、模糊PID控制的原理

1.1 模糊化

1.2 模糊规则库

1.3 模糊推理

1.4  去模糊化

1.5 PID控制输入计算

二、特点和应用场景

三、案例温度控制

简化版本:

加入重心法后的模糊PID版本:


模糊PID控制算法是将传统的PID控制与模糊逻辑控制相结合的一种控制策略。这种算法尝试通过模糊逻辑系统来自动调整PID控制器的参数(比例系数Kp​、积分系数Ki​、微分系数Kd​),以适应系统动态变化的需求,从而提高控制系统的性能。模糊PID控制在处理非线性、时变系统或者模型不完全已知的系统时尤其有效。

一、模糊PID控制的原理

传统的PID控制器根据偏差e(t)(期望输出与实际输出之间的差值)和偏差的变化率e1(t)来计算控制输入。PID控制器的输出由三部分组成:比例(P)、积分(I)和微分(D)项,计算公式为:

                               

在模糊PID控制中,系统利用模糊逻辑根据当前的偏差e(t)和偏差变化率e1(t)来动态调整Kp​、Ki​、Kd​的值,以适应系统的变化。

1.1 模糊化

将偏差e(t)和偏差变化率e1(t)的精确值转换为模糊值,这些模糊值对应于模糊集合中的语言变量,例如“正大”、“正小”、“零”、“负小”、“负大”。

1.2 模糊规则库

建立一个模糊规则库,这些规则基于专家知识或经验,描述了在特定偏差和偏差变化率的情况下如何调整PID参数。例如:如果偏差是正大,且变化率是正小,则增大比例系数Kp​。

1.3 模糊推理

根据模糊化的输入e(t)和e1(t))和模糊规则库,通过模糊推理得出每个PID参数的调整策略。

1.4  去模糊化

将模糊推理的结果转换为精确的PID参数值。

1.5 PID控制输入计算

使用调整后的PID参数计算控制输入u(t)

二、特点和应用场景

模糊PID控制器的主要优点是它结合了PID控制的直观性和模糊控制的适应性,能够在系统模型不完全已知或存在较大不确定性时提供良好的控制性能。控制更平稳。

应用场景:工业控制系统、机器人、汽车电子控制等领域

三、案例温度控制

考虑一个温度控制系统,其中模糊PID控制器用于调整加热器的功率输出,以维持设定的温度。根据温度偏差和偏差变化率的不同,模糊控制器会动态调整Kp​、Ki​、Kd​,以快速响应温度变化并减小超调,提高系统的稳定性和响应速度。

简化版本:

控制目标是使系统温度维持在一个设定值(比如25°C)。

PID参数(Kp​,Ki​,Kd​)需要根据温度偏差e(t)和偏差变化率e1(t)动态调整。

 PID控制器的结构体:

typedef struct {float Kp, Ki, Kd; // PID参数float integral;   // 积分项累计值float prev_error; // 上一次的偏差
} PIDController;

模糊规则:

void adjustPIDParams(PIDController* pid, float error, float delta_error) {// 假设根据偏差的大小和变化率调整PID参数// 这里的逻辑非常简化,实际应用中应该基于详细的模糊规则// 如果偏差大,增加Kp来快速减少偏差if (error > 5.0) pid->Kp += 0.1;else if (error < -5.0) pid->Kp -= 0.1;// 如果偏差变化快,增加Kd来减少超调if (delta_error > 0.5) pid->Kd += 0.05;else if (delta_error < -0.5) pid->Kd -= 0.05;// 保证PID参数在合理范围内if (pid->Kp < 0) pid->Kp = 0;if (pid->Kd < 0) pid->Kd = 0;
}

控制逻辑:

float computePIDOutput(PIDController* pid, float setpoint, float measured) {float error = setpoint - measured;float delta_error = error - pid->prev_error;// 简单的模糊逻辑调整PID参数adjustPIDParams(pid, error, delta_error);// 计算PID输出float output = pid->Kp * error + pid->Ki * pid->integral + pid->Kd * delta_error;// 更新状态pid->integral += error;pid->prev_error = error;return output;
}
int main() {PIDController pid = {0.1, 0.01, 0.05, 0, 0}; // 初始化PID参数和状态float setpoint = 25.0; // 目标温度float measured_temp = 20.0; // 测量温度,示例值// 模拟控制循环for (int i = 0; i < 100; ++i) {float control_signal = computePIDOutput(&pid, setpoint, measured_temp);// 应用control_signal到加热器...// 更新measured_temp...printf("Control Signal: %f\n", control_signal)

加入重心法后的模糊PID版本:

1)定义输入输出的模糊集合:

输入:温度误差e和误差变化率de

每个输入都可以定义为几个模糊集合,例如:负大(NB),负小(NS),零(ZE),正小(PS),正大(PB)。

输出:PID参数的调整量,包括ΔKpΔKiΔKd。输出也可以定义为类似的模糊集合。

 2)定义隶属度函数:

   对于每个模糊集合,定义一个隶属度函数来量化一个具体的输入值属于该模糊集合的程度。隶属度函数可以是三角形、梯形或是其他形状。

3)模糊规则

  • 基于经验或专家知识制定一组模糊规则,用于描述输入模糊集合之间的关系以及它们如何影响输出模糊集合。
  • 例如:“如果e是PB并且de是ZE,则ΔKp是PB”。

4)去模糊化

 使用重心法(或其他去模糊化方法)将模糊输出转换为一个具体的数值,用于调整PID参数。

 只考虑e的影响,以kp的变化量调整为例:

#include <stdio.h>// 示例:简化的隶属度计算函数
float calculateMembership(float value, float min, float max) {if (value <= min) return 0;else if (value >= max) return 1;else return (value - min) / (max - min);
}// 示例:计算ΔKp的重心
float calculateDeltaKp(float e, float de) {// 示例:隶属度值计算(这里仅为示例,实际情况下更复杂)float eNB = calculateMembership(e, -10, -5);float eNS = calculateMembership(e, -5, -2);float eZE = calculateMembership(e, -2, 2);float ePS = calculateMembership(e, 2, 5);float ePB = calculateMembership(e, 5, 10);// 示例:简化的模糊规则处理,假设只根据e的模糊集合调整Kpfloat deltaKp = (eNB * -2) + (eNS * -1) + (eZE * 0) + (ePS * 1) + (ePB * 2);float totalMembership = eNB + eNS + eZE + ePS + ePB;// 重心法去模糊化return totalMembership > 0 ? deltaKp / totalMembership : 0;
}int main() {float e = -3;  // 示例误差值float de = 0;  // 示例误差变化率float deltaKp = calculateDeltaKp(e, de);printf("Calculated ΔKp: %f\n", deltaKp);return 0;
}

考虑e和de影响:

#include <stdio.h>// 示例:隶属度计算函数
float calculateMembership(float value, float min, float max) {if (value < min) return 0;else if (value > max) return 1;else return (value - min) / (max - min);
}// 示例:根据e和de的模糊规则计算ΔKp
float calculateDeltaKp(float e, float de) {// 隶属度值计算float eNB = calculateMembership(e, -10, -5);float deNB = calculateMembership(de, -10, -5);float eNS = calculateMembership(e, -5, -2);float deNS = calculateMembership(de, -5, -2);float eZE = calculateMembership(e, -2, 2);float deZE = calculateMembership(de, -2, 2);float ePS = calculateMembership(e, 2, 5);float dePS = calculateMembership(de, 2, 5);float ePB = calculateMembership(e, 5, 10);float dePB = calculateMembership(de, 5, 10);float deltaKpValues[] = {-2, -1, 0, 1, 2}; // 对应NB, NS, ZE, PS, PB// 模糊规则处理float rule1Output = eNB * deNB  * deltaKpValues[0]; // float rule2Output = eNS * deNS * deltaKpValues[1]; // float rule3Output = eZE * deZE * deltaKpValues[2]; // 如果e和de都是ZE,则ΔKp保持不变float rule4Output = ePS * dePS  * deltaKpValues[3]; //float rule5Output = ePB * dePB * deltaKpValues[4]; //// 假设这是根据所有规则计算出的ΔKp总和float deltaKpTotal = rule1Output+rule2Output +rule3Output +rule4Output +rule5Output ; float totalMembership = eNB +deNB +eNS + deNS +eZE + deZE+ePB +dePB ; // 重心法去模糊化return totalMembership > 0 ? deltaKpTotal / totalMembership : 0;
}int main() {float e = -1;  // 示例误差值float de = 1;  // 示例误差变化率float deltaKp = calculateDeltaKp(e, de);printf("Calculated ΔKp: %f\n", deltaKp);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/710046.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

边读 Emacs Lisp Intro 边做题(五)

文章目录 边读Emacs Lisp Intro边做题&#xff08;五&#xff09; 边读Emacs Lisp Intro边做题&#xff08;五&#xff09; 打开emacs&#xff0c;按C-h i打开Info页&#xff0c;找到Emacs Lisp Intro。 这里的\\b\\([^ \n\t]\\)[ \n\t]\\1\\b抄自题目描述中提供的链接&#…

Decision Transformer

DT个人理解 emmm, 这里的Transformer 就和最近接触到的whisper一样,比起传统Transformer,自己还设计了针对特殊情况的tokens。比如whisper里对SOT,起始时间,语言种类等都指定了特殊tokens去做Decoder的输入和输出。 DT这里的作为输入的Tokens由RL里喜闻乐见的历史数据:…

Java优先级队列--堆

目录 1. 优先级队列 1.1 概念 2.优先级队列的模拟实现 2.1 堆的概念 2.2 堆的存储方式 2.3 堆的创建 2.3.1 堆向下调整 2.3.2 堆的创建 2.3.3 建堆的时间复杂度 2.4 堆的插入与删除 2.4.1 堆的插入 2.4.2 堆的删除 2.5 用堆模拟实现优先级队列 3.常用接口介绍 3…

Eigen-Block块操作

Block块操作 一、使用块操作二、列和行三、Corner-related操作四、向量的块运算 块是矩阵或数组的矩形部分。块表达式既可以用作右值&#xff0c;也可以用作左值。与通常的Eigen表达式一样&#xff0c;只要让编译器进行优化&#xff0c;这种抽象的运行时成本为零。优化都是自动…

什么是VR紧急情况模拟|消防应急虚拟展馆|VR游戏体验馆加盟

VR紧急情况模拟是利用虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;技术来模拟各种紧急情况和应急场景的训练和演练。通过VR技术&#xff0c;用户可以身临其境地体验各种紧急情况&#xff0c;如火灾、地震、交通事故等&#xff0c;以及应对这些紧急情况的…

贪心算法(算法竞赛、蓝桥杯)--修理牛棚

1、B站视频链接&#xff1a;A27 贪心算法 P1209 [USACO1.3] 修理牛棚_哔哩哔哩_bilibili 题目链接&#xff1a;[USACO1.3] 修理牛棚 Barn Repair - 洛谷 #include <bits/stdc.h> using namespace std; const int N205; int m,s,c,ans; int a[N];//牛的位置标号 int d[N…

奇怪的需求之与图片做交互

1.起因 客户想要展示自己的地图,该地图上有各种工作数据,和工作点位,已有的地图不能满足需求.于是提出将这张图片当成大背景 2.经过 鉴于文件格式和尺寸的原因,协商后客户提出将图片做成缩放效果,同时具有点击效果,原先直接进入的主页,现在为点击图片中的某条线路进入主页面…

Ubuntu tesseract使用全是干货

文字检测 方案 利用opencv二值化处理。最后检测使用google的开源库libtesseract识别文字。 tesseract安装 apt install libtesseract-dev # 前面那个是英文&#xff0c;后面那个是中文 apt install tesseract-oct tesseract-ocr-chi-sim手册 手册 qt creator中使用 pro文…

[LeetCode]143.重排链表

143. 重排链表 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/reorder-list/description/ 题目 示例 解题思路 寻找链表中点 链表逆序 合并链表 注意到目标链表即为将原链表的左半端和反转后的右半端合并后的结果。 这样我们的任务即可划分为三步&a…

Redis 8种基本数据类型及常用命令和数据类型的应用场景

小伙伴们好&#xff0c;欢迎关注&#xff0c;一起学习&#xff0c;无限进步 文章内容为学习的一些笔记及工作中遇到的一些问题 文章目录 Redis 五大数据类型keyStringListSetHashSorted Set 三种特殊类型Geospatial 地理位置HyperloglogBitmap Redis 五大数据类型 redis 官方网…

Python中的os库

一.OS库简介 OS是Operating System的简写&#xff0c;即操作系统。 OS库是一个操作系统接口模块&#xff0c;提供一些方便使用操作系统相关功能的函数。 二.OS库常用函数 2.1文件和目录 2.1.1&#xff1a;os.getcwd() 作用&#xff1a;返回当前工作目录&#xff0c;结果是…

Python中re(正则)模块的使用

re 是 Python 标准库中的一个模块&#xff0c;用于支持正则表达式操作。通过 re 模块&#xff0c;可以使用各种正则表达式来搜索、匹配和操作字符串数据。 使用 re 模块可以帮助在处理字符串时进行高效的搜索和替换操作&#xff0c;特别适用于需要处理文本数据的情况。 # 导入…

怎样把python字符串中的emoji表情包去掉或忽略?

要从Python字符串中去掉或忽略表情符号&#xff0c;可以使用正则表达式来过滤掉所有的Unicode码点大于\uFFFF的字符。这些字符通常是表情符号。 以下是一个示例代码&#xff1a; import redef remove_emojis(text):emoji_pattern re.compile("["u"\U0001F600…

如何在Window系统部署BUG管理软件并结合内网穿透实现远程管理本地BUG

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…

微信小程序开启横屏调试

我们先打开小程序项目 开启真机运行 目前是一个竖屏的 然后打开全局配置文件 app.json 给下面的 window 对象 下面加一个 pageOrientation 属性 值为 landscape 运行结果如下 然后 我们开启真机运行 此时 就变成了个横屏的效果

Android、ios 打包一键生成自定义尺寸应用图标

这里以uniapp 打包为例 这里是打包时分别需要使用的尺寸 打开一键生成应用图标 在线工具 一键生成应用图标https://icon.wuruihong.com/ 上传你的应用图标 上传后在这里添加你需要用到的尺寸 开始生成 下载你批量生成的图标

使用Python,networkx绘制有向层级结构图

使用Python&#xff0c;networkx绘制有向层级结构图 1. 效果图2. 源码2.1 tree.txt2.2 pyNetworkx.py参考 上一篇介绍了&#xff1a;1. 使用Python&#xff0c;networkx对卡勒德胡赛尼三部曲之《群山回唱》人物关系图谱绘制 当前博客介绍&#xff1a; 2. 使用Python&#xff0c…

11408

果然很terrible

仿牛客网项目---社区首页的开发实现

从今天开始我们来写一个新项目&#xff0c;这个项目是一个完整的校园论坛的项目。主要功能模块&#xff1a;用户登录注册&#xff0c;帖子发布和热帖排行&#xff0c;点赞关注&#xff0c;发送私信&#xff0c;消息通知&#xff0c;社区搜索等。这篇文章我们先试着写一下用户的…

剑指offer面试题21 包含min函数的栈

考察点 双栈知识点 题目 分析 题目需要一个能够得到栈的最小元素的min函数&#xff0c;并且min函数&#xff0c;pop&#xff0c;push都要求是O(1)的时间复杂度。遇到栈思维要往双栈上考虑&#xff0c;这种情况一个栈肯定完成不了&#xff0c;需要一个辅助栈&#xff0c;既然…