www.gusucode.com > control_featured 案例源码程序 matlab代码 > control_featured/DistillationColumnExample.m

    %% Decoupling Controller for a Distillation Column
% This example shows how to use |looptune| to decouple
% the two main feedback loops in a distillation column.

%   Copyright 1986-2012 The MathWorks, Inc.

%% Distillation Column Model
% This example uses a simple model of the distillation column shown below.
%
% <<../distilldemo1.png>>
% 
% *Figure 1: Distillation Column*

%%
% In the so-called LV configuration, the controlled variables are the concentrations 
% |yD| and |yB| of the chemicals |D| (tops) and |B| (bottoms), and the manipulated variables 
% are the reflux |L| and boilup |V|. This process exhibits strong coupling 
% and large variations in steady-state gain for some combinations of L and V. 
% For more details, see Skogestad and Postlethwaite, _Multivariable Feedback Control_.

%% 
% The plant is modeled as a first-order transfer function with inputs |L,V| and
% outputs |yD,yB|:
%
% $$ G(s) = \frac{1}{75s+1} \left ( \begin{array}{cc} 87.8 & -86.4 \\ 108.2 & -109.6 \end{array}\right )$$
%
% The unit of time is minutes (all plots are in minutes, not seconds).

s = tf('s');
G = [87.8 -86.4 ; 108.2 -109.6]/(75*s+1);
G.InputName = {'L','V'};
G.OutputName = {'yD','yB'};

%% Control Architecture
% The control objectives are as follows:
%
% * Independent control of the tops and bottoms concentrations by ensuring that a change 
% in the tops setpoint |Dsp| has little impact on the bottoms concentration |B| and vice versa
% * Response time of about 4 minutes with less than 15% overshoot
% * Fast rejection of input disturbances affecting the effective reflux |L| and boilup |V|
%
% To achieve these objectives we use the control architecture shown below. This architecture
% consists of a static decoupling matrix |DM| in series with two PI controllers for the 
% reflux |L| and boilup |V|.

open_system('rct_distillation')

%% Controller Tuning in Simulink with LOOPTUNE
% The |looptune| command provides a quick way to tune MIMO feedback loops. 
% When the control system is modeled in Simulink, you just specify the
% tuned blocks, the control and measurement signals, and the desired bandwidth, 
% and |looptune| automatically sets up the problem and tunes the controller 
% parameters. |looptune| shapes the open-loop response to provide integral
% action, roll-off, and adequate MIMO stability margins. 

%%
% Use the |slTuner| interface to specify the tuned blocks, the controller I/Os, 
% and signals of interest for closed-loop validation.

ST0 = slTuner('rct_distillation',{'PI_L','PI_V','DM'});

% Signals of interest
addPoint(ST0,{'r','dL','dV','L','V','y'})

%%
% Set the control bandwidth by specifying the gain crossover frequency
% for the open-loop response. For a response time of 4 minutes, the 
% crossover frequency should be approximately 2/4 = 0.5 rad/min.

wc = 0.5;

%%
% Use |TuningGoal| objects to specify the remaining control objectives.
% The response to a step command should have less than 15% overshoot.
% The response to a step disturbance at the plant input should be well damped, 
% settle in less than 20 minutes, and not exceed 4 in amplitude.

OS = TuningGoal.Overshoot('r','y',15);

DR = TuningGoal.StepRejection({'dL','dV'},'y',4,20);

%%
% Next use |looptune| to tune the controller blocks |PI_L|, |PI_V|, and
% |DM| subject to the disturbance rejection requirement.

Controls = {'L','V'};
Measurements = 'y';
[ST,gam,Info] = looptune(ST0,Controls,Measurements,wc,OS,DR);

%%
% The final value is near 1 which indicates that all requirements were met.
% Use |loopview| to check the resulting design. The responses should stay 
% outside the shaded areas.

figure('Position',[0,0,1000,1200])
loopview(ST,Info)

%% 
% Use |getIOTransfer| to access and plot the closed-loop responses from
% reference and disturbance to the tops and bottoms concentrations. The tuned responses
% show a good compromise between tracking and disturbance rejection.

figure
Ttrack = getIOTransfer(ST,'r','y');
step(Ttrack,40), grid, title('Setpoint tracking')

%%

Treject = getIOTransfer(ST,{'dV','dL'},'y');
step(Treject,40), grid, title('Disturbance rejection')

%%
% Comparing the open- and closed-loop disturbance rejection
% characteristics in the frequency domain shows a clear improvement
% inside the control bandwidth.

clf, sigma(G,Treject), grid
title('Principal gains from input disturbances to outputs')
legend('Open-loop','Closed-loop')



%% Adding Constraints on the Tuned Variables
% Inspection of the controller obtained above shows that the second
% PI controller has negative gains.

getBlockValue(ST,'PI_V')

%%
% This is due to the negative signs in the second input channels of the
% plant $G$. In addition, the tunable elements are over-parameterized 
% because multiplying |DM| by two and dividing the PI gains by two 
% does not change the overall controller. To address these issues, fix
% the (1,1) entry of |DM| to 1 and the (2,2) entry to -1.

DM = getBlockParam(ST0,'DM');
DM.Gain.Value = diag([1 -1]);
DM.Gain.Free = [false true;true false];
setBlockParam(ST0,'DM',DM)

%%
% Re-tune the controller for the reduced set of tunable parameters.

[ST,gam,Info] = looptune(ST0,Controls,Measurements,wc,OS,DR);

%%
% The step responses look similar but the values of |DM| and the PI gains
% are more suitable for implementation.

figure('Position',[0,0,700,350])

subplot(121)
Ttrack = getIOTransfer(ST,'r','y');
step(Ttrack,40), grid, title('Setpoint tracking')

subplot(122)
Treject = getIOTransfer(ST,{'dV','dL'},'y');
step(Treject,40), grid, title('Disturbance rejection')

%%

showTunable(ST)

%% Equivalent Workflow in MATLAB
% If you do not have a Simulink model of the control system, you can use LTI 
% objects and Control Design blocks to create a MATLAB representation of the 
% following block diagram.
%
% <<../distilldemo2.png>>
% 
% *Figure 2: Block Diagram of Control System*
%
% First parameterize the tunable elements using Control Design blocks.
% Use the |tunableGain| object to parameterize |DM| and fix |DM(1,1)=1|
% and |DM(2,2)=-1|.
% This creates a 2x2 static gain with the off-diagonal entries as
% tunable parameters. 

DM = tunableGain('Decoupler',diag([1 -1]));
DM.Gain.Free = [false true;true false];

%%
% Similarly, use the |tunablePID| object to parameterize the two PI controllers:

PI_L = tunablePID('PI_L','pi');
PI_V = tunablePID('PI_V','pi');

%%
% Next construct a model |C0| of the controller $C$ in Figure 2.

C0 = blkdiag(PI_L,PI_V) * DM * [eye(2) -eye(2)];

% Note: I/O names should be consistent with those of G
C0.InputName = {'Dsp','Bsp','yD','yB'};
C0.OutputName = {'L','V'};

%%
% Now tune the controller parameters with |looptune| as done previously.

% Crossover frequency
wc = 0.5;

% Overshoot and disturbance rejection requirements
OS = TuningGoal.Overshoot({'Dsp','Bsp'},{'yD','yB'},15);
DR = TuningGoal.StepRejection({'L','V'},{'yD','yB'},4,20);

% Tune controller gains
[~,C] = looptune(G,C0,wc,OS,DR);

%% 
% To validate the design, close the loop with the tuned compensator |C|
% and simulate the step responses for setpoint tracking and disturbance 
% rejection. 

Tcl = connect(G,C,{'Dsp','Bsp','L','V'},{'yD','yB'});

figure('Position',[0,0,700,350])

subplot(121)
Ttrack = Tcl(:,[1 2]);
step(Ttrack,40), grid, title('Setpoint tracking')

subplot(122)
Treject = Tcl(:,[3 4]);
Treject.InputName = {'dL','dV'};
step(Treject,40), grid, title('Disturbance rejection')

%%
% The results are similar to those obtained in Simulink.