Accelerating the pace of engineering and science

# Documentation

## Tuning of Gain-Scheduled Three-Loop Autopilot

This example uses systune to generate smooth gain schedules for a three-loop autopilot.

Airframe Model and Three-Loop Autopilot

This example uses a three-degree-of-freedom model of the pitch axis dynamics of an airframe. The states are the Earth coordinates , the body coordinates , the pitch angle , and the pitch rate . Figure 1 summarizes the relationship between the inertial and body frames, the flight path angle , the incidence angle , and the pitch angle .

Figure 1: Airframe dynamics.

We use a classic three-loop autopilot structure to control the flight path angle . This autopilot adjusts the flight path by delivering adequate bursts of normal acceleration (acceleration along ). In turn, normal acceleration is produced by adjusting the elevator deflection to cause pitching and vary the amount of lift. The autopilot uses Proportional-Integral (PI) control in the pitch rate loop and proportional control in the and loops. The closed-loop system (airframe and autopilot) are modeled in Simulink.

open_system('rct_airframeGS')


Autopilot Gain Scheduling

The airframe dynamics are nonlinear and the aerodynamic forces and moments depend on speed and incidence . To obtain suitable performance throughout the flight envelope, the autopilot gains must be adjusted as a function of and to compensate for changes in plant dynamics. This adjustment process is called "gain scheduling" and are called the scheduling variables.

Gain scheduling is a linear technique for controlling nonlinear or time-varying plants. The idea is to compute linear approximations of the plant at various operating conditions, tune the controller gains at each operating condition, and swap gains as a function of operating condition during operation. Conventional gain scheduling involves three major steps:

1. Trim and linearize the plant at each operating condition

2. Tune the controller gains for the linearized dynamics at each operating condition

3. Reconcile the gain values to provide smooth transition between operating conditions.

In this example, we combine Steps 2. and 3. by parameterizing the autopilot gains as first-order polynomials in and directly tuning the polynomial coefficients for the entire flight envelope. This approach eliminates Step 3. and guarantees smooth gain variations as a function of and . Moreover, the gain schedule coefficients can be automatically tuned with systune.

Trimming and Linearization

Assume that the incidence varies between -20 and 20 degrees and that the speed varies between 700 and 1400 m/s. When neglecting gravity, the airframe dynamics are symmetric in so consider only positive values of . Use a 5-by-9 grid of linearly spaced pairs to cover the flight envelope:

nA = 5;  % number of alpha values
nV = 9;  % number of V values
[alpha,V] = ndgrid(linspace(0,20,nA)*pi/180,linspace(700,1400,nV));


For each flight condition , linearize the airframe dynamics at trim (zero normal acceleration and pitching moment). This requires computing the elevator deflection and pitch rate that result in steady and . To do this, first isolate the airframe model in a separate Simulink model.

open_system('rct_airframeTRIM')


Use operspec to specify the trim condition, use findop to compute the trim values of and , and linearize the airframe dynamics for the resulting operating point. See the "Trimming and Linearizing an Airframe" example in Simulink Control Design for details. Repeat these steps for the 45 flight conditions .

% Compute trim condition for each (alpha,V) pair
clear op
for ct=1:nA*nV
alpha_ini = alpha(ct);      % Incidence [rad]
v_ini = V(ct);              % Speed [m/s]

% Specify trim condition
opspec = operspec('rct_airframeTRIM');
opspec.States(1).Known = [1;1];
opspec.States(3).Known = [1 1];
opspec.States(2).Known = 1;
opspec.States(4).Known = 0;

% TRIM
Options = findopOptions('DisplayReport','off');
op(ct) = findop('rct_airframeTRIM',opspec,Options);
end

% Linearization I/Os
io = [linio('rct_airframeTRIM/delta',1,'in');...        % delta
linio('rct_airframeTRIM/Airframe Model',3,'out');... % q
linio('rct_airframeTRIM/Airframe Model',4,'out');... % az
linio('rct_airframeTRIM/Airframe Model',5,'out')];   % gamma

% Linearize at trim conditions
G = linearize('rct_airframeTRIM',op,io);
G = reshape(G,[nA nV]);
G.u = 'delta';
G.y = {'q' 'az' 'gamma'};


This produces a 5-by-9 array of linearized plant models at the 45 flight conditions . The plant dynamics vary substantially across the flight envelope.

sigma(G), title('Variations in airframe dynamics')


Autopilot Modeling

The autopilot consists of four gains that must be "scheduled" (adjusted) as a function of and . Each "gain" is therefore a two-dimensional gain surface. As a first cut, seek gain surfaces with a simple multi-linear dependence on and :

.

These gain surfaces are modeled in Simulink as follows:

Figure 2: Simulink model for the gain surface .

Use gainsurf to parameterize these gain surfaces in terms of the tunable coefficients . To improve convergence of the tuning algorithm, it is recommended to replace by normalized values ranging in [-1,1]:

% Subtract the mean value of alpha and divide by its half range
Mean = 10*pi/180;  % mean = 10 degrees
HalfRange = Mean;  % half range = 10 degrees
alpha_n = (alpha - Mean)/HalfRange;   % varies in [-1,1]

% Subtract the mean value of V and divide by its half range
Mean = (700+1400)/2;
HalfRange = (1400-700)/2;
V_n = (V - Mean)/HalfRange;   % varies in [-1,1]

% Create gain surfaces
Kp = gainsurf('Kp', 0.1, alpha_n, V_n, alpha_n.*V_n);
Ki = gainsurf('Ki', 2, alpha_n, V_n, alpha_n.*V_n);
Ka = gainsurf('Ka', 0.001, alpha_n, V_n, alpha_n.*V_n);
Kg = gainsurf('Kg', -1000, alpha_n, V_n, alpha_n.*V_n);


The initial values for the constant coefficient are based on tuning results for = 10 deg and = 1000 m/s (mid-range design). Note that Kp, Ki,... are arrays of matrices (one per flight condition) parameterized by the tunable coefficients . To facilitate visualization, use the SamplingGrid property to keep track of the dependence on :

% Grid of alpha,V values
SG = struct('alpha',alpha,'V',V);

Kp.SamplingGrid = SG;
Ki.SamplingGrid = SG;
Ka.SamplingGrid = SG;
Kg.SamplingGrid = SG;


Next construct a closed-loop model T0 by connecting the linearized airframe model G, the second-order actuator model, and the autopilot gains Kp, Ki, Ka, Kg according to the block diagram rct_airframeGS. The software lets you manipulate the model arrays G, Kp, Ki,... as single entities (one block in the block diagram).

% Actuator model
Act = tf(150^2,[1 2*0.7*150 150^2]);
Act.u = 'u';  Act.y = 'delta_d';

% Controller elements
Cq = pid(Kp,Ki);
Cq.u = 'eq';  Cq.y = 'u';
Ca = ss(Ka);
Ca.u = 'eaz';  Ca.y = 'q_ref';
Cg = ss(Kg);
Cg.u = 'eg';  Cg.y = 'az_ref';

% Summing junctions
S1 = sumblk('delta = delta_d + d');
S2 = sumblk('eq = q_ref + q');
S3 = sumblk('eaz = az_ref - az');
S4 = sumblk('eg = gamma_ref - gamma');

% Connect the blocks together
T0 = connect(G,Cq,Ca,Cg,S1,S2,S3,S4,Act,...
{'gamma_ref','az_ref','d'},{'gamma','az'})

T0 =

5x9 array of generalized continuous-time state-space models.
Each model has 2 outputs, 3 inputs, 7 states, and between 4 and 16 blocks.

Type "ss(T0)" to see the current value, "get(T0)" to see all properties, and "T0.Blocks" to interact with the blocks.



This creates a 5-by-9 array of closed-loop models parameterized by the tunable coefficients of the four gain surfaces.

Autopilot Tuning

systune can automatically tune the gain surface coefficients for the entire flight envelope. Use TuningGoal objects to specify the performance objectives:

• loop: Track the setpoint with a 1 second response time, less than 2% steady-state error, and less than 30% peak error.

Req1 = TuningGoal.Tracking('gamma_ref','gamma',1,0.02,1.3);
viewSpec(Req1)


• loop: Ensure good disturbance rejection at low frequency (to track acceleration demands) and past 10 rad/s (to be insensitive to measurement noise).

% Note: The disturbance is injected at the az_ref location
RejectionProfile = frd([0.02 0.02 1.2 1.2 0.1],[0 0.02 2 15 150]);
Req2 = TuningGoal.Gain('az_ref','az',RejectionProfile);
viewSpec(Req2)


• loop: Ensure good disturbance rejection up to 10 rad/s

% Note: The disturbance d enters at the plant input
Req3 = TuningGoal.Gain('d','az',600*tf([0.25 0],[0.25 1]));
viewSpec(Req3)


• Transients: Ensure a minimum damping ratio of 0.35 for oscillation-free transients

MinDamping = 0.35;
Req4 = TuningGoal.Poles(0,MinDamping);


Using systune, tune the 16 gain surface coefficients to best meet these performance requirements at all 45 flight conditions.

T = systune(T0,[Req1 Req2 Req3 Req4]);

Final: Soft = 1.13, Hard = -Inf, Iterations = 78


The final value of the combined objective is close to 1, indicating that all requirements are nearly met. Visualize the resulting gain surfaces.

% Use the tuned values of the gain surface coefficients
Kp = setBlockValue(Kp,T);
Ki = setBlockValue(Ki,T);
Ka = setBlockValue(Ka,T);
Kg = setBlockValue(Kg,T);

% Plot gain surfaces
clf
subplot(221), view(Kp), title('Kp')
subplot(222), view(Ki), title('Ki')
subplot(223), view(Ka), title('Ka')
subplot(224), view(Kg), title('Kg')


Validation

First validate the tuned autopilot at the 45 flight conditions considered above. Plot the response to a step change in flight path angle and the response to a step disturbance in elevator deflection.

clf
subplot(211), step(T('gamma','gamma_ref'),5), grid
title('Tracking of step change in flight path angle')
subplot(212), step(T('az','d'),3), grid
title('Rejection of step disturbance at plant input')


The responses are satisfactory at all flight conditions. Next validate the autopilot against the nonlinear airframe model. First push the tuned gain surface coefficients to the Simulink model. The coefficients for the "Kp Gain" block are named "Kp_0", "Kp_1", "Kp_2", "Kp_3", and similarly for the other gain blocks.

[Kp_0,Kp_1,Kp_2,Kp_3] = gainsurfdata(Kp);
[Ki_0,Ki_1,Ki_2,Ki_3] = gainsurfdata(Ki);
[Ka_0,Ka_1,Ka_2,Ka_3] = gainsurfdata(Ka);
[Kg_0,Kg_1,Kg_2,Kg_3] = gainsurfdata(Kg);


Now simulate the autopilot performance for a maneuver that takes the airframe through a large portion of its flight envelope.

% Initial conditions
h_ini = 1000;
alpha_ini = 0;
v_ini = 700;

% Simulate
SimOut = sim('rct_airframeGS', 'ReturnWorkspaceOutputs', 'on');

% Extract simulation data
SimData = get(SimOut,'sigsOut');
Sim_gamma = getElement(SimData,'gamma');
Sim_alpha = getElement(SimData,'alpha');
Sim_V = getElement(SimData,'V');
Sim_delta = getElement(SimData,'delta');
Sim_h = getElement(SimData,'h');
Sim_az = getElement(SimData,'az');
t = Sim_gamma.Values.Time;

% Plot the main flight variables
clf
subplot(211)
plot(t,Sim_gamma.Values.Data(:,1),'r--',t,Sim_gamma.Values.Data(:,2),'b'), grid
legend('Commanded','Actual','location','SouthEast')
title('Flight path angle \gamma in degrees')
subplot(212)
plot(t,Sim_delta.Values.Data), grid
title('Elevator deflection \delta in degrees')


subplot(211)
plot(t,Sim_alpha.Values.Data), grid
title('Incidence \alpha in degrees')
subplot(212)
plot(t,Sim_V.Values.Data), grid
title('Speed V in m/s')


subplot(211)
plot(t,Sim_h.Values.Data), grid
title('Altitude h in meters')
subplot(212)
plot(t,Sim_az.Values.Data), grid
title('Normal acceleration a_z in g''s')


Tracking of the flight path angle profile remains good throughout the maneuver. Note that the variations in incidence and speed cover most of the flight envelope considered here ([-20,20] degrees for and [700,1400] for ). And while the autopilot was tuned for a nominal altitude of 3000 m, it fares well despite altitude changing from 1,000 to 10,000 m.

The nonlinear simulation results confirm that the gain-scheduled autopilot delivers consistently high performance throughout the flight envelope. The simple explicit formulas for the gain dependence on the scheduling variables is amenable to efficient hardware implementation. Alternatively, these formulas can be readily converted into 2D lookup tables for further adjustment.