www.gusucode.com > robust_featured 案例源码程序 matlab代码 > robust_featured/hinfstruct_demo.m

    %% Fixed-Structure H-infinity Synthesis with HINFSTRUCT
% This example uses the |hinfstruct| command to tune a fixed-structure 
% controller subject to $H_\infty$ constraints. 

%   Copyright 1986-2012 The MathWorks, Inc.

%% Introduction
% The |hinfstruct| command extends classical $H_\infty$ synthesis (see |hinfsyn|)
% to fixed-structure control systems. This command is meant for users already
% comfortable with the |hinfsyn| workflow. If you are unfamiliar with 
% $H_\infty$ synthesis or find augmented plants and weighting functions 
% intimidating, use |systune| and |looptune| instead. See 
%  _"Tuning Control Systems with SYSTUNE"_  for the |systune| counterpart
% of this example.

%% Plant Model
% This example uses a 9th-order model of the head-disk assembly (HDA) in a 
% hard-disk drive. This model captures the first few flexible modes in the HDA.

load hinfstruct_demo G
bode(G), grid

%%
% We use the feedback loop shown below to position the head on the 
% correct track. This control structure consists of a PI controller and 
% a low-pass filter in the return path. The head position |y| should 
% track a step change |r| with a response time of about 
% one millisecond, little or no overshoot, and no steady-state error.
%
% <<../hinfstructdemo1.png>>
%
% *Figure 1: Control Structure*


%% Tunable Elements
% There are two tunable elements in the control structure of Figure 1:
% the PI controller $C(s)$ and the low-pass filter
%
% $$ F(s) = {a \over s+a} . $$
%
% Use the |tunablePID| class to parameterize the PI block and specify the 
% filter $F(s)$ as a transfer function depending on a tunable real parameter $a$.

C0 = tunablePID('C','pi');  % tunable PI

a = realp('a',1);    % filter coefficient
F0 = tf(a,[1 a]);    % filter parameterized by a

%% Loop Shaping Design
% Loop shaping is a frequency-domain technique for enforcing requirements
% on response speed, control bandwidth, roll-off, and steady state error.
% The idea is to specify a target gain profile or "loop shape" for the open-loop response
% $L(s) = F(s) G(s) C(s)$. A reasonable loop shape for this application should have
% integral action and a crossover frequency of about 1000 rad/s (the reciprocal 
% of the desired response time of 0.001 seconds). This suggests the following loop shape:

wc = 1000;  % target crossover
s = tf('s');
LS = (1+0.001*s/wc)/(0.001+s/wc);
bodemag(LS,{1e1,1e5}), grid, title('Target loop shape')

%%
% Note that we chose a bi-proper, bi-stable realization to avoid technical
% difficulties with marginally stable poles and improper inverses.
% In order to tune $C(s)$ and $F(s)$ with |hinfstruct|, we must turn this target
% loop shape into constraints on the closed-loop gains.
% A systematic way to go about this is to instrument the feedback loop as follows:
%
% * Add a measurement noise signal |n|
% * Use the target loop shape |LS| and its reciprocal to filter the error signal 
%   |e| and the white noise source |nw|.
%
% <<../hinfstructdemo3.png>>
%
% *Figure 2: Closed-Loop Formulation*
%
% If $T(s)$ denotes the closed-loop transfer function from |(r,nw)| to |(y,ew)|,
% the gain constraint 
%
% $$ \| T \|_\infty < 1  $$
%
% secures the following desirable properties:
%
% * At low frequency (w<wc), the open-loop gain stays above the gain specified by the
%   target loop shape |LS|
% * At high frequency (w>wc), the open-loop gain stays below the gain specified by
%   |LS|
% * The closed-loop system has adequate stability margins
% * The closed-loop step response has small overshoot.
%
% We can therefore focus on tuning $C(s)$ and $F(s)$ to enforce $$ \| T \|_\infty < 1 $$.


%% Specifying the Control Structure in MATLAB
% In MATLAB, you can use the |connect| command to model $T(s)$ by connecting 
% the fixed and tunable components according to the block diagram of Figure 2:

% Label the block I/Os
Wn = 1/LS;  Wn.u = 'nw';  Wn.y = 'n';
We = LS;    We.u = 'e';   We.y = 'ew';
C0.u = 'e';   C0.y = 'u';
F0.u = 'yn';  F0.y = 'yf';

% Specify summing junctions
Sum1 = sumblk('e = r - yf');
Sum2 = sumblk('yn = y + n');

% Connect the blocks together
T0 = connect(G,Wn,We,C0,F0,Sum1,Sum2,{'r','nw'},{'y','ew'});

%%
% These commands construct a generalized state-space model |T0| of $T(s)$. 
% This model depends on the tunable blocks |C| and |a|:

T0.Blocks

%% 
% Note that |T0| captures the following "Standard Form" of the block diagram 
% of Figure 2 where the tunable components $C,F$ are separated from the fixed 
% dynamics.
%
% <<../hinfstructdemo4.png>>
%
% *Figure 3: Standard Form for Disk-Drive Loop Shaping*

%% Tuning the Controller Gains
% We are now ready to use |hinfstruct| to tune the PI controller $C$ and filter $F$
% for the control architecture of Figure 1. To mitigate the risk of local minima, run three
% optimizations, two of which are started from randomized initial values for 
% |C0| and |F0|:

rng('default')
opt = hinfstructOptions('Display','final','RandomStart',5);
T = hinfstruct(T0,opt);

%% 
% The best closed-loop gain is 1.56, so the constraint $$ \| T \|_\infty < 1 $$
% is nearly satisfied. The |hinfstruct| command returns the tuned closed-loop
% transfer $T(s)$. Use |showTunable| to see the tuned values of $C$ and 
% the filter coefficient $a$:

showTunable(T)

%% 
% Use |getBlockValue| to get the tuned value of $C(s)$ and use |getValue| 
% to evaluate the filter $F(s)$ for the tuned value of $a$:

C = getBlockValue(T,'C');
F = getValue(F0,T.Blocks);  % propagate tuned parameters from T to F

tf(F)

%%
% To validate the design, plot the open-loop response |L=F*G*C| and compare 
% with the target loop shape |LS|:

bode(LS,'r--',G*C*F,'b',{1e1,1e6}), grid, 
title('Open-loop response'), legend('Target','Actual')

%%
% The 0dB crossover frequency and overall loop shape are as expected. The stability
% margins can be read off the plot by right-clicking and selecting the *Characteristics* 
% menu. This design has 24dB gain margin and 81 degrees phase margin. Plot the 
% closed-loop step response from reference |r| to position |y|:

step(feedback(G*C,F)), grid, title('Closed-loop response')

%%
% While the response has no overshoot, there is some residual wobble due to the first
% resonant peaks in |G|. You might consider adding a notch filter in the forward path 
% to remove the influence of these modes.

%% Tuning the Controller Gains from Simulink
% Suppose you used this <matlab:open_system('rct_diskdrive') Simulink model> 
% to represent the control structure. If you have Simulink
% Control Design installed, you can tune the controller gains from this
% Simulink model as follows. First mark the signals |r,e,y,n| as 
% Linear Analysis points in the Simulink model.
%
% <<../hinfstructdemo6.png>>
%
% Then create an instance of the |slTuner| interface and mark the Simulink
% blocks |C| and |F| as tunable:

ST0 = slTuner('rct_diskdrive',{'C','F'});

%%
% Since the filter $F(s)$ has a special structure, explicitly specify how
% to parameterize the |F| block:

a = realp('a',1);    % filter coefficient
setBlockParam(ST0,'F',tf(a,[1 a]));

%%
% Finally, use |getIOTransfer| to derive a tunable model of
% the closed-loop transfer function $T(s)$ (see Figure 2)

% Compute tunable model of closed-loop transfer (r,n) -> (y,e)
T0 = getIOTransfer(ST0,{'r','n'},{'y','e'});

% Add weighting functions in n and e channels
T0 = blkdiag(1,LS) * T0 * blkdiag(1,1/LS);

%%
% You are now ready to tune the controller gains with |hinfstruct|:

rng(0)
opt = hinfstructOptions('Display','final','RandomStart',5);
T = hinfstruct(T0,opt);

%%
% Verify that you obtain the same tuned values as with the MATLAB approach:

showTunable(T)