MATLAB模糊PID实现(全流程详细报告+附实现代码)
写在前面
本文是一篇完整的报告,在写的过程中博主也查阅了一些资料,感谢各位大神的博客,详细理论可以参考教材,博主用的是刘金锟老师的智能控制教材,第6章给出了一些参考资料,个人认为非常有用。
第1章 问题的提出
当今的自动控制技术都是基于反馈的概念。反馈理论的要素包括三个部分:测量、比较和执行。测量关心的变量,与期望值相比较,用这个误差纠正调节控制系统的响应。
它由于用途广泛、使用灵活,已有系列化产品,使用中只需设定三个参数(Kp, Ti和Td)即可。在很多情况下,并不一定需要全部三个单元,可以取其中的一到两个单元,但比例控制单元是必不可少的。
首先,PID应用范围广。虽然很多工业过程 是非线性或时变的,但通过对其简化可以变成基本线性和动态特性不随时间变化的系统,这样PID就可控制了。
其次,PID参数较易整定。也就是,PID参数Kp,Ti和Td可以根据过程的动态特性及时整定。如果过程的动态特性变化,例如可能由负载的变化引起系统动态特性变化,PID参数就可以重新整定。
第三,PID控制器在实践中也不断的得到改进,下面两个改进的例子。
在工厂,总是能看到许多回路都处于手动状态,原因是很难让过程在“自动”模式下平稳工作。由于这些不足,采用PID的工业控制系统总是受产品质量、安全、产量和能源浪费等问题的困扰。PID参数自整定就是为了处理PID参数整定这个问题而产生的。现在,自动整定或自身整定的PID控制器已是商业单回路控制器和分散控制系统的一个标准。
在一些情况下针对特定的系统设计的PID控制器控制得很好,但它们仍存在一些问题需要解决:
如果自整定要以模型为基础,为了PID参数的重新整定在线寻找和保持好过程模型是较难的。闭环工作时,要求在过程中插入一个测试信号。这个方法会引起扰动,所以基于模型的PID参数自整定在工业应用不是太好。
如果自整定是基于控制律的,经常难以把由负载干扰引起的影响和过程动态特性变化引起的影响区分开来,因此受到干扰的影响控制器会产生超调,产生一个不必要的自适应转换。另外,由于基于控制律的系统没有成熟的稳定性分析方法,参数整定可靠与否存在很多问题。
因此,许多自身整定参数的PID控制器经常工作在自动整定模式而不是连续的自身整定模式。自动整定通常是指根据开环状态确定的简单过程模型自动计算PID参数。
PID在控制非线性、时变、耦合及参数和结构不确定的复杂过程时,工作地不是太好。最重要的是,如果PID控制器不能控制复杂过程,无论怎么调参数都没用。
虽然有这些缺点,PID控制器是最简单的有时却是最好的控制器
模糊控制是利用模糊数学的基本思想和理论的控制方法。在传统的控制领域里,控制系统动态模式的精确与否是影响控制优劣的最主要关键,系统动态的信息越详细,则越能达到精确控制的目的。然而,对于复杂的系统,由于变量太多,往往难以正确的描述系统的动态,于是工程师便利用各种方法来简化系统动态,以达成控制的目的,但却不尽理想。换言之,传统的控制理论对于明确系统有强而有力的控制能力,但对于过于复杂或难以精确描述的系统,则显得无能为力了。因此便尝试着以模糊数学来处理这些控制问题。模糊控制在智能控制领域由于理论研究比较成熟、实现相对比较简单、适应面宽而得到了广泛的应用。不论是对复杂的水泥回砖窑的控制,还是在智能化家用电器中的应用,模糊控制都充当着重要的角色。
本文针对固定系统,分别利用传统PID控制方法和模糊控制方法对其进行仿真控制,并对两种控制的控制结果进行了比较,通过比较表明了模糊控制相比传统的PID控制改善控制系统的动态性能。
第2章 PID控制器的设计
2.1 PID控制原理图
PID控制其结构框图如下图所示:
2.2 PID控制器传递函数的一般表达式
PID控制器传递函数的一般表达形式为:
其中kp为比例增益;ki为积分增益;kd为微分增益。
调整PID参数,以满足系统要求,从而使被控对象有更优良的动态响应和静态响应。
比例环节:根据偏差量成比例的调节系统控制量,以此产生控制作用,减少偏差。比例系数的作用是增加系统响应的速度,比例系数越大,系统响应越快,但系统容易产生超调,比例系数过小,会影响系统调节的精度,系统响应时间变长,系统的动态响应变差。
积分环节:用于消除静差,提高系统的无差度,积分时间常数决定着积分环节作用的强度,但是积分作用过强的话会影响系统的稳定性。
微分环节:根据偏差量的变化趋势来调节系统控制量,在偏差信号发生较大变化之前,提早引入一个校正信号,起到加快系统动作速度,减少调节时间的作用,调节微分参数需要注意微分作用太强可能会引起系统振荡。
第3章 模糊控制器的设计
3.1 模糊控制原理图
模糊控制器结构框图如下图所示:
模糊控制器结构如下图:
3.2 模糊控制器传递函数一般表达形式
一个典型工业过程通常可以等效为二阶系统加上一个非线性环节(如纯滞后),给出如下经典控制对象传递函数的一般形式:
其中模糊控制规则是模糊控制器的核心,是设计控制系统的主要内容。
一个基本模糊控制器主要有三个功能:
(1)模糊化:把精确量(如偏差e和偏差变化ec)转化为相应的模糊量(E、EC);
(2)模糊推理:按总结的语言规则(模糊控制规划表)进行模糊推理;
(3)模糊判决:把推理结果(U)从模糊量转化为可以用于实际控制的精确量(u)。
模糊规则是由一系列的模糊条件语句组成的,即由许多模糊蕴含关系构成。这些条件语句是推理的出发点和得到的正确结论的根据和基础。每条模糊条件语句都给出模糊蕴含关系,即一条控制规则。若有n条规则,就把它们表达的n个模糊蕴含关系(i=l,2,⋯,n)做并运算,构成系统总的模糊蕴含关系:
第4章 系统仿真
4.1 经典PID
本文采用的传递函数为:
选用的输入是单位阶跃信号。
首先使用以下语句在MATLAB中输入传递函数:
sys=tf(4.23,[1,1.64,8.46],‘ioDelay’,3); %建立被控对象传递函数
运行结果如图:
采样时间ts=0.1,使用以下语句对传递函数作Z变换:
dsys=c2d(sys,ts,‘z’) %离散化
运行结果如图:
将Z变换转化为差分方程,输出序列y(k), 设置kp=0.36;ki=0.035; kd=0.3结果如下图:
4.2 模糊PID
设计模糊控制器的主要步骤为:
选择偏差e、偏差变化ec的模糊语言变量为e、ec。根据e、ec实际的基本论域,设定e、ec论域都为[-3,3]。
选取E、EC和U的各语言变量值:正大为PB,正中为PM,正小为PS,为零为Z,负小为NS,负中为NM,负大为NB,它们各自在论域上的模糊子集隶属度函数均为三角形。
选择一种模糊判决方法,将控制量由模糊量变为精确量,这个过程叫做“去模糊化”,这里采用的是“重心法”。
对上述传递函数同样进行z变换,转换为差分方程,其中PID参数初值为kp0=0.35; ki0=0.35; kd0=1;语言值的隶属函数选择三角形的隶属度函数如下图所示:
(1)e的隶属度函数:
(2)ec的隶属度函数:
(3)kp的隶属度函数
(4)ki的隶属度函数
(5)kd的隶属度函数
Δkp的控制规则如表1所示:
表1:Δkp模糊规则表:
Δki的控制规则如表2所示:
Δkd的控制规则如表3所示:
将规则输入到编辑器中(如图8所示)一共有7×7=49条规则,输入后可以在变量器中查看对具体输入的模糊推理及输出情况,输入各种不同的数据,查看模糊推理情况及输出数据。也可以用于检查,看自己输入的规则和有没有错误。
编辑器中Rule Viewer
实验得到的结果图形如下所示:
kp变化曲线
ki变化曲线
kd变化曲线
第5章 MATLAB代码实现
经典PID代码
%经典pid,Matlab实现
clear all;
close all;
ts=0.1; %采样时间=0.1s
sys=tf(4.23,[1,1.64,8.46],'ioDelay',3) %建立被控对象传递函数
dsys=c2d(sys,ts,'z') %离散化
[num,den]=tfdata(dsys,'v'); %
e_1=0; %前一时刻的偏差
Ee=0; %累积偏差
%X={0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}
%[u_1,u_2,u_3,u_4,u_5,u_6,u_7,u_8,u_9,u_10,u_11,u_12,u_13,u_14,u_15,u_16,u_17,u_18,u_19,u_20,u_21,u_22,u_23,u_24,u_25,u_26,u_27,u_28,u_29,u_30,u_31,u_32,u_33]=deal(X{:});
%前一时刻的控制量
%y_1=0; y_2=0; %前一时刻的输出
%PID参数
% kp=0.35;
% ki=0.02;
% kd=0.9;
kp=0.36; ki=0.035; kd=0.3
u=zeros(1,1000);
for j=1:32;%差分方程,0时刻前的32个点
u(j)=0.0;
end
%y=zeros(1,2);%预先分配内存
time=zeros(1,1000);%时刻点(设定1000个)
for k=1:1:1000
time(k)=(k)*ts; %时间参数
r(k)=1; %期望值
y(1)=0;y(2)=0;
y(k+2)=-1*den(3)*y(k-2+2)-1*den(2)*y(k-1+2)+num(2)*u(k-31+32)+num(3)*u(k-32+32);%系统响应输出序列
e(k)=r(k)-y(k+2); %误差信号
m=e(k)-e_1;
u(k+32)=kp*e(k)+ki*Ee+kd*m; %系统PID控制器输出序列
Ee=Ee+e(k); %误差的累加和
%前一个的控制器输出值
%y_1=y(k);y_2=y(k-1);
%前一个的系统响应输出值
e_1=e(k); %前一个误差信号的值
end
%(仅绘制过渡过程的曲线,x坐标限制为[0,1])
%p1=plot(time,r,'*');xlim([0,100]);hold on;%指令信号的曲线(即期望输入)
p2=plot(time,y(3:1002),'--');xlim([0,100]);ylim([0,1.2]);grid on;%不含积分分离的PID曲线
hold on;
模糊PID代码
第一个文件,用于制定定模糊规则,文件名"Fuzzyrule"
%第一个文件,用于制定定模糊规则,文件名"Fuzzyrule"
%Fuzzy Tunning PID Control
clear all;
close all;
a=newfis('fuzzpid');
a=addvar(a,'input','e',[-3,3]); %Parameter e
a=addmf(a,'input',1,'NB','zmf',[-3,-1]);
a=addmf(a,'input',1,'NM','trimf',[-3,-2,0]);
a=addmf(a,'input',1,'NS','trimf',[-3,-1,1]);
a=addmf(a,'input',1,'Z','trimf',[-2,0,2]);
a=addmf(a,'input',1,'PS','trimf',[-1,1,3]);
a=addmf(a,'input',1,'PM','trimf',[0,2,3]);
a=addmf(a,'input',1,'PB','smf',[1,3]);
a=addvar(a,'input','ec',[-3,3]); %Parameter ec
a=addmf(a,'input',2,'NB','zmf',[-3,-1]);
a=addmf(a,'input',2,'NM','trimf',[-3,-2,0]);
a=addmf(a,'input',2,'NS','trimf',[-3,-1,1]);
a=addmf(a,'input',2,'Z','trimf',[-2,0,2]);
a=addmf(a,'input',2,'PS','trimf',[-1,1,3]);
a=addmf(a,'input',2,'PM','trimf',[0,2,3]);
a=addmf(a,'input',2,'PB','smf',[1,3]);
a=addvar(a,'output','kp',[-0.3,0.3]); %Parameter kp
a=addmf(a,'output',1,'NB','zmf',[-0.3,-0.1]);
a=addmf(a,'output',1,'NM','trimf',[-0.3,-0.2,0]);
a=addmf(a,'output',1,'NS','trimf',[-0.3,-0.1,0.1]);
a=addmf(a,'output',1,'Z','trimf',[-0.2,0,0.2]);
a=addmf(a,'output',1,'PS','trimf',[-0.1,0.1,0.3]);
a=addmf(a,'output',1,'PM','trimf',[0,0.2,0.3]);
a=addmf(a,'output',1,'PB','smf',[0.1,0.3]);
a=addvar(a,'output','ki',[-0.06,0.06]); %Parameter ki
a=addmf(a,'output',2,'NB','zmf',[-0.06,-0.02]);
a=addmf(a,'output',2,'NM','trimf',[-0.06,-0.04,0]);
a=addmf(a,'output',2,'NS','trimf',[-0.06,-0.02,0.02]);
a=addmf(a,'output',2,'Z','trimf',[-0.04,0,0.04]);
a=addmf(a,'output',2,'PS','trimf',[-0.02,0.02,0.06]);
a=addmf(a,'output',2,'PM','trimf',[0,0.04,0.06]);
a=addmf(a,'output',2,'PB','smf',[0.02,0.06]);
a=addvar(a,'output','kd',[-3,3]); %Parameter kp
a=addmf(a,'output',3,'NB','zmf',[-3,-1]);
a=addmf(a,'output',3,'NM','trimf',[-3,-2,0]);
a=addmf(a,'output',3,'NS','trimf',[-3,-1,1]);
a=addmf(a,'output',3,'Z','trimf',[-2,0,2]);
a=addmf(a,'output',3,'PS','trimf',[-1,1,3]);
a=addmf(a,'output',3,'PM','trimf',[0,2,3]);
a=addmf(a,'output',3,'PB','smf',[1,3]);
rulelist=[1 1 7 1 5 1 1;%前m个数字表示各输入语言变量的语言之(隶属度函数的编号),此处m=2
1 2 7 1 3 1 1;%随后的n个数字表示输出语言变量的语言值,此处n=3
1 3 6 2 1 1 1;%第n+m+1个数字是该规则的权重,权重的值在0到1之间,一般为1
1 4 6 2 1 1 1;%第n+m+2个数字为0或1两者之一,各输入语言变量之间的关系,1为与,0为或
1 5 5 3 1 1 1;
1 6 4 4 2 1 1;
1 7 4 4 5 1 1;
2 1 7 1 5 1 1;
2 2 7 1 3 1 1;
2 3 6 2 1 1 1;
2 4 5 3 2 1 1;
2 5 5 3 2 1 1;
2 6 4 4 3 1 1;
2 7 3 4 4 1 1;
3 1 6 1 4 1 1;
3 2 6 2 3 1 1;
3 3 6 3 2 1 1;
3 4 5 3 2 1 1;
3 5 4 4 3 1 1;
3 6 3 5 3 1 1;
3 7 3 5 4 1 1;
4 1 6 2 4 1 1;
4 2 6 2 3 1 1;
4 3 5 3 3 1 1;
4 4 4 4 3 1 1;
4 5 3 5 3 1 1;
4 6 2 6 3 1 1;
4 7 2 6 4 1 1;
5 1 5 2 4 1 1;
5 2 5 3 4 1 1;
5 3 4 4 4 1 1;
5 4 3 5 4 1 1;
5 5 3 5 4 1 1;
5 6 2 6 4 1 1;
5 7 2 7 4 1 1;
6 1 5 4 7 1 1;
6 2 4 4 5 1 1;
6 3 3 5 5 1 1;
6 4 2 5 5 1 1;
6 5 2 6 5 1 1;
6 6 2 7 5 1 1;
6 7 1 7 7 1 1;
7 1 4 4 7 1 1;
7 2 4 4 6 1 1;
7 3 2 5 6 1 1;
7 4 2 6 6 1 1;
7 5 2 6 5 1 1;
7 6 1 7 5 1 1;
7 7 1 7 7 1 1];
a=addrule(a,rulelist);
a=setfis(a,'DefuzzMethod','centroid');
writefis(a,'fuzzpid');
a=readfis('fuzzpid');
figure(1);
plotmf(a,'input',1);
figure(2);
plotmf(a,'input',2);
figure(3);
plotmf(a,'output',1);
figure(4);
plotmf(a,'output',2);
figure(5);
plotmf(a,'output',3);
figure(6);
plotfis(a);
fuzzy fuzzpid;
showrule(a);
ruleview fuzzpid;
第二个文件
%模糊PID
%Fuzzy PID Control
close all;
clear all;
a=readfis('fuzzpid'); %Load fuzzpid.fis
% ts=0.001;
% sys=tf(5.235e005,[1,87.35,1.047e004,0]);
% dsys=c2d(sys,ts,'tustin');
% [num,den]=tfdata(dsys,'v');
ts=0.1; %采样时间=0.1s
sys=tf(4.23,[1,1.64,8.46],'ioDelay',3); %建立被控对象传递函数
dsys=c2d(sys,ts,'z') %离散化
[num,den]=tfdata(dsys,'v'); %
x=[0,0,0]';
e_1=0;
ec_1=0;
kp0=0.35;
ki0=0.35;
kd0=1;
for j=1:32;
u(j)=0.0;
end
for k=1:1:3000
time(k)=k*ts;
r(k)=1;
%Using fuzzy inference to tunning PID
k_pid=evalfis([e_1,ec_1],a);
kp(k)=kp0+k_pid(1);
ki(k)=ki0+k_pid(2);
kd(k)=kd0+k_pid(3);
y(1)=0;y(2)=0;
y(k+2)=-1*den(3)*y(k-2+2)-1*den(2)*y(k-1+2)+num(2)*u(k-31+32)+num(3)*u(k-32+32);%系统响应输出序列
e(k)=r(k)-y(k+2);
u(k+32)=kp(k)*x(1)+kd(k)*x(2)+ki(k)*x(3);
x(1)=e(k); % Calculating P
x(2)=e(k)-e_1; % Calculating D
x(3)=x(3)+e(k)*ts; % Calculating I
ec_1=x(2);
e_2=e_1;
e_1=e(k);
end
figure(1);
plot(time,r,'b',time,y(3:3002),'r');
xlim([0,300]);ylim([0,1.2]);grid on;
xlabel('time(s)');ylabel('rin,yout');
figure(2);
plot(time,e,'r');
xlabel('time(s)');ylabel('error');
figure(3);
plot(time,u(33:3032),'r');
xlabel('time(s)');ylabel('u');
figure(4);
plot(time,kp,'r');
xlabel('time(s)');ylabel('kp');
figure(5);
plot(time,ki,'r');
xlabel('time(s)');ylabel('ki');
figure(6);
plot(time,kd,'r');
xlabel('time(s)');ylabel('kd');
第6章 参考资料
1.模糊控制的MATLAB实现具体过程(强势吐血推荐)… - 百度文库 https://wenku.baidu.com/view/d91945925ebfc77da26925c52cc58bd63086931c.html
2.刘金锟智能控制教材源代码及各章ppt(CSDN有下载)
3. 《Matlab仿真PID控制(带M文件、simulink截图和参数分析)》,https://blog.csdn.net/weixin_44044411/article/details/85891109?utm_source=app