Note: This page has been translated by MathWorks. Click here to see

To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

This example shows how to use `slTuner`

and `systune`

to tune the current and velocity loops in a linear electric actuator with saturation limits.

Open the Simulink model of the linear electric actuator:

```
open_system('rct_linact')
```

The electrical and mechanical components are modeled using Simscape Electrical and Simscape Multibody. The control system consists of two cascaded feedback loops controlling the driving current and angular speed of the DC motor.

**Figure 1: Current and Speed Controllers.**

Note that the inner-loop (current) controller is a proportional gain while the outer-loop (speed) controller has proportional and integral actions. The output of both controllers is limited to plus/minus 5.

We need to tune the proportional and integral gains to respond to a 2000 rpm speed demand in about 0.1 seconds with minimum overshoot. The initial gain settings in the model are P=50 and PI(s)=0.2+0.1/s and the corresponding response is shown in Figure 2. This response is too slow and too sensitive to load disturbances.

**Figure 2: Untuned Response.**

You can use `systune`

to jointly tune both feedback loops. To set up the design, create an instance of the `slTuner`

interface with the list of tuned blocks. All blocks and signals are specified by their names in the model. The model is linearized at t=0.5 to avoid discontinuities in some derivatives at t=0.

TunedBlocks = {'Current PID','Speed PID'}; tLinearize = 0.5; % linearize at t=0.5 % Create tuning interface ST0 = slTuner('rct_linact',TunedBlocks,tLinearize);

The data structure `ST0`

contains a description of the control system and its tunable elements. Next specify that the DC motor should follow a 2000 rpm speed demand in 0.1 seconds:

TR = TuningGoal.Tracking('Speed Demand (rpm)','rpm',0.1);

You can now tune the proportional and integral gains with `looptune`

:

ST1 = systune(ST0,TR);

Final: Soft = 1.12, Hard = -Inf, Iterations = 34

This returns an updated description `ST1`

containing the tuned gain values. To validate this design, plot the closed-loop response from speed demand to speed:

T1 = getIOTransfer(ST1,'Speed Demand (rpm)',{'rpm','i'}); figure step(T1)

The response looks good in the linear domain so push the tuned gain values to Simulink and further validate the design in the nonlinear model.

writeBlockValue(ST1)

The nonlinear simulation results appear in Figure 3. The nonlinear behavior is far worse than the linear approximation, a discrepancy that can be traced to saturations in the inner loop (see Figure 4).

**Figure 3: Nonlinear Simulation of Tuned Controller.**

**Figure 4: Current Controller Output (limited to plus/minus 5).**

So far we have only specified a desired response time for the outer (speed) loop. This leaves `systune`

free to allocate the control effort between the inner and outer loops. Saturations in the inner loop suggest that the proportional gain is too high and that some rebalancing is needed. One possible remedy is to explicitly limit the gain from the speed command to the outputs of the P and PI controllers. For a speed reference of 2000 rpm and saturation limits of plus/minus 5, the average gain should not exceed 5/2000 = 0.0025. To be conservative, we can try to keep the gain from speed reference to controller outputs below 0.001. To do this, add two gain requirements and retune the controller gains with all three requirements in place.

% Mark the control signals as points of interest so that they can be % referenced in the gain requirements addPoint(ST0,{'Current PID','Speed PID'}) % Limit gain from speed demand to control signals to avoid saturation MG1 = TuningGoal.Gain('Speed Demand (rpm)','Speed PID',0.001); MG2 = TuningGoal.Gain('Speed Demand (rpm)','Current PID',0.001); % Retune with these additional requirements ST2 = systune(ST0,[TR,MG1,MG2]);

Final: Soft = 1.39, Hard = -Inf, Iterations = 42

The final gain 1.39 indicates that the requirements are nearly but not exactly met (all requirements are met when the final gain is less than 1). Use `viewGoal`

to inspect how the tuned controllers fare against each requirement.

```
figure('Position',[100,100,560,550])
viewGoal([TR,MG1,MG2],ST2)
```

Next compare the two designs in the linear domain.

T2 = getIOTransfer(ST2,'Speed Demand (rpm)',{'rpm','i'}); figure step(T1,'b',T2,'g--') legend('Initial tuning','Tuning with Gain Constraints')

The second design is less aggressive but still meets the response time requirement. Finally, push the new tuned gain values to the Simulink model and simulate the response to a 2000 rpm speed demand and 500 N load disturbance. The simulation results appear in Figure 5 and the current controller output is shown in Figure 6.

writeBlockValue(ST2)

**Figure 5: Nonlinear Response of Tuning with Gain Constraints.**

**Figure 6: Current Controller Output.**

The nonlinear responses are now satisfactory and the current loop is no longer saturating. The additional gain constraints have forced `systune`

to re-distribute the control effort between the inner and outer loops so as to avoid saturation.

`TuningGoal.Gain`

| `TuningGoal.Tracking`

| `slTuner`

| `systune (slTuner)`

| `writeBlockValue`