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;i19)
//{
//target=300;
//}
}
//fuzzypid.showInfo();
}
}
}
以上就是c#实现模糊PID控制算法的详细内容,更多关于c#模糊PID控制算法的资料请关注毛票票其它相关文章!