模糊PID控制算法的C++实现
2017-10-14 20:17
330 查看
很久没有更新博客了,今天就来讲讲模糊PID的C++实现方法。先来看一下整体的框架:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/07/32e137db157f5ab0c526fcdd524121c0)
解释下上面框图的意思,模糊PID其实是在普通PID的基础之上,通过输入的两个变量:误差和误差的变化率的情况来动态的调整PID控制器的三个重要的参数Kp,Ki,Kd。从而使得控制器的性能达到最优。这里的PID参数的整定,使用的是增量的方式,这样可以避免过大的误差,提高整定的精度。
所使用的模糊控制器的设计方法与普通的模糊控制器设计是一样的,具体为:首先,确定模糊控制器的输入为二维输入,即把误差和误差的变化率作为模糊控制器的输入,实际设计时也可以设计成三维或者是其他的输入形式;模糊控制器的输出为PID参数的增量值,分别为kp’, ki’, kd’;
则PID的参数为:
Kp(n)=Kp(n-1)+kp’;
Ki(n)=Ki(n-1)+Ki’;
Kd(n)=Kd(n-1)+kd’;
然后对模糊控制器的输入变量和输出变量划分模糊区间,这里为了模糊控制器设计的简单起见将它们都映射到[-3,3]区间上,统一划分的区间为{-3,-2,-1,0,1,2,3}即为{NB,NM,NS,ZO,PS,PM,PB};确定隶属度函数的形式,常用的隶属度函数类型有三角形隶属度函数,梯形隶属度函数,钟形隶属度函数,正态分布隶属度函数,根据控制对象的需要选择适当的隶属度函数;这里选择的是三角型隶属度函数,因为它形式简单,计算量小,便于在微控制器上实现。隶属度函数下图所示:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/07/6dbef79696b90178f0d1678f69f123c6)
接下来是设计模糊控制器的关键,确定模糊规则,根据前人的大量研究,模糊PID的模糊控制规则一般采用如下的形式,这也是我看过的论文中普遍选择的方式。可能有的控制对象比较特殊需要做一些调整。模糊规则如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/07/f1f95b8e4bcf5aaeb4a9e154e1923223)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/07/fdfacabfe143aa84eb85645d41b062e0)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/07/eace5efd62853144441af510f047e7d9)
有了这些规则就完成了模糊控制器的核心设计,然后就需要确定去模糊的方法,还是使用老的办法,加权平均法计算输出值,公式如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/07/c2326bf341e35761d82270b61f319fbd)
该公式的解释任意一篇关于模糊控制的论文都可以找到,不在赘述。
由以上的描述可以,模糊PID只是使用模糊控制方法来调整PID的参数,从而实现简单的自适应控制,与普通的模糊控制原理并无不同。
需要注意的是:模糊PID一般需要一个比较接近理想控制效果的PID参数初始值,否则,效果并不理想。
了解了模糊PID的控制原理,然后开始编写C++代码,并不是什么难事。这里采用的是C++面向对象的编程思想,设计一个fuzzy_pid类,需要使用时,只需要实例化这个类即可得到一个fuzzy_pid对象,然后调用它的方法就可以实现模糊PID控制,是不是感觉很酷炫;不多说了,直接看代码:
首先是设计fuzzy_pid类的接口;
然后是fuzzy_pid类的实现方法:
之后是简单的测试:
OK,完工,有不明白的欢迎交流!
解释下上面框图的意思,模糊PID其实是在普通PID的基础之上,通过输入的两个变量:误差和误差的变化率的情况来动态的调整PID控制器的三个重要的参数Kp,Ki,Kd。从而使得控制器的性能达到最优。这里的PID参数的整定,使用的是增量的方式,这样可以避免过大的误差,提高整定的精度。
所使用的模糊控制器的设计方法与普通的模糊控制器设计是一样的,具体为:首先,确定模糊控制器的输入为二维输入,即把误差和误差的变化率作为模糊控制器的输入,实际设计时也可以设计成三维或者是其他的输入形式;模糊控制器的输出为PID参数的增量值,分别为kp’, ki’, kd’;
则PID的参数为:
Kp(n)=Kp(n-1)+kp’;
Ki(n)=Ki(n-1)+Ki’;
Kd(n)=Kd(n-1)+kd’;
然后对模糊控制器的输入变量和输出变量划分模糊区间,这里为了模糊控制器设计的简单起见将它们都映射到[-3,3]区间上,统一划分的区间为{-3,-2,-1,0,1,2,3}即为{NB,NM,NS,ZO,PS,PM,PB};确定隶属度函数的形式,常用的隶属度函数类型有三角形隶属度函数,梯形隶属度函数,钟形隶属度函数,正态分布隶属度函数,根据控制对象的需要选择适当的隶属度函数;这里选择的是三角型隶属度函数,因为它形式简单,计算量小,便于在微控制器上实现。隶属度函数下图所示:
接下来是设计模糊控制器的关键,确定模糊规则,根据前人的大量研究,模糊PID的模糊控制规则一般采用如下的形式,这也是我看过的论文中普遍选择的方式。可能有的控制对象比较特殊需要做一些调整。模糊规则如下:
有了这些规则就完成了模糊控制器的核心设计,然后就需要确定去模糊的方法,还是使用老的办法,加权平均法计算输出值,公式如下:
该公式的解释任意一篇关于模糊控制的论文都可以找到,不在赘述。
由以上的描述可以,模糊PID只是使用模糊控制方法来调整PID的参数,从而实现简单的自适应控制,与普通的模糊控制原理并无不同。
需要注意的是:模糊PID一般需要一个比较接近理想控制效果的PID参数初始值,否则,效果并不理想。
了解了模糊PID的控制原理,然后开始编写C++代码,并不是什么难事。这里采用的是C++面向对象的编程思想,设计一个fuzzy_pid类,需要使用时,只需要实例化这个类即可得到一个fuzzy_pid对象,然后调用它的方法就可以实现模糊PID控制,是不是感觉很酷炫;不多说了,直接看代码:
首先是设计fuzzy_pid类的接口;
class FuzzyPID { public: const static int N=7; private: float target; //系统的控制目标 float actual; //采样获得的实际值 float e; //误差 float e_pre_1; //上一次的误差 float e_pre_2; //上上次的误差 float de; //误差的变化率 float emax; //误差基本论域上限 float demax; //误差辩化率基本论域的上限 float delta_Kp_max; //delta_kp输出的上限 float delta_Ki_max; //delta_ki输出上限 float delta_Kd_max; //delta_kd输出上限 float Ke; //Ke=n/emax,量化论域为[-3,-2,-1,0,1,2,3] float Kde; //Kde=n/demax,量化论域为[-3,-2,-1,0,1,2,3] float Ku_p; //Ku_p=Kpmax/n,量化论域为[-3,-2,-1,0,1,2,3] float Ku_i; //Ku_i=Kimax/n,量化论域为[-3,-2,-1,0,1,2,3] float Ku_d; //Ku_d=Kdmax/n,量化论域为[-3,-2,-1,0,1,2,3] int Kp_rule_matrix ;//Kp模糊规则矩阵 int Ki_rule_matrix ;//Ki模糊规则矩阵 int Kd_rule_matrix ;//Kd模糊规则矩阵 string mf_t_e; //e的隶属度函数类型 string mf_t_de; //de的隶属度函数类型 string mf_t_Kp; //kp的隶属度函数类型 string mf_t_Ki; //ki的隶属度函数类型 string mf_t_Kd; //kd的隶属度函数类型 float *e_mf_paras; //误差的隶属度函数的参数 float *de_mf_paras;//误差的偏差隶属度函数的参数 float *Kp_mf_paras; //kp的隶属度函数的参数 float *Ki_mf_paras; //ki的隶属度函数的参数 float *Kd_mf_paras; //kd的隶属度函数的参数 float Kp; float Ki; float< 4000 /span> Kd; float A; float B; float C; void showMf(const string & type,float *mf_paras); //显示隶属度函数的信息 void setMf_sub(const string & type,float *paras,int n);//设置模糊隶属度函数的子函数 public: FuzzyPID(float e_max,float de_max,float kp_max,float ki_max,float kd_max,float Kp0,float Ki0,float Kd0); FuzzyPID(float *fuzzyLimit,float *pidInitVal); ~FuzzyPID(); float trimf(float x,float a,float b,float c); //三角隶属度函数 float gaussmf(float x,float ave,float sigma); //正态隶属度函数 float trapmf(float x,float a,float b,float c,float d); //梯形隶属度函数 void setMf(const string & mf_type_e,float *e_mf, const string & mf_type_de,float *de_mf, const string & mf_type_Kp,float *Kp_mf, const string & mf_type_Ki,float *Ki_mf, const string & mf_type_Kd,float *Kd_mf); //设置模糊隶属度函数的参数 void setRuleMatrix(int kp_m ,int ki_m ,int kd_m ); //设置模糊规则 float realize(float t,float a); //实现模糊控制 void showInfo(); //显示该模糊控制器的信息 };
然后是fuzzy_pid类的实现方法:
#include"fuzzy_PID.h" FuzzyPID::FuzzyPID(float e_max,float de_max,float kp_max,float ki_max,float kd_max,float Kp0,float Ki0,float Kd0): target(0),actual(0),emax(e_max),demax(de_max),delta_Kp_max(kp_max),delta_Ki_max(ki_max),delta_Kd_max(kd_max),e_mf_paras(NULL),de_mf_paras(NULL), Kp_mf_paras(NULL),Ki_mf_paras(NULL),Kd_mf_paras(NULL) { e=target-actual; e_pre_1=0; e_pre_2=0; de=e-e_pre_1; Ke=(N/2)/emax; Kde=(N/2)/demax; Ku_p=delta_Kp_max/(N/2); Ku_i=delta_Ki_max/(N/2); Ku_d=delta_Kd_max/(N/2); mf_t_e="No type"; mf_t_de="No type"; mf_t_Kp="No type"; mf_t_Ki="No type"; mf_t_Kd="No type"; Kp=Kp0; Ki=Ki0; Kd=Kd0; A=Kp+Ki+Kd; B=-2*Kd-Kp; C=Kd; } FuzzyPID::FuzzyPID(float *fuzzyLimit,float *pidInitVal) { target=0; actual=0; e=0; e_pre_1=0; e_pre_2=0; de=e-e_pre_1; emax=fuzzyLimit[0]; demax=fuzzyLimit[1]; delta_Kp_max=fuzzyLimit[2]; delta_Ki_max=fuzzyLimit[3]; delta_Kd_max=fuzzyLimit[4]; Ke=(N/2)/emax; Kde=(N/2)/demax; Ku_p=delta_Kp_max/(N/2); Ku_i=delta_Ki_max/(N/2); Ku_d=delta_Kd_max/(N/2); mf_t_e="No type"; mf_t_de="No type"; mf_t_Kp="No type"; mf_t_Ki="No type"; mf_t_Kd="No type"; e_mf_paras=NULL; de_mf_paras=NULL; Kp_mf_paras=NULL; Ki_mf_paras=NULL; Kd_mf_paras=NULL; Kp=pidInitVal[0]; Ki=pidInitVal[1]; Kd=pidInitVal[2]; A=Kp+Ki+Kd; B=-2*Kd-Kp; C=Kd; } FuzzyPID::~FuzzyPID() { delete [] e_mf_paras; delete [] de_mf_paras; delete [] Kp_mf_paras; delete [] Ki_mf_paras; delete [] Kd_mf_paras; } //三角隶属度函数 float FuzzyPID::trimf(float x,float a,float b,float c) { float u; if(x>=a&&x<=b) u=(x-a)/(b-a); else if(x>b&&x<=c) u=(c-x)/(c-b); else u=0.0; return u; } //正态隶属度函数 float FuzzyPID::gaussmf(float x,float ave,float sigma) { float u; if(sigma<0) { cout<<"In gaussmf, sigma must larger than 0"<<endl; } u=exp(-pow(((x-ave)/sigma),2)); return u; } //梯形隶属度函数 float FuzzyPID::trapmf(float x,float a,float b,float c,float d) { float u; if(x>=a&&x<b) u=(x-a)/(b-a); else if(x>=b&&x<c) u=1; else if(x>=c&&x<=d) u=(d-x)/(d-c); else u=0; return u; } //设置模糊规则Matrix void FuzzyPID::setRuleMatrix(int kp_m ,int ki_m ,int kd_m ) { for(int i=0;i<N;i++) for(int j=0;j<N;j++) { Kp_rule_matrix[i][j]=kp_m[i][j]; Ki_rule_matrix[i][j]=ki_m[i][j]; Kd_rule_matrix[i][j]=kd_m[i][j]; } } //设置模糊隶属度函数的子函数 void FuzzyPID::setMf_sub(const string & type,float *paras,int n) { int N_mf_e,N_mf_de,N_mf_Kp,N_mf_Ki,N_mf_Kd; switch(n) { case 0: if(type=="trimf"||type=="gaussmf"||type=="trapmf") mf_t_e=type; else cout<<"Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\""<<endl; if(mf_t_e=="trimf") N_mf_e=3; else if(mf_t_e=="gaussmf") N_mf_e=2; else if(mf_t_e=="trapmf") N_mf_e=4; e_mf_paras=new float [N*N_mf_e]; for(int i=0;i<N*N_mf_e;i++) e_mf_paras[i]=paras[i]; break; case 1: if(type=="trimf"||type=="gaussmf"||type=="trapmf") mf_t_de=type; else cout<<"Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\""<<endl; if(mf_t_de=="trimf") N_mf_de=3; else if(mf_t_de=="gaussmf") N_mf_de=2; else if(mf_t_de=="trapmf") N_mf_de=4; de_mf_paras=new float [N*N_mf_de]; for(int i=0;i<N*N_mf_de;i++) de_mf_paras[i]=paras[i]; break; case 2: if(type=="trimf"||type=="gaussmf"||type=="trapmf") mf_t_Kp=type; else cout<<"Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\""<<endl; if(mf_t_Kp=="trimf") N_mf_Kp=3; else if(mf_t_Kp=="gaussmf") N_mf_Kp=2; else if(mf_t_Kp=="trapmf") N_mf_Kp=4; Kp_mf_paras=new float [N*N_mf_Kp]; for(int i=0;i<N*N_mf_Kp;i++) Kp_mf_paras[i]=paras[i]; break; case 3: if(type=="trimf"||type=="gaussmf"||type=="trapmf") mf_t_Ki=type; else cout<<"Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\""<<endl; if(mf_t_Ki=="trimf") N_mf_Ki=3; else if(mf_t_Ki=="gaussmf") N_mf_Ki=2; else if(mf_t_Ki=="trapmf") N_mf_Ki=4; Ki_mf_paras=new float [N*N_mf_Ki]; for(int i=0;i<N*N_mf_Ki;i++) Ki_mf_paras[i]=paras[i]; break; case 4: if(type=="trimf"||type=="gaussmf"||type=="trapmf") mf_t_Kd=type; else< 11ba6 /span> cout<<"Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\""<<endl; if(mf_t_Kd=="trimf") N_mf_Kd=3; else if(mf_t_Kd=="gaussmf") N_mf_Kd=2; else if(mf_t_Kd=="trapmf") N_mf_Kd=4; Kd_mf_paras=new float [N*N_mf_Kd]; for(int i=0;i<N*N_mf_Kd;i++) Kd_mf_paras[i]=paras[i]; break; default: break; } } //设置模糊隶属度函数的类型和参数 void FuzzyPID::setMf(const string & mf_type_e,float *e_mf, const string & mf_type_de,float *de_mf, const string & mf_type_Kp,float *Kp_mf, const string & mf_type_Ki,float *Ki_mf, const string & mf_type_Kd,float *Kd_mf) { setMf_sub(mf_type_e,e_mf,0); setMf_sub(mf_type_de,de_mf,1); setMf_sub(mf_type_Kp,Kp_mf,2); setMf_sub(mf_type_Ki,Ki_mf,3); setMf_sub(mf_type_Kd,Kd_mf,4); } //实现模糊控制 float FuzzyPID::realize(float t,float a) { float u_e ,u_de ,u_u ; int u_e_index[3],u_de_index[3];//假设一个输入最多激活3个模糊子集 float delta_Kp,delta_Ki,delta_Kd; float delta_u; target=t; actual=a; e=target-actual; de=e-e_pre_1; e=Ke*e; de=Kde*de; /* 将误差e模糊化*/ int j=0; for(int i=0;i<N;i++) { if(mf_t_e=="trimf") u_e[i]=trimf(e,e_mf_paras[i*3],e_mf_paras[i*3+1],e_mf_paras[i*3+2]);//e模糊化,计算它的隶属度 else if(mf_t_e=="gaussmf") u_e[i]=gaussmf(e,e_mf_paras[i*2],e_mf_paras[i*2+1]);//e模糊化,计算它的隶属度 else if(mf_t_e=="trapmf") u_e[i]=trapmf(e,e_mf_paras[i*4],e_mf_paras[i*4+1],e_mf_paras[i*4+2],e_mf_paras[i*4+3]);//e模糊化,计算它的隶属度 if(u_e[i]!=0) u_e_index[j++]=i; //存储被激活的模糊子集的下标,可以减小计算量 } for(;j<3;j++)u_e_index[j]=0; //富余的空间填0 /*将误差变化率de模糊化*/ j=0; for(int i=0;i<N;i++) { if(mf_t_de=="trimf") u_de[i]=trimf(de,de_mf_paras[i*3],de_mf_paras[i*3+1],de_mf_paras[i*3+2]);//de模糊化,计算它的隶属度 else if(mf_t_de=="gaussmf") u_de[i]=gaussmf(de,de_mf_paras[i*2],de_mf_paras[i*2+1]);//de模糊化,计算它的隶属度 else if(mf_t_de=="trapmf") u_de[i]=trapmf(de,de_mf_paras[i*4],de_mf_paras[i*4+1],de_mf_paras[i*4+2],de_mf_paras[i*4+3]);//de模糊化,计算它的隶属度 if(u_de[i]!=0) u_de_index[j++]=i; //存储被激活的模糊子集的下标,可以减小计算量 } for(;j<3;j++)u_de_index[j]=0; //富余的空间填0 float den=0,num=0; /*计算delta_Kp和Kp*/ for(int m=0;m<3;m++) for(int n=0;n<3;n++) { num+=u_e[u_e_index[m]]*u_de[u_de_index ]*Kp_rule_matrix[u_e_index[m]][u_de_index ]; den+=u_e[u_e_index[m]]*u_de[u_de_index ]; } delta_Kp=num/den; delta_Kp=Ku_p*delta_Kp; if(delta_Kp>=delta_Kp_max) delta_Kp=delta_Kp_max; else if(delta_Kp<=-delta_Kp_max) delta_Kp=-delta_Kp_max; Kp+=delta_Kp; if(Kp<0)Kp=0; /*计算delta_Ki和Ki*/ den=0;num=0; for(int m=0;m<3;m++) for(int n=0;n<3;n++) { num+=u_e[u_e_index[m]]*u_de[u_de_index ]*Ki_rule_matrix[u_e_index[m]][u_de_index ]; den+=u_e[u_e_index[m]]*u_de[u_de_index ]; } delta_Ki=num/den; delta_Ki=Ku_i*delta_Ki; if(delta_Ki>=delta_Ki_max) delta_Ki=delta_Ki_max; else if(delta_Ki<=-delta_Ki_max) delta_Ki=-delta_Ki_max; Ki+=delta_Ki; if(Ki<0)Ki=0; /*计算delta_Kd和Kd*/ den=0;num=0; for(int m=0;m<3;m++) for(int n=0;n<3;n++) { num+=u_e[u_e_index[m]]*u_de[u_de_index ]*Kd_rule_matrix[u_e_index[m]][u_de_index ]; den+=u_e[u_e_index[m]]*u_de[u_de_index ]; } delta_Kd=num/den; delta_Kd=Ku_d*delta_Kd; if(delta_Kd>=delta_Kd_max) delta_Kd=delta_Kd_max; else if(delta_Kd<=-delta_Kd_max) delta_Kd=-delta_Kd_max; Kd+=delta_Kd; if(Kd<0)Kd=0; A=Kp+Ki+Kd; B=-2*Kd-Kp; C=Kd; delta_u=A*e+B*e_pre_1+C*e_pre_2; delta_u=delta_u/Ke; if(delta_u>=0.95*target)delta_u=0.95*target; else if(delta_u<=-0.95*target)delta_u=-0.95*target; e_pre_2=e_pre_1; e_pre_1=e; return delta_u; } void FuzzyPID::showMf(const string & type,float *mf_paras) { int tab; if(type=="trimf") tab=2; else if(type=="gaussmf") tab==1; else if(type=="trapmf") tab=3; cout<<"函数类型:"<<mf_t_e<<endl; cout<<"函数参数列表:"<<endl; float *p=mf_paras; for(int i=0;i<N*(tab+1);i++) { cout.width(3); cout<<p[i]<<" "; if(i%(tab+1)==tab) cout<<endl; } } void FuzzyPID::showInfo() { cout<<"Info of this fuzzy controller is as following:"<<endl; cout<<"基本论域e:["<<-emax<<","<<emax<<"]"<<endl; cout<<"基本论域de:["<<-demax<<","<<demax<<"]"<<endl; cout<<"基本论域delta_Kp:["<<-delta_Kp_max<<","<<delta_Kp_max<<"]"<<endl; cout<<"基本论域delta_Ki:["<<-delta_Ki_max<<","<<delta_Ki_max<<"]"<<endl; cout<<"基本论域delta_Kd:["<<-delta_Kd_max<<","<<delta_Kd_max<<"]"<<endl; cout<<"误差e的模糊隶属度函数参数:"<<endl; showMf(mf_t_e,e_mf_paras); cout<<"误差变化率de的模糊隶属度函数参数:"<<endl; showMf(mf_t_de,de_mf_paras); cout<<"delta_Kp的模糊隶属度函数参数:"<<endl; showMf(mf_t_Kp,Kp_mf_paras); cout<<"delta_Ki的模糊隶属度函数参数:"<<endl; showMf(mf_t_Ki,Ki_mf_paras); cout<<"delta_Kd的模糊隶属度函数参数:"<<endl; showMf(mf_t_Kd,Kd_mf_paras); cout<<"模糊规则表:"<<endl; cout<<"delta_Kp的模糊规则矩阵"<<endl; for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { cout.width(3); cout<<Kp_rule_matrix[i][j]<<" "; } cout<<endl; } cout<<"delta_Ki的模糊规则矩阵"<<endl; for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { cout.width(3); cout<<Ki_rule_matrix[i][j]<<" "; } cout<<endl; } cout<<"delta_Kd的模糊规则矩阵"<<endl; for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { cout.width(3); cout<<Kd_rule_matrix[i][j]<<" "; } cout<<endl; } cout<<endl; cout<<"误差的量化比例因子Ke="<<Ke<<endl; cout<<"误差变化率的量化比例因子Kde="<<Kde<<endl; cout<<"输出的量化比例因子Ku_p="<<Ku_p<<endl; cout<<"输出的量化比例因子Ku_i="<<Ku_i<<endl; cout<<"输出的量化比例因子Ku_d="<<Ku_d<<endl; cout<<"设定目标target="<<target<<endl; cout<<"误差e="<<e<<endl; cout<<"Kp="<<Kp<<endl; cout<<"Ki="<<Ki<<endl; cout<<"Kd="<<Kd<<endl; cout<<endl; }
之后是简单的测试:
#include<iostream> #include"fuzzy_PID.h" #define NB -3 #define NM -2 #define NS -1 #define ZO 0 #define PS 1 #define PM 2 #define PB 3 int main() { float target=600; float actual=0; float u=0; int deltaKpMatrix[7][7]={{PB,PB,PM,PM,PS,ZO,ZO}, {PB,PB,PM,PS,PS,ZO,NS}, {PM,PM,PM,PS,ZO,NS,NS}, {PM,PM,PS,ZO,NS,NM,NM}, {PS,PS,ZO,NS,NS,NM,NM}, {PS,ZO,NS,NM,NM,NM,NB}, {ZO,ZO,NM,NM,NM,NB,NB}}; int deltaKiMatrix[7][7]={{NB,NB,NM,NM,NS,ZO,ZO}, {NB,NB,NM,NS,NS,ZO,ZO}, {NB,NM,NS,NS,ZO,PS,PS}, {NM,NM,NS,ZO,PS,PM,PM}, {NM,NS,ZO,PS,PS,PM,PB}, {ZO,ZO,PS,PS,PM,PB,PB}, {ZO,ZO,PS,PM,PM,PB,PB}}; int deltaKdMatrix[7][7]={{PS,NS,NB,NB,NB,NM,PS}, {PS,NS,NB,NM,NM,NS,ZO}, {ZO,NS,NM,NM,NS,NS,ZO}, {ZO,NS,NS,NS,NS,NS,ZO}, {ZO,ZO,ZO,ZO,ZO,ZO,ZO}, {PB,NS,PS,PS,PS,PS,PB}, {PB,PM,PM,PM,PS,PS,PB}}; float e_mf_paras[]={-3,-3,-2,-3,-2,-1,-2,-1,0,-1,0,1,0,1,2,1,2,3,2,3,3}; float de_mf_paras[]={-3,-3,-2,-3,-2,-1,-2,-1,0,-1,0,1,0,1,2,1,2,3,2,3,3}; float Kp_mf_paras[]={-3,-3,-2,-3,-2,-1,-2,-1,0,-1,0,1,0,1,2,1,2,3,2,3,3}; float Ki_mf_paras[]={-3,-3,-2,-3,-2,-1,-2,-1,0,-1,0,1,0,1,2,1,2,3,2,3,3}; float Kd_mf_paras[]={-3,-3,-2,-3,-2,-1,-2,-1,0,-1,0,1,0,1,2,1,2,3,2,3,3}; FuzzyPID fuzzypid(1500,650,0.3,0.9,0.6,0.01,0.04,0.01); fuzzypid.setMf("trimf",e_mf_paras,"trimf",de_mf_paras,"trimf",Kp_mf_paras,"trimf",Ki_mf_paras,"trimf",Kd_mf_paras); fuzzypid.setRuleMatrix(deltaKpMatrix,deltaKiMatrix,deltaKdMatrix); cout<<"num target actual"<<endl; /*fuzzy.showInfo();*/ for(int i=0;i<50;i++) { u=fuzzypid.realize(target,actual); actual+=u; cout<<i<<" "<<target<<" "<<actual<<endl; } fuzzypid.showInfo(); system("pause"); return 0; }
OK,完工,有不明白的欢迎交流!
相关文章推荐
- 一个轻量级Actor并发框架的c++实现, libgsc(Game Server Communication Library)(一)
- c++接口实现
- k-means聚类算法C++实现
- 采用C++的ACE库实现的一个通用的C/S架构通信程序(最终版)
- 设计模式C++实现(1)——工厂模式
- 常见设计模式的解析和实现(C++)之十一-TemplateMethod模式
- 矩阵相乘strassen-c++代码实现及运行实例结果
- c++ 虚函数的实现机制
- AVL树(C++模块实现)
- 设计模式C++实现(16)——状态模式
- 常见设计模式的解析和实现(C++)之二十一-完结篇
- C++调用HTTP实现方式
- C++实现文件关联
- 数值的整数次方(C++ 和 Python 实现)
- c++实现平面上的形状编辑
- linux c++线程池的实现(多线程服务器)
- Windows下C++开机启动功能实现
- 单向链表类(C++实现)
- 复数四则运算-c++代码实现及运行实例结果
- 数据结构:BF算法,KMP算法之C、C++的实现