模糊控制算法的C++实现
在现代智能控制算法中,模糊控制是在实际控制系统设计中使用比较成熟的一种方法。模糊控制可以使用在一些无法建立系统模型的场合,根据专家经验确定模糊规则,实现对系统的控制。本篇文章适合对模糊控制算法有一定了解的人阅读,给大家提供一种如何用C++实现模糊控制的方法,仅供参考。
实现模糊控制器需要以下步骤:
- 确定模糊控制器的输入和输出量
- 设计模糊控制器的控制规则
- 确立模糊化和非模糊化的方法
- 选择模糊控制器的输入变量和输出变量的论域并确定模糊控制器的参数(如量化因子,比例因子等)
- 编制模糊控制算法的应用程序
- 合理选择模糊控制算法的采样时间
首先我们需要确定系统的输入输出数量,假设系统为单输入单输出。对输入变量x,输出变量y分别划分模糊集合,可以使用正态分布隶属度函数,或者三角隶属度函数来划分。这叫做变量的模糊化。如x的论域为[0,2],划分13个模糊集合,分别为A1,A2,A3,…,A13,如下图:
对于输出y,论域为[-1.5,1.5],划分13个模糊集合,为B1,B2,B3,…,B13,如下图所示:
需要分别计算每一个数据点在模糊集合上的隶属度,选取最高的隶属度值作为确定一条模糊规则的依据。如样本点(0.2,1),需要计算0.2在输入隶属度函数中的隶属度值,需要计算13个值,找出其中最大的值如A5,则输入为A5;再计算输出1在13个模糊集合中的隶属度函数值,找出最大的那个,如B2,则输出为B2;由此可以确定一条模糊规则:IF x=A5 THEN y=B2;由此可以确定21个规则;但是这些规则有大量的重复和冲突的规则,需要计算它们置信度
conf=u(Ax)*u(By);
由此公式可以求出矛盾规则的置信度,把置信度低的规则去掉;按照WM算法的提出则王立新的做法,还应该乘上一个专家经验系数,也就是专家认为这条规则的可信度大不大。上面的公式改写为:
conf=u*u(Ax)*u(By);
由此可以建立模糊规则库;
上面表中的第一行代表输入x的隶属集合的下标,第二行代表输出y的隶属集合的下标。
模糊控制最重要的是要确定模糊控制规则,它可以通过专家经验获得,也可以通过采样数据获得,这里举出一个模糊控制规则表例子;
在微处理器中实现模糊控制的一般采用离线查表的方法。首先模糊化输入到控制器中的e和de,计算他们的在每个模糊子集中的隶属度值,然后找出激活的模糊子集,存储起来,最后使用加权平均的方法计算输出值。具体的公式如下:
Zi为u的模糊隶属度函数的尖点所对应的横坐标值。
下面讲讲怎么用C++实现模糊控制器。
首先需要建立一个Fuzzy_controller的类:
class Fuzzy_controller
{public:const static int N=7;//定义量化论域模糊子集的个数
private:float target;//系统的控制目标float actual;//采样获得的实际值float e; //误差float e_pre; //上一次的误差float de; //误差的变化率float emax; //误差基本论域上限float demax; //误差辩化率基本论域的上限float umax; //输出的上限float Ke; //Ke=n/emax,量化论域为[-3,-2,-1,0,1,2,3]float Kde; //Ke=n/demax,量化论域为[-3,-2,-1,0,1,2,3]float Ku; //Ke=umax/n,量化论域为[-3,-2,-1,0,1,2,3]int rule[N][N];//模糊规则表string mf_t_e; //e的隶属度函数类型string mf_t_de; //de的隶属度函数类型string mf_t_u; //u的隶属度函数类型float *e_mf_paras; //误差的隶属度函数的参数float *de_mf_paras;//误差的偏差隶属度函数的参数float *u_mf_paras; //输出的隶属度函数的参数public:Fuzzy_controller(float e_max,float de_max,float u_max);~Fuzzy_controller();float trimf(float x,float a,float b,float c); //三角隶属度函数float gaussmf(float x,float ave,float sigma); //正态隶属度函数float trapmf(float x,float a,float b,float c,float d); //梯形隶属度函数//设置模糊隶属度函数的参数void setMf(const string & mf_type_e,float *e_mf,const string & mf_type_de,float *de_mf,const string & mf_type_u,float *u_mf);void setRule(int rulelist[N][N]); //设置模糊规则float realize(float t,float a); //实现模糊控制void showInfo(); //显示该模糊控制器的信息void showMf(const string & type,float *mf_paras); //显示隶属度函数的信息
};
然后给出类方法的定义:
Fuzzy_controller::Fuzzy_controller(float e_max,float de_max,float u_max):
target(0),actual(0),emax(e_max),demax(de_max),umax(u_max),e_mf_paras(NULL),de_mf_paras(NULL),u_mf_paras(NULL)
{e=target-actual;e_pre=0;de=e-e_pre;Ke=(N/2)/emax;Kde=(N/2)/demax;Ku=umax/(N/2);mf_t_e="trimf";mf_t_de="trimf";mf_t_u="trimf";
}Fuzzy_controller::~Fuzzy_controller()
{delete [] e_mf_paras;delete [] de_mf_paras;delete [] u_mf_paras;
}
//三角隶属度函数
float Fuzzy_controller::trimf(float x,float a,float b,float c)
{float u;if(x>=a&&x<=b)u=(x-a)/(b-a);else if(x>b&&x<=c)u=(c-x)/(c-b);elseu=0.0;return u;}
//正态隶属度函数
float Fuzzy_controller::gaussmf(float x,float ave,float sigma)
{float u;if(sigma<0){cout<<"In gaussmf, sigma must larger than 0"<<endl;}u=exp(-pow(((x-ave)/sigma),2));return u;
}
//梯形隶属度函数
float Fuzzy_controller::trapmf(float x,float a,float b,float c,float d)
{float u;if(x>=a&&x<b)u=(x-a)/(b-a);else if(x>=b&&x<c)u=1;else if(x>=c&&x<=d)u=(d-x)/(d-c);elseu=0;return u;
}
//设置模糊规则
void Fuzzy_controller::setRule(int rulelist[N][N])
{for(int i=0;i<N;i++)for(int j=0;j<N;j++)rule[i][j]=rulelist[i][j];
}//设置模糊隶属度函数的类型和参数
void Fuzzy_controller::setMf(const string & mf_type_e,float *e_mf,const string & mf_type_de,float *de_mf,const string & mf_type_u,float *u_mf)
{if(mf_type_e=="trimf"||mf_type_e=="gaussmf"||mf_type_e=="trapmf")mf_t_e=mf_type_e;elsecout<<"Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\""<<endl;if(mf_type_de=="trimf"||mf_type_de=="gaussmf"||mf_type_de=="trapmf")mf_t_de=mf_type_de;elsecout<<"Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\""<<endl;if(mf_type_u=="trimf"||mf_type_u=="gaussmf"||mf_type_u=="trapmf")mf_t_u=mf_type_u;elsecout<<"Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\""<<endl;e_mf_paras=new float [N*3];de_mf_paras=new float [N*3];u_mf_paras=new float [N*3];for(int i=0;i<N*3;i++)e_mf_paras[i]=e_mf[i];for(int i=0;i<N*3;i++)de_mf_paras[i]=de_mf[i];for(int i=0;i<N*3;i++)u_mf_paras[i]=u_mf[i];
}
//实现模糊控制
float Fuzzy_controller::realize(float t,float a)
{float u_e[N],u_de[N],u_u[N];int u_e_index[3],u_de_index[3];//假设一个输入最多激活3个模糊子集float u;int M;target=t;actual=a;e=target-actual;de=e-e_pre;e=Ke*e;de=Kde*de;if(mf_t_e=="trimf")M=3; //三角函数有三个参数else if(mf_t_e=="gaussmf")M=2; //正态函数有两个参数else if(mf_t_e=="trapmf")M=4; //梯形函数有四个参数int j=0;for(int i=0;i<N;i++){u_e[i]=trimf(e,e_mf_paras[i*M],e_mf_paras[i*M+1],e_mf_paras[i*M+2]);//e模糊化,计算它的隶属度if(u_e[i]!=0)u_e_index[j++]=i; //存储被激活的模糊子集的下标,可以减小计算量}for(;j<3;j++)u_e_index[j]=0;if(mf_t_e=="trimf")M=3; //三角函数有三个参数else if(mf_t_e=="gaussmf")M=2; //正态函数有两个参数else if(mf_t_e=="trapmf")M=4; //梯形函数有四个参数j=0;for(int i=0;i<N;i++){u_de[i]=trimf(de,de_mf_paras[i*M],de_mf_paras[i*M+1],de_mf_paras[i*M+2]);//de模糊化,计算它的隶属度if(u_de[i]!=0)u_de_index[j++]=i; //存储被激活的模糊子集的下标,可以减小计算量}for(;j<3;j++)u_de_index[j]=0;float den=0,num=0;for(int m=0;m<3;m++)for(int n=0;n<3;n++){num+=u_e[u_e_index[m]]*u_de[u_de_index[n]]*rule[u_e_index[m]][u_de_index[n]];den+=u_e[u_e_index[m]]*u_de[u_de_index[n]];}u=num/den;u=Ku*u;if(u>=umax) u=umax;else if(u<=-umax) u=-umax;e_pre=e;return u;
}
void Fuzzy_controller::showMf(const string & type,float *mf_paras)
{int tab;if(type=="trimf")tab=2;else if(type=="gaussmf")tab==1;else if(type=="trapmf")tab=3;cout<<"函数类型:"<<mf_t_e<<endl;cout<<"函数参数列表:"<<endl;float *p=mf_paras;for(int i=0;i<N*(tab+1);i++){cout.width(3);cout<<p[i]<<" ";if(i%3==tab)cout<<endl;}
}
void Fuzzy_controller::showInfo()
{cout<<"Info of this fuzzy controller is as following:"<<endl;cout<<"基本论域e:["<<-emax<<","<<emax<<"]"<<endl;cout<<"基本论域de:["<<-demax<<","<<demax<<"]"<<endl;cout<<"基本论域u:["<<-umax<<","<<umax<<"]"<<endl;cout<<"误差e的模糊隶属度函数参数:"<<endl;showMf(mf_t_e,e_mf_paras);cout<<"误差变化率de的模糊隶属度函数参数:"<<endl;showMf(mf_t_de,de_mf_paras);cout<<"输出u的模糊隶属度函数参数:"<<endl;showMf(mf_t_u,u_mf_paras);cout<<"模糊规则表:"<<endl;for(int i=0;i<N;i++){for(int j=0;j<N;j++){cout.width(3);cout<<rule[i][j]<<" ";}cout<<endl;}cout<<endl;cout<<"误差的量化比例因子Ke="<<Ke<<endl;cout<<"误差变化率的量化比例因子Kde="<<Kde<<endl;cout<<"输出的量化比例因子Ku="<<Ku<<endl;cout<<"设定目标target="<<target<<endl;cout<<"误差e="<<e<<endl;cout<<endl;
}
此模糊控制的类,允许用户使用不同的模糊隶属度函数,如三角型,正态分布型和梯形。但是需要相应的给出适当的函数参数。用户可以修改模糊控制规则表,以提高模糊控制器的性能。但是用户需要首先明确误差e,误差变化率de和输出u的最大范围,因为这里需要依据他们来确定量化因子和缩放因子,如果给出的范围不合适,则很难达到理想的控制效果。
下面是一个测试的例子,仅供参考:
#include<iostream>
#include”fuzzy_controller.h”
#define NB -3
#define NM -2
#define NS -1
#define ZO 0
#define PS 1
#define PM 2
#define PB 3
int main()
{float target=600;
float actual=0;
float u=0;
int ruleMatrix[7][7]={{NB,NB,NM,NM,NS,ZO,ZO},
{NB,NB,NM,NS,NS,ZO,PS},
{NM,NM,NM,NS,ZO,PS,PS},
{NM,NM,NS,ZO,PS,PM,PM},
{NS,NS,ZO,PS,PS,PM,PM},
{NS,ZO,PS,PM,PM,PM,PB},
{ZO,ZO,PM,PM,PM,PB,PB}};//模糊规则表
float e_mf_paras[21]={-3,-3,-2,-3,-2,-1,-2,-1,0,-1,0,1,0,1,2,1,2,3,2,3,3};//误差e的隶属度函数参数,这里隶属度函数为三角型,所以3个数据为一组,-3,-3,-2代表第一个只有一半
float de_mf_paras[21]={-3,-3,-2,-3,-2,-1,-2,-1,0,-1,0,1,0,1,2,1,2,3,2,3,3};//误差变化率de的模糊隶属度函数参数
float u_mf_paras[21]={-3,-3,-2,-3,-2,-1,-2,-1,0,-1,0,1,0,1,2,1,2,3,2,3,3};//输出量u的隶属度函数参数
Fuzzy_controller fuzzy(1000,650,500);//控制器初始化,设定误差,误差变化率,输出的最大值
fuzzy.setMf(“trimf”,e_mf_paras,”trimf”,de_mf_paras,”trimf”,u_mf_paras);//设定模糊隶属度函数
fuzzy.setRule(ruleMatrix);//设定模糊规则
cout<<”num target actual“<<endl;
for(int i=0;i<100;i++)
{u=fuzzy.realize(target,actual);
actual+=u;
cout<<i<<” “<<target<<” “<<actual<<endl;
}
fuzzy.showInfo();
system(“pause“);
return 0;
}
运行结果:
这里设定的目标值为600,可见,控制器在运行到9次时就稳定在了600,控制效果比较好。
代码已上传至我的github仓库,有兴趣的可以下载看看
https://github.com/shuoyueqishi/fuzzy-controller
下面是使用VM的模糊控制仿真结果
参考链接
https://blog.csdn.net/cyb519/article/details/77993834
模糊控制算法的C++实现相关推荐
- 【原创】MATLAB模糊控制算法Fuzzy Control
各种模糊控制算法案例word+程序+建模过程 Fuzzy controller 自动控制理论 控制理论与应用 基于MATLAB /Simulink搭建驾驶员制动意图识别模型,基于踏板位移和踏板速度,利 ...
- 基于模糊控制算法的快速反射镜 系统扰动抑制
1.内容简介 略 484-可以交流.咨询.答疑 2.内容说明 快速反射镜是光学系统中光源与接收器之间控制光束传播方向的一种精密光学仪器,是复合轴系统精跟踪部分的重要组成器件.快速反射镜凭借其结构紧凑. ...
- 计算机控制技术答案王书峰,模糊控制算法研究(16页)-原创力文档
. . <智能控制> 课程设计报告 专 业: 自动化 班 级: 学号: 学生姓名: 时 间:13年12月30日-13年1月3日 ―――――――以下指导教师填写――――― 分项成绩:出勤 设 ...
- 计算机控制技术答案王书峰,《模糊控制算法研究》(19页)-原创力文档
<智能控制> 课程设计报告 专 业: 自动化 班 级: 学号: 学生姓名: 时 间:13年12月30日-13年1月3日 ―――――――以下指导教师填写――――― 分项成绩:出勤 设计报告 ...
- 模糊控制算法详细讲解
双输入单输出模糊控制器详细设计流程 一.模糊语言确定及等级划分 如表1是模糊语言的确定,认为确定 表1 模糊语言表 人类模糊语言 负大 负中 负小 负零 正零 正小 正中 正大 符号 NL NM NS ...
- 车辆换道决策的模糊控制算法实例
目录 一.模糊控制在换道决策应用上的概念介绍 1.1 模糊化 1.2 建立模糊规则 1.3 解模糊 二.Matlab建立模糊逻辑系统 2.1 Matlab模糊逻辑工具箱 2.2 建立模糊系统的步骤 2 ...
- fcm模糊聚类matlab实例_模糊控制
1.模糊控制的基本原理 模糊控制是以模糊集理论.模糊语言变量和模糊逻辑推理为基础的一种智能控制方法,它是从行为上模仿人的模糊推理和决策过程的一种智能控制方法.该方法首先将操作人员或专家经验编成模糊规则 ...
- 温控中使用PID控制算法
本文主要介绍各种PID控制算法的调节器在温度控制中控制特性.功能及主要应用场合,对大家合理选用用于温度控制提供方向. 对于温度控制算法包括常规PID.模糊控制.神经网络.Fuzzy_PID.神经网络P ...
- T-S型模糊算法简述及FPGA的实现
目录 0 引言 1 将清晰的数据模糊化 2.模糊推理 2.1模糊命题 2.2T-S模糊推理 3.将模糊的数据清晰化 4.使用模糊算法逼近一阶线性定常系统在MATLAB中实现 5.在FPGA中实现模糊算 ...
- 【Python】近似熵,样本熵,模糊熵计算高效版
文章目录 前言 整体思路 1 近似熵(Approximate Entropy, ApEn) 1.1 理论基础 1.2 python第三方库实现 1.3 基于多线程numpy矩阵运算实现 2 样本熵 ( ...
最新文章
- mysql 查询不使用索引_简单的mySQL查询不使用索引
- dw上按钮事件 pb_「React TS3 专题」使用 TS 的方式在类组件里定义事件
- 查询表授权给谁了_SQL Server 全局临时表竞争条件漏洞利用
- MySQLi学习笔记 :一 1. 数据库的基本概念 2. MySQL数据库软件 	 安装-- 卸载--. 配置 3. SQL
- Coinbase在2020年下半年共收到执法机构2313次信息申请
- c语言按键实现跳转程序,C语言中的跳转语句
- 数值溢出(arithmetic overflow)问题与解决方案
- 普中28335开发攻略_DSP28335汇编教程
- 一些常见监控服务如Nagios、Cacti和Zabbix的搭建
- 软件开发模式之敏捷开发(scrum)
- WiFi 2.4G和5G信道分布说明(认证相关)
- android 截图工具 mac,在Mac上截屏的三种方法 | MOS86
- 什么是京东自营商品?京东自营是什么意思?京东自营?
- 2021-2027全球与中国低代码业务流程管理软件市场现状及未来发展趋势
- 量化指标公式源码_量化指标副图指标 源码 通达信 贴图 无未来
- DP4344音频转换芯片ACD/DAC完全兼容CS4344音频解码
- 黑客宣称可以越狱苹果T2安全芯片
- SQLPrompt v7.2
- 网络协议(二) Socket
- Unity实现多屏显示