Main Content

Validating Results

This example shows how to interpret and validate tuning results from systune.

Background

You can tune the parameters of your control system with systune or looptune. The design specifications are captured using TuningGoal requirement objects. This example shows how to interpret the results from systune, graphically verify the design requirements, and perform additional open- and closed-loop analysis.

Controller Tuning with SYSTUNE

We use an autopilot tuning application as illustration; see the "Tuning of a Two-Loop Autopilot" example for details. The tuned compensator is the "MIMO Controller" block highlighted in orange in the model below.

open_system('rct_airframe2')

The setup and tuning steps are repeated below for completeness.

ST0 = slTuner('rct_airframe2','MIMO Controller');

% Compensator parameterization
C0 = tunableSS('C',2,1,2);
C0.D.Value(1) = 0;
C0.D.Free(1) = false;
setBlockParam(ST0,'MIMO Controller',C0)

% Requirements
Req1 = TuningGoal.Tracking('az ref','az',1);                  % tracking
Req2 = TuningGoal.Gain('delta fin','delta fin',tf(25,[1 0])); % roll-off
Req3 = TuningGoal.Margins('delta fin',7,45);                  % margins
MaxGain = frd([2 200 200],[0.02 2 200]);
Req4 = TuningGoal.Gain('delta fin','az',MaxGain);  % disturbance rejection

% Tuning
Opt = systuneOptions('RandomStart',3);
rng('default')
[ST1,fSoft] = systune(ST0,[Req1,Req2,Req3,Req4],Opt);
Final: Soft = 1.51, Hard = -Inf, Iterations = 52
Final: Soft = 1.15, Hard = -Inf, Iterations = 153
Final: Soft = 1.15, Hard = -Inf, Iterations = 57
Final: Soft = 1.15, Hard = -Inf, Iterations = 96

Interpreting Results

systune run three optimizations from three different starting points and returned the best overall result. The first output ST is an slTuner interface representing the tuned control system. The second output fSoft contains the final values of the four requirements for the best design.

fSoft
fSoft =

    1.1476    1.1476    0.5461    1.1476

Requirements are normalized so a requirement is satisfied if and only if its value is less than 1. Inspection of fSoft reveals that Requirements 1,2,4 are active and slightly violated while Requirement 3 (stability margins) is satisfied.

Verifying Requirements

Use viewGoal to graphically inspect each requirement. This is useful to understand whether small violations are acceptable or what causes large violations. First verify the tracking requirement.

viewGoal(Req1,ST1)

We observe a slight violation across frequency, suggesting that setpoint tracking will perform close to expectations. Similarly, verify the disturbance rejection requirement.

viewGoal(Req4,ST1)
legend('location','NorthWest')
ans = 

  Legend (Principal gains, Max gain) with properties:

         String: {'Principal gains'  'Max gain'}
       Location: 'northwest'
    Orientation: 'vertical'
       FontSize: 9
       Position: [0.1491 0.7968 0.2464 0.0789]
          Units: 'normalized'

  Use GET to show all properties

Most of the violation is at low frequency with a small bump near 35 rad/s, suggesting possible damped oscillations at this frequency. Finally, verify the stability margin requirement.

viewGoal(Req3,ST1)

This requirement is satisfied at all frequencies, with the smallest margins achieved near the crossover frequency as expected.

Evaluating Requirements

You can also use evalGoal to evaluate each requirement, that is, compute its contribution to the soft and hard constraints. For example

[H1,f1] = evalGoal(Req1,ST1);

returns the value f1 of the requirement and the underlying frequency-weighted transfer function H1 used to computed it. You can verify that f1 matches the first entry of fSoft and coincides with the peak gain of H1.

[f1 fSoft(1) getPeakGain(H1,1e-6)]
ans =

    1.1476    1.1476    1.1476

Analyzing System Responses

In addition to verifying requirements, you can perform basic open- and closed-loop analysis using getIOTransfer and getLoopTransfer. For example, verify tracking performance in the time domain by plotting the response az to a step command azref for the tuned system ST1.

T = ST1.getIOTransfer('az ref','az');
step(T)

Also plot the open-loop response measured at the plant input delta fin. You can use this plot to assess the classical gain and phase margins at the plant input.

L = ST1.getLoopTransfer('delta fin',-1);  % negative-feedback loop transfer
margin(L)
grid

Soft vs Hard Requirements

So far we have treated all four requirements equally in the objective function. Alternatively, you can use a mix of soft and hard constraints to differentiate between must-have and nice-to-have requirements. For example, you could treat Requirements 3,4 as hard constraints and optimize the first two requirements subject to these constraints. For best results, do this only after obtaining a reasonable design with all requirements treated equally.

[ST2,fSoft,gHard] = systune(ST1,[Req1 Req2],[Req3 Req4]);
Final: Soft = 1.29, Hard = 0.99982, Iterations = 182
fSoft
fSoft =

    1.2887    1.2887

gHard
gHard =

    0.4664    0.9998

Here fSoft contains the final values of the first two requirements (soft constraints) and gHard contains the final values of the last two requirements (hard constraints). The hard constraints are satisfied since all entries of gHard are less than 1. As expected, the best value of the first two requirements went up as the optimizer strived to strictly enforce the fourth requirement.