© Apress 2015

Michael Paluszek and Stephanie Thomas, MATLAB Recipes, 10.1007/978-1-4842-0559-4_11

11. Aircraft

Michael Paluszek and Stephanie Thomas2

(1)Princeton, New Jersey, USA

(2)Princeton Junction, New Jersey, USA

Electronic supplementary material: The online version of this chapter (doi: 10.​1007/​978-1-4842-0559-4_​11) contains supplementary material, which is available to authorized users.

Our aircraft model is a three-dimensional point mass. This models only the translational dynamics in three dimensions. Translation is motion in the x, y, and z directions. An aircraft controls its motion by changing its orientation with respect to the wind (banking and angle of attack) and by changing the thrust its engine produces. In our model we assume that our airplane can instantaneously change its orientation and thrust for control purposes. This simplifies our model but at the same time allows us to simulate most aircraft operations, such as takeoff, level flight and landing. We also assume that the mass of the aircraft does not vary with time.

11.1 Creating a Dynamic Model of an Aircraft

Problem

You need a numerical model to simulate the three-dimensional trajectory of an aircraft in the atmosphere. The model should allow you to demonstrate control of the aircraft from takeoff to landing.

Solution

You will build a six-state model using flight path coordinates. The controls will be roll angle, angle of attack, and thrust. You will not simulate the attitude dynamics of the aircraft. The attitude dynamics are necessary if you want to simulate how long it takes for the aircraft to change angle of attack and roll angle. In our model, you assume the aircraft can instantaneously change angle of attack, roll angle, and thrust.

How It Works

Our aircraft will have six states, needed to simulate velocity and position in three dimensions, and three controls. The controls are roll angle, φ; angle of attack, α; and thrust, T. You aren’t going to use Cartesian coordinates and their time derivatives (i.e., velocities) as states; instead, you will use flight path coordinates. Flight path coordinates are shown in two dimensions in Figure 11-1. Roll, φ, is about the x axis and heading ψ is out of the page. Drag, D, is opposite the velocity vector.

A335353_1_En_11_Fig1_HTML.jpg
Figure 11-1. Flight path coordinates in two dimensions

The angle of attack, α, is adjusted to change the lift, L, and drag. The thrust vector, T, is aligned with the body x axis. The flight path angle, γ, is the angle between the x axis and the velocity vector, V. The state vector, s, is

$$ s=left[egin{array}{r}hfill v\ {}hfill gamma \ {}hfill psi \ {}hfill x\ {}hfill y\ {}hfill hend{array}
ight] $$
(11.1)
v is the velocity magnitude; γ is the flight path angle in the xz plane; ψ is the angle in the xy plane; x,y,h are the Cartesian coordinates. h is altitude, or the z coordinate. The dynamical equations are

$$ left[egin{array}{r}hfill dot{v}\ {}hfill dot{gamma}\ {}hfill dot{psi}\ {}hfill dot{x}\ {}hfill dot{y}\ {}hfill dot{h}end{array}
ight]=left[egin{array}{l}frac{T cos alpha -D}{m}-g cos gamma hfill \ {}frac{left(L+T sin alpha 
ight) cos phi - mg cos gamma }{mv}hfill \ {}frac{left(L+T sin alpha 
ight) sin phi }{mv cos gamma}hfill \ {}v cos gamma cos psi hfill \ {}v cos gamma sin psi hfill \ {}v sin gamma hfill end{array}
ight] $$
(11.2)
g is the gravitational acceleration, m is mass, D is drag force, and L is lift force. Define the dynamic pressure as

$$ q=frac{1}{2}
ho {v}^2 $$
(11.3)
where ρ is the atmospheric density. Our simple lift and drag model is

$$ D=qleft({C}_{D_0}+k{C}_L^2
ight) $$
(11.4)

$$ L=q{C}_L $$
(11.5)

$$ {C}_L={C}_{L_{alpha }}alpha $$
(11.6)

The first equation is called the drag polar. 
$$ {C}_{D_0} $$
is the drag at zero lift. k is the drag from lift coupling coefficient. s is the wetted area. This lift model is only valid for small angles of attack α, as it does not account for stall, which is when the airflow becomes detached from the wing and lift goes to zero rapidly.

Our RHS function that implements these equations is RHSAircraft. Notice that the equations are singular when v = 0 in equation 11.2. The header provides a warning about this singularity.

%% RHSAIRCRAFT Six DOF point mass aircraft model.

%% Form:

% d = RHSAircraft;

% [sDot, D, LStar] = RHSAircraft( t, s, d )

%% Description

% Computes the right hand side for a point mass aircraft. If you call it

% without any arguments, it will return the default data structure.

% sDot(2) and sDot(3) will be infinite when v = 0. The default atmosphere

% model is AtmosphericDensity which uses an exponential atmosphere.

%

%% Inputs

% t (1,1) Time (unused)

% s (6,1) State vector [v;gamma;psi;x;y;h]

% d (.) Data structure

% .m (1,1) Aircraft mass

% .g (1,1) Gravitational acceleration

% .thrust (1,1) Thrust

% .alpha (1,1) Angle of attack

% .phi (1,1) Roll angle

% .s (1,1) Surface area

% .cD0 (1,1) Zero lift drag

% .k (1,1) Lift drag coupling term

% .cLAlpha (1,1) Lift coefficient

% .density (1,1) Pointer to the atmospheric

% density function

%

%% Outputs

% sDot (6,1) State vector derivative d[v;gamma;psi;x;y;h]/dt

% D (1,1) Drag

% LStar (1,1) Lift/angle of attack

The function body is shown next. Assemble the state derivative, sDot, as one array since the terms are simple. Each element is on a separate line for readability. Return D and LStar as auxiliary outputs for use by the equilibrium calculation.

function [sDot, D, LStar] = RHSAircraft( ˜, s, d )

% Default data structure

if ( nargin == 0 )

sDot = struct('m',5000, 'g', 9.806, 'thrust',0,'alpha',0, 'phi',0,...

'cLAlpha',2* pi ,'cD0',0.006,'k',0.06,'s',20,'density',

@AtmosphericDensity);

return

end

% Save as local variables

V = s(1);

gamma = s(2);

psi = s(3);

h = s(6);

% Trig functions

cG = cos ( gamma);

sG = sin ( gamma);

cPsi = cos (psi);

sPsi = sin (psi);

cB = cos (d.phi);

sB = sin (d.phi);

% Exponential atmosphere

rho = feval (d.density,h);

% Lift and Drag

qS = 0.5*rho*d.s*vˆ2; % dynamic pressure

cL = d.cLAlpha*d.alpha;

cD = d.cD0 + d.k*cLˆ2;

LStar = qS*d.cLAlpha;

L = qS*cL;

D = qS*cD;

% Velocity derivative

% sDot is d[v;gamma;psi;x;y;h]/dt

lT = L + d.thrust* sin (d.alpha);

sDot = [ (d.thrust* cos (d.alpha)D)/d.md.g*sG;...

(lT*cBd.m*d.g*cG)/(d.m*v);...

lT*sB/(d.m*v*cG);...

v*cPsi*cG;...

v*sPsi*cG;...

v*sG];

A more sophisticated right-hand side would pass function handles for the drag and lift calculations so that the user could use their own model. We passed a function handle for the atmospheric density calculation to allow the user to select their density function. We could have done the same for the aerodynamics model. This would make RHSAircraftmore flexible.

Notice that we had to write an atmospheric density model, AtmosphericDensity, to provide as a default for the RHS function. This model uses an exponential equation for the density, which is the simplest possible representation. The function has a demo of the model, which uses a log scale for the plot.

%% AtmosphericDensity Atmospheric density from an exponential model.

% Computes the atmospheric density at the given altitude using an

% exponential model. Produces a demo plot up to an altitude of 100 km.

%% Form:

% rho = AtmosphericDensity( h )

%

%% Inputs

% h (1,:) Altitude (m)

%

%% Outputs

% rho (1,:) Density (kg/mˆ3)

function rho = AtmosphericDensity( h )

% Demo

if ( nargin < 1 )

h = linspace (0,100000);

AtmosphericDensity( h );

return

end

% Density

rho = 1.225* exp (2.9e05*h.ˆ1.15);

% Plot if no outputs are requested

if ( nargout < 1 )

PlotSet(h,rho,'x˽label','h˽(m)','y˽label','Density˽(kg/mˆ3)',...

'figure˽title','Exponential˽Atmosphere',...

'plot˽title','Exponential Atmosphere',...

'plot˽type','y˽log');

clear rho

end

11.2 Finding the Equilibrium Controls for an Aircraft Using Numerical Search

Problem

You want to find roll angles, thrusts and angles of attack that cause the velocity, flight path angle, and bank angle state (roll angle) derivatives to be zero. This is a point of equilibrium.

Solution

You will use Downhill Simplex, via the MATLAB function fminsearch, to find the equilibrium angles.

How It Works

The first step is to find the controls that produce a desired equilibrium state, known as the set point. Define the set point as the vector 
$$ left[egin{array}{l}{v}_s\ {}{gamma}_s\ {}{psi}_send{array}
ight] $$
(11.7)
with set values for the velocity, v s ; heading, ψ s ; and flight path angle, γ s . Substitute these into the first three dynamical equations from equation 11.2 and set the left-hand side to zero.

$$ 0=left[egin{array}{l}T cos alpha -Dleft({v}_s,alpha 
ight)- mg cos {gamma}_s\ {}left(Lleft({v}_s,alpha 
ight)+T sin alpha 
ight) cos phi - mg cos {gamma}_s\ {}left(Lleft({v}_s,alpha 
ight)+T sin alpha 
ight) sin phi end{array}
ight] $$
(11.8)

The controls are angle of attack, α; roll angle, φ; and thrust, T. Since there are three equations in three unknowns, you can get a single solution. The easiest way to solve for the equilibrium controls is to use fminsearch. This routine finds the three controls that zero the three equations.

The function, EquilibriumControl.m, uses fminsearch in a loop to handle multiple states. Within the loop, you compute an initial guess of the control. The thrust needs to balance drag so you compute this at zero angle of attack. The lift must balance gravity so you compute the angle of attack from that relationship. Without a reasonable initial guess, the algorithm may not converge or may converge to a local minimum. The cost function is nested within the control function.

function [u, c] = EquilibriumControl( x, d, tol )

n = size (x,2);

u = zeros (3,n);

c = zeros (1,n);

p = optimset('TolFun',tol);

% additional options during testing:

% ' PlotFcns ' ,{@optimplotfval,@PlotIteration}, ' Display ' , ' iter ' , ' MaxIter ' ,50);

for k = 1:n

[˜,D,LStar] = RHSAircraft(0,x(:,k),d);

alpha = d.m*d.g/LStar;

u0 = [D;alpha;0];

[umin,cval,exitflag,output] = fminsearch( @Cost, u0, p, x(:,k), d );

u(:,k) = umin;

c(k) = Cost( u(:,k), x(:,k), d );

end

The default output is to plot the results.

% Plot if no outputs are specified

if ( nargout == 0 )

yL = {'T (N)', 'alpha⊔(rad)', 'phi⊔(rad)' 'Cost'};

s = 'Equilibrium⊔Control:Controls';

PlotSet(1:n,[u;c],'x⊔label','set','y⊔label',yL, ...

'plot⊔title',s, 'figure⊔title',s);

yL = {'v' 'gamma' 'psi' 'h'};

s = 'Equilibrium Control:States';

PlotSet(1:n,x([1:3 6],:),'x⊔label','set','y⊔label',yL, ...

'plot⊔title',s,'figure⊔title',s);

clear u

end

The cost function is shown next. Use a quadratic cost that is the unweighted sum of the squares of the state derivatives.

%% Find the cost of a given control

function c = Cost( u, x, d )

d.thrust = u(1);

d.alpha = u(2);

d.phi = u(3);

xDot = RHSAircraft(0,x,d);

y = xDot(1:3);

c = sqrt (y'*y);

The function has a built-in demo that looks at thrust and angle of attack at a constant velocity but increasing altitude, from 0 to 10 km.

if( nargin < 1 )

x = [200*ones(1,101);...

zeros(4,101);...

linspace(0,10000,101)];

d = RHSAircraft;

EquilibriumControl( x, d )

return;

end

Figure 11-2 shows the states for which the controls are calculated in the built-in demo. Figure 11-3 shows the resulting controls. As expected, the angle of attack goes up with altitude, but the thrust goes down. The decreasing air density reduces drag and lift, so you need to decrease thrust but increase angle of attack to generate more lift. The roll angle is nearly zero.

A335353_1_En_11_Fig2_HTML.jpg
Figure 11-2. States for the demo. Only altitude (h) is changing
A335353_1_En_11_Fig3_HTML.jpg
Figure 11-3. Controls for the demo. Thrust decreases with altitude and angle of attack increases

Figure 11-3 also plots the cost. The cost should be nearly zero if the function is working as desired.

During debugging, while writing a function requiring optimization, it may be helpful to have additional insight into the numerical search process. While you only need umin, consider the additional outputs available from fminsearch in this version of the function call.

[umin,cval,exitflag,output] = fminsearch( @Cost, u0, p, x(:,k), d )

The output structure includes the number of iterations and the exit flag indicates the exit condition of the function: whether the tolerance was reached (1), the maximum number of allowed iterations was exceeded (0), or if a user-supplied output function terminated the search (−1). We put a breakpoint in the script to check these outputs. For a state of v = 200 and h = 300 at k = 4, the output will be

>> u0

u0 =

2880.4

0.016255

0

>> [umin,cval,exitflag,output] = fminsearch( @Cost, u0, p, x(:,k), d );

umin =

3180.7

0.016237

3.459e-08

cval =

3.2473e-09

exitflag =

1

output =

iterations: 141

funcCount: 260

algorithm: 'Nelder-Mead⊔simplex⊔direct⊔search'

message: 'Optimization⊔terminated:⊔the⊔current⊔x⊔satisfies⊔the⊔termination criteria⊔usin...'

So you can see that the search required 141 iterations and that the thrust increased to 3180 N from our initial guess of 2880 N. The resulting cost is 3e−9. Another alternative for more information is to set the Display option of fminsearch to iter or final, with the default being notify. In this case, the options look like

p = optimset('TolFun',tol,'Display','iter');

and the following type of output is printed to the Command Window:

>> d = RHSAircraft;

>> x = [200;0;0.5;0;0;5000];

>> EquilibriumControl( x, d )

Iteration Func-count min f(x) Procedure

0 1 0.0991747

1 4 0.0817065 initial simplex

2 6 0.0630496 expand

3 7 0.0630496 reflect

4 9 0.0133862 expand

5 10 0.0133862 reflect

6 11 0.0133862 reflect

7 13 0.0133862 contract outside

8 15 0.0133862 contract inside

...

49 87 2.1869e-05 contract inside

50 89 2.1869e-05 contract outside

Exiting: Maximum number of iterations has been exceeded

- increase MaxIter option.

Current function value: 0.000022

For additional insight, you can add a plot function to be called at every iteration. MATLAB provides some default plot functions; for example, optimplotfval plots the cost function value at every iteration. You have to actually open optimplotfval in an editor to learn the necessary syntax. We add the function to the optimization options like this

p = optimset('TolFun',tol,'PlotFcns',@optimplotfval);

Figure 11-4 is generated from the first iteration of the demo.

A335353_1_En_11_Fig4_HTML.jpg
Figure 11-4. Function value plot using optimplotfval

You can see that the cost value was nearly constant on this plot, for the final 100 iterations. You can add additional plots using a cell array for PlotFcns, and each plot will be given its own subplot axis automatically by MATLAB. For tough numerical problems, you might want to generate a surface and trace the iterations of the optimization. For our problem, we add our custom plot function PlotIteration, and the results look like Figure 11-5.

A335353_1_En_11_Fig5_HTML.jpg
Figure 11-5. Custom optimization plot function using a surface

p = optimset('TolFun',tol,'PlotFcns',{@optimplotfval,@PlotIteration});

We wrote two functions: one to generate the surface and a second to plot the iteration step. MATLAB sets the iteration value to zero during initialization, so in that case, you generate the surface from the given initial state. For all other iteration values, you plot the cost on the surface using an asterisk.

% Plot an iteration of the numerical search

function stop = PlotIteration (u0,optimValues,state,varargin)

stop = false;

x0 = varargin{1};

d = varargin{2};

switch state

case 'iter'

if optimValues.iteration == 0

a = PlotSurf( x0, u0, d );

end

plot3 (u0(1),u0(2),optimValues.fval,'k*');

end

% Plot a surface using the given initial state for a range of controls.

% MATLAB will already have an empty axis available for plotting.

function a = PlotSurf( x0, u0, d )

u1 = linspace ( max (u0(1)-1000,0),u0(1)+1000);

u2 = linspace (0, max (2*u0(2),0.1));

u3 = u0(3);

cvals = zeros (100,100);

for m = 1:100

for l = 1:100

cvals(l,m) = Cost( [u1(m);u2(l);u3], x0, d );

end

end

s = surf (u1,u2,cvals);

set (s,'edgecolor','none');

a = gca ;

set (a,'Tag','equilibriumcontrol');

hold on;

xlabel ('Thrust')

ylabel ('Angle˽of˽Attack')

Finally, note that to see the default set of options that MATLAB uses for fminsearch, call optimiset with the name of the optimization function.

>> options = optimset('fminsearch')

options =

Display: 'notify'

MaxFunEvals: '200*numberofvariables'

MaxIter: '200*numberofvariables'

TolFun: 0.0001

TolX: 0.0001

FunValCheck: 'off'

OutputFcn: []

PlotFcns: []

You see that the default tolerances are equal, at 0.0001, and the number of function evaluations and iterations is dependent on the number of variables in the input state x.

11.3 Designing a Control System for an Aircraft

Problem

You want to design a control system for an aircraft that will control the trajectory and allow for three-dimensional motion.

Solution

You will use dynamic plant inversion to feedforward the desired controls for the aircraft. Proportional controllers will be used for thrust, angle of attack, and roll angle to adjust the nominal controls to account for disturbances such as wind gusts. You will not use feedback control of the roll angle to control the heading, ψ. This is left as an exercise for you.

How It Works

Recall from the dynamic model in Recipe 11-1 that our aircraft state is 
$$ left[egin{array}{cccccc}hfill vhfill & hfill gamma hfill & hfill psi hfill & hfill xhfill & hfill yhfill & hfill hhfill end{array}
ight] $$
(11.9)
where v is the velocity, γ is the flight path angle, ψ is the heading, x and y are the coordinate in the flight plane, and h is the altitude. The control variables are the roll angle, φ; angle of attack, α; and thrust, T.

The controller is of the form 
$$ T={T}_s+{k}_Tleft({v}_s-v
ight) $$
(11.10)

$$ alpha ={alpha}_s+{k}_{alpha}left({gamma}_s-gamma 
ight) $$
(11.11)

If the state is at s, then the controls should be at the values T s , α s , φ s , which are the equilibrium controls. The gains k T and k a push the states in the right direction. The gains are a function of the flight condition. You need to expand the first two dynamical equations from equation 11.2.

$$ left[egin{array}{c}hfill dot{v}hfill \ {}hfill dot{gamma}hfill end{array}
ight]=left[egin{array}{c}hfill frac{T cos alpha -qleft({C}_{D_0}+k{left({C}_{L_{alpha }}alpha 
ight)}^2
ight)}{m}-g cos gamma hfill \ {}hfill frac{left(q{C}_{L_{alpha }}alpha +T sin alpha 
ight) cos phi - mg cos gamma }{mv}hfill end{array}
ight] $$
(11.12)

Linearize and drop the terms not involving the controls. 
$$ left[egin{array}{c}hfill dot{v}hfill \ {}hfill dot{gamma}hfill end{array}
ight]=left[egin{array}{c}hfill frac{T}{m}hfill \ {}hfill frac{q cos phi {C}_{L_{alpha }}alpha }{mv}hfill end{array}
ight] $$
(11.13)

You want the time constants τ γ and τ v so that the equations become

$$ left[egin{array}{c}hfill dot{v}hfill \ {}hfill dot{gamma}hfill end{array}
ight]=left[egin{array}{c}hfill -frac{v}{	au_v}hfill \ {}hfill -frac{gamma }{	au_{gamma }}hfill end{array}
ight] $$
(11.14)

Therefore 
$$ {k}_T=frac{m}{	au_v} $$
(11.15)

$$ {k}_{alpha }=frac{mv}{q cos phi {C}_{L_{alpha }}{	au}_{gamma }} $$
(11.16)

The control system is implemented in the function AircraftControl.

function [T, alpha] = AircraftControl( s, d, tauGamma, tauV, vSet, gammaSet )

u = EquilibriumControl( s, d );

v = s(1);

gamma = s(2);

h = s(6);

rho = feval (d.density,h);

qS = 0.5*d.s*rho*vˆ2;

kV = d.m/tauV;

kGamma = (d.m*v)/(qS* cos (d.phi)*d.cLAlpha*tauGamma);

T = u(1) + kV *(vSet - v);

alpha = u(2) + kGamma*(gammaSet - gamma);

The performance of the control system is shown in the simulation recipe (11-5). The function requires information about the flight conditions, including the atmospheric density. It first uses EquilibriumControl to find the controls that are needed at the current state s. The aircraft data structure is required. Additional inputs are the time constants for the controllers and the set points. You compute the atmospheric density in the function using feval and the input function handle. This should be the same computation as is done in RHSAircraft.

11.4 Plotting a 3D Trajectory for an Aircraft

Problem

You want to plot the trajectory of the aircraft in three dimensions and show the aircraft axes and times along the trajectory.

Solution

You use the MATLAB plot3 function with custom code to draw the aircraft axes and times at select points on the trajectory. The resulting figure is shown in Figure 11-6.

A335353_1_En_11_Fig6_HTML.jpg
Figure 11-6. Demo of aircraft trajectory function

How It Works

You use plot3 to draw the 3D display. The function Plot3DTrajectory.mallows for argument pairs via varargin.

%% PLOT3DTRAJECTORY Plot the trajectory of an aircraft in 3D.

%% Form:

% Plot3DTrajectory( x, varargin )

%% Description

% Plot a 3D trajectory of an aircraft with times and local axes.

%

%% Inputs

% x (6,:) State vector [v;gamma;phi;x;y;h]

% varargin {:} Parameters

%

We skip the demo code for now and show the drawing code next. There are similarities with our 2D plotting function, PlotSet. We use text to insert time labels and a patch object to draw the ground.

% Draw the figure

h = figure;

set (h,'Name',figTitle);

plot3 (x(4,:),x(5,:),x(6,:));

xlabel (xLabel);

ylabel (yLabel);

zlabel (zLabel);

% Draw time and axes

if ( ˜ isempty (t) && ˜ isempty (tIndex) )

[t,˜,tL] = TimeLabel(t);

for k = 1: length (t)

s = sprintf ('⊔t⊔=⊔%3.0f⊔(%s)',t(k), tL);

i = tIndex(k);

text (x(4,i),x(5,i),x(6,i),s);

DrawAxes(x(:,i),alpha(1,i),phi(1,i));

end

end

% Add the ground

xL = get ( gca ,'xlim');

yL = get ( gca ,'ylim');

v = [xL(1) yL(1) 0;...

xL(2) yL(1) 0;...

xL(2) yL(2) 0;...

xL(1) yL(2) 0];

patch ('vertices',v,'faces',[1 2 3 4],'facecolor',[0.65 0.5 0.0],'edgecolor',[0.65 0.5

0.0]);

grid on

rotate3d on

axis image

zL = get ( gca ,'zlim');

set ( gca ,'zlim',[0 zL(2)],'ZLimMode','manual');

The plot commands are straightforward. If a time array is entered, it draws the times along the track using sprintf and text. We use TimeLabel to get reasonable units. It also draws the aircraft axes using the nested function DrawAxes.

%%% Plot3DTrajectory>DrawAxes subfunction

%% DrawAxes

function DrawAxes( x, alpha, phi )

gamma = x(2);

psi = x(3);

% Aircraft frame is x forward, y out the right wing and z down

u0 = [1 0 0;0 1 0;0 0 -1];

cG = cos (gamma+alpha);

sG = sin (gamma+alpha);

cP = cos (psi);

sP = sin (psi);

cR = cos (phi);

sR = sin (phi);

u = [cP -sP 0;sP cP 0; 0 0 1]...

*[cG 0 -sG; 0 1 0;sG 0 cG]...

*[1 0 0;0 cR sR; 0 -sR cR]*u0;

% Find a length for scaling of the axes

xL = get ( gca ,'xlim');

yL = get ( gca ,'ylim');

zL = get ( gca ,'zlim');

l = sqrt ((xL(2)-xL(1))ˆ2 + (yL(2)-yL(1))ˆ2 + (zL(2)-zL(1))ˆ2)/20;

x0 = x(4:6);

for k = 1:3

x1 = x0 + u(:,k)*l;

c = [0 0 0];

c(k) = 1;

line ([x0(1);x1(1)],[x0(2);x1(2)],[x0(3);x1(3)],'color',c);

end

This function draws an axis system for the aircraft, x out the nose, y out the right wing, and z down. It uses the state vector, so needs to convert from γ and ψ to rotation matrices. The axis system is in wind axes.

The function takes parameter pairs to allow the user to customize the plot. The parameter pairs are processed here:

xLabel = 'x⊔(m)';

yLabel = 'y⊔(m)';

zLabel = 'z⊔(m)';

figTitle = 'Trajectory';

t = [];

tIndex = [];

alpha = 0.02*ones(1, size (x,2));

phi = 0.25* pi *ones(1, size (x,2));

for k = 1:2: length (varargin)

switch lower (varargin{k})

case 'x⊔label'

xLabel = varargin{k+1};

case 'y⊔label'

yLabel = varargin{k+1};

case 'z⊔label'

zLabel = varargin{k+1};

case 'figure⊔title'

figTitle = varargin{k+1};

case 'time'

t = varargin{k+1};

case 'time index'

tIndex = varargin{k+1};

case 'alpha'

alpha = varargin{k+1};

case 'phi'

phi = varargin{k+1};

otherwise

error ('%s⊔is⊔not⊔a⊔valid⊔parameter',varargin{k});

end

end

We use lower in the switch statement to allow the user to input capital letters and not have to worry about case issues. Most of the parameters are straightforward. The time input could have been done in many ways. We chose to allow the user to enter specific times for the time labels. As part of this, the user must enter the indices to the state vector.

The function includes a demo. You can type Plot3DTrajectory and get the example trajectory shown in Figure 11-6. In the case of a graphics function, the demo literally shows the user what the graphics should look like and provides examples about how to use the function.

% Demo

if ( nargin < 1 )

l = linspace (0,1e5);

x = [200* ones (1,100);...

( pi /4)* ones (1,100);...

( pi /4)* ones (1,100);l;l;l];

t = [200 300 400 500 600];

k = [20 40 60 80 100];

Plot3DTrajectory( x, 'time', t, 'time˽index', k, 'alpha',0.01* ones (1,100) )

return ;

end

11.5 Simulating the Controlled Aircraft

Problem

You want to simulate the motion of the aircraft with the trajectory controls.

Solution

You will create a script with the control system and flight dynamics. The dynamics will be propagated by RungeKutta. This is a fourth-order method, meaning the truncation errors go as the fourth power of the timestep. Given the typical sample time for a flight control system, fourth-order is sufficiently accurate for flight simulations. We will display the results using our 3D plotting function Plot3DTrajectory described in the previous recipe.

How It Works

The simulation script, AircraftSim.m, reads the data structure from RHSAircraft and changes values to match an F-35 fighter. The model only involves the thrust and drag, and even these are very simple models. The initial flight path angle and velocity are set. We turn on the control and establish the set points and time constants for the velocity and flight path angle states. For output, we plot the states, control, and a 3D trajectory.

%% A trajectory control simulation of an F-35 aircraft.

% The dynamics of a point mass aircraft is simulated.

%% See also

% RungeKutta, RHSAircraft, PDControl, EquilibriumControl

The script begins with obtaining our default data structure from the RHS function.

%% Data structure for the right hand side

d = RHSAircraft;

%% User initialization

d.m = 13300.00; % kg

d.s = 204.00; % mˆ2

v = 200; % m/sec

fPA = pi /6; % rad

% Initialize duration and delta time

tEnd = 40;

dT = 0.1;

% Controller

controlIsOn = true;

tauV = 1;

tauGamma = 1;

d.phi = 0;

vSet = 220;

gammaSet = pi /8;

%% Simulation

% State vector

x = [v;fPA;0;0;0;0];

% Plotting and number of steps

n = ceil (tEnd/dT);

xP = zeros ( length (x)+2,n);

% Find non-feedback settings

[˜,D,LStar] = RHSAircraft(0,x,d);

thrust0 = D;

alpha0 = d.m*d.g/LStar;

% Run the simulation

for k = 1:n

if ( controlIsOn )

[d.thrust, d.alpha] = AircraftControl( x, d, tauGamma, tauV, vSet, gammaSet );

else

d.thrust = thrust0;

d.alpha = alpha0;

end

% Plot storage

xP(:,k) = [x;d.thrust;d.alpha];

% Right hand side

x = RungeKutta(@RHSAircraft,0,x,dT,d);

end

%% Plotting

[t,tL] = TimeLabel((0:(n-1))*dT);

yL = {'T⊔(N)', 'alpha (rad)'};

s = 'Aircraft⊔Sim:Controls';

PlotSet(t,xP(7:8,:),'x⊔label',tL,'y⊔label',yL,'plot⊔title',s, 'figure⊔title',s);

yL = {'v' 'gamma' 'psi' 'x' 'y' 'h'};

s = 'Aircraft⊔Sim:States';

PlotSet(t,xP(1:6,:),'x⊔label',tL,'y⊔label',yL,'plot⊔title',s,'figure⊔title',s);

k = floor ( linspace (2,n,8));

t = t(k);

Plot3DTrajectory( xP, 'time', t, 'time⊔index', k, 'alpha', xP(8,:) );

If the control is off, set the thrust and angle of attack to constant values to balance drag and gravity. The set points for velocity and flight path angle are slightly different than the initial conditions. This allows you to demonstrate the transient response of the controller.

The states are shown in Figure 11-7. The velocity and flight path angle converge to their set points.

A335353_1_En_11_Fig7_HTML.jpg
Figure 11-7. Velocity and flight path angle converge to their desired values

The controls are shown in Figure 11-8. The controls reach their steady values. Thrust and angle of attack change as the plane climbs. Thrust drops because the drag drops and angle of attack increases to maintain the lift/gravity balance.

A335353_1_En_11_Fig8_HTML.jpg
Figure 11-8. The controls converge to the steady-state values and then change slowly to accommodate the decrease in atmospheric density as the aircraft climbs

The 3D trajectory is shown in Figure 11-9. As expected, it climbs at a nearly constant angle at a constant velocity.

A335353_1_En_11_Fig9_HTML.jpg
Figure 11-9. The trajectory
Summary

This chapter demonstrated how to write the dynamics for a point mass aircraft. You learned how to find the equilibrium control state using a search algorithm. This includes utilizing the debug output available from MATLAB for its optimization algorithms and adding custom plotting for each search iteration. You learned how to design a control system to maintain a desired velocity, bank angle and flight path angle. You learned how to make 3D plots with annotations of both text and other drawing objects. You also learned how to pass function handles to other functions to make functions more versatile. Table 11-1 lists the code developed in the chapter.

Table 11-1. Chapter Code Listing

File

Description

RHSAircraft

Six degree of freedom RHS for a point mass aircraft.

AtmosphericDensity

Atmospheric density as a function of altitude from an exponential model.

EquilibriumControl

Find the equilibrium control for a point mass aircraft.

AircraftControl

Computes the angle of attack and thrust for a 3D point mass aircraft.

Plot3DTrajectory

Plot a 3D trajectory of an aircraft with times and local axes.

AircraftSim

A trajectory control simulation of an aircraft.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset