模糊PID控制实验报告.docx
《模糊PID控制实验报告.docx》由会员分享,可在线阅读,更多相关《模糊PID控制实验报告.docx(23页珍藏版)》请在冰豆网上搜索。
![模糊PID控制实验报告.docx](https://file1.bdocx.com/fileroot1/2023-1/23/0eda21a6-fe1e-4263-97eb-660dce5d554d/0eda21a6-fe1e-4263-97eb-660dce5d554d1.gif)
模糊PID控制实验报告
编号:
实验一普通PI控制方法的设计与实现
一、实验目的
1.掌握数字PI及其算法的实现
2.熟悉在在keil环境下进行单片机程序的设计
3.熟悉仿真软件protues的使用
二、实验设备及条件
1.计算机系统
2.编程软件keil4和仿真软件protues7.8
三、实验原理及其实验步骤
(1)PID算法的数字化实现
在模拟系统中,PID算法的表达式为
式中
u(t):
调节器的输出信号;
e(t):
调节器的偏差信号,它等于测量值与给定值之差;
Kp:
调节器的比例系数;
TI:
调节器的积分时间;
TD:
调节器的微分时间;
离散化的PID为:
Δt=T:
采样周期,必须使T足够少,才能保证系统有一定的精度;
E(k):
第K次采样时的偏差值;
E(k-1):
第K-1次采样时的偏差值;
K:
采样序号,K=0,1,2……;
P(k-1):
第K次采样时调节器的输出;
上式计算复杂,经过化简为:
式中:
为积分系数
为微分系数
要计算第K次输出值u(k),只需要知道u(k-1),e(k),E(k-1),e(k-2)即可。
上式也称为位置型PID的位置控制算法。
在很多控制系统中,由于执行机构是采用布进电机进行控制,所以只要给一个增量信号即可。
因此得到增量型PID的位置控制算法。
(2)控制系统的结构框图
整个系统的控制框图如下所示:
图1PID控制系统结构框图
在本次设计中,经过计算,被控对象的传递函数是:
其中:
C=10uf,R=20K;带入上式后可得:
显然是一个二阶系统。
(3)控制系统的仿真实现
在本次试验中,考虑到实际的需要,只采用了PI控制就完全可以实现很好的控制效果,故为了简化就采用PI来控制,用51单片单片机来作为中央处理器,在protues下搭建的控制系统框图如下:
图2在protues下的控制系统结构图
示波器A端口用来观察PI控制器输出的电压信号,示波器C端口用来观察对象输出的信号变化,示波器的D端口用来观察参考信号变化。
开关SW1用来改变参考信号,开关SW2的关断用来模拟扰动的加入和消除,开关SW3用来改变被控对象的结构参数。
当SW1断开,SW2断开,SW3断开时,系统输出波形为:
从上图中可以看出,对象的输出波形(最上层的波形曲线)基本达到期望输出(即在2.5V和3.5V之间做周期变化)。
当扰动加入后,即保持SW1、SW3断开,SW2突然闭合(闭合时刻为8.30S),系统输出波形为:
从对象的输出波形可以看出,曲线经过极其微小的波动后又恢复到未加入扰动前的形状。
当继续保持SW1断开,SW2闭合,突然闭合SW3(即改变被控对象的结构参数),此时的系统波形图如下:
由上图可以知道,当开关SW3闭合时,被控对象的输出波箱出现了很大扰动,但是很快系统又达到了预期输出波形,说明系统具备了良好的自调整能力。
四、实验结论
通过仿真测试,由仿真结构可以知道,用数字PI算法能够很好对给定的二阶对象实现控制。
当系统出现轻微扰动的时候,PI控制器能够实现非常好的控制,当系统的结构参数发生改变的时候,对象的输出瞬时会出现大的扰动,这可能造成系统的某些部件的损坏,但是在此PI控制器的作用下,系统又能很快的消除扰动,又能很快的跟踪参考输入,这说明此系统的快速性非常好。
从整体效果来看,基本达到控制要求。
上述控制方法的程序设计如下:
#include
#include"math.h"
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
sbitADAT=P2^5;
sbitACLK=P2^6;
sbitACS=P2^7;
floatLTC1292(void)//采集输出端的电压值
{
uinti,x;
floatm;
ACLK=0;ADAT=1;ACS=0;
for(i=0;i<14;i++)
{
ACLK=1;
x<<=1;
if(ADAT==1)x++;
ACLK=0;
}
ACS=1;
m=x&0xfff;m=m*5.0/4095;
return(m);
}
sbitDDAT=P3^4;
sbitDCS=P3^3;
sbitDCLK=P3^2;
voidTLC5615(floatx)//输出一个电压值
{
uchari;
uintj;
x=x*1023/5.0;
j=x;
DCLK=0;DCS=0;
j=j<<6;
for(i=0;i<12;i++)
{
j=j<<1;DDAT=CY;
DCLK=0;DCLK=1;
}
DCLK=0;DCS=1;
}
floate0,e1,e2,de,r,y,u,x1,x2,x3,wp,wi,wd,wknum,zk;
floatxite_p=0.50,xite_i=0.55,xite_d=0.40,k=0.04;
floatwkp_1=0.05,wki_1=0.20,wkd_1=0.10,u1=0.0;//u1为神经网络控制器的输出
#defineTIM-35000
voidneural_network()interrupt3
{
TH1=TIM>>8;TL1=TIM&0XFF;
y=LTC1292();
e2=e1;e1=e0;e0=r-y;de=e0-e1;
zk=e0-0.2*e1;
x1=de;//误差的变化
x2=r-y;//误差
x3=e0-2*e1+e2;
wkp_1=wkp_1+xite_p*zk*u1*x1;
wki_1=wki_1+xite_i*zk*u1*x2;
wkd_1=wkd_1+xite_d*zk*u1*x3;
wknum=fabs(wkp_1)+fabs(wki_1)+fabs(wkd_1);
wp=wkp_1/wknum;//把权值变成0到1之间的数,按百分比分配
wi=wki_1/wknum;
wd=wkd_1/wknum;
u1=u1+k*(wp*x1+wi*x2+wd*x3);
if(u1>5)u=5;
if(u1<0)u=0;
TLC5615(u1);
}
voidmain()
{
ucharg;
IE=0x88;TMOD=0X11;
TH1=TIM>>8;TL1=TIM&0xff;TR1=1;
while
(1)
{
g=P3>>6;
switch(g)
{
case0:
r=1.0;break;
case2:
r=1.5;break;
case1:
r=2.5;break;
case3:
r=3.5;break;
}
}
}
实验二模糊PI控制算法的设计与实现
一、实验目的
1.掌握模糊PI算法及其算法的实现
2.熟悉在keil4环境下进行单片机程序的设计
3.熟悉仿真软件protues7.8的使用
二、实验设备及条件
1.计算机系统
2.编程软件keil4和仿真软件protues7.8
三、实验原理
模糊控制器的输入为误差和误差变化率:
误差e=r-y,误差变化率ec=de/dt,其中r和y分别为液位的给定值和测量值。
把误差和误差变化率的精确值进行模糊化变成模糊量E和EC,从而得到误差E和误差变化率EC的模糊语言集合,然后由E和EC模糊语言的的子集和模糊控制规则R(模糊关系矩阵)根据合成推理规则进行模糊决策,这样就可以得到模糊控制向量U,最后再把模糊量解模糊转换为精确量u,再经D/A转换为模拟量去控制执行机构动作。
模糊控制器组成原理图如下所示:
图1模糊控制器组成原理
本次实验的控制对象和实验一控制的对象完全一样,控制要求也完全一样,被控对象的传递函数如下所示:
在protues环境下搭建的系统控制系统图如下所示:
图2protues下整个系统的控制仿真结构图
模糊化处理:
根据精确量实际变化范围[a,b],合理选择模糊变量的论域[-n,n],通过量化因子
,将其转换成若干个等级的离散论域,如7个等级为{负大,负中,负小,零,正小,正中,正大},简写成{NB,NM,NS,0,PS,PM,PB}。
确定模糊子集的隶属度函数,一般采用三角形,梯形和正态分布曲线。
然后由隶属曲线得出模糊变量E、EC、U的赋值表。
模糊控制规则:
模糊控制规则是根据操作经验和专家知识总结的,是进行模糊推理的依据。
在设计模糊控制规则的时候,必须考虑控制规则的完备性、交叉性和一致性。
既保证对任意给定的输入,都有相应的控制规则起作用;控制器的输出值总是由数条控制规则来决定;控制规则中不存在相互矛盾的规则。
在总结专家经验和过程知识的基础上,可以得出下表的控制规则。
表1控制规则表
NB
NM
NS
O
PS
PM
PB
NB
NM
NS
O
PS
PM
PB
PS
NS
NM
NB
NB
NB
NB
PS
PS
NS
NM
NM
NB
NB
PS
PS
O
NS
NS
NM
NM
PS
PS
O
O
O
NS
NS
PM
PM
PS
PS
O
NS
NS
PB
PM
PM
PM
PS
PS
NS
PB
PB
PM
PM
PM
PS
NS
模糊推理:
模糊推理是模糊控制器的核心,模糊控制系统目前采用的由CRI推理的查表法、CRI推理的解析法、Mamdani直接推理法、后件函数法等。
本实验可采用Mamdani直接推理法。
Mamdani直接推理法是先求出模糊关系R,再根据输入求出控制量,把控制量清晰化,可得控制查询表。
本实验设计了容量为7*7条控制规则表,整个规则表可以用27条模糊条件语句来加以描述。
如ifE=NBandEC=NBthenU=PS.对应的模糊关系式
,A是E的模糊集合,B是EC的模糊集合,C是U的模糊集合。
四、实验步骤
1.根据控制器原理图和被控对象在protues中搭建控制系统图(图2)
2.在keil4编程环境下编写系统的控制程序
3.把keil4环境下生成的hex文件加载到单片机中,准备进行仿真
4.开关SW1、SW2、SW3、均断开,点击Protues的左下角的三角行进行仿真,观察并记录输出波形。
5.在步骤4的基础上闭合SW2,观察并记录实验数据。
6.在步骤5的基础上闭合SW3,观察并记录实验数据
7.重复步骤4到6,观察并记录实验数据
五、实验结果与分析
步骤4的实验结果如下所示:
从上图可以看出基本达到了所期望的控制要求,即要求输出电压在2.5V和3.5V之间周期变化,显然由输出曲线(最上面的曲线)可以看出曲线的快速性和超调都达到了很好的效果。
步骤5的实验结果如下所示:
在此步骤中,开关SW2闭合,相当于加入一个扰动信号,在图中的2.8秒的时刻SW2闭合,输出曲线微小波动后,又恢复到以前的变化规律,实现了很好的抗扰性能,基本达到控制要求。
步骤6的实验结果如下图所示:
在此步骤中,SW3闭合,相当于改变被控对象的结构与参数,必然会引起输出的较大波动,如图所示,在SW3闭合瞬间,输出曲线出现了很大的波动,但是很快又进行了自我调整,是曲线迅速恢复到以前的变化规律。
从上述结果来看,总体的控制效果还是比较理想的,唯一的不足点就是当被控对象的结构参数发生改变的时候,如何使对象的输出波动限制在一个比较理想的范围值得深入讨论。
本实验的控制程序如下:
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
sbitADAT=P2^5;
sbitACLK=P2^6;
sbitACS=P2^7;
floatLTC1292(void)//采集输出端的电压值
{
uinti,x;
floatm;
ACLK=0;ADAT=1;ACS=0;
for(i=0;i<14;i++)
{
ACLK=1;
x<<=1;
if(ADAT==1)x++;
ACLK=0;
}
ACS=1;
m=x&0xfff;m=m*5.0/4095;
return(m);
}
sbitDDAT=P3^4;
sbitDCS=P3^3;
sbitDCLK=P3^2;
voidTLC5615(floatx)//输出一个电压值
{
uchari;
uintj;
x=x*1023/5.0;
j=x;
DCLK=0;DCS=0;
j=j<<6;
for(i=0;i<12;i++)
{
j=j<<1;DDAT=CY;
DCLK=0;DCLK=1;
}
DCLK=0;DCS=1;
}
/*********************************************/
enum{FL,FM,FS,ZO,ZS,ZM,ZL};
codecharSET[7][7]={
FL,FL,FL,FL,FM,FS,FS,
FL,FL,FL,FM,FS,ZS,ZS,
FL,FL,FM,FS,ZO,ZS,ZM,
FL,FM,FS,ZO,ZS,ZM,ZL,
FM,FS,ZO,ZS,ZM,ZL,ZL,
FS,FS,ZS,ZM,ZL,ZL,ZL,
ZS,ZS,ZM,ZL,ZL,ZL,ZL};
floatER[7],CE[7];
codefloatOUT[7]={-0.4,-0.2,-0.06,0,0.06,0.2,0.4};
codefloatTABER[7]={-1,-0.5,-0.2,0,0.2,0.5,1};
codefloatTABCE[7]={-0.2,-0.05,-0.02,0,0.02,0.05,0.2};
/***********************************************/
voidFuzzy_er(floater)/*偏差三角模糊化*/
{
chari;
if(erif(er>TABER[6])er=TABER[6];
for(i=0;i<7;i++)ER[i]=0;
for(i=0;i<6;i++)
{
if(er>=TABER[i]&er<=TABER[i+1])
{
ER[i+1]=(er-TABER[i])/(TABER[i+1]-TABER[i]);
ER[i]=(TABER[i+1]-er)/(TABER[i+1]-TABER[i]);
}
}
}
voidFuzzy_ce(floatce)/*变化三角模糊化*/
{
chari;
if(ceif(ce>TABCE[6])ce=TABCE[6];
for(i=0;i<7;i++)CE[i]=0;
for(i=0;i<6;i++)
{
if(ce>=TABCE[i]&ce<=TABCE[i+1])
{
CE[i+1]=(ce-TABCE[i])/(TABCE[i+1]-TABCE[i]);
CE[i]=(TABCE[i+1]-ce)/(TABCE[i+1]-TABCE[i]);
}
}
}
floatFuzzy_cu()/*三角化模糊推理*/
{
chari,j;
floats,s1;
s1=0;
for(i=0;i<7;i++)
for(j=0;j<7;j++)
{
s=ER[i]*CE[j];
s1+=s*OUT[SET[i][j]];
}
returns1;
}
floate0,e1,de,r,y,u;
#defineTIM-30000
voidFuzzy()interrupt3
{
TH1=TIM>>8;TL1=TIM&0XFF;
y=LTC1292();
e1=e0;e0=r-y;de=e0-e1;
Fuzzy_er(e0);
Fuzzy_ce(de);
u+=Fuzzy_cu();
if(u>5)u=5;
if(u<0)u=0;
TLC5615(u);
}
voidmain()
{
ucharg;
IE=0x88;TMOD=0X11;
TH1=TIM>>8;TL1=TIM&0xff;TR1=1;
while
(1)
{
g=P3>>6;
switch(g)
{
case0:
r=1.0;break;
case2:
r=1.5;break;
case1:
r=2.5;break;
case3:
r=3.5;break;
}
}
}
实验三单神经元PID控制算法的设计与实现
一、实验目的
1.掌握单神经元PID算法及其算法的实现
2.熟悉单神经元PID控制器的原理。
3.通过实验进一步掌握有监督的Hebb学习规则及其算法仿真。
4.熟悉在keil4环境下进行单片机程序的设计
5.熟悉仿真软件protues7.8的使用
二、实验设备及条件
1.计算机系统
2.编程软件keil4和仿真软件protues7.8
三、实验内容
利用单神经元实现自适应PID控制器,对如下二阶对象进行控制,在protues7.8环境中进行仿真。
被控对象为:
四、实验原理
线性神经网络是最简单的一种神经元结构,它不同于感知器,其函数是一线性函数,因此神经元的输出可以是任意值。
我们可以用它实现增量PID控制器的功能,误差为神经元的输入,权系数为PID控制系数,由于神经网络可以用在线学习对权系数进行实时修改,所以使得PID控制具有了自适应功能。
PID控制器的增量公式为
一个3输入的线性神经元的计算公式为
k为神经元的比例系数,wi为神经元权系数,xi为神经元输入,u为神经元的输出。
神经元的学习方法可以采用Hebb学习规则。
有监督的Hebb学习算法规范法处理后为
五、实验步骤
1.根据控制器原理图和被控对象在protues中搭建控制系统图(图2)
2.在keil4编程环境下编写系统的控制程序。
3.把keil4环境下生成的hex文件加载到单片机中,准备进行仿真
4.开关SW1、SW2、SW3、均断开,点击Protues的左下角的三角行进行仿真,观察并记录输出波形。
5.在步骤4的基础上闭合SW2,观察并记录实验数据。
6.在步骤5的基础上闭合SW3,观察并记录实验数据
7.重复步骤4到6,观察并记录实验数据
六、实验结果与分析
步骤4的实验结果如下所示:
从上图可以看出基本达到了所期望的控制要求,即要求输出电压在2.5V和3.5V之间周期变化,显然由输出曲线(最上面的曲线)可以看出曲线的快速性和超调都达到了很好的效果。
步骤5的实验结果如下所示:
在此步骤中,开关SW2闭合,相当于加入一个扰动信号,在图中的7.63秒的时刻SW2闭合,输出曲线微小波动后,又恢复到以前的变化规律,实现了很好的抗扰性能,基本达到控制要求。
步骤6的实验结果如下图所示:
在此步骤中,SW3闭合,相当于改变被控对象的结构与参数,必然会引起输出的较大波动,如图所示,在SW3闭合瞬间,输出曲线和常规PI控制、模糊PI控制相比,波动明显减小,并且很快又恢复到正常跟踪效果。
从上述结果来看,总体的控制效果还是比较理想的,改进的地方就是需要对算法做进一步优化,是输出曲线的的超调变得更小。
单神经元的PID控制程序如下:
#include
#include"math.h"
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
sbitADAT=P2^5;
sbitACLK=P2^6;
sbitACS=P2^7;
floatLTC1292(void)//采集输出端的电压值
{
uinti,x;
floatm;
ACLK=0;ADAT=1;ACS=0;
for(i=0;i<14;i++)
{
ACLK=1;
x<<=1;
if(ADAT==1)x++;
ACLK=0;
}
ACS=1;
m=x&0xfff;m=m*5.0/4095;
return(m);
}
sbitDDAT=P3^4;
sbitDCS=P3^3;
sbitDCLK=P3^2;
voidTLC5615(floatx)//输出一个电压值
{
uchari;
uintj;
x=x*1023/5.0;
j=x;
DCLK=0;DCS=0;
j=j<<6;
for(i=0;i<12;i++)
{
j=j<<1;DDAT=CY;
DCLK=0;DCLK=1;
}
DCLK=0;DCS=1;
}
floate0,e1,e2,de,r,y,u,x1,x2,x3,wp,wi,wd,wknum,zk;
floatxite_p=0.50,xite_i=0.55,xite_d=0.40,k=0.04;
floatwkp_1=0.05,wki_1=0.20,wkd_1=0.10,u1=0.0;//u1为神经网络控制器的输出
#defineTIM-35000
voidneural_network()interrupt3
{
TH1=TIM>>8;TL1=TIM&0XFF;
y=LTC1292();
e2=e1;e1=e0;e0=r-y;de=e0-e1;
zk=e0-0.2*e1;
x1=de;//误差的变化
x2=r-y;//误差
x3=e0-2*e1+e2;
wkp_1=wkp_1+xite_p*zk*u1*x1;
wki_1=wki_1+xite_i*zk*u1*x2;
wkd_1=wkd_1+xite_d*zk*u1*x3;
wknum=fabs(wkp_1)+fabs(wki_1)+fabs(wkd_1);
wp=wkp_1/wknum;//把权值变成0到1之间的数,按百分比分配
wi=wki_1/wknum;
wd=wkd_1/wknum;
u1=u1+k*(wp*x1+wi*x2+wd*x3);
if(u1>5)u=5;
if(u1<0)u=0;
TLC5615(u1