Loop Margins for an Airframe Autopilot
Contents
This demonstration is drawn from the Simulink® Control Design™ demo scdairframe.m involving analysis of a missile autopilot. See "Trimming and Linearizing an Airframe" demonstration in the Simulink Control Design Toolbox for details on the operating point specification, linearization I/O objects and linearization.
In this demonstration the focus is on loopmargin, using it to analyze the closed-loop robustness of Simulink models with specified loop-breaking points.
Open the Aiframe Autopilot Model
airframemargin

Stability Margin Analysis with LOOPMARGIN
Linearized Stability Margin analysis of the missile 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+003] 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+003] 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.6233 1.6044] PhaseMargin: [-26.1306 26.1306] Frequency: 3.6190 info = OperatingPoint: [1x1 opcond.OperatingPoint] LinearizationIO: [1x2 LinearizationObjects.LinearizationIO] 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 = GainMargin: [] PhaseMargin: [] Frequency: [] info = OperatingPoint: [1x3 opcond.OperatingPoint] LinearizationIO: [1x2 LinearizationObjects.LinearizationIO] 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')