Accelerating the pace of engineering and science

# Robust Control Toolbox

## 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')
```