Contents

Loop Margins for an Airframe Autopilot

This example shows how to use loopmargin to analyze the closed-loop robustness of Simulink models with specified loop-breaking points.

This example is drawn from the Simulink® Control Design™ example "Trimming and Linearizing an Airframe". See this example for details on the operating point specification, linearization I/O objects, and linearization. The airframe autopilot is modeled as follows:

airframemargin

Stability Margin Analysis with LOOPMARGIN

Linearized Stability Margin analysis of the airframe autopilot feedback loops is done using loopmargin. Define margin analysis points at the outputs of the Airframe Model block corresponding to the normal acceleration, az, and pitch rate, q.

block1 = 'airframemargin/Airframe Model';
port1 = 1;

Use loopmargin to compute the linearized margins at all loop-opening points (in this case, there are two), at the forward speed of 984 m/s operating condition.

[cm,dm,mm,info] = loopmargin('airframemargin',{block1},port1);

For comparison, the results are compared with those derived using the commands linearize and allmargin.

L = linearize('airframemargin',info.OperatingPoint,info.LinearizationIO);
cm1 = allmargin(-L)
cm(1)
cm1 = 

     GainMargin: [4.5652 2.5055e+03]
    GMFrequency: [7.1979 314.1593]
    PhaseMargin: 65.1907
    PMFrequency: 2.1463
    DelayMargin: 53.0113
    DMFrequency: 2.1463
         Stable: 1


ans = 

     GainMargin: [4.5652 2.5055e+03]
    GMFrequency: [7.1979 314.1593]
    PhaseMargin: 65.1907
    PMFrequency: 2.1463
    DelayMargin: 53.0113
    DMFrequency: 2.1463
         Stable: 1

LOOPMARGIN with Multiple Operating Points

Create an additional margin analysis point at the output of the Combustion block.

block2 = 'airframemargin/Airframe Model';
port2 = 2;

Note that there are now two margin analysis points in the Simulink model. The multi-loop stability margins for the two loops are calculated using loopmargin. Here the calculation is performed at the single operating point. CM (classical margin) and DM (disc margin) are 2-by-1 struct arrays, while MM (multi-loop margin) is a scalar struct.

block = {block1; block2};
port = [port1; port2];
[CM,DM,MM,info] = loopmargin('airframemargin',block,port)
L = linearize('airframemargin',info.OperatingPoint,info.LinearizationIO);
cm2 = allmargin(lft(-1,-L,1,1))
CM(2)
CM = 

2x1 struct array with fields:

    GainMargin
    GMFrequency
    PhaseMargin
    PMFrequency
    DelayMargin
    DMFrequency
    Stable


DM = 

2x1 struct array with fields:

    GainMargin
    PhaseMargin
    Frequency


MM = 

     GainMargin: [0.6218 1.6083]
    PhaseMargin: [-26.2561 26.2561]
      Frequency: 3.8690


info = 

     OperatingPoint: [1x1 opcond.OperatingPoint]
    LinearizationIO: [2x1 linearize.IOPoint]
        SignalNames: {2x1 cell}
                  L: [2x2 ss]


cm2 = 

     GainMargin: [0.3456 17.4301]
    GMFrequency: [3.4362 49.8484]
    PhaseMargin: [-78.2436 52.6040]
    PMFrequency: [1.5686 6.5428]
    DelayMargin: [313.5079 14.0324]
    DMFrequency: [1.5686 6.5428]
         Stable: 1


ans = 

     GainMargin: [0.3456 17.4301]
    GMFrequency: [3.4362 49.8484]
    PhaseMargin: [-78.2436 52.6040]
    PMFrequency: [1.5686 6.5428]
    DelayMargin: [313.5079 14.0324]
    DMFrequency: [1.5686 6.5428]
         Stable: 1

Similarly, the stability margins for the two loops at the three operating points are calculated. CM and DM are 2-by-3 struct arrays, where the second dimension corresponds to dimensions of the OperPoint object.

snapt = [0.1; 15; 20];  % snapt = 0 gives a different # of states than snapt>0
[CM,DM,MM,info] = loopmargin('airframemargin',block,port,snapt)
CM = 

2x3 struct array with fields:

    GainMargin
    GMFrequency
    PhaseMargin
    PMFrequency
    DelayMargin
    DMFrequency
    Stable


DM = 

2x3 struct array with fields:

    GainMargin
    PhaseMargin
    Frequency


MM = 

1x3 struct array with fields:

    GainMargin
    PhaseMargin
    Frequency


info = 

     OperatingPoint: [1x3 opcond.OperatingPoint]
    LinearizationIO: [2x1 linearize.IOPoint]
        SignalNames: {2x1 cell}
                  L: [4-D ss]

info is a structure with fields OperatingPoint, LinearizationIO, L, and SignalNames. SignalNames is a cell containing the names of the individual loops.

info.SignalNames
ans = 

    'Airframe Model/1'
    'Airframe Model/2'

Close the model.

bdclose('airframemargin')
Was this topic helpful?