模糊控制器与自适应模糊控制设计
题一:已知某被控对象的传递函数为:
(1) 采用二维PD模糊控制器,输入变量 和 ,输出变量为 ,其模糊集论域均为[-5,5],语言变量取值[NL,NM,NS,ZO,PS,PM,PL],隶属函数为对称三角形;规则前件及蕴涵均采用“取小”运算,采用COG反模糊化方法。用Simulink建立单位反馈仿真系统,适当调整模糊控制器的增益系数 , 及 ,求出系统的阶跃响应曲线;
(2) 已知条件同条件(1),求系统单位斜坡输入时的系统响应曲线,分析系统响应曲线,分析系统响应曲线是否有静态偏差存在,为什么?
(3) 已知条件同条件(1),针对单位斜坡输入,要求系统无静态偏差,该怎样设计模糊控制器?设计相应的模糊控制器并进行系统仿真。
解:
(1):建立系统Simulink模型及单位阶跃响应曲线:
图1 模糊规则表
图2 系统Simulink模型
图3 不同参数下的阶跃响应曲线
(2) 单位斜坡输入下的系统响应曲线
图4 斜坡输入下不同参数系统响应
结论:综合图3和图4可以看出,误差量化因子能够对系统的快速响应特性和超调量起到很好的控制作用,而误差变化率因子对系统的动态特性起到很好的调节作用,同时系统均存在稳态误差,所以整体上模糊控制器的作用类似与PD控制器。
(3):加入积分环节
图5 Simulink模型
图6 斜坡响应输出
结论:将积分因子加入模糊控制器后可以看出系统的稳态误差得到消除,整体上类似于PID控制器。
题二:设被控对象的传递函数为
式中 。参考模型为一阶系统。系统参考输入为 。
(1) 针对 设计一个直接模糊控制器(非自适应),使得对象的输出尽可能接近参考模型的性能指标。模糊控制器为二维模糊控制器,其输入变量为偏差 , 为系统参考输入, 为被控对象输出;偏差变化 (用一阶后向差分近似)。
(2) 针对 设计模糊模型参考学习自适应控制系统,使得对象输出跟踪参考模型输出并尽可能地靠近它。将(1)中所设计的模糊控制器作为初始模糊控制器并为FMRLC(模糊模型参考学习控制)所调整,进行系统仿真。
解:
(1).模糊控制器设计:
(a) 设计步骤:输入变量e 和ec ,输出变量为 u,其模糊集论域分别为[-8,8],[-1.6,1.6],[-4,4],语言变量均为[NL,NM,NS,ZO,PS,PM,PL],隶属函数为对称三角形;规则前件及蕴涵均采用“取小”运算,采用COG反模糊化方法,模糊规则采用与图1相同。
(b) Simulink模型:
图7 Simulink模型
仿真结果:
图8 模糊控制跟踪曲线
结论:从结果可以看出单纯的模糊控制器输出存在很严重的相位滞后,控制系统的响应跟踪较差。
(2) 模糊模型参考学习自适应(FMRLC)控制系统:
设计方法1:根据模糊逆模型实际输出得到控制量校正kp,对原模糊控制器的输出隶属度函数位置进行平移,得到系统的实时响应曲线和误差变化。图9,10,11,分别为系统Simulink模型,系统实时跟踪响应和系统误差响应曲线。
主要设计步骤为(核心代码说明见附录A.1):
(a) 根据输入变量e和ec确定各自对应的模糊论域等级;
(b) 查询规则表中由e和ec**的规则,并获取在规则**下输出u的论域等级;
(c) 根据获取的逆模型输出校正量p,对**输出下的u的隶属度函数进行平移,当p为正时向右平移,当p为负时向左平移,平移量均为p;
图9 模糊参考模型自适应控制Simulink图
图10 系统跟踪响应
图11 系统跟踪误差
可以看出,通过对模糊控制器规则的实时修改可以起到稳定跟踪的效果,系统的响应误差在0.004附近。
设计方法2:在方法1的基础进一步对**规则的权重进行修改,修改的原则在于,当模糊逆模型控制输出量p较大时,其**规则的权重应该相应的增大以保证增大系统输出,减小跟踪误差,反之亦然。
主要步骤(核心代码见附录A.2):
(a) 根据输入变量e和ec确定各自对应的模糊论域等级;
(b) 查询规则表中由e和ec**的规则,并获取在规则**下输出u的论域等级;
(c) 根据获取的逆模型输出校正量p,对**输出下的u的隶属度函数进行平移,当p为正时向右平移,当p为负时向左平移,平移量均为p;
(d) 将**的规则权重在原来的基础上增加p;
图12 增加规则权重修改的模糊控制器Simulink模型
图13 系统跟踪响应
图14 系统跟踪误差
图15 增加规则权重修改与规则修改误差跟踪曲线对比
可以看出,在进一步引入权重修改后,其系统响应更加平滑,系统在波峰波谷处的跟踪效果有所提高。
附录
A.1:
function u = adaptive_fuzzy(p, e, ec)
coder.extrinsic('readfis');
coder.extrinsic('writefis');
coder.extrinsic('evalfis');
coder.extrinsic('newfis');
coder.extrinsic('addvar');
coder.extrinsic('addmf');
coder.extrinsic('addrule');
coder.extrinsic('setfis');
a = newfis('adapfuzzy');
%确定e和ec的模糊论域等级
dist_e = fix((e+1)*3);%截尾取整
degleft_e = 1 + dist_e;
degright_e = degleft_e + 1;
dist_ec = fix((ec+1)*3);%截尾取整
degleft_ec = 1 + dist_ec;
degright_ec = degleft_ec +1;
%规则列表
rulelist = [1 1 1 1 1
1 2 1 1 1
1 3 1 1 1
1 4 1 1 1
1 5 2 1 1
1 6 3 1 1
1 7 4 1 1
2 1 1 1 1
2 2 1 1 1
2 3 2 1 1
2 4 2 1 1
2 5 3 1 1
2 6 4 1 1
2 7 4 1 1
3 1 1 1 1
3 2 2 1 1
3 3 2 1 1
3 4 3 1 1
3 5 4 1 1
3 6 4 1 1
3 7 3 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 4 1 1
5 3 4 1 1
5 4 5 1 1
5 5 6 1 1
5 6 6 1 1
5 7 7 1 1
6 1 4 1 1
6 2 4 1 1
6 3 5 1 1
6 4 6 1 1
6 5 6 1 1
6 6 7 1 1
6 7 7 1 1
7 1 4 1 1
7 2 5 1 1
7 3 6 1 1
7 4 7 1 1
7 5 7 1 1
7 6 7 1 1
7 7 7 1 1];
u_index = zeros(1,4);
index = 1;
%根据**的规则获取对应输出u的论域等级
for i=degleft_e:degright_e
for j=degleft_ec:degright_ec
ifrulelist(7*(i-1)+j,3)==u_index(1)||rulelist(7*(i-1)+j,3)==u_index(2)||rulelist(7*(i-1)+j,3)==u_index(3)||rulelist(7*(i-1)+j,3)==u_index(4)
continue;
else
u_index(index)=rulelist(7*(i-1)+j,3);
index=index+1;
end
end
end
%设置输入e的隶属度函数
a = addvar(a,'input','e',[-1,1]);
for i=1:7
a = addmf(a,'input',1,i,'trimf',[-4/3+(i-1)/3,-1+(i-1)/3,-2/3+(i-1)/3]);
end
%设置输入ec的隶属度函数
a = addvar(a,'input','ec',[-1,1]);
for i=1:7
a = addmf(a,'input',2,i,'trimf',[-4/3+(i-1)/3,-1+(i-1)/3,-2/3+(i-1)/3]);
end
%根据控制量p设置输出隶属度函数
a = addvar(a,'output','u',[-1,1]);
for i=1:7
%对相应的隶属度函数进行平移
ifi==u_index(1)||i==u_index(2)||i==u_index(3)||i==u_index(4)
a = addmf(a,'output',1,i,'trimf',[-4/3+(i-1)/3+p,-1+(i-1)/3+p,-2/3+(i-1)/3+p]);
else
a = addmf(a,'output',1,i,'trimf',[-4/3+(i-1)/3,-1+(i-1)/3,-2/3+(i-1)/3]);
end
end
a = addrule(a,rulelist);
adapfuzzy = setfis(a,'DefuzzMethod','centroid');%面积重心法去模糊化·¨
u = 0.0;
u =evalfis([e,ec],adapfuzzy);
A.2 在A.1的基础上增添以下代码
%根据修改**规则权重
for i=degleft_e:degright_e
for j=degleft_ec:degright_ec
rulelist(7*(i-1)+j,4)=rulelist(7*(i-1)+j,4) + p;
end
end