补充
//https://max.book118.com/html/2022/1122/5313224300010022.shtm
//C语言实现模糊控制算法--以洗衣机的模糊控制为例
double xy_control(double XIN,double YIN)
{
double result;
double XF[3]={6,9,12};//X隶属度函数划分区间
double YF[3]={1160,1180,1200};
double ZF[5]={105000,110000,115000,120000,125000};
int Rule[3][3]={{0,1,2},
{1,2,3},
{2,3,4}};
double XU[2],YU[2],ZU[4];//隶属度
int Xn,Yn;//隶属度对应下标
int Zn[4];//4条有效推理结果
double Temp[4];
int i,j,iu;
double Zij,ZUmax[4];//输出隶属度最大值
//限幅
if(XIN<=XF[0])
{
XIN=XF[0];
}
if(XIN>=XF[2])
{
XIN=XF[2];
}
if(YIN<=YF[0])
{
YIN=YF[0];
}
if(YIN>=YF[2])
{
YIN=YF[2];
}
if(XIN<=XF[1])
{
Xn=0;
XU[0]=(XF[1]-XIN)/(XF[1]-XF[0]);
XU[1]=1-XU[0];
}
else if(XIN<=XF[2])
{
Xn=1;
XU[0]=(XF[2]-XIN)/(XF[2]-XF[1]);
XU[1]=1-XU[0];
}
if(YIN<=YF[1])
{
Yn=0;
YU[0]=(YF[1]-YIN)/(YF[1]-YF[0]);
YU[1]=1-YU[0];
}
else if(YIN<=YF[2])
{
Yn=1;
YU[0]=(YF[2]-YIN)/(YF[2]-YF[1]);
YU[1]=1-YU[0];
}
Zn[0]=Rule[Xn][Yn];
Zn[1]=Rule[Xn+1][Yn];
Zn[2]=Rule[Xn][Yn+1];
Zn[3]=Rule[Xn+1][Yn+1];
//规则前提的可信度取小运算
if(XU[0]<=YU[0])
ZU[0]=XU[0];
else
ZU[0]=YU[0];
if(XU[1]<=YU[0])
ZU[1]=XU[1];
else
ZU[1]=YU[0];
if(XU[0]<=YU[1])
ZU[2]=XU[0];
else
ZU[2]=YU[1];
if(XU[1]<=YU[1])
ZU[3]=XU[1];
else
ZU[3]=YU[1];
//同隶属度函数总规则的可信度取大运算
if(Zn[0]==Zn[1])
{
if(ZU[0]>ZU[1])
ZU[1]=0;
else
ZU[0]=0;
}
if(Zn[0]==Zn[2])
{
if(ZU[0]>ZU[2])
ZU[2]=0;
else
ZU[0]=0;
}
if(Zn[0]==Zn[3])
{
if(ZU[0]>ZU[3])
ZU[3]=0;
else
ZU[0]=0;
}
//
if(Zn[1]==Zn[2])
{
if(ZU[1]>ZU[2])
ZU[2]=0;
else
ZU[1]=0;
}
if(Zn[1]==Zn[3])
{
if(ZU[1]>ZU[3])
ZU[3]=0;
else
ZU[1]=0;
}
if(Zn[2]==Zn[3])
{
if(ZU[2]>ZU[3])
ZU[3]=0;
else
ZU[2]=0;
}
//重心法反模糊
for(i=0;i<4;i++)
ZUmax[i]=ZU[i];
for(j=0;j<3;j++)
for(i=0;i<3-j;i++)
if(ZUmax[i]>=ZUmax[i+1])
{
Zij=ZUmax[i];
ZUmax[i]=ZUmax[i+1];
ZUmax[i+1]=Zij;
}
//最大隶属度1个
if(ZUmax[3]>ZUmax[2])
{
for(i=0;i<4;i++)
if(ZUmax[3]==ZU[i])
{iu=i;break;}
if(Zn[iu]==0)//VS
{
Temp[0]=ZF[0];
Temp[1]=ZF[1]-(ZU[iu]*(ZF[1]-ZF[0]));
}
else if(Zn[iu]==1)//S
{
Temp[0]=ZU[iu]*(ZF[1]-ZF[0]);
Temp[1]=ZF[2]-(ZU[iu]*(ZF[2]-ZF[1]));
}
else if(Zn[iu]==2)//M
{
Temp[0]=ZU[iu]*(ZF[2]-ZF[1])+ZF[1];
Temp[1]=ZF[3]-(ZU[iu]*(ZF[3]-ZF[2]));
}
else if(Zn[iu]==3)//L
{
Temp[0]=ZU[iu]*(ZF[3]-ZF[2])+ZF[2];
Temp[1]=ZF[4]-(ZU[iu]*(ZF[4]-ZF[3]));
}
else if(Zn[iu]==4)//VL
{
Temp[0]=ZU[iu]*(ZF[4]-ZF[3])+ZF[3];
Temp[1]=ZF[4];
}
result=(Temp[0]+Temp[1])/2;
}
//最大隶属度2个
if(ZUmax[3]==ZUmax[2])
{
for(i=0;i<4;i++)
if(ZUmax[3]==ZU[i])
{iu=i;break;}
if(Zn[iu]==0)//VS+S
{
Temp[0]=ZF[0];
Temp[1]=ZF[1]-(ZU[iu]*(ZF[1]-ZF[0]));
Temp[2]=ZU[iu]*(ZF[1]-ZF[0]);
Temp[3]=ZF[2]-(ZU[iu]*(ZF[2]-ZF[1]));
}
else if(Zn[iu]==1)//S+M
{
Temp[0]=ZU[iu]*(ZF[1]-ZF[0]);
Temp[1]=ZF[2]-(ZU[iu]*(ZF[2]-ZF[1]));
Temp[2]=ZU[iu]*(ZF[2]-ZF[1])+ZF[1];
Temp[3]=ZF[3]-(ZU[iu]*(ZF[3]-ZF[2]));
}
else if(Zn[iu]==2)//M+L
{
Temp[0]=ZU[iu]*(ZF[2]-ZF[1])+ZF[1];
Temp[1]=ZF[3]-(ZU[iu]*(ZF[3]-ZF[2]));
Temp[2]=ZU[iu]*(ZF[3]-ZF[2])+ZF[2];
Temp[3]=ZF[4]-(ZU[iu]*(ZF[4]-ZF[3]));
}
else if(Zn[iu]==3)//L+VL
{
Temp[0]=ZU[iu]*(ZF[3]-ZF[2])+ZF[2];
Temp[1]=ZF[4]-(ZU[iu]*(ZF[4]-ZF[3]));
Temp[2]=ZU[iu]*(ZF[4]-ZF[3])+ZF[3];
Temp[3]=ZF[4];
}
result=(Temp[0]+Temp[1]+Temp[2]+Temp[3])/4;
}
//限幅
if(result<=ZF[0])
{
result=ZF[0];
}
if(result>=ZF[4])
{
result=ZF[4];
}
return result;
}
1
double td_fuzzy(double ec)
{
double EC=0;
double out=0;
int i=0;
double degree_left = 0,degree_right = 0;
int degree_left_index = 0,degree_right_index = 0;
double DFF[7]={-3000,-2000,-1000,0,1000,2000,3000};
double UFF[7];
double kd_m=2;
int rule_d[7] = { 6 , 5 , 3 , 2 , 3 , 5 , 6};//
EC=ec+1/10000;
for(i=0;i<7;i++)
UFF[i]=kd_m/6*i;
if(EC<DFF[0])
{
degree_left = 1;
degree_right = 0;
degree_left_index = 0;
}
else if (EC>DFF[6]) {
degree_left = 1;
degree_right = 0;
degree_left_index = 6;
}
else {
for(i=0;i<6;i++)
{
if(EC>=DFF[i]&&EC<DFF[i+1])
{
degree_left = (float)(DFF[i+1] - EC)/(DFF[i+1] - DFF[i]);
degree_right = 1 - degree_left;
degree_left_index = i;
degree_right_index = i+1;
break;
}
}
}
out = UFF[rule_d[degree_left_index]]*degree_left+UFF[rule_d[degree_right_index]]*degree_right;
return out;
}
2
double gain_fuzzy(double e,double ec)
{
int rule_p[7][7]=
{
{ 6 , 5 , 4 , 4 , 3 , 0 , 0},//-36
{ 6 , 4 , 3 , 3 , 2 , 0 , 0},//-24
{ 4 , 3 , 2 , 1 , 0 , 1 , 2},//-12
{ 2 , 1 , 1 , 0 , 1 , 1 , 2},//0
{ 2 , 1 , 0 , 1 , 2 , 3 , 4},//12
{ 0 , 0 , 2 , 3 , 3 , 4 , 6},//24
{ 0 , 1 , 3 , 4 , 4 , 5 , 6},//36
};//模糊规则表 P
int i2;
/*输入量P语言值特征点*/
double EFF[7]={-6000,-4000,-2000,0,2000,4000,6000};
/*输入量D语言值特征点*/
double DFF[7]={-4500,-3000,-1500,0,1500,3000,4500};
/*输出量U语言值特征点*/
double UFF[7];
double kp_m=2;
double U=0; /*偏差,偏差微分以及输出值的精确量*/
double PF[2]={0},DF[2]={0},UF[4]={0};
/*偏差,偏差微分以及输出值的隶属度*/
int Pn=0,Dn=0,Un[4]={0};
double t1=0,t2=0,t3=0,t4=0,temp1=0,temp2=0;
double E,EC;
E=e+1/10000;
EC=ec+1/10000;
for(i2=0;i2<7;i2++)
UFF[i2]=kp_m/6*i2;
/*隶属度的确定*/
/*根据PD的指定语言值获得有效隶属度*/
if(E>EFF[0] && E<EFF[6])
{
if(E<=EFF[1])
{
Pn=-2;
PF[0]=(EFF[1]-E)/(EFF[1]-EFF[0]);
}
else if(E<=EFF[2])
{
Pn=-1;
PF[0]=(EFF[2]-E)/(EFF[2]-EFF[1]);
}
else if(E<=EFF[3])
{
Pn=0;
PF[0]=(EFF[3]-E)/(EFF[3]-EFF[2]);
}
else if(E<=EFF[4])
{
Pn=1;
PF[0]=(EFF[4]-E)/(EFF[4]-EFF[3]);
}
else if(E<=EFF[5])
{
Pn=2;
PF[0]=(EFF[5]-E)/(EFF[5]-EFF[4]);
}
else if(E<=EFF[6])
{
Pn=3;
PF[0]=(EFF[6]-E)/(EFF[6]-EFF[5]);
}
}
else if(E<=EFF[0])
{
Pn=-2;
PF[0]=1;
}
else if(E>=EFF[6])
{
Pn=3;
PF[0]=0;
}
PF[1]=1-PF[0];
//判断D的隶属度
if(EC>DFF[0]&&EC<DFF[6])
{
if(EC<=DFF[1])
{
Dn=-2;
DF[0]=(DFF[1]-EC)/(DFF[1]-DFF[0]);
}
else if(EC<=DFF[2])
{
Dn=-1;
DF[0]=(DFF[2]-EC)/(DFF[2]-DFF[1]);
}
else if(EC<=DFF[3])
{
Dn=0;
DF[0]=(DFF[3]-EC)/(DFF[3]-DFF[2]);
}
else if(EC<=DFF[4])
{
Dn=1;
DF[0]=(DFF[4]-EC)/(DFF[4]-DFF[3]);
}
else if(EC<=DFF[5])
{
Dn=2;
DF[0]=(DFF[5]-EC)/(DFF[5]-DFF[4]);
}
else if(EC<=DFF[6])
{
Dn=3;
DF[0]=(DFF[6]-EC)/(DFF[6]-DFF[5]);
}
}
//不在给定的区间内
else if (EC<=DFF[0])
{
Dn=-2;
DF[0]=1;
}
else if(EC>=DFF[6])
{
Dn=3;
DF[0]=0;
}
DF[1]=1-DF[0];
/*使用误差范围优化后的规则表rule[7][7]*/
/*输出值使用13个隶属函数,中心值由UFF[7]指定*/
/*一般都是四个规则有效*/
Un[0]=rule_p[Pn+2][Dn+2];
Un[1]=rule_p[Pn+3][Dn+2];
Un[2]=rule_p[Pn+2][Dn+3];
Un[3]=rule_p[Pn+3][Dn+3];
if(PF[0]<=DF[0]) //求小
UF[0]=PF[0];
else
UF[0]=DF[0];
if(PF[1]<=DF[0])
UF[1]=PF[1];
else
UF[1]=DF[0];
if(PF[0]<=DF[1])
UF[2]=PF[0];
else
UF[2]=DF[1];
if(PF[1]<=DF[1])
UF[3]=PF[1];
else
UF[3]=DF[1];
/*同隶属函数输出语言值求大*/
if(Un[0]==Un[1])
{
if(UF[0]>UF[1])
UF[1]=0;
else
UF[0]=0;
}
if(Un[0]==Un[2])
{
if(UF[0]>UF[2])
UF[2]=0;
else
UF[0]=0;
}
if(Un[0]==Un[3])
{
if(UF[0]>UF[3])
UF[3]=0;
else
UF[0]=0;
}
if(Un[1]==Un[2])
{
if(UF[1]>UF[2])
UF[2]=0;
else
UF[1]=0;
}
if(Un[1]==Un[3])
{
if(UF[1]>UF[3])
UF[3]=0;
else
UF[1]=0;
}
if(Un[2]==Un[3])
{
if(UF[2]>UF[3])
UF[3]=0;
else
UF[2]=0;
}
t1=UF[0]*UFF[Un[0]];
t2=UF[1]*UFF[Un[1]];
t3=UF[2]*UFF[Un[2]];
t4=UF[3]*UFF[Un[3]];
temp1=t1+t2+t3+t4;
temp2=UF[0]+UF[1]+UF[2]+UF[3];//模糊量输出
if(temp2!=0)
U=temp1/temp2;
else {
U=0;
}
// temp1=PF[0]*UFF[Un[0]]+PF[1]*UFF[Un[1]]+PF[0]*UFF[Un[2]]+PF[1]*UFF[Un[3]]+DF[0]*UFF[Un[0]]+DF[0]*UFF[Un[1]]+DF[1]*UFF[Un[2]]+DF[0]*UFF[Un[3]];
// U=temp1;
return U;
}
3 返回整数
/*模糊运算引擎*/
int d_fuzzy(int x,int y)
{
/*偏差,偏差微分以及输出值的精确量*/
int z;
/*偏差,偏差微分以及输出值的隶属度*/
int x_f[2],y_f[2],z_f[4];
int x_n,y_n,z_n[4];
int tem_1,tem_2;
int f_max =100;
/*输入量偏差x语言值特征点*/
/*很小、小、一般、大*/
int x_ff[4]={0,2000,4000,6000};
/*输入量偏差变化率y语言值特征点*/
/*很小、小、一般、大*/
int y_ff[4]={0,1500,3000,4500};
/*输出量模糊控制器输出z语言值特征点*/
/*很小-3、较小-2、小-1、一般0、较大、大、很大*/
int z_ff[7]={0,10,12,14,16,18,20};
/*误差变化率 -3,-2,-1, 0, 1, 2, 3 // 误差 -3 -2 -1 0 1 2 3
/*定义控制查询表*/
/*
//增量式 //误差变化率EC
int rule[7][7]={ // -3,-2,-1, 0, 1, 2, 3
{-6,-6,-6,-5,-5,-5,-4,}, // -3
{-5,-4,-4,-3,-2,-2,-1,}, // -2
{-4,-3,-2,-1, 0, 1, 2,}, // -1
{-4,-3,-1, 0, 1, 3, 4,}, // 0 // 误差E
{-2,-1, 0, 1, 2, 3, 4,}, // 1
{ 1, 2, 2, 3, 4, 4, 5,}, // 2
{ 4, 5, 5, 5, 6, 6, 6}}; // 3
*/
//位置式 //误差变化率EC
int rule[7][7]={ // -3,-2,-1, 0, 1, 2, 3
{ 6, 6, 6, 5, 5, 5, 4,}, // -3
{ 5, 4, 4, 3, 2, 2, 1,}, // -2
{ 4, 3, 2, 1, 0, 1, 2,}, // -1
{ 4, 3, 1, 0, 1, 3, 4,}, // 0 // 误差E
{ 2, 1, 0, 1, 2, 3, 4,}, // 1
{ 1, 2, 2, 3, 4, 4, 5,}, // 2
{ 4, 5, 5, 5, 6, 6, 6}}; // 3
/*隶属度的确定*/
/*根据x、y的指定语言值获得有效隶属度*/
if(x>-x_ff[3] && x<x_ff[3])
{
if(x<=-x_ff[2])
{
x_n=-2;
x_f[0]=f_max*((-x_ff[2]-x)/(x_ff[3]-x_ff[2]));
}
else if(x<=-x_ff[1])
{
x_n=-1;
x_f[0]=f_max*((-x_ff[1]-x)/(x_ff[2]-x_ff[1]));
}
else if(x<=x_ff[0])
{
x_n=0;
x_f[0]=f_max*((-x_ff[0]-x)/(x_ff[1]-x_ff[0]));
}
else if(x<=x_ff[1])
{
x_n=1; x_f[0]=f_max*((x_ff[1]-x)/(x_ff[1]-x_ff[0]));
}
else if(x<=x_ff[2])
{
x_n=2; x_f[0]=f_max*((x_ff[2]-x)/(x_ff[2]-x_ff[1]));
}
else if(x<=x_ff[3])
{
x_n=3; x_f[0]=f_max*((x_ff[3]-x)/(x_ff[3]-x_ff[2]));
}
}
else if(x<=-x_ff[3])
{
x_n=-2; x_f[0]=f_max;
}
else if(x>=x_ff[3])
{
x_n=3; x_f[0]=0;
}
x_f[1]=f_max-x_f[0];
if(y>-y_ff[3] && y<y_ff[3])
{
if(y<=-y_ff[2])
{
y_n=-2;y_f[0]=f_max*((-y_ff[2]-y)/(y_ff[3]-y_ff[2]));
}
else if(y<=-y_ff[1])
{
y_n=-1;
y_f[0]=f_max*((-y_ff[1]-y)/(y_ff[2]-y_ff[1]));
}
else if(y<=y_ff[0])
{
y_n=0;
y_f[0]=f_max*((-y_ff[0]-y)/(y_ff[1]-y_ff[0]));
}
else if(y<=y_ff[1])
{
y_n=1;
y_f[0]=f_max*((y_ff[1]-y)/(y_ff[1]-y_ff[0]));
}
else if(y<=y_ff[2])
{
y_n=2; y_f[0]=f_max*((y_ff[2]-y)/(y_ff[2]-y_ff[1]));
}
else if(y<=y_ff[3])
{
y_n=3; y_f[0]=f_max*((y_ff[3]-y)/(y_ff[3]-y_ff[2]));
}
}
else if(y<=-y_ff[3])
{
y_n=-2;
y_f[0]=f_max;
}
else if(y>=y_ff[3])
{
y_n=3;
y_f[0]=0;
}
y_f[1]=f_max-y_f[0];
/*使用误差范围优化后的规则表rule[7][7]*/
/*输出值使用13个隶属函数,中心值由z_ff[7]指定*/
/*一般都是四个规则有效*/
z_n[0]=rule[x_n-1+3][y_n-1+3];
z_n[1]=rule[x_n+3][y_n-1+3];
z_n[2]=rule[x_n-1+3][y_n+3];
z_n[3]=rule[x_n+3][y_n+3];
if(x_f[0]<=y_f[0])
z_f[0]=x_f[0];
else
z_f[0]=y_f[0];
if(x_f[1]<=y_f[0])
z_f[1]=x_f[1];
else
z_f[1]=y_f[0];
if(x_f[0]<=y_f[1])
z_f[2]=x_f[0];
else
z_f[2]=y_f[1];
if(x_f[1]<=y_f[1])
z_f[3]=x_f[1];
else
z_f[3]=y_f[1];
/*同隶属函数输出语言值求大*/
if(z_n[0]==z_n[1])
{
if(z_f[0]>z_f[1])
z_f[1]=0;
else
z_f[0]=0;
}
if(z_n[0]==z_n[2])
{
if(z_f[0]>z_f[2])
z_f[2]=0;
else
z_f[0]=0;
}
if(z_n[0]==z_n[3])
{
if(z_f[0]>z_f[3])
z_f[3]=0;
else
z_f[0]=0;
}
if(z_n[1]==z_n[2])
{
if(z_f[1]>z_f[2])
z_f[2]=0;
else
z_f[1]=0;
}
if(z_n[1]==z_n[3])
{
if(z_f[1]>z_f[3])
z_f[3]=0;
else
z_f[1]=0;
}
if(z_n[2]==z_n[3])
{
if(z_f[2]>z_f[3])
z_f[3]=0;
else
z_f[2]=0;
}
/*重心法反模糊*/
/*z_n[]原值为输出隶属函数标号,转换为隶属函数值*/
if(z_n[0]>=0)
z_n[0]=z_ff[z_n[0]];
else
z_n[0]=-z_ff[-z_n[0]];
if(z_n[1]>=0)
z_n[1]=z_ff[z_n[1]];
else
z_n[1]=-z_ff[-z_n[1]];
if(z_n[2]>=0)
z_n[2]=z_ff[z_n[2]];
else
z_n[2]=-z_ff[-z_n[2]];
if(z_n[3]>=0)
z_n[3]=z_ff[z_n[3]];
else
z_n[3]=-z_ff[-z_n[3]];
tem_1=z_f[0]*z_n[0]+z_f[1]*z_n[1]+z_f[2]*z_n[2]+z_f[3]*z_n[3];
tem_2=z_f[0]+z_f[1]+z_f[2]+z_f[3];
z=tem_1/tem_2;
return z;
}
4 返回实数
/*模糊运算引擎*/
double d_fuzzy(double x,double y)
{
double t1=0,t2=0,t3=0,t4=0,temp1=0,temp2=0;
/*偏差,偏差微分以及输出值的精确量*/
double z;
/*偏差,偏差微分以及输出值的隶属度*/
double x_f[2],y_f[2],z_f[4];
int x_n,y_n,z_n[4];
double f_max =100;
/*输入量偏差x语言值特征点*/
/*很小、小、一般、大*/
double x_ff[4]={0,2000,4000,6000};
/*输入量偏差变化率y语言值特征点*/
/*很小、小、一般、大*/
double y_ff[4]={0,1500,3000,4500};
/*输出量模糊控制器输出z语言值特征点*/
/*很小-3、较小-2、小-1、一般0、较大、大、很大*/
double z_ff[7]={0,0.2,0.4,0.6,0.8,1.0,1.2};
/*误差变化率 -3,-2,-1, 0, 1, 2, 3 // 误差 -3 -2 -1 0 1 2 3
/*定义控制查询表*/
/*
//增量式正作用 //误差变化率EC
int rule[7][7]={ // -3,-2,-1, 0, 1, 2, 3
{-6,-6,-6,-5,-5,-5,-4,}, // -3
{-5,-4,-4,-3,-2,-2,-1,}, // -2
{-4,-3,-2,-1, 0, 1, 2,}, // -1
{-4,-3,-1, 0, 1, 3, 4,}, // 0 // 误差E
{-2,-1, 0, 1, 2, 3, 4,}, // 1
{ 1, 2, 2, 3, 4, 4, 5,}, // 2
{ 4, 5, 5, 5, 6, 6, 6}}; // 3
*/
//增量式反作用 //误差变化率EC
int rule[7][7]={ // 3, 2, 1, 0, 1, 2, 3
{ 6, 6, 6, 5, 5, 5, 4,}, // 3
{ 5, 4, 4, 3, 2, 2, 1,}, // 2
{ 4, 3, 2, 1, 0,-1,-2,}, // 1
{ 4, 3, 1, 0,-1,-3,-4,}, // 0 // 误差E
{ 2, 1, 0,-1,-2,-3,-4,}, // 1
{-1,-2,-2,-3,-4,-4,-5,}, // 2
{-4,-5,-5,-5,-6,-6,-6}}; // 3
/*
//位置式 //误差变化率EC
int rule[7][7]={ // -3,-2,-1, 0, 1, 2, 3
{ 6, 6, 6, 5, 5, 5, 4,}, // -3
{ 5, 4, 4, 3, 2, 2, 1,}, // -2
{ 4, 3, 2, 1, 0, 1, 2,}, // -1
{ 4, 3, 1, 0, 1, 3, 4,}, // 0 // 误差E
{ 2, 1, 0, 1, 2, 3, 4,}, // 1
{ 1, 2, 2, 3, 4, 4, 5,}, // 2
{ 4, 5, 5, 5, 6, 6, 6}}; // 3
*/
/*隶属度的确定*/
/*根据x、y的指定语言值获得有效隶属度*/
if(x>-x_ff[3] && x<x_ff[3])
{
if(x<=-x_ff[2])
{
x_n=-2;
x_f[0]=f_max*((-x_ff[2]-x)/(x_ff[3]-x_ff[2]));
}
else if(x<=-x_ff[1])
{
x_n=-1;
x_f[0]=f_max*((-x_ff[1]-x)/(x_ff[2]-x_ff[1]));
}
else if(x<=x_ff[0])
{
x_n=0;
x_f[0]=f_max*((-x_ff[0]-x)/(x_ff[1]-x_ff[0]));
}
else if(x<=x_ff[1])
{
x_n=1; x_f[0]=f_max*((x_ff[1]-x)/(x_ff[1]-x_ff[0]));
}
else if(x<=x_ff[2])
{
x_n=2; x_f[0]=f_max*((x_ff[2]-x)/(x_ff[2]-x_ff[1]));
}
else if(x<=x_ff[3])
{
x_n=3; x_f[0]=f_max*((x_ff[3]-x)/(x_ff[3]-x_ff[2]));
}
}
else if(x<=-x_ff[3])
{
x_n=-2; x_f[0]=f_max;
}
else if(x>=x_ff[3])
{
x_n=3; x_f[0]=0;
}
x_f[1]=f_max-x_f[0];
if(y>-y_ff[3] && y<y_ff[3])
{
if(y<=-y_ff[2])
{
y_n=-2;y_f[0]=f_max*((-y_ff[2]-y)/(y_ff[3]-y_ff[2]));
}
else if(y<=-y_ff[1])
{
y_n=-1;
y_f[0]=f_max*((-y_ff[1]-y)/(y_ff[2]-y_ff[1]));
}
else if(y<=y_ff[0])
{
y_n=0;
y_f[0]=f_max*((-y_ff[0]-y)/(y_ff[1]-y_ff[0]));
}
else if(y<=y_ff[1])
{
y_n=1;
y_f[0]=f_max*((y_ff[1]-y)/(y_ff[1]-y_ff[0]));
}
else if(y<=y_ff[2])
{
y_n=2; y_f[0]=f_max*((y_ff[2]-y)/(y_ff[2]-y_ff[1]));
}
else if(y<=y_ff[3])
{
y_n=3; y_f[0]=f_max*((y_ff[3]-y)/(y_ff[3]-y_ff[2]));
}
}
else if(y<=-y_ff[3])
{
y_n=-2;
y_f[0]=f_max;
}
else if(y>=y_ff[3])
{
y_n=3;
y_f[0]=0;
}
y_f[1]=f_max-y_f[0];
/*使用误差范围优化后的规则表rule[7][7]*/
/*输出值使用13个隶属函数,中心值由z_ff[7]指定*/
/*一般都是四个规则有效*/
z_n[0]=rule[x_n-1+3][y_n-1+3];
z_n[1]=rule[x_n+3][y_n-1+3];
z_n[2]=rule[x_n-1+3][y_n+3];
z_n[3]=rule[x_n+3][y_n+3];
if(x_f[0]<=y_f[0])
z_f[0]=x_f[0];
else
z_f[0]=y_f[0];
if(x_f[1]<=y_f[0])
z_f[1]=x_f[1];
else
z_f[1]=y_f[0];
if(x_f[0]<=y_f[1])
z_f[2]=x_f[0];
else
z_f[2]=y_f[1];
if(x_f[1]<=y_f[1])
z_f[3]=x_f[1];
else
z_f[3]=y_f[1];
/*同隶属函数输出语言值求大*/
if(z_n[0]==z_n[1])
{
if(z_f[0]>z_f[1])
z_f[1]=0;
else
z_f[0]=0;
}
if(z_n[0]==z_n[2])
{
if(z_f[0]>z_f[2])
z_f[2]=0;
else
z_f[0]=0;
}
if(z_n[0]==z_n[3])
{
if(z_f[0]>z_f[3])
z_f[3]=0;
else
z_f[0]=0;
}
if(z_n[1]==z_n[2])
{
if(z_f[1]>z_f[2])
z_f[2]=0;
else
z_f[1]=0;
}
if(z_n[1]==z_n[3])
{
if(z_f[1]>z_f[3])
z_f[3]=0;
else
z_f[1]=0;
}
if(z_n[2]==z_n[3])
{
if(z_f[2]>z_f[3])
z_f[3]=0;
else
z_f[2]=0;
}
/*重心法反模糊*/
/*z_n[]原值为输出隶属函数标号,转换为隶属函数值*/
if(z_n[0]>=0)
t1= z_f[0]*z_ff[ z_n[0]];
else
t1=-z_f[0]*z_ff[-z_n[0]];
if(z_n[1]>=0)
t2= z_f[1]*z_ff[ z_n[1]];
else
t2=-z_f[1]*z_ff[-z_n[1]];
if(z_n[2]>=0)
t3= z_f[2]*z_ff[ z_n[2]];
else
t3=-z_f[2]*z_ff[-z_n[2]];
if(z_n[3]>=0)
t4= z_f[3]*z_ff[ z_n[3]];
else
t4=-z_f[3]*z_ff[-z_n[3]];
printf("t1:%4.4f,t2:%4.4f,t3:%4.4f,t4:%4.4f \r\n",t1,t2,t3,t4);
temp1=t1+t2+t3+t4;
temp2=z_f[0]+z_f[1]+z_f[2]+z_f[3];//模糊量输出
if(temp2!=0)
z=temp1/temp2;
else
z=0;
return z;
}
增量式修正
//增量式 //误差变化率EC
int rule[7][7]={ //
{-6,-6,-6,-5,-5,-5,-4,}, // -3
{-5,-4,-4,-3,-2,-2,-1,}, // -2
{-4,-3,-2,-1, 0, 1, 2,}, // -1
{-4,-3,-1, 0, 1, 3, 4,}, // 0 // 误差E
{-2,-1, 0, 1, 2, 3, 4,}, // 1
{ 1, 2, 2, 3, 4, 4, 5,}, // 2
{ 4, 5, 5, 5, 6, 6, 6}}; // 3
//累积方式得到空燃比修正值
pidkpxz=pidkpxz+d_fuzzy(e,ec);
pidkp=pidkpjz+pidkpxz;
位置式修正
//位置式 //误差变化率EC
int rule[7][7]={ //
{ 6, 6, 6, 5, 5, 5, 4,}, // -3
{ 5, 4, 4, 3, 2, 2, 1,}, // -2
{ 4, 3, 2, 1, 0, 1, 2,}, // -1
{ 4, 3, 1, 0, 1, 3, 4,}, // 0 // 误差E
{ 2, 1, 0, 1, 2, 3, 4,}, // 1
{ 1, 2, 2, 3, 4, 4, 5,}, // 2
{ 4, 5, 5, 5, 6, 6, 6}}; // 3
//位置方式得到空燃比修正值
pidkpxz=d_fuzzy(e,ec);
pidkp=pidkpjz+pidkpxz;