## Documentation Center |

Another approach to optimizing the control
parameters in the Simulink^{®} model shown in Plant with Actuator Saturation is to use the `fminimax` function. In this case, rather
than minimizing the error between the output and the input signal,
you minimize the maximum value of the output at any time `t` between
0 and 100.

The code for this example, shown below, is contained in the
function `runtrackmm`, in which the objective function
is simply the output `yout` returned by the `sim` command. But minimizing the maximum
output at all time steps might force the output to be far below unity
for some time steps. To keep the output above `0.95` after
the first `20` seconds, the constraint function `trackmmcon` contains
the constraint `yout >= 0.95` from `t=20` to `t=100`.
Because constraints must be in the form `g ≤ 0`,
the constraint in the function is `g = -yout(20:100)+.95`.

Both `trackmmobj` and `trackmmcon` use
the result `yout` from `sim`,
calculated from the current PID values. To avoid calling the simulation
twice, `runtrackmm` has nested functions so that
the value of `yout` is shared between the objective
and constraint functions. The simulation is called only when the current
point changes.

The following is the code for `runtrackmm`:

function [Kp, Ki, Kd] = runtrackmm optsim % initialize Simulink(R) pid0 = [0.63 0.0504 1.9688]; % a1, a2, yout are shared with TRACKMMOBJ and TRACKMMCON a1 = 3; a2 = 43; % Initialize plant variables in model yout = []; % Give yout an initial value pold = []; % tracks last pid options = optimoptions('fminimax','Display','iter',... 'TolX',0.001,'TolFun',0.001); pid = fminimax(@trackmmobj,pid0,[],[],[],[],[],[],... @trackmmcon,options); Kp = pid(1); Ki = pid(2); Kd = pid(3); function F = trackmmobj(pid) % Track the output of optsim to a signal of 1. % Variables a1 and a2 are shared with RUNTRACKMM. % Variable yout is shared with RUNTRACKMM and % RUNTRACKMMCON. updateIfNeeded(pid) F = yout; end function [c,ceq] = trackmmcon(pid) % Track the output of optsim to a signal of 1. % Variable yout is shared with RUNTRACKMM and % TRACKMMOBJ updateIfNeeded(pid) c = -yout(20:100)+.95; ceq=[]; end function updateIfNeeded(pid) if ~isequal(pid,pold) % compute only if needed Kp = pid(1); Ki = pid(2); Kd = pid(3); myobj = sim('optsim','SrcWorkspace','Current'); yout = myobj.get('yout'); pold = pid; end end end

Copy the code for `runtrackmm` to a file named `runtrackmm.m`,
placed in a folder on your MATLAB^{®} path.

When you run the code, it returns the following results:

[Kp,Ki,Kd] = runtrackmm Done initializing optsim. Objective Max Line search Directional Iter F-count value constraint steplength derivative Procedure 0 5 0 1.11982 1 11 1.184 0.07978 1 0.482 2 17 1.012 0.04285 1 -0.236 3 23 0.9996 0.00397 1 -0.0195 Hessian modified twice 4 29 0.9996 3.464e-005 1 0.000687 Hessian modified 5 35 0.9996 2.272e-009 1 -0.0175 Hessian modified twice Local minimum possible. Constraints satisfied. fminimax stopped because the size of the current search direction is less than twice the selected value of the step size tolerance and constraints are satisfied to within the default value of the constraint tolerance. Kp = 0.5894 Ki = 0.0605 Kd = 5.5295

The last value in the `Objective value` column
of the output shows that the maximum value for all the time steps
is `0.9997`. The closed loop response with this result
is shown in the figure Closed-Loop Response Using fminimax.

This solution differs from the solution obtained in lsqnonlin with a Simulink Model because you are solving different problem formulations.

Was this topic helpful?