Professional Documents
Culture Documents
⎢⎥ ⎢
Comparison of the Linear and Nonlinear
Equations of Motion: Aircraft Simulation
The nonlinear equations of motion have been derived and will be repeated here:
⎡
˙
⎡U + QW − U R⎤
˙
V + RU − P W
⎣ ˙
W + P V − QU
Ṗ ⋅ I xx
Q̇ ⋅ I yy
⎣ Ṙ ⋅ I zz
⎦
⎡Φ̇ ⎤
˙
Θ
⎣˙⎦
Ψ
P
R
⎤
=
=
⎣
⎡
0
0
0
−mg sin Θ − D cos α + L sin α + T cos Θ T
Q ⋅ r (I zz − I yy )
P ⋅ R (I xx − I yy )
P ⋅ Q (I yy − I xx )
1 0
cos Φ
− sin Φ
sin Φ tan Θ
cos Φ
sin Φ
cos Θ
V = P = R = Φ = Ψ = Θ0 = 0
mg sin Φ cos Θ + F A
+
(P
2
sin Φ cos Θ
cos Φ cos Θ
˙
˙
I yy Q = M A − T Δ zT
Θ = Q
− sin Φ
cos Φ
cos Θ
⎦
⎤
⎣˙⎦
cos Φ tan Θ
Ψ
⎤ ⎡
P
2
− R )I xz
(Q ⋅ R − Ṗ )I xz ⎦
− sin Θ
⎤
Y
˙
(R + P ⋅ Q)I xz ⎤
⎡ Φ̇⎤
˙
Θ
⎦ ⎣R ⎦
a simulation of this aircraft in the longitudinal plane will be presented in this section. By
constraining to longitudinal motion only, the solution of the nonlinear equations is heavily
simplified, but the analysis can be expanded for the unconstrained case and if we assume the
thrust inclination is zero. The simplifying assumption is:
+ FT
Q
=
Y
⎣
L
N
⎤
⎦
HS125 (Hawker 800) Business Jet)
The data for the HS125 Business jet are given in the table below. The aerodynamic model gives
the lift, drag, and pitching moment coefficients as:
C L = C L0 + C Lα α + C Lδ δe
e
2
CD = CD + CD α + CD 2
α
0 α α
CM = CM + CM α + CM δe + CM q
^
0 α δe q
Q c̄
q
^≜
Vf
Mass m 7500kg
MAC c̄ 2.29m
Lift Coefficients CL , CL , CL
0 α δe
0.895, 5.01, 0.722
Drag Coefficients CD , CD , CD
0 α α2
0.177, 0.232, 1.393
PM Coefficients CM , CM , CM
0 α α
2, C Mq -0.046, -1.087, -1.88, -7.055
The reduced nonlinear equations of motion can be constructed into a function eqnofmotion800:
def eqnofmotion800(y, t=[], Thrust=13878):
# The reduced state vector is a 7 x 1 vector
# y = [U, W, Q, Theta, X_E, Z_E, dE]
q_inf = .5*rho*Vf**2*s
return ydot
To determine the transient aircraft response, first the trim state must be determined.
0 = M A − T Δ zT
The knowns in the above are flightspeed, V , density (from altitude), ρ, and climb angle/flight
f
path angle γ (setting U and W ). These may be solved via any means you like to get the
E E
qh = 0 # Trim definition
rho = Atmosphere(h).density
q_infs = .5*rho*Vf**2*s
# Dimensional lift
lift = q_infs*CL
drag = q_infs*CD
pm = q_infs*cbar*CM
# First guess and increments for the jacobian <---- may need to adjust these
T = 15000
dT = 1
de = 0*np.pi/180
dde = .01*np.pi/180
Theta = 2*np.pi/180
dTheta = dde;
itercount = 0
while max(abs(trim)) > 1e-5:
itercount = itercount + 1
# Get value of the function
trim = TotalForces(T, de, Theta, Vf, h, gamma);
T = Trimstate[0]
de = Trimstate[1]
Theta = Trimstate[2]
return Trimstate
TrimState();
For a trim input of sea-level and 120kn, the trim is found to be - T = 13.84 kN, δ e = −0.98
∘
,
Θ = 0.84
∘
. A quick sense check shows that the aircraft is slightly nose up (less than a degree)
so the aerodynamic pitching moment from the wing/fuselage will be nose-up, and the elevator
is deflected trailing edge up to balance the pitching moment.
Transient Simulation
For level flight (trim), the initial conditions are given from from the previous step - if the aircraft
remains undisturbed, then there will be no variation in any of the parameters. The nonlinear
equations cannot be solved analytically, so if the aircraft response to control inputs is desired,
then a numerical scheme must be used.
pushing the stick forward and holding it, keeping other controls constant.
The equations are solved numerically using scipy’s odeint (which is very similar to ODE45 in
MATLAB)
# Set the inputs
de = -1
de = np.radians(de)
h = 0
Vf = 120*.51444
gamma = 0
# Initial conditions
from scipy.integrate import odeint
y0 = np.array([Ue[0], We[0], Qe, ThetaE[0], Xe, Ze, (de + trimstate[1])[0]])
U = output[:, 0]
W = output[:, 1]
Q = output[:, 2]
Theta = output[:, 3]
Alt = output[:, 5]
alpha = np.arctan2(W, U)
FS = np.sqrt(U**2 + W**2)
# Plot 'em
from plotly.subplots import make_subplots
import plotly.graph_objects as go
fig.add_trace(
go.Scatter(x = t, y = U, showlegend=False), row=1, col=1)
fig.add_trace(
go.Scatter(x = t, y = W, showlegend=False), row=1, col=2)
fig.add_trace(
go.Scatter(x = t, y = Q, showlegend=False), row=2, col=1)
fig.add_trace(
go.Scatter(x = t, y = Theta, showlegend=False), row=2, col=2)
fig.add_trace(
go.Scatter(x = output[:, 4], y = Alt, showlegend=False), row=3, col=1)
fig.add_trace(
go.Scatter(x = t, y = alpha, showlegend=False), row=3, col=2)
Xu =
62
60
58
56
54
600
400
200
0
0
0.04
0.02
∂X
∂u
⎢⎥
⎣ ˙⎦
0
θ
q̇
0
→
˙
Forward Speed
x =
2000
M u ≜ M u + M ẇ Z u
∗
⎣
Time
Pitch Rate
Time
Altitude
≜ M δ 0 + M ẇ Z δ 0
50
50
Horizontal Distance
∗
u
example
1
=
m
1
[
M
Zw
4000
It should be noted that the values above are total values and NOT perturbational values. We can
compare a linear model of the HS125 with the reduced nonlinear model, above - but rather than
sourcing HS 125 data of unknown legacy, it makes more sense (but more work) to use the
HS125 model to produce numerical derivatives based upon small perturbation theory using the
model itself.
This section shall stick with the HS 125 business jet. For the longitudinal equations of motion:
⎡
u̇
ẇ
⎤ ⎡
Xu
Zu
Xw
0
w
∗
Ax + Bu→
0
U0
∗
q
∗
M w ≜ M w + M ẇ Z w
∗
100
θ / deg
100
AoA / deg
−g ⋅ cos θ 0
−g ⋅ sin θ 0
M θ ≜ −M ẇ g sin θ 0
For each of the derivatives contained above, a central-difference approach may be utilised. That
X = f (U , W , Q, Θ 0 , δ e 0 )
then each of the stability derivatives may be expressed as a numerical partial derivative. For
W / (m/s)
0
0.15
0.05
0.06
0.05
0.04
0.03
0.02
θ
3
1
0
0.1
0
0
⎤⎡
⎦⎣
f (U 0 + δU , W 0 , Q 0 , θ 0 , δ e ) − f (U 0 − δU , W 0 , Q 0 , θ 0 , δ e )
Note that the variable that the derivative is with respect to is altered, and the others are held
constant - this is a partial derivative. This can be repeated for the remaining derivatives. This
procedure has been used below to create stability derivatives.
,
X Z , and M force and moments, and then
NumerialDerivatives uses a central difference approach with TotalForces to create the
numerical derivatives about this trim state
0
2δU
u
θ
⎤
′⎦
+
∗
Heave Velocity
⎣
0
Zδ
0
∗
Time
Time
δ0
M q ≜ M q + M ẇ U 0
50
Pitch Attitude
Time
AoA
50
50
⎦
[δ 0 ]
0
100
100
100
]
def perturbationalForces(U, W, Q, Theta, de, h, gamma, T):
'''This gives the total forces for the HS 125 simplified longitudinal
aircraft
Inputs: Thrust/N, elevator deflection/deg, theta/rad, flightspeed/m/s,
flightpath/rad
altitude/m
'''
qh = 0 # Trim definition
rho = float(Atmosphere(h).density[0])
# Recalculate alpha
CL = CL0 + CLa*alpha + CLde*de
CD = CD0 + CDa*alpha + CDa2*alpha*alpha
CM = CM0 + CMa*alpha + CMde * (de) + CMq*(Qhat)
q_infs = .5*rho*Vf**2*s
# Dimensional lift
lift = q_infs*CL
drag = q_infs*CD
pm = q_infs*cbar*CM
# Derivatives wrt u
Xpde, Zpde, Mpde = perturbationalForces(Ue+dUe, We, Qe, ThetaE, de, h, gamma, T)
Xmde, Zmde, Mmde = perturbationalForces(Ue-dUe, We, Qe, ThetaE, de, h, gamma, T)
# Derivatives wrt w
[Xpdw, Zpdw, Mpdw] = perturbationalForces(Ue, We+dWe, Qe, ThetaE, de, h, gamma,
T)
[Xmdw, Zmdw, Mmdw] = perturbationalForces(Ue, We-dWe, Qe, ThetaE, de, h, gamma,
T)
Xw = 1 /m*(Xpdw - Xmdw) /2 /dWe
Zw = 1 /m*(Zpdw - Zmdw) /2 /dWe;
Mw = 1 /Iyy*(Mpdw - Mmdw) /2 /dWe;
# Derivatives wrt q
[Xpdq, Zpdq, Mpdq] = perturbationalForces(Ue, We, Qe+dQe, ThetaE, de, h, gamma,
T)
[Xmdq, Zmdq, Mmdq] = perturbationalForces(Ue, We, Qe-dQe, ThetaE, de, h, gamma,
T)
Xq = 1 / m *(Xpdq - Xmdq) /2 /dQe;
Zq = 1 / m *(Zpdq - Zmdq) /2 /dQe;
Mq = 1 / Iyy *(Mpdq - Mmdq) /2 /dQe;
With the system and control matrix above, the response of the aircraft to the same input
disturbance may be evaluated.
import control
import control.matlab
# We will make a B matrix to enable us to use the control system toolbox by _exciting
the aircraft_ through
# Elevator input. Turn from Zde in 1/radians to 1/degree to put a useful input in.
SIunits=True
# Look at the first 100 seconds response to a unit impulse in the only
timeVec = np.linspace(0, 100, 1000)
Time, [u, w, q, theta] = control.forced_response(LonSS, U=de *
np.ones(timeVec.shape), T=timeVec)
fig.add_trace(
go.Scatter(x = Time, y = u + Ue, showlegend=True, name="Linear",
line_color="blue"), row=1, col=1)
# tNonlinear = t
# Unonlinear = U
# Wnonlinear = W
# Qnonlinear = Q
# Thetanonlinear = Theta
fig.add_trace(
go.Scatter(x = tNonlinear, y = Unonlinear, line_color="blue", showlegend=True,
line={"dash":"dash"}, name="Nonlinear"), row=1, col=1)
fig.add_trace(
go.Scatter(x = Time, y = w+We, showlegend=False, line_color="blue"), row=1,
col=2)
fig.add_trace(
go.Scatter(x = tNonlinear, y = Wnonlinear, showlegend=False, line_color="blue",
line={"dash":"dash"}, name="Nonlinear"), row=1, col=2)
fig.add_trace(
go.Scatter(x = Time, y = np.radians(q), showlegend=False, line_color="blue"),
row=2, col=1)
fig.add_trace(
go.Scatter(x = Time, y = Qnonlinear, showlegend=False, line_color="blue", line=
{"dash":"dash"}), row=2, col=1)
fig.add_trace(
go.Scatter(x = Time, y = np.radians(theta), showlegend=False, line_color="blue"),
row=2, col=2)
fig.add_trace(
go.Scatter(x = Time, y = Thetanonlinear, showlegend=False, line_color="blue",
line={"dash":"dash"}), row=2, col=2)
w / (m/s)
u / (m/s)
2
55
1
0 50 100 0 50 100
Time Time
0.02
θ / deg
0.1
0 0.05
0
0 50 100 0 50 100
Time Time
The linear model matches the response pretty well - with differences only really occuring after
significant time has passed.
It is clear that the aircraft response in pitch is a couple of two characteristic motions - one
highly-damped with a short period, and one with a much longer period. These are the short
period and Phugoid motions, respectively. They will be discussed in further detail in the following
chapter, but for the present discussion it can be seen that the linear model initially correlates
very well with the nonlinear model, but that it slowly begins to drift apart. This is to be expected
from any linear model - particularly as the model diverges away from the trim point at which the
stability derivatives were evaluated.
From an analysis standpoint, it is difficult to de-couple the motion in the first few seconds - the
motion from 0-5s comprises the superposition of short-period and Phugoid mode. Whilst the
Phugoid motion can be removed from the plot numerically, this requires determination of the
final value.
This highlights a chief benefit of the linear equation of motion - as will be explored in the next
Chapter, system stability information (ω , ζ ) can be determined directly from the system matrix
n
[4] You will not be tested on things like this in an examination in this course, but it’s really in your
interest to ensure that you can a) understand how this solver works and b) be confident you could
write something that does the same job yourself.
By Harry Smith
© Copyright 2022.
Aircraft Flight Mechanics by Harry Smith is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
Based on a work at www.aircraftflightmechanics.com.