实验二、 数字PID控制

系统结构图如3-1图:
图3-1 系统结构图
图中,
Gp1=tf(5,conv([0.5 1],[0.1 1]));
Gp2=tf(1,conv([1 0],[0.1 1]));
由于MATLAB,和书本P156上的PID并列形式(parallel form)都写作如下形式,所以本脚本也使用该形式。

一、建立MATLAB系统模型

对连续系统使用zoh法(带零阶保持器的z变换)进行离散化
Ts=0.01;
Gp1d=c2d(Gp1,Ts,'zoh');
Gp2d=c2d(Gp2,Ts,'zoh');

二、确定 PID 控制器的参数

Gc1 = pidtune(Gp1d,'PID');
Gc2 = pidtune(Gp2d,'PID');

三、改变 PID 控制器的参数后的阶跃响应性能

Tf=0;

3.1 对于系统一

计算闭环传递函数
names={'原PID参数下','增大Kp','增大KI','增大KD'};
Gc=pid(Gc1.Kp,Gc1.Ki,Gc1.Kd,Tf,Ts);
Phi1=feedback(series(Gc,Gp1d),1);
%增大比例环节
Gc=pid(Gc1.Kp+1,Gc1.Ki,Gc1.Kd,Tf,Ts);
Phi2=feedback(series(Gc,Gp1d),1);
%增大积分环节
Gc=pid(Gc1.Kp,Gc1.Ki+1,Gc1.Kd,Tf,Ts);
Phi3=feedback(series(Gc,Gp1d),1);
%增大微分环节
Gc=pid(Gc1.Kp,Gc1.Ki,Gc1.Kd+0.1,Tf,Ts);
Phi4=feedback(series(Gc,Gp1d),1);
绘制系统一在不同PID参数下的阶跃响应
step(Phi1,Phi2,Phi3,Phi4);
legend(names);
计算阶跃相应的性能指标
s=[stepinfo(Phi1);stepinfo(Phi2);stepinfo(Phi3);stepinfo(Phi4)];
info=struct2table(orderfields(s,[5,2,1,8,3,4,7,6]),'RowNames',names');
display(info);
info = 4×8 table
 OvershootSettlingTimeRiseTimePeakTimeSettlingMinSettlingMaxPeakUndershoot
1 原PID参数下5.40231.64000.48001.04000.90771.05401.05400
2 增大Kp2.18992.08000.16000.29000.92161.02191.02190
3 增大KI20.21741.92000.33000.72000.90961.20221.20220
4 增大KD5.15932.38000.75001.62000.91001.05161.05160

3.2 对于系统二

names={'原PID参数下','增大Kp','增大KI','增大KD'};
Gc=pid(Gc2.Kp,Gc2.Ki,Gc2.Kd,Tf,Ts);
Ph1=feedback(series(Gc,Gp2d),1);
%增大比例环节
Gc=pid(Gc2.Kp+10,Gc2.Ki,Gc2.Kd,Tf,Ts);
Ph2=feedback(series(Gc,Gp2d),1);
%增大积分环节
Gc=pid(Gc2.Kp,Gc2.Ki+10,Gc2.Kd,Tf,Ts);
Ph3=feedback(series(Gc,Gp2d),1);
%增大微分环节
Gc=pid(Gc2.Kp,Gc2.Ki,Gc2.Kd+1,Tf,Ts);
Ph4=feedback(series(Gc,Gp2d),1);
绘制系统一在不同PID参数下的阶跃响应
figure;
step(Ph1,Ph2,Ph3,Ph4);
legend(names);
xlim([-0.0177724, 0.787915]);
ylim([0.886364, 1.20372]);
计算阶跃相应的性能指标
s2=[stepinfo(Ph1);stepinfo(Ph2);stepinfo(Ph3);stepinfo(Ph4)];
info=struct2table(orderfields(s2,[5,2,1,8,3,4,7,6]),'RowNames',names');
display(info);
info = 4×8 table
 OvershootSettlingTimeRiseTimePeakTimeSettlingMinSettlingMaxPeakUndershoot
1 原PID参数下11.17380.78000.08000.20000.92341.11171.11170
2 增大Kp14.40690.54000.07000.16000.96041.14411.14410
3 增大KI12.43580.71000.08000.21000.92731.12441.12440
4 增大KD5.30840.91000.08000.31000.93751.05311.05310

3.3 分析控制效果

不同环节对系统的控制作用不同,PID的三个环节对于控制效果的影响可以概括如下:
  1. 比例环节:成比例地反映控制系统的偏差信号e(t),偏差一旦产生,控制器立即产生控制作用,以减小偏差。
  2. 积分环节:主要用于消除静差,提高系统的无差度。积分作用的强弱取决于积分时间常数T,T越大,积分作用越弱,反之则越强。
  3. 微分环节:反映偏差信号的变化趋势,并能在偏差信号变得太大之前,在系统中引入一个有效的早期修正信号,从而加快系统的动作速度,减少调节时间。

四、PID改进算法

使用simulink进行PID改进算法的模拟并通过Simulink交互命令简单进行演示。Run Simulations Programmatically - MATLAB & Simulink (mathworks.com)

4.1 教材中的积分抑制算法

教材中给出了四种抑制积分饱和的算法,使用simulink仿真结果如下,可以看出,PID控制器在考虑饱和特性后,控制的快速性下降,需要一定时间才能推出饱和状态,增大系统超调量。使用积分抑制算法后,可以较好地抑制饱和,提前退出饱和。实验中观察到,使用积分分离法会出现小幅震荡,使用遇限削弱积分法和饱和停止积分法在实验中控制效果相同。
%run simulink
N=4;
simOut = sim('system2/antiwindup2.slx',...
'SaveOutput','on','OutputSaveName','yout','SaveFormat', 'Dataset');
%get data
outputs = simOut.get('yout');
u = (outputs.get('u').Values);
y = (outputs.get('y').Values);
udata=repmat(u,1,N+2);
ydata=repmat(y,1,N+2);
for i=0:N
ut=strcat("u",num2str(i));
yt=strcat("y",num2str(i));
udata(i+2)= (outputs.get(ut).Values);
ydata(i+2)= (outputs.get(yt).Values);
end
%plot the control and output signal
labels=["无饱和特性","考虑饱和特性",...
"积分分离法","遇限削弱积分法",...
"饱和停止积分法","反馈抑制停止积分法"];
figure();hold on;
for i=1:N+2
plot(udata(i));
end
xlabel('Time');ylabel('u');
legend(labels);
title("不同抗饱和算法下的控制信号")
figure();
hold on;
for i=1:N+2
plot(ydata(i));
end
xlabel('Time');ylabel('y');
legend(labels);
title('不同抗饱和算法下的响应曲线');

4.1 SIMULINK PID模块的抗饱和算法

Simulink 的PID模块提供两种内置的抗饱和方法(back-calculationclamping),还提供一种跟踪模式来处理更复杂的场景。可以参考使用 PID 控制器进行抗饱和控制 - MATLAB & Simulink - MathWorks 中国
首先需要在PID模块的Output Saturation中设置输出限制Limit Output,来产生控制器输出饱和特性,再设计相应的抗饱和算法。从图中可以看出,采用抗饱和算法之后,系统能够更快退出饱和状态。
%run simulink
N=2;
simOut = sim('system2/antiwindup1.slx','SaveOutput','on','OutputSaveName','yout','SaveFormat', 'Dataset');
%get data
outputs = simOut.get('yout');
u = (outputs.get('u').Values);
y = (outputs.get('y').Values);
udata=repmat(u,1,N+2);
ydata=repmat(y,1,N+2);
for i=0:N
ut=strcat("u",num2str(i));
yt=strcat("y",num2str(i));
udata(i+2)= (outputs.get(ut).Values);
ydata(i+2)= (outputs.get(yt).Values);
end
%plot the control and output signal
labels=["无饱和特性","考虑饱和特性","反算","积分器钳位"];
figure();hold on;
for i=1:N+2
plot(udata(i));
end
xlabel('Time');ylabel('u');
legend(labels);
title("不同抗饱和算法下的控制信号")
figure();
hold on;
for i=1:N+2
plot(ydata(i));
end
xlabel('Time');ylabel('y');
legend(labels);
title('不同抗饱和算法下的响应曲线');

  1. 抗饱和算法仿真时,未对参数进行刻意调整