c# 实现模糊PID控制算法
跑起来的效果看每个类的test方法,自己调用来测试
目的是看看哪个算法好用,移植的时候比较单纯没有研究懂算法,代码结构也没改动,只是移植到C#方便查看代码和测试,大家要拷贝也很方便,把整个类拷贝到.cs文件即可
这段算法在实际值低于目标值是工作正常,超过后会有问题,不知道如何调教
usingSystem; usingSystem.Collections.Generic; usingSystem.Diagnostics; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; namespaceFuzzyPID { classFuzzyPID { publicconstintN=7; doubletarget;//系统的控制目标 doubleactual;//采样获得的实际值 doublee;//误差 doublee_pre_1;//上一次的误差 doublee_pre_2;//上上次的误差 doublede;//误差的变化率 doubleemax;//误差基本论域上限 doubledemax;//误差辩化率基本论域的上限 doubledelta_Kp_max;//delta_kp输出的上限 doubledelta_Ki_max;//delta_ki输出上限 doubledelta_Kd_max;//delta_kd输出上限 doubleKe;//Ke=n/emax,量化论域为[-3,-2,-1,0,1,2,3] doubleKde;//Kde=n/demax,量化论域为[-3,-2,-1,0,1,2,3] doubleKu_p;//Ku_p=Kpmax/n,量化论域为[-3,-2,-1,0,1,2,3] doubleKu_i;//Ku_i=Kimax/n,量化论域为[-3,-2,-1,0,1,2,3] doubleKu_d;//Ku_d=Kdmax/n,量化论域为[-3,-2,-1,0,1,2,3] int[,]Kp_rule_matrix=newint[N,N];//Kp模糊规则矩阵 int[,]Ki_rule_matrix=newint[N,N];//Ki模糊规则矩阵 int[,]Kd_rule_matrix=newint[N,N];//Kd模糊规则矩阵 stringmf_t_e;//e的隶属度函数类型 stringmf_t_de;//de的隶属度函数类型 stringmf_t_Kp;//kp的隶属度函数类型 stringmf_t_Ki;//ki的隶属度函数类型 stringmf_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的隶属度函数的参数 doubleKp; doubleKi; doubleKd; doubleA; doubleB; doubleC; publicFuzzyPID(doublee_max,doublede_max,doublekp_max,doubleki_max,doublekd_max,doubleKp0,doubleKi0,doubleKd0) { 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; } //三角隶属度函数 doubletrimf(doublex,doublea,doubleb,doublec) { doubleu; if(x>=a&&x<=b) u=(x-a)/(b-a); elseif(x>b&&x<=c) u=(c-x)/(c-b); else u=0; returnu; } //正态隶属度函数 doublegaussmf(doublex,doubleave,doublesigma) { doubleu; if(sigma<0) { thrownewException("Ingaussmf,sigmamustlargerthan0"); } u=Math.Exp(-Math.Pow(((x-ave)/sigma),2)); returnu; } //梯形隶属度函数 doubletrapmf(doublex,doublea,doubleb,doublec,doubled) { doubleu; if(x>=a&&x=b&&x=c&&x<=d) u=(d-x)/(d-c); else u=0; returnu; } //设置模糊规则Matrix publicvoidsetRuleMatrix(int[,]kp_m,int[,]ki_m,int[,]kd_m) { for(inti=0;i =delta_Kp_max)delta_Kp=delta_Kp_max; elseif(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(intm=0;m<3;m++) for(intn=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; elseif(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(intm=0;m<3;m++) for(intn=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; elseif(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; elseif(delta_u<=-0.95*target)delta_u=-0.95*target; e_pre_2=e_pre_1; e_pre_1=e; returndelta_u; } voidshowMf(stringtype,double[]mf_paras) { inttab=0; if(type=="trimf") tab=2; elseif(type=="gaussmf") tab=1; elseif(type=="trapmf") tab=3; this.WriteLine($"函数类型:{mf_t_e}"); this.WriteLine("函数参数列表:"); double[]p=mf_paras; for(inti=0;i 19) //{ //target=300; //} } //fuzzypid.showInfo(); } } }
以上就是c#实现模糊PID控制算法的详细内容,更多关于c#模糊PID控制算法的资料请关注毛票票其它相关文章!