Skip to content

McDonnell Douglas F‑4C — Longitudinal Dynamics

The F‑4C Phantom II is an American 3rd‑generation fighter bomber. This page mirrors the ELV layout: quick start, math model, derivatives, and API.

F4C Model

  • Quick start

    Launch the environment or the model within minutes.

    See example

  • Model API

    Python class documentation for the F‑4C longitudinal dynamics.

    Go to API

  • Gymnasium environment

    Ready environment for RL agents.

    Explore

  • Theory

    State equations and numerical parameters.

    Learn more

Control object structure

The model is defined in the state space:

\[\dot{x} = A x + B u, \quad y = C x + D u\]

where:

\[ x = \begin{bmatrix} u & w & q & \theta \end{bmatrix}^{\top}, \quad u_{in} = \delta_e \]

The typical matrix structure is:

\[ \begin{bmatrix} \dot{u} \\ \dot{w} \\ \dot{q} \\ \dot{\theta} \end{bmatrix} = \begin{bmatrix} x_u & x_w & x_q & x_{\theta} \\ z_u & z_w & z_q & z_{\theta} \\ m_u & m_w & m_q & m_{\theta} \\ 0 & 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} u \\ w \\ q \\ \theta \end{bmatrix} + \begin{bmatrix} x_{\delta_e} \\ z_{\delta_e} \\ m_{\delta_e} \\ 0 \end{bmatrix} \delta_e \]
  • u: longitudinal speed, m/s
  • w: vertical speed, m/s
  • q: pitch rate, rad/s
  • θ: pitch angle, rad
  • δₑ: elevator deflection, rad
  • x_u, x_w, x_q, x_θ — partial derivatives of longitudinal force \(X\) with respect to \(u, w, q, \theta\)
  • z_u, z_w, z_q, z_θ — partial derivatives of normal force \(Z\)
  • m_u, m_w, m_q, m_θ — partial derivatives of pitch moment \(M\)
  • x_δₑ, z_δₑ, m_δₑ — derivatives with respect to the control \(\delta_e\)

Units

Angles and angular rates are in radians. API methods can return values in degrees.

Mathematical model

\[ \dot{x} = A x + B u, \qquad y = C x + D u \]

The model is described by the standard state-space equation:

\[ \dot{x} = Ax + Bu \]

where:

  • x — state vector, \(x = [u, w, q, \theta]^{\top}\), representing deviations of longitudinal velocity, vertical velocity, pitch rate, and pitch angle.
  • u — control vector, in this case \(u = [\delta_e]\), where \(\delta_e\) is the elevator deflection.
  • A — state matrix (or system matrix).
  • B — control matrix.

Units

State vector \(x = [u, w, q, \theta]^{\top}\):

  • u, w: m/s (velocities)
  • q: rad/s (angular velocity)
  • θ: rad (angle)

Control vector \(u = [\delta_e]\):

  • δₑ: rad (elevator deflection)

Flight Conditions

The computed matrices A and B for the F-4C are provided for the following flight conditions:

  • Mach number: 0.6
  • Altitude: 35,000 feet

Numerical Matrices

\[ \begin{bmatrix} \dot{u} \\ \dot{w} \\ \dot{q} \\ \dot{\theta} \end{bmatrix} = \begin{bmatrix} 7.6180 \times 10^{-4} & 4.7612 \times 10^{-3} & 0 & -9.8100 \\ -6.6657 \times 10^{-2} & -2.8567 \times 10^{-1} & 1.8000 \times 10^{2} & 0 \\ 1.5124 \times 10^{-3} & -1.0083 \times 10^{-2} & -1.6384 \times 10^{-1} & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} u \\ w \\ q \\ \theta \end{bmatrix} + \begin{bmatrix} 2.6533 \times 10^{-3} \\ -6.8562 \\ -5.4446 \\ 0 \end{bmatrix} \delta_e \]

Derivatives (numerical values)

  • Matrix A (derivatives):
Coefficient Value
x_u 7.6180 × 10⁻⁴
x_w 4.7612 × 10⁻³
x_q 0.0
x_θ -9.8100
z_u -6.6657 × 10⁻²
z_w -2.8567 × 10⁻¹
z_q 1.8000 × 10²
z_θ 0
m_u 1.5124 × 10⁻³
m_w -1.0083 × 10⁻²
m_q -1.6384 × 10⁻¹
m_θ 0
  • Input δₑ (column B):
Coefficient Value
x_δₑ 2.6533 × 10⁻³
z_δₑ -6.8562
m_δₑ -5.4446

Actuator limits

The default control bounds are:

  • Maximum magnitude: \(\pm 25^\circ\)
  • Maximum rate: \(60^\circ/\text{s\)

Internal computations use radians; the bounds are converted accordingly.

Sources

  1. Heffley R. K., Jewell W. F. Aircraft handling qualities data. – NASA, 1972. № AD‑A277031.
  2. Etkin B., Reid L. D. Dynamics of flight. – New York : Wiley, 1959. – Vol. 2

Reward

The default reward function returns the negative absolute tracking error for the pitch angle:

\[r_t = -|\theta(t) - \theta_{\text{ref}}(t)|\]

Higher reward (closer to 0) indicates better tracking performance. A custom reward function can be passed via the reward_func parameter.

Quick start

import gymnasium as gym
import numpy as np

from tensoraerospace.envs import LinearLongitudinalF4C
from tensoraerospace.utils import generate_time_period
from tensoraerospace.signals.standard import unit_step

dt = 0.01
tp = generate_time_period(tn=20, dt=dt)
number_time_steps = len(tp)
reference_signals = unit_step(degree=5, tp=tp, time_step=10, output_rad=True).reshape(1, -1)

env = gym.make(
    'LinearLongitudinalF4C-v0',
    number_time_steps=number_time_steps,
    initial_state=[[0],[0],[0],[0]],
    reference_signal=reference_signals,
)
state, info = env.reset()
for _ in range(200):
    action = np.array([[0.1]])
    state, reward, terminated, truncated, info = env.step(action)
    if terminated or truncated:
        break
import numpy as np
from tensoraerospace.aerospacemodel import LongitudinalF4C

dt = 0.01
number_time_steps = 200

x0 = np.array([0.0, 0.0, 0.0, 0.0])  # [u, w, q, theta]

model = LongitudinalF4C(
    x0=x0,
    number_time_steps=number_time_steps,
    selected_state_output=["u", "w", "q", "theta"],
    dt=dt,
)

for t in range(number_time_steps - 1):
    u = np.array([[0.05]])  # control (rad)
    x_next = model.run_step(u)

Python API

LongitudinalF4C(x0, number_time_steps, selected_state_output=None, t0=0, dt=0.01)

Bases: ModelBase

McDonnell Douglas F-4C in longitudinal control channel.

Parameters:

Name Type Description Default
x0 ndarray | list[float]

Initial state of the control object.

required
number_time_steps int

Number of time steps.

required
selected_state_output optional

Selected states of the control object. Defaults to None.

None
t0 int

Initial time. Defaults to 0.

0
dt float

Discretization frequency. Defaults to 0.01.

0.01
Action space

ele: elevator [rad]

State space

u: Longitudinal aircraft velocity [ft/s] w: Normal aircraft velocity [ft/s] q: Pitch angular velocity [rad/s] theta: Pitch angle [rad]

Output space

u: Longitudinal aircraft velocity [ft/s] w: Normal aircraft velocity [ft/s] q: Pitch angular velocity [rad/s] theta: Pitch angle [rad]

Initialize LongitudinalF4C instance.

Parameters:

Name Type Description Default
x0 ndarray | list[float]

Initial state of the control object.

required
number_time_steps int

Number of time steps.

required
selected_state_output list[int] | None

Selected states of the control object. Defaults to None.

None
t0 float

Initial time. Defaults to 0.

0
dt float

Discretization frequency. Defaults to 0.01.

0.01

import_linear_system()

Load (set) stored linearized system matrices.

initialise_system(x0, number_time_steps)

Initialize the system and allocate history buffers.

Parameters:

Name Type Description Default
x0 ndarray | list[float]

Initial state.

required
number_time_steps int

Number of simulation steps.

required

run_step(ut_0)

Run one discrete-time simulation step.

Parameters:

Name Type Description Default
ut_0 ndarray

Control vector.

required

Returns:

Type Description
ndarray

np.ndarray: Next state at time t+1.

update_system_attributes()

Update time-dependent attributes after each simulation step.

get_state(state_name, to_deg=False, to_rad=False)

Return the time history of a state.

Parameters:

Name Type Description Default
state_name str

State name.

required
to_deg bool

Convert radians to degrees.

False
to_rad bool

Convert degrees to radians.

False

Returns:

Type Description
ndarray

np.ndarray: State history array.

get_control(control_name, to_deg=False, to_rad=False)

Return the time history of a control input.

Parameters:

Name Type Description Default
control_name str

Control signal name.

required
to_deg bool

Convert radians to degrees.

False
to_rad bool

Convert degrees to radians.

False

Returns:

Type Description
ndarray

np.ndarray: Control history array.

get_output(state_name, to_deg=False, to_rad=False)

Return the time history of an output signal.

Parameters:

Name Type Description Default
state_name str

Output name.

required
to_deg bool

Convert radians to degrees.

False
to_rad bool

Convert degrees to radians.

False

Returns:

Type Description
ndarray

np.ndarray: Output history array.

plot_output(output_name, time, lang='rus', to_deg=False, to_rad=False, figsize=(10, 10))

Plot an output signal over time.

Parameters:

Name Type Description Default
output_name str

Output name.

required
time ndarray

Time vector.

required
lang str

Axis label language ('rus' or 'eng'). Defaults to 'rus'.

'rus'
to_deg bool

Convert radians to degrees.

False
to_rad bool

Convert degrees to radians.

False
figsize tuple

Figure size.

(10, 10)

Returns:

Type Description
Figure

matplotlib.figure.Figure: Figure object.

LinearLongitudinalF4C(initial_state, reference_signal, number_time_steps, tracking_states=None, state_space=None, control_space=None, output_space=None, reward_func=None)

Bases: Env

Simulation of LongitudinalF4C control object in OpenAI Gym environment for training AI agents.

Parameters:

Name Type Description Default
initial_state Union[ndarray, list[float]]

Initial state.

required
reference_signal Union[ndarray, Callable]

Reference signal.

required
number_time_steps int

Number of simulation steps.

required
tracking_states Optional[list[str]]

Tracked states.

None
state_space Optional[list[str]]

State space.

None
control_space Optional[list[str]]

Control space.

None
output_space Optional[list[str]]

Full output space (including noise).

None
reward_func Optional[Callable]

Reward function (WIP status).

None

Initialize F-4C longitudinal environment.

reward(state, ref_signal, ts) staticmethod

Evaluate control performance.

Parameters:

Name Type Description Default
state _type_

Current state.

required
ref_signal _type_

Reference state.

required
ts _type_

Time step.

required

Returns:

Name Type Description
reward float

Control performance evaluation.

step(action)

Execute a simulation step.

Parameters:

Name Type Description Default
action ndarray

Array of control signals for selected control surfaces.

required

Returns:

Name Type Description
next_state ndarray

Next state of the control object.

reward ndarray

Evaluation of control algorithm actions.

done bool

Simulation status, whether completed or not.

logging any

Additional information (not used).

reset(seed=None, options=None)

Reset simulation environment to initial conditions.

Parameters:

Name Type Description Default
seed int

Seed for random number generator.

None
options dict

Additional options for initialization.

None

render()

Visual display of actions in the environment. Status: WIP.

Raises:

Type Description
NotImplementedError

Rendering is not implemented for this environment.