系列文章目录
模糊控制——(一)理论基础
模糊控制——(二)设计流程
模糊控制——(三)模糊洗衣机
模糊控制——(四)模糊自适应整定PID控制
模糊控制——(五)Sugeno模糊模型
关键字:模糊控制器;MATLAB;模糊化;解模糊;Simulink
文章目录
前言
在之前的博文中博主已经介绍了模糊控制的理论基础,本文将在此基础上介绍如何利用简单的模糊控制设计系统控制器,还没看的小伙伴可以通过系列文章目录连接转跳。
提示:想详细了解的小伙伴可以参考刘金琨老师的《智能控制 -第4版》的第4.1~4.3节(需要电子版请私戳)
一、模糊控制的基本原理
模糊控制(Fuzzy Control)是以模糊集理论 、模糊语言变量和模糊逻辑推理为基础的一种智能控制方法,它从行为上模仿人的模糊推理和决策过程。模糊控制的基本原理框图如下:
其中 模糊控制器是一个模糊控制系统的核心,其组成图如下:

一个模糊控制系统的性能优劣,主要取决于模糊控制的结构、所采用的模糊规则、合成推理算法、模糊决策等因素。
1.模糊化接口(Fuzzy Interface)
在传统的自动控制原理中,控制器的输入是设定量与反馈量的误差量
e
e
e,输出是控制量
u
u
u,在模糊控制中输入则是模糊误差量
e
e
e与模糊控制量
u
u
u,但是实际上检测的是某一个确定的值,这就需要一个模糊化接口将一个确定的数值进行模糊化,用于推理机进行推理。
对于模糊输入变量
e
e
e,模糊子集通常可以划分为:
- e e e={负大, 负小, 零, 正小, 正大}={NB, NS, ZO, PS, PB}
- e e e={负大, 负中, 负小, 零, 正小, 正中, 正大}={NB, NM, NS, ZO, PS, PM, PB}
- e e e={负大, 负中, 负小, 零负, 零正, 正小, 正中, 正大}={NB, NM, NS, NZ, PZ, PS, PM, PB}
2.知识库(Knowledge Base KB)
知识库分为两部分构成:
- 数据库:对于离散的论域存放输入、输出变量的全部模糊子集的隶属度向量值,对于连续的论域则存放隶属度函数。
- 规则库:存放全部模糊控制的规则,对于误差
E
E
E、误差的变化率
E
C
EC
EC控制输出
U
U
U的一组规则示例为:
R 1 : I F E i s N B a n d E C i s N B t h e n U i s P B R 1 : I F E i s N B a n d E C i s N S t h e n U i s P M (1) \begin{align} R_1:IF \quad E \quad is \quad NB \quad and \quad EC \quad is \quad NB \quad then \quad U \quad is \quad PB \\ R_1:IF \quad E \quad is \quad NB \quad and \quad EC \quad is \quad NS \quad then \quad U \quad is \quad PM \end{align} \tag{1} R1:IFEisNBandECisNBthenUisPBR1:IFEisNBandECisNSthenUisPM(1)上述规则其实可以转化为:
I F A a n d B t h e n C (2) IF \quad A \quad and \quad B \quad then \quad C \tag{2} IFAandBthenC(2)在模糊控制——(一)理论基础一文中我们已经对上述模糊语句如何得到模糊关系有了介绍:
R = ( A × B ) T 1 ○ C C = ( A × B ) T 2 ○ R (3) \begin{align} R=\left(A×B\right)^{T_1}○C \\ C=\left(A×B\right)^{T_2}○R \end{align} \tag{3} R=(A×B)T1○CC=(A×B)T2○R(3)规则库的中的规则条数于模糊变量的模糊子集划分有关,划分越细,规则的条数越多,但并不代表规则库的准确度越高,规则库的“准确性”还与专家知识的准确度有关。
3.推理机
推理机中将进行从输入到输出的模糊推理,根据输入模糊量,由模糊控制规则完成模糊推理来求解模糊关系方程,并获得模糊控制量的功能部分。考虑到推理时间,常用比较基本的Zadeh近似推理,该推理包含正向推理与逆向推理两类,其中正向推理常被用于模糊控制中,而逆向推理一般哟用于知识工程学领域的专家系统中。
4.解模糊口(DeFuzzy-Interface)
上述从模糊化接口到推理机中,已经将输入数值转化为输入模糊量,输入模糊量通过推理机转为输出模糊量,但是输出的模糊两不能直接用于被控对象,必须通过解模糊口将模糊量转化为确定量,从而实现控制。
二、模糊控制器的设计
1.设计步骤
模糊控制器中,以模糊控制规则转化为一个控制表写入程序为设计理念的控制器是最基本的形式,下面对这种设计方式进行介绍:
- 确定模糊控制器的结构
模糊控制器的以输入输出的数量为标准可划分为一维模糊控制器、二维模糊控制器和三维模糊控制器:
图2.1 多输入单输出模糊控制器
如图所示,一维模糊控制器的输入往往选择为受控变量和输入给定的偏差 e e e由于仅仅采用偏差值,很难反映过程的动态特性;二维模糊器的两个输入变量基本上都选用受控变量值和输入给定值的偏差 e e e和偏差变化量 e c ec ec,由于两者的结合可以较好的反应动态特性,目前使用广泛;三维模糊控制器的三个输入量分贝为偏差量 e e e、偏差变化量 e c ec ec、偏差变化量的变化率 e c c ecc ecc,此种结构虽然比二维的更能反应系统的动态特性,但是也因为结构复杂推理运算时间长,故排除动态特性要求较高的场合,一般较少选用三维模糊控制器。当然除了多输入单输出的控制器也有多输入多输出的控制器:
图2.2 多输入多输出模糊控制器
当然直接设计一个多变量模糊控制器是十分困难的,可以利用模糊控制器本身的解耦特点,通过模糊关系方程求解,在控制器结构上实现解耦,即将一个多输入、多输出(MIMO)的模糊控制器分解成若干个多输入、单输出(MISO)的模糊控制器。 - 定义输入/输出的模糊集
输入/输出的模糊集在上文的介绍中其实已经出现:{NB, NS, ZO, PS, PB}、{NB, NM, NS, ZO, PS, PM, PB}或{NB, NM, NS, NZ, PZ, PS, PM, PB},也可以转化为数字的形式,以{NB, NM, NS, ZO, PS, PM, PB}举🧉,就可以写为{-3, -2, -1, 0, 1, 2, 3}或者{-4.5, -3, -1, 0, 1, 3, 4.5}当然这些都是我们根据实际情况自己定义的。 - 定义输入/输出隶属度/函数
对于离散的论域我们可以使用隶属度,对于连续的论域使用隶属函数。 - 建立模糊控制规则
- 建立模糊控制表
通过模糊控制语句可以得到模糊控制表:
图2.3 模糊控制表示例 - 模糊推理
- 反模糊化
在Matlab中常用的解模糊方法有:①centroiid,面积重心法;②bisector,面积等分法;③mom,最大隶属度平均法;④som,最大隶属度取小法;⑤lom,最大隶属度取大法。
2.工程环境
以下的案例基于:
- PC操作系统:WIN11
- MATLAB:2019a
3.Matlab仿真
自动控制原理的控制系统流程图告诉我们,整个系统包括控制器、执行机构、被控对象、传感器:
在仿真中我们认为控制器输出直接作用到被控对象,传感器也直接传递输出,故系统简化为两部分——模糊控制器与被控对象:
控制表采用如图2.3,控制规则为49条。设定误差 e e e、误差变化率 e c ec ec的范围 [ − 3.0 , 3.0 ] [-3.0, 3.0] [−3.0,3.0],控制输入 u u u的范围为 [ − 4.5 , 4.5 ] [-4.5, 4.5] [−4.5,4.5],则在MATLAB中实现的总体步骤有六步:
- 创建模糊系统接口(fis——fuzzy interface system)
- 创建输入与输出模糊变量并设置隶属度函数
- 创建并添加模糊规则
- 保存当前模糊文件
- 读取模糊文件并利用模糊工具箱仿真
- 绘图
实际代码如下:
% Fuzzy Control Design
% 在使用chap4.3sim之前首先运行本程序
clc;
clear;
close all;
% 创建模糊系统接口
% Use a mamfis object to represent a Mamdani fuzzy inference system
% newfis指令未来将被移除 详情通过help newfis参见帮助页
% a=newfis('fuzzf');
% a=mamfis('Name','fuzzf');
a=mamfis();
a.Name='fuzzf';
%%
% 创建输入与输出模糊变量并设置隶属度函数
% 创建第一个输入模糊变量与隶属度函数
% addvar未来将被移除 详情通过help addvar参见帮助页
% a=addvar(a,'input','e',[-0.3,0.3]);
a.Input(1).Name='e';
a.Input(1).Range=[-0.3,0.3];
a=addMF(a,'e','zmf' ,[-0.3,-0.1] ,'Name','NB');
a=addMF(a,'e','trimf',[-0.3,-0.2,0] ,'Name','NM');
a=addMF(a,'e','trimf',[-0.3,-0.1,0.1],'Name','NS');
a=addMF(a,'e','trimf',[-0.2,0,0.2] ,'Name','Z' );
a=addMF(a,'e','trimf',[-0.1,0.1,0.3] ,'Name','PS');
a=addMF(a,'e','trimf',[0,0.2,0.3] ,'Name','PM');
a=addMF(a,'e','smf' ,[0.1,0.3] ,'Name','PB');
plotmf(a,"input",1);
% 创建第二个输入模糊变量与隶属度函数
% a=addvar(a,'input','ec',[-0.3,0.3]);
a.Input(2).Name='ec';
a.Input(2).Range=[-0.3,0.3];
a=addMF(a,'ec','zmf' ,[-0.3,-0.1] ,'Name','NB');
a=addMF(a,'ec','trimf',[-0.3,-0.2,0] ,'Name','NM');
a=addMF(a,'ec','trimf',[-0.3,-0.1,0.1],'Name','NS');
a=addMF(a,'ec','trimf',[-0.2,0,0.2] ,'Name','Z' );
a=addMF(a,'ec','trimf',[-0.1,0.1,0.3] ,'Name','PS');
a=addMF(a,'ec','trimf',[0,0.2,0.3] ,'Name','PM');
a=addMF(a,'ec','smf' ,[0.1,0.3] ,'Name','PB');
plotmf(a,"input",2);
% 创建第一个输出模糊变量与隶属度函数
% a=addvar(a,'output','u',[-30,30]);
a.Output(1).Name='u';
a.Output(1).Range=[-30,30];
a=addMF(a,'u','zmf' ,[-30,-30] ,'Name','NB');
a=addMF(a,'u','trimf',[-30,-20,0] ,'Name','NM');
a=addMF(a,'u','trimf',[-30,-10,10] ,'Name','NS');
a=addMF(a,'u','trimf',[-20,0,20] ,'Name','Z' );
a=addMF(a,'u','trimf',[-10,10,30] ,'Name','PS');
a=addMF(a,'u','trimf',[0,20,30] ,'Name','PM');
a=addMF(a,'u','smf' ,[10,30] ,'Name','PB');
plotmf(a,"output",1);
%%
% 创建并添加模糊规则
rulelist=[1 1 1 1 1;
1 2 1 1 1;
1 3 2 1 1;
1 4 2 1 1;
1 5 3 1 1;
1 6 3 1 1;
1 7 4 1 1;
2 1 1 1 1;
2 2 2 1 1;
2 3 2 1 1;
2 4 3 1 1;
2 5 3 1 1;
2 6 4 1 1;
2 7 5 1 1;
3 1 2 1 1;
3 2 2 1 1;
3 3 3 1 1;
3 4 3 1 1;
3 5 4 1 1;
3 6 5 1 1;
3 7 5 1 1;
4 1 2 1 1;
4 2 3 1 1;
4 3 3 1 1;
4 4 4 1 1;
4 5 5 1 1;
4 6 5 1 1;
4 7 6 1 1;
5 1 3 1 1;
5 2 3 1 1;
5 3 4 1 1;
5 4 5 1 1;
5 5 5 1 1;
5 6 6 1 1;
5 7 6 1 1;
6 1 3 1 1;
6 2 4 1 1;
6 3 5 1 1;
6 4 5 1 1;
6 5 6 1 1;
6 6 6 1 1;
6 7 7 1 1;
7 1 4 1 1;
7 2 5 1 1;
7 3 5 1 1;
7 4 6 1 1;
7 5 6 1 1;
7 6 7 1 1;
7 7 7 1 1;];
a=addRule(a,rulelist); % 添加模糊规则
showrule(a) % 显示模糊规则
%%
% 保存当前模糊文件
% setfis指令未来将被移除,可用FIS对象的属性代替
% al=setfis(a,'DefuzzMethod','mom');
a.defuzzification='mom';
writeFIS(a,'fuzzf');
%%
% 用模糊工具箱进行仿真
a_new=readfis('fuzzf'); %读取模糊文件
disp('---------------------------------------------------------------');
disp('fuzzy controller table:e=[-3,+3], ec=[-3,+3]');
disp('---------------------------------------------------------------');
Ulist=zeros(7,7);
e=zeros(1,7);
ec=zeros(1,7);
for i=1:1:7
for j=1:1:7
e(i)=i-4;
ec(j)=j-4;
Ulist(i,j)=evalfis([e(i),ec(j)],a_new);
end
end
Ulist=ceil(Ulist);
%%
%绘图
figure(1);
plotfis(a_new);
figure(2);
plotmf(a,'input',1);
figure(3);
plotmf(a,'input',2);
figure(4);
plotmf(a,'output',1);
% figure(5);
% plot(out.simout(:,1));
% hold on;
% plot(out.simout(:,2));
% legend('R','Y');
通过代码得到的结果如下:
从图像上可以大概观察到控制器使用的是mamfis模糊接口,也可观察到两个模糊输入与一个模糊输出的隶属函数。
在m文件中定义好模糊控制器后,针对一个传递函数:
400
s
2
+
500
s
\frac{400}{s^2+500s}
s2+500s400进行仿真实验:
在Simulink的仿真中有几点需要注意:
-
sin函数的表示
图2.10 Simulink中的Sine Wave块
决定三角函数的公式如下:
y = a m p l i t u d e × sin ( f r e q u e n c y × t i m e + p h a s e ) + b i a s y=amplitude×\sin{\left( frequency×time+phase \right)}+bias y=amplitude×sin(frequency×time+phase)+bias上图中的 S a m p l e t i m e Sample time Sampletime可以设定采样时间,当 S a m p l e t i m e = 0 Sample time=0 Sampletime=0时使用连续时间输出,当 S a m p l e t i m e > 0 Sample time>0 Sampletime>0时使用离散时间输出,连续时间与离散时间各有利弊,MATLAB的帮助文档中做了详细的介绍,这里就不宰赘述。 -
仿真过程中的非有限值问题
在运行程序后可能有小伙伴会出现报错:图2.11 非有限值报错
上述报文中的大意是“在运行中一个错误导致了仿真的停止,该错误是由于chap4_3sim仿真文件中Transfer Fcn块在4.20时刻的状态1的微分为非有限数值。仿真将因此停止,在方程的解中可能存在一个奇点。如果,并非上述原因,可以尝试减小仿真的步长来消除此错误"。如果我们观察仿真器设置的仿真时间:
图2.12 仿真时间的设置
其中我们看一看到这里设置的仿真时间类型为”Variable-step“可以翻译为”变步长“,博主在这里将变步长的模式改为了固定步长:
图2.13 固定步长 0.01
这里设定固定步长为0.01,但是仿真后发现还是出现了错误代码如下:图2.14 非有限值报错
将固定步长改为0.05:
图2.15 固定步长 0.005
仿真后将不会报错:
图2.16 仿真结果 -
将数据输出到工作空间
如果想要以数组的形式输出数据到工作空间,记得调整保存类型:图2.17 To Workspace设置 -
设置模糊控制器模块参数
图2.18 Fuzzy Logic Controller with Ruleviewer设置
FIS sructure参数是之前通过m文件保存到工作区的模糊接口系统变量的名称:
图2.19 通过m文件的程序将模糊接口系统保存到工作区
在运行上述的Simulink仿真过程中可以通过规则观测器实时观察:
在Simulink运行完成后会在MATLAB的工作区中生成我们通过simout块导出的数据:
通过下述代码绘制图像(其实就是之前代码注释的部分):
figure(5);
plot(out.simout(:,1));
hold on;
plot(out.simout(:,2));
legend('R','Y');
得到结果:
我们看到其实模糊控制器的仿真效果不是很理想,实际上是因为我们在仿真步长中设置了固定步长0.005:
如果我们将步长逐步调小:
可以看到随着步长的缩小,仿真结果也越来越精确,但是需要注意,仿真步长缩小意味着计算步骤的增多,也会增加仿真时间。
注意
有小伙伴说把注释的代码取消注释后没有绘图成功,在这里多做一点说明为什么出现这样的原因。首先是我自己猜测会有小伙伴在完成图2.1的步骤后,直接取消了程序的注释,并点击了运行,我这里来模拟一下:
①运行slx文件后:
可以看到已经将仿真程序中的数据导入工作区,而且画图代码称注释状。
②取消注释代码,并点击运行
③图5的图像界面没有正常显示
上述就是我推测的失败操作过程。具体原因还要从m文件的程序分析:
这三行代码会清除工作区,也就是说如果运行全部程序,那么在仿真程序中导出的数据也会被清除:
针对上述问题有两个解决办法:
①在仿真程序的数据导入到工作区后不要点击“运行”,而是“运行节”:
这样只运行绘图程序而不会运行前面清除工作区的程序,即可正常绘图。
②创建一个全新的myplot.m绘图程序:
总结
以上简单介绍了模糊控制器的结构与设计步骤,并给出了一个简单的🧉,下一篇博主将简单介绍一个模糊洗衣机的🧉咕咕咕。
参考文献
[1]刘金琨.智能控制.第4版[M].电子工业出版社,2017.