PID算法Matlab仿真程序和C程序
end
增量式PID控制算法%Linear model
yout(k)=-den(2)*y_1-den(3)*y_2+num(
Matlab仿真程序 2)*u_1+num(3)*u_2;
设一被控对象G(s)=50/(0.125s^2+7s),error(k)=rin(k)-yout(k); 用增量式PID控制算法编写仿真程序 %Return of parameters
(输入分别为单位阶跃、正弦信号,u_2=u_1;u_1=u(k);
采样时间为1ms,控制器输出限幅:y_2=y_1;y_1=yout(k);
[-5,5],仿真曲线包括系统输出及误差x(1)=error(k)-error_1; %Cal曲线,并加上注释、图例)。程序如下 culating P
clear all; x(2)=error(k)-2*error_1+error_2; %Cclose all; alculating D
ts=0.001; x(3)=error(k); %Calculating I sys=tf(50,[0.125,7, 0]); error_2=error_1;
dsys=c2d(sys,ts,'z'); error_1=error(k);
[num,den]=tfdata(dsys,'v'); end
u_1=0.0;u_2=0.0; figure(1);
y_1=0.0;y_2=0.0; plot(time,rin,'b',time,yout,'r'); x=[0,0,0]'; xlabel('time(s)'),ylabel('rin,yout'); error_1=0; figure(2);
error_2=0; plot(time,error,'r')
for k=1:1:1000 xlabel('time(s)');ylabel('error'); time(k)=k*ts;
S=2;
微分先行PID算法if S==1
kp=10;ki=0.1;kd=15;
Matlab仿真程序
rin(k)=1; %%PID Controler with differential in Step Signal advance
elseif S==2 clear all;
close all;
kp=10;ki=0.1;kd=15; %Sine
Signal ts=20;
rin(k)=0.5*sin(2*pi*k*ts); sys=tf([1],[60,1],'inputdelay',80); end dsys=c2d(sys,ts,'zoh');
du(k)=kp*x(1)+kd*x(2)+ki*x(3); %[num,den]=tfdata(dsys,'v'); PID Controller
u(k)=u_1+du(k); u_1=0;u_2=0;u_3=0;u_4=0;u_5=0; %Restricting the output of controller ud_1=0;
if u(k)>=5 y_1=0;y_2=0;y_3=0;
u(k)=5; error_1=0;error_2=0;
end ei=0;
if u(k)<=-5 for k=1:1:400
u(k)=-5; time(k)=k*ts;
1
end
%Linear model figure(1);
yout(k)=-den(2)*y_1+num(2)*u_5; plot(time,rin,'r',time,yout,'b');
xlabel('time(s)');ylabel('rin,yout'); kp=0.36;kd=14;ki=0.0021; figure(2);
plot(time,u,'r');
rin(k)=1.0*sign(sin(0.00025*2*pi*k*ts)xlabel('time(s)');ylabel('u'); );
error(k)=rin(k)-yout(k);
不完全微分PID算法ei=ei+error(k)*ts;
Matlab仿真程序 gama=0.50;
Td=kd/kp; %PID Controler with Partial differential
Ti=0.5; clear all;
close all;
c1=gama*Td/(gama*Td+ts);
c2=(Td+ts)/(gama*Td+ts); ts=20;
c3=Td/(gama*Td+ts); sys=tf([1],[60,1],'inputdelay',80);
dsys=c2d(sys,ts,'zoh'); M=1; [num,den]=tfdata(dsys,'v'); if M==1 %PID Control with
differential in advance u_1=0;u_2=0;u_3=0;u_4=0;u_5=0;
ud(k)=c1*ud_1+c2*yout(k)-c3*y_1ud_1=0;
; y_1=0;y_2=0;y_3=0;
u(k)=kp*error(k)+ud(k)+ki*ei; error_1=0;
elseif M==2 %Simple PID Control ei=0;
u(k)=kp*error(k)+kd*(error(k)-error
_1)/ts+ki*ei; for k=1:1:100
end time(k)=k*ts;
if u(k)>=110 rin(k)=1.0;
u(k)=110;
end %Linear model
if u(k)<=-110 yout(k)=-den(2)*y_1+num(2)*u_5;
u(k)=-110;
end error(k)=rin(k)-yout(k); %Update parameters
u_5=u_4;u_4=u_3;u_3=u_2;u_2=u_1;u_%PID Controller with partly differential
1=u(k); ei=ei+error(k)*ts;
y_3=y_2;y_2=y_1;y_1=yout(k); kc=0.30;
ki=0.0055;
error_2=error_1; TD=140;
error_1=error(k);
2
kd=kc*TD/ts; figure(2);
plot(time,u,'r'); Tf=180; xlabel('time(s)');ylabel('u');
Q=tf([1],[Tf,1]); %Low Freq Signal figure(3);
plot(time,rin-yout,'r'); Filter
xlabel('time(s)');ylabel('error');
figure(4); M=2;
if M==1 %Using PID with Partial bode(Q,'r'); differential加在简单PID后的不完全微dcgain(Q);
分
C语言PID演示程序 alfa=Tf/(ts+Tf);
u(k)=alfa*u_1+(1-alfa)*(kc*error(k#include )+kd*(error(k)-error_1)+ki*ei); #include
u_1=u(k);
elseif M==2 %Using PID with typedef struct PID{ Partial differential只加在微分环节上的 double Command; //输入指令 不完全微分 double Proportion; //比例系数
alfa=Tf/(ts+Tf); double Integral; //积分系数
ud(k)=kd*(1-alfa)*(error(k)-error_1 double Derivative; //微分系数 )+alfa*ud_1; double preErr; //前一拍误差
u(k)=kc*error(k)+ud(k)+ki*ei; double sumErr; //误差累积
ud_1=ud(k); }PID;
elseif M==3 %Using Simple PID 简
单的PID微分 double PIDCale(PID *p,double
u(k)=kc*error(k)+kd*(error(k)-errorfeedback)
_1)+ki*ei; {
end double dErr,Err;
Err=p->Command-feedback; //当前%Restricting the output of controller 误差
if u(k)>=10 p->sumErr+=Err; //误差累加
u(k)=10; dErr=Err-p->preErr; //误差微分 end p->preErr=Err; if u(k)<=-10 return(p->Proportion*Err //比例项
u(k)=-10; +p->Derivative*dErr //微分项 end +p->Integral*p->sumErr); //积分项
}
u_5=u_4;u_4=u_3;u_3=u_2;u_2=u_1;u_
1=u(k); void PIDInit(PID *p) y_3=y_2;y_2=y_1;y_1=yout(k); {
error_1=error(k); memset(p,0,sizeof(PID)); //初始化 end }
figure(1);
plot(time,rin,'b',time,yout,'r'); typedef struct motor{ xlabel('time(s)');ylabel('rin,yout'); double lastY;
3
double preY; =%f\n",k,sPID.Command,y,sPID
double lastU; .Command-y,u);
double preU;
}motor; u=PIDCale(&sPID,y);
y=motorCal(&m_motor,u);
k++; void motorInit(motor *m)
} {
printf("%f\n",y); memset(m,0,sizeof(motor));
fclose(fp); }
}
double motorCal(motor *m,double u)
{
double 增量式PID控制C语言代码 y=1.9753*m->lastY-0.9753*m->preY+0.00003284*u+0.00006568*m->lastU+0.增量式PID控制C语言代码 00003284*m->preU;//二阶系统
m->preY=m->lastY;
m->lastY=y; ///////////////////////////////////////////////////////////
m->preU=m->lastU; /////
m->lastU=u; // 定义PID参数结构体
return y; ///////////////////////////////////////////////////////////
} ////
typedef struct PID {
void main() //结构体定义
{ int SetPoint //
FILE *fp=fopen("data.txt","w+"); 设定值
PID sPID; int Proportion; //
motor m_motor; Proportion 比例系数
int k=0; int Integral; //
double u; Integral 积分系数
double y=0; int Derivative; //
PIDInit(&sPID); Derivative 微分系数
sPID.Proportion=2; int LastError; //
sPID.Derivative=1; Error[-1] 前一拍误差
sPID.Integral=0.00001; int PreError; //
sPID.Command=10; Error[-2] 前两拍误差
} PID;
motorInit(&m_motor);
main()
while(k<=1000) {
{ PID vPID;
• fprintf(fp,"%d 设定值=%f //定义结构变量名
被控量=%f 偏差=%f 控PIDInit ( &vPID );
制量 //Initialize Structure
4
// memset()函数在mem.h头文件中vPID.Proportion = 10;
声明,它把数组的起始地址作为其第 //Set PID Coefficients
一个参数, vPID.Integral = 10;
//第二个参数是设置数组每个字节的 // Set PID Integral
值,第三个参数是数组的长度(字节数, vPID.Derivative = 10;
不是元素个数)。 // Set PID Derivative
//其函数原型为: void *memset(voi vPID. SetPoint =
//根据实际情况设定 d*,int,unsigned);
//头文件
while(1) }
{
Verror=Measure(); ///////////////////////////////////////////////////////////
//得到AD的输出值 ////////////
//Title:增量式PID算法程序 Error =vPID. SetPoint- Verr
or; //与设定值比较,得到误差值 //Description:给出一个误差增量
//Input: PID的P、I控制常数和之前tempi=PIDCal(&vPID, Error;
的误差量(PID *pp)& 当前误差量(T laser.Value+=tempi;
// Value与Num[2]为共同体,共同hisError)
体名laser //Return: 误差增量templ
LASERH=laser.Num[0]; ///////////////////////////////////////////////////////////
LASERL=laser.Num[1]; ///////////
} int PIDCal( PID *pp, int ThisError )} {
//增量式PID算法(需要控制的不是
控制量的绝对值,而是控制量的增量) /////////////////////////////////////////////////////////////////////// int pError,dError,iError; //Title:PID参数初始化 long templ;
//Description: Proportion="0" pError = ThisError-pp->LastErr// Integral=0 or;
// LastError=0 iError = ThisError; //Input: PID的P、I控制常数和之前 dError = ThisError-2*(pp->Last的误差量(PID *pp) Error)+pp->PreError;
//Return:
//增量计算 ////////////////////////////////////////////////////////////////////// templ=pp->Proportion*pError +void PIDInit (PID *pp) pp->Integral*iError+pp->Derivative*
//PID参数初始化,都置0 dError; //增量
{
//存储误差用于下次运算 memset ( pp,0,sizeof(PID));
pp->PreError = pp->LastError; //memset()的函数, 它可以一字节一 pp->LastError = ThisError; 字节地把整个数组设置为一个指定的
值。 return ((int)(templ>>8));
}
5
6
本文档为【PID算法Matlab仿真程序和C程序】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。