该装置是一个连续搅拌釜式反应器(CSTR),可在大范围的操作点上运行。单台PID控制器可以有效地利用冷却液温度在PID控制器设计的小工作范围内调节输出浓度。然而,由于该装置是一个强非线性系统,当工作点发生显著变化时,控制性能会下降。闭环系统甚至会变得不稳定。
首先打开CSTR装置的模型
mdl = 'scdcstrctrlplant';
open_system(mdl)
求解非线性控制问题的一般方法就是调度增益——用系列线性控制器去调度。一般来说,设计一个调度增益控制系统需要以下4步:
输出浓度C通常用来描述不同的工作点。
确定工作范围
C = [2 3 4 5 6 7 8 9];
创建一个默认工作点operating point specification数组
op = operspec(mdl,numel(C));
初始化工作点,确定输出浓度(确定值),和输出浓度值
for ct = 1:numel(C)
op(ct).Outsputs.known = true;
op(ct).Outputs.y = C(ct);
end
根据C的值计算平衡运行点 equilibrium operating points
opoint = findop(mdl,op,findopOptions('DisplayReport','off'));
在这些工作点线性化
Plants = linearize(mdl,opoint);
因为CSTR模型是非线性的,而线性系统显示出了不同的特性。
比如说,装置的模型在低转换率和高转换率的时候是稳定的,但是在其他时候就不稳定(0表示不稳定)
isStable(Plants,'elem')
# ehcho
ans =
1x8 logical array
1 1 0 0 0 0 1
使用pidtune
函数,可以批量的生成PID控制器。理想的开环交叉频率为1 rad/sec,相位裕度为默认值60度。
Controllers = pidtune(Plants,'pidf',pidtuneOptions('Crossover',1));
为了分析步长跟踪step setpoint tracking的闭环响应,首先构造闭环系统。
clsys = feedback(Plants*Controllers,1)
画出闭环的响应
figure
hold on
for ct = 1:length(C)
sys = clsys(:,:,ct);
sys.Name = ['C=',num2str(C(ct))];
syss.InputName = 'Reference';
stepplot(sys,20);
end
legend('show','location','southeast')
所有的闭环都是稳定的,但是超调有点大,增加目标开环带宽到10rad/sec。
对不稳定的装置模型重新设计控制器
Controllers = pidtune(Plants,'pidf',10)
构造闭环系统,并且画出新控制器闭环阶跃响应的图。
clsys = feedback(Plants*Controllers,1);
figure
hold on
for ct = 1:length(C)
% Select a system from the LTI array
sys = clsys(:,:,ct);
set(sys,'Name',['C=',num2str(C(ct))],'InputName','Reference');
% Plot step response
stepplot(sys,20);
end
legend('show','location','southeast')
所有的闭环响应现在都是令人满意的。为了进行比较,检验在所有操作点使用同一个控制器时的响应。创建一组闭环系统,其中每个系统使用C = 2控制器,并绘制它们的响应。
% clsys_flat用的都是C=2的控制器
clsys_flat = feedback(Plants*Controllers(:,:,1),1);
figure
stepplot(clsys,clsys_flat,20)
legend('C-dependent Controllers','Single Controller')
为每个浓度单独设计的PID控制器阵列比单个控制器具有更好的性能。然而,上面所示的闭环响应是基于整个非线性系统的线性近似来计算的。要验证设计,还需要使用PID控制器块在模型中实现调度机制。
最后,关闭模型
bdclose(mdl)
参考文章:
Design Family of PID Controllers for Multiple Operating Points - MATLAB & Simulink - MathWorks 中国
完整代码附录
clc
clear all
close all
mdl = 'scdcstrctrlplant';
open_system(mdl)
%sepcify the operating regions
C = [2 3 4 5 6 7 8 9];
% creat an array of default operating point specifications
op = operspec(mdl,numel(C));
for ct = 1:numel(C)
op(ct).Outputs.known = true;
op(ct).Outputs.y = C(ct);
end
% equilibrium operating points corresponding to values of c
opoint = findop(mdl,op,findopOptions('DisplayReport','off'));
% linearize the plant at operating points
Plants = linearize(mdl,opoint)
isstable(Plants,'elem')'
Controllers = pidtune(Plants,'pidf',pidtuneOptions('Crossover',1));
Controllers(:,:,4)
% closed loop systems
clsys = feedback(Plants*Controllers,1);
figure
hold on
for ct = 1:length(C)
% Select a system from the LTI array
sys = clsys(:,:,ct);
sys.Name = ['C=',num2str(C(ct))];
sys.InputName = 'Reference';
% Plot step response
hold on;
stepplot(sys,20);
end
legend('show','location','southeast')
% open-loop bandwidth to 10rad/sec
Controllers = pidtune(Plants,'pidf',10);
% display controller for c = 4
Controllers(:,:,4)
% closed-loop step response for the new controllers
clsys = feedback(Plants*Controllers,1);
figure
hold on
for ct = 1:length(C)
% Select a system from the LTI array
sys = clsys(:,:,ct);
set(sys,'Name',['C=',num2str(C(ct))],'InputName','Reference');
% Plot step response
hold on;
stepplot(sys,20);
end
legend('show','location','southeast')
clsys_flat = feedback(Plants*Controllers(:,:,1),1);
figure
stepplot(clsys,clsys_flat,20)
legend('C-dependent Controllers','Single Controller')