精华内容
下载资源
问答
  • 模糊PID控制算法

    2018-10-21 20:41:30
    模糊PID控制算法,里面有文档介绍,m文件,清晰解释模糊PID算法的过程
  • 电脑鼠模糊PID控制算法研究,很好的电脑鼠资料,适合学习PID等一系列学习。
  • 本文给出了一种采用双层恒温槽及采用模糊PID控制算法,外层加温部分控制基础加温,内层加温部分实现精确加温,从而提高恒温石英晶体振荡器的稳定性和启动性的设计方法。同时,在MATLAB环境下建立了数学模型,进行了...
  • 针对开关磁阻电机非线性严重、参数及结构易变的特点,在开关磁阻电机的调速中引入变论域模糊PID控制算法。首先从基本电磁规律出发,分析了开关磁阻电机的工作原理及调速特性。介绍了变论域模糊PID的控制原理,并对...
  • 模糊PID控制算法的C++实现

    万次阅读 多人点赞 2017-10-14 20:17:53
    模糊PID的C++实现方法

    很久没有更新博客了,今天就来讲讲模糊PID的C++实现方法。先来看一下整体的框架:
    模糊PID的整体框架

    解释下上面框图的意思,模糊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[N][N];//Kp模糊规则矩阵
    	int Ki_rule_matrix[N][N];//Ki模糊规则矩阵
    	int Kd_rule_matrix[N][N];//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 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[N][N],int ki_m[N][N],int kd_m[N][N]);  //设置模糊规则
    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[N][N],int ki_m[N][N],int kd_m[N][N])
    {
    	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
    		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[N],u_de[N],u_u[N];
    	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[n]]*Kp_rule_matrix[u_e_index[m]][u_de_index[n]];
    		   den+=u_e[u_e_index[m]]*u_de[u_de_index[n]];
    		}
    	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[n]]*Ki_rule_matrix[u_e_index[m]][u_de_index[n]];
    		   den+=u_e[u_e_index[m]]*u_de[u_de_index[n]];
    		}
    
    	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[n]]*Kd_rule_matrix[u_e_index[m]][u_de_index[n]];
    		   den+=u_e[u_e_index[m]]*u_de[u_de_index[n]];
    		}
    	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,完工,有不明白的欢迎交流!
    代码已经上传至CSDN,需要参考的朋友可以下载看看:
    https://download.csdn.net/download/shuoyueqishilove/10433941

    展开全文
  • 以汽车制动力学方程为基础,设计了参数模糊PID控制器,对参数模糊PID控制算法在汽车制动系统中应用进行研究. 该控制算法补充了常规PID、逻辑门限制控制算法的不足. 仿真结果表明,该参数模糊控制系统能够达到预期...
  • 本论文将探索用模糊PID控制算法来控制高炉鼓风机的运行,以TMS320F2812DSP为硬件平台,通过调节防喘振阀,对鼓风机的风压、风量进行实时监测,当发生喘振时,通过调控防喘振阀开闭,使高炉鼓风机工作在安全区域。
  • 基于视觉的智能车模糊PID控制算法 ,基于freescale公司的16位HCS12单片机设计一种智能车系统。系统摄像头采集路径信息,通过单片机 的模糊推理机在线整定PID参数,使小车能按照任意给定的黑色引导线平稳地寻迹。
  • 1.积分分离PID控制算法PID控制中引入积分环节,主要是为了消除静差,提高控制精度。但在启动、结束或大幅度增减指令时,短时间内系统有很大输出,由于积分积累的作用,致使控制量超过执行机构可能运行的最大动作...

    一些原来在模拟PID控制器中无法实现的问题,现在我们很容易就能在数字计算机上实现了,于是产生来了一系列改进的控制算法,形成非标准的控制算法,改善系统品质,满足不同控制系统的需要。

    1.积分分离PID控制算法

    PID控制中引入积分环节,主要是为了消除静差,提高控制精度。但在启动、结束或大幅度增减指令时,短时间内系统有很大输出,由于积分积累的作用,致使控制量超过执行机构可能运行的最大动作范围对应的极限控制量,引起系统较大的超调,甚至引起系统较大的振荡,这在生产中是绝对不允许的。积分分离的基本思想是:当偏差较大时取消积分作用,当被控量接近给定值时,引入积分控制,以减小静差。

    积分分离PID的控制形式为:

    b67d535af5204007d69a9ef1aca0b5ef.png

    2.遇限削弱积分法

    这一方法是考虑了在实际过程中,控制变量U因受到执行元件机械和物理性能的约束而控制在有限范围内,即

    Umin≤U≤Umax

    该方法的思想是:一旦控制变量进入饱和区,将只执行削弱积分项的运算而停止进行增大积分项的运算。也就是说,在计算U(k)时,将判断上一时刻的控制量U(k)是否已超出限制范围,如果已超出,那么将根据偏差的符号,判断系统输出是否在超调区域,由此决定是否将相应偏差计入积分项。其计算流程图如图1所示。

    c26205b5b4b8df719a969ad2b11786a7.png

    3.不完全微分PID控制

    当信号突变时,PID控制的微分项输出的控制量可能比较大,尤其是阶跃信号时,微分项急剧增加,容易引起调节过程的振荡,导致系统的动态品质下降。

    不完全微分PID控制算法就是采用一个带惯性的微分环节来克服常规PID控制的这一缺点。它的控制结构如图2所示。

    2eb4a42d1d497f92b0e0d0fb1c0941e7.png

    4.微分先行PID控制

    微分先行PID控制是只对输出量进行微分,而对给定指令不起微分作用,因此它适合于给定指令频繁升降的场合,可以避免指令的改变导致超调过大。

    它的控制结构如图3所示。

    50eb79c7418394b4db852cdffa0738fa.png

    5.带死区的PID控制

    在控制精度要求不高、控制过程要求平稳的场合,为了避免控制动作过于频繁,消除由此引起的振荡,可以人为的设置一个不灵敏区B,即带死区的PID控制。只有不在死区范围内时,才按PID算式计算控制量。其结构如图4所示。

    e73611854784bebda8a82e246e443796.png

    以上是一些常用的较为简单的改进PID控制,当然,随着控制理论的发展,目前各种新的改进型PID控制不断出现,包括与智能控制相结合而形成的模糊PID,神经网络PID等等,但是从实用性来看,上述方法在很长的一段时间内都将是工程设计人员的首选。

    展开全文
  • 模糊PID控制算法讲解与代码

    千次下载 热门讨论 2011-05-01 21:08:48
    本资源讲解了利用模糊理论与PID控制理论相结合的思路,设计了模糊PID控制器,并用于液压伺服系统中。
  • 反应釜的温度控制占有着极为重要的地位。在实际的化工生产过程中,温度是工业生产中常见的工艺参数之一,任何物理变化和化学反应过程都与温度密切相关。反应过程中伴随有大量的吸、放热现象,具有大滞后、时变、非...

    化工行业在我国国民经济发展中占有重要地位,其中反应釜作为化工生产中实现化学反应的主要设备。在实际的化工生产过程中,反应釜的温度决定了产品的产量、质量,有时甚至影响到生产过程中的安全性。

    反应釜的温度控制占有着极为重要的地位。在实际的化工生产过程中,温度是工业生产中常见的工艺参数之一,任何物理变化和化学反应过程都与温度密切相关。

    a1c60ec43f7a89e585dfa3cf1a51f80a.png

    反应过程中伴随有大量的吸、放热现象,具有大滞后、时变、非线性、反应机理复杂等特点。因此如何对反应釜内化学反应温度进行精确、有效的控制,显得至关重要。

    然而,由于温度控制系统的过程复杂多变,具有不确定性,因此温度系统的要求更为先进的控制技术和控制理论。反应釜控温设备模糊控制是一种基于规则的语言控制,在设计中不需要建立被控对象的准确数学模型,鲁棒性强,干扰和参数变化对控制效果的影响被大大减弱,摔制效果好。

    34b4d96859f82e5f52b016d837bbdbc6.png

    传统的PID控制是一种基于过程参数的控制方法,具有控制原理简单、稳定性好、可靠性高、参数易调整等优点,但其设计依赖于被控对象的准确数学模型,在线整定参数的能力差,而反应釜因为机理复杂、各个参数在系统反应过程中时变,不能建立准确的数学模型,不能满足系统在不同条件下对参数自整定的要求,因而采用一般的PID控制器无法实现对反应釜的准确控制。

    模糊控制器是以误差和误差变化作为输入变量,这种控制器具有模糊比例-微分控制作用,精度不太高、稳态误差较大、自适应能力有限和易产生振荡现象。预测控制是一种优化控制算法,它是通过对某一性能指标的较优来确定未来的控制作用的,具有对模型要求低、鲁棒性好、适用于数字计算机控制的优点。

    7f36b133cfd38a098c89f264b24c5574.png

    由于计算机模型预测控制具有良好的跟踪性能,能有效地提高系统的稳定性和消除误差,对滞后过程有明显控制效果,更加符合工业温度控制的实际要求,从而大大提高了温度控制系统的性能。

    反应釜控温设备总结当前温度控制系统精度差的根本原因,在此基础上采用基于预测的模糊自整定PID集成控制技术实现反应釜温度控制,其主要思想是利用系统模型的预测输出,结合常规PID的控制经验,采用模糊推理方法,对控制器算法进行改进。

    模糊PID控制的反应釜控温设备与普通控制方案相比,该方案提高了系统的鲁棒性和适应性,较好的解决了反应釜温度控制的难题。控制性能更加稳定,可靠性更高,实时性、适应性、鲁棒性都显著增强,控制效果较好。

    展开全文
  • 目的是看看哪个算法好用,移植的时候比较单纯没有研究懂算法,代码结构也没改动,只是移植到C#方便查看代码和测试,大家要拷贝也很方便,把整个类拷贝到.cs文件即可 这段算法在实际值低于目标值c#教程是工作正常,...

    跑起来的效果看每个类的test方法,自己调用来测试

    目的是看看哪个算法好用,移植的时候比较单纯没有研究懂算法,代码结构也没改动,只是移植到C#方便查看代码和测试,大家要拷贝也很方便,把整个类拷贝到.cs文件即可

    这段算法在实际值低于目标值c#教程是工作正常,超过后会有问题,不知道如何调教

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace FuzzyPID
    {
      class FuzzyPID
      {
        public const int N = 7;
     
        double target; //系统的控制目标
        double actual; //采样获得的实际值
        double e; //误差
        double e_pre_1; //上一次的误差
        double e_pre_2; //上上次的误差
        double de;   //误差的变化率
        double emax;  //误差基本论域上限
        double demax;  //误差辩化率基本论域的上限
        double delta_Kp_max;  //delta_kp输出的上限
        double delta_Ki_max;  //delta_ki输出上限
        double delta_Kd_max;  //delta_kd输出上限
        double Ke;   //Ke=n/emax,量化论域为[-3,-2,-1,0,1,2,3]
        double Kde;   //Kde=n/demax,量化论域为[-3,-2,-1,0,1,2,3]
        double Ku_p;  //Ku_p=Kpmax/n,量化论域为[-3,-2,-1,0,1,2,3]
        double Ku_i;  //Ku_i=Kimax/n,量化论域为[-3,-2,-1,0,1,2,3]
        double Ku_d;  //Ku_d=Kdmax/n,量化论域为[-3,-2,-1,0,1,2,3]
        int[,] Kp_rule_matrix = new int[N, N];//Kp模糊规则矩阵
        int[,] Ki_rule_matrix = new int[N, N];//Ki模糊规则矩阵
        int[,] Kd_rule_matrix = new int[N, N];//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的隶属度函数类型
        double[] e_mf_paras; //误差的隶属度函数的参数
        double[] de_mf_paras;//误差的偏差隶属度函数的参数
        double[] Kp_mf_paras; //kp的隶属度函数的参数
        double[] Ki_mf_paras; //ki的隶属度函数的参数
        double[] Kd_mf_paras; //kd的隶属度函数的参数
        double Kp;
        double Ki;
        double Kd;
        double A;
        double B;
        double C;
     
        public FuzzyPID(double e_max, double de_max, double kp_max, double ki_max, double kd_max, double Kp0, double Ki0, double Kd0)
        {
          emax = e_max;
          demax = de_max;
          delta_Kp_max = kp_max;
          delta_Ki_max = ki_max;
          delta_Kd_max = kd_max;
          e = target - actual;
          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);
          Kp = Kp0;
          Ki = Ki0;
          Kd = Kd0;
          A = Kp + Ki + Kd;
          B = -2 * Kd - Kp;
          C = Kd;
        }
     
        //三角隶属度函数
        double trimf(double x, double a, double b, double c)
        {
          double 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;
          return u;
        }
     
        //正态隶属度函数
        double gaussmf(double x, double ave, double sigma)
        {
          double u;
          if (sigma < 0)
          {
            throw new Exception("In gaussmf, sigma must larger than 0");
          }
          u = Math.Exp(-Math.Pow(((x - ave) / sigma), 2));
          return u;
        }
     
        //梯形隶属度函数
        double trapmf(double x, double a, double b, double c, double d)
        {
          double 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
        public void 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 setMf_sub(string type, double[] paras, int n)
        {
          int N_mf_e = 0, N_mf_de = 0, N_mf_Kp = 0, N_mf_Ki = 0, N_mf_Kd = 0;
          switch (n)
          {
            case 0:
              if (type == "trimf" || type == "gaussmf" || type == "trapmf")
                mf_t_e = type;
              else
                throw new Exception("Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\"");
              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 double[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
                throw new Exception("Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\"");
              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 double[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
                throw new Exception("Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\"");
              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 double[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
                throw new Exception("Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\"");
              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 double[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
                throw new Exception("Type of membership function must be \"trimf\" or \"gaussmf\" or \"trapmf\"");
              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 double[N * N_mf_Kd];
              for (int i = 0; i < N * N_mf_Kd; i++)
                Kd_mf_paras[i] = paras[i];
              break;
     
            default: break;
          }
        }
     
     
        //设置模糊隶属度函数的类型和参数
        public void setMf(string mf_type_e, double[] e_mf,
           string mf_type_de, double[] de_mf,
           string mf_type_Kp, double[] Kp_mf,
           string mf_type_Ki, double[] Ki_mf,
           string mf_type_Kd, double[] 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);
        }
     
        //实现模糊控制
        public double realize(double t, double a)
        {
          double[] u_e = new double[N],
            u_de = new double[N],
            u_u = new double[N];
          int[] u_e_index = new int[3], u_de_index = new int[3];//假设一个输入最多激活3个模糊子集
          double delta_Kp, delta_Ki, delta_Kd;
          double 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
     
          double 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[n]] * Kp_rule_matrix[u_e_index[m], u_de_index[n]];
              den += u_e[u_e_index[m]] * u_de[u_de_index[n]];
            }
          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[n]] * Ki_rule_matrix[u_e_index[m], u_de_index[n]];
              den += u_e[u_e_index[m]] * u_de[u_de_index[n]];
            }
     
          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[n]] * Kd_rule_matrix[u_e_index[m], u_de_index[n]];
              den += u_e[u_e_index[m]] * u_de[u_de_index[n]];
            }
          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 showMf(string type, double[] mf_paras)
        {
          int tab = 0;
          if (type == "trimf")
            tab = 2;
          else if (type == "gaussmf")
            tab = 1;
          else if (type == "trapmf")
            tab = 3;
          this.WriteLine($"函数类型:{mf_t_e}");
          this.WriteLine("函数参数列表:");
          double[] p = mf_paras;
          for (int i = 0; i < N * (tab + 1); i++)
          {
            this.Write(p[i] + " ");
            if (i % (tab + 1) == tab)
              this.Write("\r\n");
          }
        }
     
        public void showInfo()
        {
          this.WriteLine("Info of this fuzzy controller is as following:");
          this.WriteLine($"基本论域e:[{-emax},{emax}]");
          this.WriteLine($"基本论域de:[{-demax},{demax}]");
          this.WriteLine($"基本论域delta_Kp:[{-delta_Kp_max},{delta_Kp_max}]");
          this.WriteLine($"基本论域delta_Ki:[{-delta_Ki_max},{delta_Ki_max}]");
          this.WriteLine($"基本论域delta_Kd:[{-delta_Kd_max},{delta_Kd_max}]");
          this.WriteLine("误差e的模糊隶属度函数参数:");
          showMf(mf_t_e, e_mf_paras);
          this.WriteLine("误差变化率de的模糊隶属度函数参数:");
          showMf(mf_t_de, de_mf_paras);
          this.WriteLine("delta_Kp的模糊隶属度函数参数:");
          showMf(mf_t_Kp, Kp_mf_paras);
          this.WriteLine("delta_Ki的模糊隶属度函数参数:");
          showMf(mf_t_Ki, Ki_mf_paras);
          this.WriteLine("delta_Kd的模糊隶属度函数参数:");
          showMf(mf_t_Kd, Kd_mf_paras);
          this.WriteLine("模糊规则表:");
          this.WriteLine("delta_Kp的模糊规则矩阵");
          for (int i = 0; i < N; i++)
          {
            for (int j = 0; j < N; j++)
            {
              this.Write(Kp_rule_matrix[i, j]);
            }
            this.Write("\r\n");
          }
          this.WriteLine("delta_Ki的模糊规则矩阵"); ;
          for (int i = 0; i < N; i++)
          {
            for (int j = 0; j < N; j++)
            {
              this.WriteLine(Ki_rule_matrix[i, j]);
            }
            WriteEnd();
          }
          this.WriteLine("delta_Kd的模糊规则矩阵"); ;
          for (int i = 0; i < N; i++)
          {
            for (int j = 0; j < N; j++)
            {
              this.WriteLine(Kd_rule_matrix[i, j]);
            }
            WriteEnd();
          }
          this.WriteLine($"误差的量化比例因子Ke={Ke}");
          this.WriteLine($"误差变化率的量化比例因子Kde={Kde}");
          this.WriteLine($"输出的量化比例因子Ku_p={Ku_p}");
          this.WriteLine($"输出的量化比例因子Ku_i={Ku_i}");
          this.WriteLine($"输出的量化比例因子Ku_d={Ku_d}");
          this.WriteLine($"设定目标target={target}");
          this.WriteLine($"误差e={e}");
          this.WriteLine($"Kp={Kp}");
          this.WriteLine($"Ki={Ki}");
          this.WriteLine($"Kd={Kd}");
          WriteEnd();
        }
     
        public void Write(object str)
        {
          Console.Write(str);
        }
        public void WriteLine(object str)
        {
          Console.WriteLine(str);
        }
        public void WriteEnd()
        {
          Console.Write("\r\n");
        }
     
     
        public static void test()
        {
          int NB = -3;
          int NM = -2;
          int NS = -1;
          int ZO = 0;
          int PS = 1;
          int PM = 2;
          int PB = 3;
     
          double target = 300;
          double actual = 400;
          double u = 0;
     
          int[,] deltaKpMatrix = new int[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 = new int[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 = new int[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}};
          double[] e_mf_paras = { -3, -3, -2, -3, -2, -1, -2, -1, 0, -1, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 3 };
          double[] de_mf_paras = { -3, -3, -2, -3, -2, -1, -2, -1, 0, -1, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 3 };
          double[] Kp_mf_paras = { -3, -3, -2, -3, -2, -1, -2, -1, 0, -1, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 3 };
          double[] Ki_mf_paras = { -3, -3, -2, -3, -2, -1, -2, -1, 0, -1, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 3 };
          double[] Kd_mf_paras = { -3, -3, -2, -3, -2, -1, -2, -1, 0, -1, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 3 };
     
          var fuzzypid = new FuzzyPID(1500, 1000, 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);
     
          for (int i = 0; i < 50; i++)
          {
            u = fuzzypid.realize(target, actual);
            actual += u;
            Console.WriteLine($"{i}  {target} {u} {actual}");
     
            //if (i>19)
            //{
            //  target = 300;
            //}
          }
          //fuzzypid.showInfo();
     
        }
     
      }
    }
    

    以上就是c# 实现模糊PID控制算法的详细内容

    展开全文
  • 一 ,PID控制 在工业控制中,PID控制(比例-积分-微分控制)得到了广泛的应用,这是因为PID控制具有以下优点:01不需要知道被控对象的数学模型。实际上大多数工业对象准确的数学模型是无法获得的,对于这一类系统,...
  • 昨天的文章中出现了以下两个图:图1:PID控制原理图2:理想的开环控制 对比以上两个图,我们就会发现, 控制实际上就是通过调节 三个参数,让 尽可能的去逼近未知的 。 神经网络中经常提到一个东西,叫“万能逼近”...
  • 摘要:以螺旋桨的电液比例周控制系统为研究对象,针对被控对象的非时变性和时变性的特点,采用了一种基于自适应模糊PID控制策略;利用Madab中Fuzzy和Simulink有机结合,方便的实现了模糊自整定PID参数控制系统的仿真...
  • 广义预测模糊控温应用方案1.背景在精细化工行业中,反应釜是厂用的一种反应容器,而温度是其主要被控制对象,是保证产品质量的一个重要因素。反应釜常规温度控制分为两种方式。一种是反应釜利用导热介质通过反应釜的...
  • 代码不能自动运行,需要将模糊控制FIS文件加载到工作区中。此外输入变量系数需要自己根据自己的项目调整,并且更改论域大小,不然会显示输入数据超过范围。适合有一定编程经验的人下载应用,程序通过m文件更改仿真中...
  • 采用模糊 PID 控制算法,实现了对方向和速度的优化控制,即采用模糊 PD 算法对智能小车方向进行控制,采用模糊 PID 算法对速度进行控制。该方案运用于智能车控制系统,克服了传统 PID 控制的不足,通过模糊规则进行...
  • 模糊PID算法控制

    2018-08-09 09:11:47
    PID模糊控制,将需要使用的场景根据实际需要建模模糊化处理,进而PID的进一步调控,可用于飞思卡尔小车的控制,代码有详细注解
  • Fuzzy pid 非常好用的模糊PID温度控制算法,已经在自己的项目中使用,你只需要按照自己的控制对象修改误差变化率最大值和误差阈值即可
  • 第3章 智能汽车设计...3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法
  • 模糊PID C 算法

    2018-10-09 21:39:33
    模糊PID C 算法,温控 这个是非常好用的模糊PID温度控制算法,已经在自己的项目中使用,你只需要按照自己的控制对象修改误差变化率最大值和误差阈值即可。
  • Pid控制算法-模糊算法简介

    万次阅读 多人点赞 2017-04-19 16:15:29
    PID控制算法的C++语言实现中,文章已经对模糊PID的实质做了一个简要说明。基本概念和思路进行一下说明,相信有C++语言基础的朋友可以通过这些介绍性的文字自行实现。这篇文章主要说明一下模糊算法的含义和原理。 ...
  • 模糊PID控制算法代码

    热门讨论 2008-12-04 18:03:05
    包括模糊PID算法,输入量模糊化,输出量去模糊,模糊控制规则
  • 非常好用的模糊PID温度控制算法

    热门讨论 2017-09-04 09:23:59
    这个是非常好用的模糊PID温度控制算法,已经在自己的项目中使用,你只需要按照自己的控制对象修改误差变化率最大值和误差阈值即可。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 650
精华内容 260
关键字:

模糊pid控制算法