基础PID控制

参考资料 :刘金琨《先进PID控制MATLAB仿真(第四版)》

一、位置式与增量式

%  基础 PID 控制器
%  PID 控制器分为 位置式和增量式
%  位置式  u = kp*e + ki*ei + kd*(e - e_1)/ts      ei = ei + e*ts
%  增量式  u = u_1 + delta_u     delta_u = kp*(e - e_1) + ki*e + kd*(e - 2*e_1 + e_2)

clear all;
close all;

ts = 0.01;

a = 25;
b = 133;
sys = tf(a,[1 b 0]);
dsys = c2d(sys,ts,'z');
[num,den] = tfdata(dsys,'v');

upos_2 = 0;  upos_1 = 0;
ypos_2 = 0;  ypos_1 = 0;
epos_2 = 0;  epos_1 = 0;
ei = 0;

uinc_2 = 0;  uinc_1 = 0;
yinc_2 = 0;  yinc_1 = 0;
einc_2 = 0;  einc_1 = 0;

kp_pos = 80;  ki_pos = 1;  kd_pos = 0;
kp_inc = 140;  ki_inc = 0.3;  kd_inc = 0;

for k = 1:1:2000
   time(k) = k*ts;
   if k <= 500          %    输入信号
       r(k) = sin(time(k));
   else
       r(k) = 1;
   end
   ypos(k) = -den(3)*ypos_2 - den(2)*ypos_1 + num(3)*upos_2 + num(2)*upos_1;
   yinc(k) = -den(3)*yinc_2 - den(2)*yinc_1 + num(3)*uinc_2 + num(2)*uinc_1;
   
   epos(k) = r(k) - ypos(k);     %   位置式 PID 的误差以及ki的乘积项ei
   ei = ei + epos(k)*ts;
   
   einc(k) = r(k) - yinc(k);     %   增量式 PID 的误差以及ki的乘积项ei
   
   u_pos(k) = kp_pos*epos(k) + ki_pos*ei + kd_pos*(epos(k) - epos_1)/ts;    %   位置式 PID 控制器
   
   deltau(k) = kp_inc*(einc(k) - einc_1) + ki_inc*einc(k) + kd_inc*(einc(k) - 2*einc_1 + einc_2);   %  增量式 PID 控制器  ∆u + u_1
   u_inc(k) = uinc_1 + deltau(k);
   
   upos_2 = upos_1;  upos_1 = u_pos(k);      %  位置式 PID 状态、输出、误差更新
   ypos_2 = ypos_1;  ypos_1 = ypos(k);
   epos_2 = epos_1;  epos_1 = epos(k);
   
   uinc_2 = uinc_1;  uinc_1 = u_inc(k);      %  增量式 PID 状态、输出、误差更新
   yinc_2 = yinc_1;  yinc_1 = yinc(k);
   einc_2 = einc_1;  einc_1 = einc(k);
   
end

figure(1)
plot(time,r,'k',time,ypos,'b',time,yinc,'r');grid

仿真结果如图所示:

在这里插入图片描述

如果PID参数都改成相同(kp = 80; ki = 1; kd = 0;)的话:
数据还是有所区别的
在这里插入图片描述

二、几种基础的PID控制器

以位置式PID为例:

clear all;
close all;

ts = 0.01;

a = 25;
b = 133;
sys = tf(a,[1 b 0]);
dsys = c2d(sys,ts,'z');
[num,den] = tfdata(dsys,'v');

A = 0.04;
B = 0.06;
u_max = 8;
u_min = -8;

u_2 = 0;  u_1 = 0;
y_2 = 0;  y_1 = 0;
e_2 = 0;  e_1 = 0;
ei = 0;

kp = 80;  ki = 0.35;  kd = 0;

for k = 1:1:2000
   time(k) = k*ts;
   r(k) = sin(time(k));
   dr(k) = cos(time(k));
   ddr(k) = -sin(time(k));

   y(k) = -den(3)*y_2 - den(2)*y_1 + num(3)*u_2 + num(2)*u_1;
   
   e(k) = r(k) - y(k);    
   
%  变速积分PID(未使用)
%  系统对积分的要求是:系统偏差大时积分作用应减弱;偏差小时应加强
%  通过 fe 参数控制 fe*ki
%    if abs(e(k)) <= B                 
%        fe = 1;                      
%    elseif abs(e(k)) > A + B
%        fe = 0;
%    else 
%        fe = (A - abs(e(k) + B))/A;
%    end
   
%  带死区的PID  
%  避免控制作用过于频繁,从而消除由于频繁动作所引起的震荡   
   if abs(e(k)) <= 0.005
       e(k) = 0;
   end
   
%    ei = ei + fe*e(k)*ts;
    ei = ei + e(k)*ts;

%    积分分离PID : 当误差过大时
%    采用PD控制,可避免产生超调;
%    否则采用PID控制
%    通过 beta*ki 实现
   if abs(e(k)) >= 0.1
       beta = 0; 
   elseif abs(e(k)) <= 0.05
       beta = 1;
   end
   
   u(k) = kp*e(k) + beta*ki*ei + kd*(e(k) - e_1)/ts;  
   
%    抗积分饱和PID
%    当状态达到饱和情况时不再增大,只累计负偏差
%    可以避免控制量长时间停留在饱和区
   if u(k) > u_max          
       u(k) = u_max;  
   elseif u(k) < u_min
       u(k) = u_min;
   end
   
%  基于前馈补偿的PID
%  在高精度伺服系统中,前馈控制可用来提高系统的跟踪性能
%  前馈环节与闭环系统的传递函数之积为1,从而实现在输出处完全复现输入
%  ut = up + uf;
   uf = 25/133*dr(k) + 1/133*ddr(k);
   u(k) = u(k) + uf; 
   
   u_2 = u_1;  u_1 = u(k);
   y_2 = y_1;  y_1 = y(k);
   e_2 = e_1;  e_1 = e(k);
   
end

figure(1)
plot(time,r,'k',time,y,'b');grid
figure(2)
plot(time,e,'b')
figure(3)
plot(time,u,'b')

仿真结果如下:
1、输出跟踪输入
在这里插入图片描述
2、误差 e(t)
在这里插入图片描述
3、状态变量 u(t)
在这里插入图片描述

Ps: 我个人认为这几种基础的控制器实现方式是只加上了一些限制条件,好像确实有些道理,可能我现在只是仍然处于仿真阶段,在实际应用中这些控制器的作用可能会更加重要

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值