North American X‑15 — продольная динамика¶
Экспериментальный ракетоплан X‑15 для исследований гиперзвукового полёта. Страница оформлена по аналогии с ELV: быстрый старт, математика, производные и API.
Как устроен объект управления¶
Модель задана в пространстве состояний:
Где:
О единицах измерения
Углы и угловые скорости — в радианах. Методы API поддерживают выдачу в градусах.
Математическая модель¶
Численные матрицы (пример линеаризации):
Производные (численные значения)¶
- Матрица A (производные):
| Коэффициент | Значение |
|---|---|
| x_u | -0.0087 |
| x_α | -0.0190 |
| x_q | 0 |
| x_θ | -32.174 |
| z_u | 0.0117 |
| z_α | -0.3110 |
| z_q | 1936 |
| z_θ | 0 |
| m_u | 0.000471 |
| m_α | -0.0067 |
| m_q | -0.1820 |
| m_θ | 0 |
- Вход η (столбец B):
| Коэффициент | Значение |
|---|---|
| x_η | 0.0129 |
| z_η | -0.1844 |
| m_η | -0.0001225 |
Источники¶
- Heffley R. K., Jewell W. F. Aircraft handling qualities data. – NASA, 1972. № AD‑A277031.
- Etkin B., Reid L. D. Dynamics of flight. – New York : Wiley, 1959. – Т. 2
Награда¶
Функция награды по умолчанию возвращает отрицательную абсолютную ошибку отслеживания угла тангажа:
Чем выше награда (ближе к 0), тем лучше качество отслеживания. Пользовательская функция награды может быть передана через параметр reward_func.
Быстрый старт¶
import gymnasium as gym
import numpy as np
from tensoraerospace.envs import LinearLongitudinalX15
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(
'LinearLongitudinalX15-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 LongitudinalX15
dt = 0.01
number_time_steps = 200
x0 = np.array([0.0, 0.0, 0.0, 0.0])
model = LongitudinalX15(
x0=x0,
number_time_steps=number_time_steps,
selected_state_output=["u", "alpha", "q", "theta"],
dt=dt,
)
for t in range(number_time_steps - 1):
u = np.array([[0.05]])
x_next = model.run_step(u)
Python API¶
LongitudinalX15(x0, number_time_steps, selected_state_output=None, t0=0, dt=0.01)
¶
Bases: ModelBase
North American X-15 in longitudinal control channel.
.. warning::
This linearized model uses the FPS (foot-pound-second) unit
system, NOT SI. The A/B matrices are taken directly from the
reference Simulink source
tensoraerospace/aerospacemodel/simulinkModel/x15/x15_data.m
where g = 32.174 ft/s^2 and the trim velocity
U0 = 1936 ft/s (~Mach 1.8 at altitude). Linear velocities
u and w are perturbations in ft/s, and the gravity
term A[0,3] = -32.174 is in ft/s^2.
If SI-valued states are fed in (e.g. ``u`` in m/s), the dynamics
will be silently inconsistent with the matrices. Callers that
operate in SI must convert (1 m/s = 3.28084 ft/s) at the
environment boundary.
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] (input saturation at |ele| <= 25 deg,
rate limit 60 deg/s, both converted to radians
internally).
State space (FPS units): u: Longitudinal aircraft velocity perturbation [ft/s] w: Normal aircraft velocity perturbation [ft/s] q: Pitch angular velocity [rad/s] theta: Pitch angle [rad]
Output space (FPS units): u: Longitudinal aircraft velocity perturbation [ft/s] w: Normal aircraft velocity perturbation [ft/s] q: Pitch angular velocity [rad/s] theta: Pitch angle [rad]
Initialize LongitudinalX15 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[str] | 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()
¶
Saved linearized matrices.
Units: matrices are in FPS (foot-pound-second) system,
matching the reference Simulink file x15_data.m. In the
A matrix the last column of the first row is
-g = -32.174 ft/s^2 and A[1,2] = U0 = 1936 ft/s is the
trim airspeed, not an SI (m/s) quantity. See the class
docstring for a full unit list.
initialise_system(x0, number_time_steps)
¶
System initialization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x0
|
ndarray | list[float]
|
Initial state of the control object. |
required |
number_time_steps
|
int
|
Number of time steps in iteration. |
required |
run_step(ut_0)
¶
Execute one time step iteration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ut_0
|
ndarray
|
Control vector. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Control object state at step t+1. |
update_system_attributes()
¶
Update attributes that change with each time step.
get_state(state_name, to_deg=False, to_rad=False)
¶
Get state array history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state_name
|
str
|
State name. |
required |
to_deg
|
bool
|
Convert to degrees. Defaults to False. |
False
|
to_rad
|
bool
|
Convert to radians. Defaults to False. |
False
|
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Array of selected state history. |
Example
state_hist = model.get_state('alpha', to_deg=True)
get_control(control_name, to_deg=False, to_rad=False)
¶
Get control signal array history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
control_name
|
str
|
Control signal name. |
required |
to_deg
|
bool
|
Convert to degrees. Defaults to False. |
False
|
to_rad
|
bool
|
Convert to radians. Defaults to False. |
False
|
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Array of selected control signal history. |
Example
control_hist = model.get_control('stab', to_deg=True)
get_output(state_name, to_deg=False, to_rad=False)
¶
Get output signal array history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state_name
|
str
|
Output signal name. |
required |
to_deg
|
bool
|
Convert to degrees. Defaults to False. |
False
|
to_rad
|
bool
|
Convert to radians. Defaults to False. |
False
|
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Array of selected output signal history. |
Example
output_hist = model.get_output('alpha', to_deg=True)
plot_output(output_name, time, lang='rus', to_deg=False, to_rad=False, figsize=(10, 10))
¶
Plot output signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output_name
|
str
|
Output signal name. |
required |
time
|
ndarray
|
Time array. |
required |
lang
|
str
|
Label language ('rus' or 'eng'). Defaults to "rus". |
'rus'
|
to_deg
|
bool
|
Convert to degrees. Defaults to False. |
False
|
to_rad
|
bool
|
Convert to radians. Defaults to False. |
False
|
figsize
|
tuple
|
Figure size. Defaults to (10, 10). |
(10, 10)
|
Returns:
| Type | Description |
|---|---|
Figure
|
plt.Figure: Matplotlib figure object. |
Raises:
| Type | Description |
|---|---|
Exception
|
If both to_rad and to_deg are specified, or if output_name is invalid. |
Example
fig = model.plot_output('alpha', time_array, lang='rus', to_deg=True)
LinearLongitudinalX15(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 LongitudinalX15 in OpenAI Gym for training agents.
.. warning::
The underlying :class:LongitudinalX15 uses FPS units
(ft, lb, s). Linear velocities in the state vector are in
ft/s, not m/s.
State vector: [u, w, q, theta] (FPS units)
where:
u - longitudinal velocity perturbation (ft/s)
w - normal velocity perturbation (ft/s)
q - pitch rate (rad/s)
theta - pitch angle (rad)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_state
|
ndarray | list[float]
|
Initial state. |
required |
reference_signal
|
ndarray | Callable
|
Reference signal. |
required |
number_time_steps
|
int
|
Number of simulation steps. |
required |
tracking_states
|
list[str] | None
|
Tracked states. |
None
|
state_space
|
list[str] | None
|
State space. |
None
|
control_space
|
list[str] | None
|
Control space. |
None
|
output_space
|
list[str] | None
|
Full output space (including noise). |
None
|
reward_func
|
Callable | None
|
Reward function (WIP status). |
None
|
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 available. |
