This example shows how to interpret and validate tuning results from
You can tune the parameters of your control system with
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.
The setup and tuning steps are repeated below for completeness.
ST0 = slTuner('rct_airframe2','MIMO Controller'); % Compensator parameterization C0 = ltiblock.ss('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,~,Info] = systune(ST0,[Req1,Req2,Req3,Req4],Opt);
Final: Soft = 1.5, Hard = -Inf, Iterations = 63 Final: Soft = 1.49, Hard = -Inf, Iterations = 94 Final: Soft = 1.15, Hard = -Inf, Iterations = 69 Final: Soft = 1.15, Hard = -Inf, Iterations = 109
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 = 1.1477 1.1477 0.5458 1.1477
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.
viewSpec to graphically inspect each requirement. This is useful to understand whether small violations are acceptable or what causes large violations. Make sure to provide the structure
Info returned by
systune to properly account for scalings and other parameters computed by the optimization algorithms. First verify the tracking requirement.
We observe a slight violation across frequency, suggesting that setpoint tracking will perform close to expectations. Similarly, verify the disturbance rejection requirement.
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.
This requirement is satisfied at all frequencies, with the smallest margins achieved near the crossover frequency as expected. To see the actual margin values at a given frequency, click on the red curve and read the values from the data tip.
You can also use
evalSpec to evaluate each requirement, that is, compute its contribution to the soft and hard constraints. For example
[H1,f1] = evalSpec(Req1,ST1,Info);
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
[f1 fSoft(1) getPeakGain(H1,1e-6)]
ans = 1.1477 1.1477 1.1477
Analyzing System Responses
In addition to verifying requirements, you can perform basic open- and closed-loop analysis using
getLoopTransfer. For example, verify tracking performance in the time domain by plotting the response
az to a step command
azref for the tuned system
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,Info] = ST1.systune([Req1 Req2],[Req3 Req4]);
Final: Soft = 1.3, Hard = 0.99963, Iterations = 182
fSoft = 1.2356 1.3044
gHard = 0.4781 0.9996
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.