www.gusucode.com > mpc_featured 案例源码 matlab代码程序 > mpc_featured/mpcdistillation.m
%% Design and Cosimulate Control of High-Fidelity Distillation Tower with Aspen Plus Dynamics % This example shows how to design a model predictive controller in MATLAB % for a high-fidelity distillation tower model built in Aspen Plus % Dynamics(R). The controller performance is then verified through % cosimulation between Simulink and Aspen Plus Dynamics. % Copyright 1990-2014 The MathWorks, Inc. %% Distillation Tower % The distillation tower uses 29 ideal stages to separate a mixture of % benzene, toluene, and xylenes (represented by p-xylene). The % distillation process is continuous. The equipment includes a reboiler % and a total condenser as shown below: % % <<../mpcdistillation_tower.jpg>> % % The distillation tower operates at a nominal steady-state condition: %% % * The feed stream contains 30% of benzene, 40% of toluene and 30% of % xylenes. % * The feed flow rate is 500 kmol/hour. % * To satisfy the distillate purity requirement, the distillate contains % 95% of benzene. % * To satisfy the requirement of recovering 95% of benzene in the feed, % the benzene impurity in the bottoms is 1.7%. %% % The control objectives are listed below, sorted by their importance: %% % # Hold the tower pressure constant. % # Maintain 5% of toluene in the distillate (it is equivalent to maintain % 95% of benzene in the distillate because the distillate only contains % benzene and toluene). % # Maintain 1.7% of the benzene in the bottoms. % # Keep liquid levels in the sump and the reflux drum within specified % limits. %% Build High-Fidelity Plant Model in Aspen Plus Dynamics % Use an Aspen Plus |RADFRAC| block to define the tower's steady-state % characteristics. In addition to the usual information needed for a % steady-state simulation, you must specify tray hydraulics, tower sump % geometry, and the reflux drum size. The trays are a seive design spaced % 18 inches apart. All trays have a 1.95 m in diameter with a 5 cm weir % height. Nominal liquid depths are 0.67 m and 1.4875 m in the horizontal % reflux drum and sump respectively. % % The steady-state model is ported to Aspen Plus Dynamics (APD) for a % flow-driven simulation. This neglects actuator dynamics and assumes % accurate regulation of manipulated flow rates. By default, APD adds PI % controllers to regulate the tower pressure and the two liquid levels. In % this example, the default PI controllers are intentionally removed. % % The APD model of the high-fidelity distillation tower is shown below: % % <<../mpcdistillation_apd_model.png>> %% Linearize Plant Using Aspen Plus Control Design Interface % Model Predictive Controller requires an LTI model of the plant. In this % example, the plant inputs are: %% % # Condenser duty (W) % # Reboiler duty (W) % # Reflux mass flow rate (kg/h) % # Distillate mass flow rate (kg/h stream #2) % # Bottoms mass flow rate (kg/h stream #3) % # Feed molar flow rate (kmol/h stream #1) %% % The plant outputs are: %% % # Tower pressure (in the condenser: stage 1, bar) % # Reflux drum liquid level (m) % # Sump liquid level (m) % # Mass fraction toluene in the distillate % # Mass fraction benzene in the bottoms %% % Aspen Plus Dynamics provides a Control Design Interface (CDI) tool that % linearizes a dynamic model at a specified condition. %% % The following steps are taken to obtain the linear plant model in Aspen % Plus Dynamics. %% % |Step 1|: Add a "script" to the APD model under the "Flowsheet" folder. % In this example, the script name is |CDI_Calcs| (as shown above) and it % contains the following APD commands: % % Set Doc = ActiveDocument % set CDI = Doc.CDI % CDI.Reset % CDI.AddInputVariable "blocks(""B1"").condenser(1).QR" % CDI.AddInputVariable "blocks(""B1"").QrebR" % CDI.AddInputVariable "blocks(""B1"").Reflux.FmR" % CDI.AddInputVariable "streams(""2"").FmR" % CDI.AddInputVariable "streams(""3"").FmR" % CDI.AddInputVariable "streams(""1"").FR" % CDI.AddOutputVariable "blocks(""B1"").Stage(1).P" % CDI.AddOutputVariable "blocks(""B1"").Stage(1).Level" % CDI.AddOutputVariable "blocks(""B1"").SumpLevel" % CDI.AddOutputVariable "streams(""2"").Zmn(""TOLUENE"")" % CDI.AddOutputVariable "streams(""3"").Zmn(""BENZENE"")" % CDI.Calculate %% % |Step 2|: Initialize the APD model to the nominal steady-state condition. %% % |Step 3|: Invoke the script, which generates the following text files: %% % * |cdi_A.dat|, |cdi_B.dat|, |cdi_C.dat| define the A, B, and C matrices % of a standard continuous-time LTI state-space model. D matrix is zero. % The A, B, C matrices are sparse matrices. % * |cdi_list.lis| lists the model variables and their nominal values. % * |cdi_G.dat| defines the input/output static gain matrix at the nominal % condition. The gain matrix is also a sparse matrix. %% % In this example, |cdi_list.lis| includes the following information: % %% % A matrix computed, number of non-zero elements = 1408 % B matrix computed, number of non-zero elements = 26 % C matrix computed, number of non-zero elements = 20 % G matrix computed, number of non-zero elements = 30 % Number of state variables: 120 % Number of input variables: 6 % Number of output variables: 5 % Input variables: % 1 -3690034.247458334 BLOCKS("B1").Condenser(1).QR % 2 3819023.193875 BLOCKS("B1").QRebR % 3 22135.96620144 BLOCKS("B1").Reflux.FmR % 4 11717.39655353 STREAMS("2").FmR % 5 34352.86345834 STREAMS("3").FmR % 6 500 STREAMS("1").FR % Output variables: % 1 1.100022977953499 BLOCKS("B1").Stage(1).P % 2 0.6700005140605662 BLOCKS("B1").Stage(1).Level % 3 1.4875 BLOCKS("B1").SumpLevel % 4 0.05002582161855798 STREAMS("2").Zmn("TOLUENE") % 5 0.01705308738356429 STREAMS("3").Zmn("BENZENE") %% % The nominal values of the state variables listed in the file are ignored % because they are not needed in the MPC design. %% Create Scaled and Reduced LTI State-Space Model % |Step 1|: Convert the CDI-generated sparse-matrices to a state-space % model. % % Load state-space matrices from the CDI data files to MATLAB workspace and % convert the sparse matrices to full matrices. load mpcdistillation_cdi_A.dat load mpcdistillation_cdi_B.dat load mpcdistillation_cdi_C.dat A = full(spconvert(mpcdistillation_cdi_A)); B = full(spconvert(mpcdistillation_cdi_B)); C = full(spconvert(mpcdistillation_cdi_C)); D = zeros(5,6); %% % It is possible that an entire sparse matrix row or column is zero, in % which case the above commands are insufficient. Use the following % additional checks to make sure A, B, and C have the correct dimensions: [nxAr,nxAc] = size(A); [nxB,nu] = size(B); [ny,nxC] = size(C); nx = max([nxAr, nxAc, nxB, nxC]); if nx > nxC C = [C, zeros(ny,nx-nxC)]; end if nx > nxAc A = [A zeros(nxAr,nx-nxAc)]; end if nx > nxAr nxAc = size(A,2); A = [A; zeros(nx-nxAr, nxAc)]; end if nxB < nx B = [B; zeros(nx-nxB,nu)]; end %% % |Step 2|: Scale the plant signals. % % It is good practice, if not essential, to convert plant signals from % engineering units to a uniform dimensionless scale (e.g., 0-1 or 0-100%). % One alternative is to define scale factors as part of a Model Predictive % Controller design. This can simplify controller tuning significantly. % See, e.g., the demo "mpcscalefactor". % % In the present example, however, we will use a model reduction procedure % prior to controller design, and we therefore scale the plant model, using % the scaled model in both model reduction and controller design. We % define a _span_ for each input and output, i.e., the difference between % expected maximum and minimum values in engineering units. Also record % the _nominal_ and _zero_ values in engineering units to facilitate % subsequent conversions. U_span = [2*(-3690034), 2*3819023, 2*22136, 2*11717, 2*34353, 2*500]; U_nom = 0.5*U_span; U_zero = zeros(1,6); Y_nom = [1.1, 0.67, 1.4875, 0.050026, 0.017053]; Y_span = [0.4, 2*Y_nom(2:5)]; Y_zero = [0.9, 0, 0, 0, 0]; %% % Scale the B and C matrices such that all input/output variables are % expressed as percentages. B = B.*(ones(nx,1)*U_span); C = C./(ones(nx,1)*Y_span)'; %% % |Step 3|: Define the state-space plant model. G = ss(A,B,C,D); G.TimeUnit = 'hours'; G.u = {'Qc','Qr','R','D','B','F'}; G.y = {'P','RLev','Slev','xD','xB'}; %% % |Step 4|: Reduce model order. % % Model reduction speeds up the calculations with negligible effect on % prediction accuracy. Use the "hsvd" command to determine which states % can be safely discarded. Use the "balred" function to remove these % states and reduce model order. [hsv, baldata] = hsvd(G); order = find(hsv>0.01,1,'last'); Options = balredOptions('StateElimMethod','Truncate'); G = balred(G,order,baldata,Options); %% % The original model has 120 states and the reduced model has only 16 % states. Note that the "Truncate" option is used in the "balred" function % to preserve a zero D matrix. The model has two poles at zero, which % correspond to the two liquid levels. %% Test Accuracy of the Linear Plant Model % Before continuing with the MPC design, it is good practice to verify that % the scaled LTI model is accurate for small changes in the plant inputs. % To do so, you need to compare the response of the nonlinear plant in APD % and the response of linear model |G|. % % |Step 1|: To obtain the response of the nonlinear plant, create a % Simulink model and add the *Aspen Modeler* interface block to it. %% % The block is provided by Aspen Plus Dynamics in their |AMSimulink| % library shown below: % % <<../mpcdistillation_sl_interface.png>> % %% % |Step 2|: Double-click the block and provide the location of the APD % model. %% % The APD model information is then imported into Simulink. For large APD % models, the importing process may take some time. % % |Step 3|: Specify input and output signals in the "AMSimulation" block % dialog. %% % Use the same variable names and sequence as in the CDI script. % % <<../mpcdistillation_apd_inputs.png>> % % <<../mpcdistillation_apd_outputs.png>> % % The block now shows inports and outports for each signal that you % defined. %% % |Step 4|: Expand the Simulink model with an input signal coming from the % variable |Umat| and an output signal saved to variable |Ypct_NL|. Both % variables are created in Step 5. % % Since |Umat| is in the percentage units, the "Pct2Engr" block is % implemented to convert from percentage units to engineering units. % % <<../mpcdistillation_sl_pct2engr.png>> % % Since |Ypct_NL| is in the percentage units, the "Engr2Pct" block is % implemented to convert from engineering units to percentage units. % % <<../mpcdistillation_sl_engr2pct.png>> % % With everything connected and configured, the model appears as follows: % % <<../mpcdistillation_sl_distillation.png>> %% % |Step 5|: Verify linear model with cosimulation. %% % In this example, 1 percent increase in the scaled reflux rate (input #3) % is used as the excitation signal to the plant. U_nom_pct = (U_nom - U_zero)*100./U_span; % Convert nominal condition from engineering units to percentages Y_nom_pct = (Y_nom - Y_zero)*100./Y_span; Tend = 1; % Simulation duration (1 hour) t = (0:1/60:Tend)'; % Sample period is 1 minute nT = length(t); Upct = ones(nT,1)*U_nom_pct; DUpct = zeros(nT,6); DUpct(:,3) = ones(nT,1); % Input signal where step occurs in channel #3 %% % The response of the linear plant model is computed using the |lsim| % command and stored in variable |Ypct_L|. Ypct_L = lsim(G,DUpct,t); Ypct_L = Ypct_L + ones(nT,1)*Y_nom_pct; %% % The response of the nonlinear plant is obtained through cosimulation % between Simulink and Aspen Plus Dynamics. The excitation signal |Umat| % is constructed as below. The result is stored in variable |Ypct_NL|. Umat = [t, Upct+DUpct]; %% % Compare the linear and nonlinear model responses. % % <<../mpcdistillation_compare_plant.png>> % %% % The LTI model predictions track the nonlinear responses well. The amount % of prediction error is acceptable. In any case, a Model Predictive % Controller must be tuned to accommodate prediction errors, which are % inevitable in applications. % % You can repeat the above steps to verify similar agreement for the other % five inputs. %% Design Model Predictive Controller % Given an LTI prediction model, you are ready to design a Model Predictive % Controller. In this example, the manipulated variables are the first % five plant inputs. The sixth plant input (feed flow rate) is a measured % disturbance for feed-forward compensation. All the plant outputs are % measured. %% % |Step 1|: Augment the plant to model unmeasured load disturbances. %% % Lacking any more specific details regarding load disturbances, it is % common practice to assume an unmeasured load disturbance occurring at % each of the five inputs. This allows the MPC state estimator to % eliminate offset in each controlled output when a load disturbance % occurs. % % In this example, 5 unmeasured load disturbances are added to the plant % model |G|. In total, there are now 11 inputs to the prediction model % |Gmpc|: 5 manipulated variables, 1 measured disturbance, and 5 unmeasured % disturbances. Gmpc = ss(G.A,G.B(:,[1:6,1:5]),G.C,zeros(5,11),'TimeUnit','hours'); InputName = cell(1,11); for i = 1:5 InputName{i} = G.InputName{i}; InputName{i+6} = [G.InputName{i}, '-UD']; end InputName{6} = G.InputName{6}; Gmpc.InputName = InputName; Gmpc.InputGroup = struct('MV',1:5,'MD',6,'UD',7:11); Gmpc.OutputName = G.OutputName; %% % |Step 2|: Create an initial model predictive controller and specify % sample time and horizons. %% % In this example, the controller sample period is 30 seconds. The % prediction horizon is 60 intervals (30 minutes), which is large enough to % make the controller performance insensitive to further increases of the % prediction horizon. The control horizon is 4 intervals (2 minutes), % which is relatively small to reduce computational effort. Ts = 30/3600; % sample time PH = 60; % prediction horizon CH = 4; % control horizon MPCobj = mpc(Gmpc,Ts,PH,CH); % MPC object %% % |Step 3|: Specify weights for manipulated variables and controlled % outputs. %% % Weights are key tuning adjustments in MPC design and they should be % chosen based on your control objectives. % % There is no reason to hold a particular MV at a setpoint, so set the % |Weights.ManipulatedVariables| property to zero: MPCobj.Weights.ManipulatedVariables = [0, 0, 0, 0, 0]; %% % The distillate product (MV #4) goes to storage. The only MV affecting % downstream unit operations is the bottoms rate (MV #5). To discourage % rapid changes in bottoms rate, retain the default weight of 0.1 for its % rate of change. Reduce the other rate of change weights by a factor of % 10: MPCobj.Weights.ManipulatedVariablesRate = [0.01, 0.01, 0.01, 0.01, 0.1]; %% % The control objectives provide guidelines to choose weights on controlled % outputs: % % # The tower pressure must be regulated tightly for safety reasons and for % minimizing upsets in tray temperatures and hydraulics. (objective #1) % # The distillate composition must also be regulated tightly. (objective #2) % # The bottoms composition can be regulated less tightly. (objective #3) % # The liquid levels are even less important. (objective #4) % % With these priorities in mind, weights on controlled outputs are chosen % as follows:: MPCobj.Weights.OutputVariables = [10, 0.1, 0.1, 1, 0.5]; %% % Scaling the model simplifies the choice of the optimization weights. % Otherwise, in addition to the relative priority of each variable, you % would also have to consider the relative magnitudes of the variables and % choose weights accordingly. %% % |Step 4|: Specify nominal plant input/output values. %% % In this example, the nominal values are scaled as percentages. MPC % controller demands that the nominal values for unmeasured disturbances % must be zero. MPCobj.Model.Nominal.U = [U_nom_pct'; zeros(5,1)]; MPCobj.Model.Nominal.Y = Y_nom_pct'; %% % |Step 5|: Adjust state estimator gain. %% % Adjusting the state estimator gain affects the disturbance rejection % performance. Increasing the state estimator gain (e.g. by increasing the % gain of the input/output disturbance model) makes the controller respond % more aggressively towards output changes (because the controller assumes % the main source of the output changes is a disturbance, instead of % measurement noise). On the other hand, decreasing the state estimator % gain makes the closed-loop system more robust. %% % First, check whether using the default state estimator provides a decent % disturbance rejection performance. %% % Simulate the closed-loop response to a 1% unit step in reflux (MV #3) in % MATLAB. The simulation uses |G| as the plant, which implies no model % mismatch. T = 30; % Simulation time r = Y_nom_pct; % Nominal setpoints v = U_nom_pct(6); % No measured disturbance SimOptions = mpcsimopt(MPCobj); SimOptions.InputNoise = [0 0 1 0 0]; % 1% unit step in reflux [y_L,t_L,u_L] = sim(MPCobj, T, r, v, SimOptions); % Closed-loop simulation % plot responses f1 = figure(); subplot(2,1,1); plot(t_L,y_L,[0 t_L(end)],[50 50],'k--') title('Controlled Outputs, %') legend(Gmpc.OutputName,'Location','NorthEastOutside') subplot(2,1,2); plot(t_L,u_L(:,1:5),[0 t_L(end)],[50 50],'k--') title('Manipulated Variables, %') legend(Gmpc.InputName(1:5),'Location','NorthEastOutside') xlabel('Time, h') %% % The default estimator provides sluggish load rejection. In particular, % the critical xD output drops to 49% and has just begun to return to the % setpoint after 0.25 hours. %% % Secondly, increase the estimator gain by multiplying the default input % disturbance model gain by a factor of 25. EstGain = 25; % factor of 25 Gd = getindist(MPCobj); % get default input disturbance model Gd_new = EstGain*Gd; % create new input disturbance model setindist(MPCobj,'Model',Gd_new); % set input disturbance model [y_L,t_L,u_L] = sim(MPCobj,T,r,v,SimOptions); % Closed-loop simulation % plot responses f2 = figure(); subplot(2,1,1); plot(t_L,y_L,[0 t_L(end)],[50 50],'k--') title('Controlled Outputs, %') legend(Gmpc.OutputName,'Location','NorthEastOutside') subplot(2,1,2) plot(t_L,u_L(:,1:5),[0 t_L(end)],[50 50],'k--') title('Manipulated Variables, %') legend(Gmpc.InputName(1:5),'Location','NorthEastOutside') xlabel('Time, h') %% % Now, the peak deviation in xD is 50% less than the default case and xD % returns to its setpoint much faster. Other variables also respond more % rapidly. %% % Thirdly, look at the reflux response (#3 in the "Manipulated Variables" % plot). Because the disturbance is a 1% unit step, the response begins at % 51% and its final value is 50% at steady state. The reflux response % overshoots by 20% (reaching 49.8%) before settling. This amount of % overshoot is acceptable. % % If the estimator gain were increased further (e.g. by a factor of 50), % the controller overshoot would increase too. However, such aggressive % behavior is unlikely to be robust when applied to the nonlinear plant % model. % % You can introduce other load disturbances to verify that disturbance % rejection is now rapid in all cases. % % Scaling the model also simplifies disturbance model tuning. Otherwise, % you would need to adjust the gain of each channel in the disturbance % model to achieve good disturbance rejection for all loads. % % Generally, you next check the response to setpoint changes. If the % response is too aggressive, you can use setpoint filter to smooth it. % Setpoint filter has no effect on load disturbance rejection and % thus can be tuned independently. %% Cosimulate MPC Controller and Nonlinear Plant % Use cosimulation to determine whether the MPC design is robust enough to % control the nonlinear plant model. %% % |Step 1|: Add constraints to the MPC controller %% % Because the nonlinear plant model has input and output constraints during % operation, MV and OV constraints are defined in the MPC controller as % follows: MV = MPCobj.MV; OV = MPCobj.OV; % Physical bounds on MVs at 0 and 100 for i = 1:5 MV(i).Min = 0; MV(i).Max = 100; end MPCobj.MV = MV; % Keep liquid levels greater than 25% and less than 75% of capacity. for i = 2:3 OV(i).Min = 25; OV(i).Max = 75; end MPCobj.OV = OV; %% % |Step 2|: Build Simulink model for cosimulation. % % <<../mpcdistillation_sl_mpc.png>> % % The model can simulate 1% unit step in reflux (MV #3). It can also % simulate a change in feed composition, which is a common disturbance and % differs from the load disturbances considered explicitly in the design. %% % |Step 3|: Simulate 1% unit step in reflux (MV #3). Compare the % closed-loop responses between using the linear plant model and using the % nonlinear plant model. %% % Plot distillate product composition (xD) and the reflux rate (R): % % <<../mpcdistillation_compare_reflux.png>> % %% % In cosimulation, the model predictive controller rejects the small load % disturbance in a manner almost identical to the linear simulation. % %% % |Step 4|: Simulate a large decrease of benzene fraction (from 0.3 to % 0.22) in the feed stream. Compare the closed-loop responses between % using the linear and nonlinear plant models. % % <<../mpcdistillation_feed_disturbance.png>> %% % The drop in benzene fraction requires a sustained decrease in the % distillate rate and a corresponding increase in the bottoms rate. There % are also sustained drops in the heat duties and a minor increase in the % reflux. All MV adjustments are smooth and all controlled outputs are % nearly back to their setpoints within 0.5 hours. %%