Communication Satellite (ComSat) — Longitudinal Dynamics¶
A communications satellite operates in orbit to relay and process radio signals. This page mirrors the ELV layout: quick start, math model, derivative tables, and API.
-
Quick start
Launch the environment or the model within minutes.
-
Model API
Python class documentation for ComSat.
-
Gymnasium environment
Ready environment for RL agents.
-
Theory
State equations and numerical parameters.
Control object structure¶
The model is defined in the state space:
where:
The linearized system:
- x₁ = ρ: radial position - distance from Earth center, km
- x₃ = ρ̇: radial velocity, m/s
- x₄ = θ̇: angular velocity, rad/s
- u₂: tangential thrust, N
- u₂ > 0 — thrust in direction of motion (acceleration)
- u₂ < 0 — thrust against direction of motion (deceleration)
- u₂ = 0 — no thrust
- a₁₃ = 1.0 — radial position changes with radial velocity
- a₃₁ = 0.01036 — radial acceleration component from position
- a₃₄ = 0.7753 — radial acceleration component from angular velocity
- a₄₃ = -0.01775 — angular acceleration component from radial velocity
- b₄ = 0.1513 — tangential thrust influence on angular acceleration
Units
Angular rates are in radians. Position in km, velocity in m/s. API methods can convert units.
Mathematical model¶
Numerical matrices (linearized system):
Expanded form: [ \begin{aligned} \dot{x}_1 &= x_3 \ \dot{x}_3 &= 0.01036 \cdot x_1 + 0.7753 \cdot x_4 \ \dot{x}_4 &= -0.01775 \cdot x_3 + 0.1513 \cdot u_2 \end{aligned} ]
Derivatives (numerical values)¶
- Matrix A (state derivatives):
| Coefficient | Value | Physical Meaning |
|---|---|---|
| a₁₃ (∂ẋ₁/∂x₃) | 1.0 | Radial position rate = radial velocity |
| a₃₁ (∂ẋ₃/∂x₁) | 0.01036 | Position effect on radial acceleration |
| a₃₄ (∂ẋ₃/∂x₄) | 0.7753 | Angular velocity effect on radial acceleration |
| a₄₃ (∂ẋ₄/∂x₃) | -0.01775 | Radial velocity effect on angular acceleration |
- Matrix B (control input):
| Coefficient | Value | Physical Meaning |
|---|---|---|
| b₄ (∂ẋ₄/∂u₂) | 0.1513 | Tangential thrust effect on angular acceleration |
Actuator limits
Default control limits inside the model (normalized):
- Maximum magnitude: \(\pm 25^\circ\)
- Maximum rate: \(60^\circ/\text{s\)
Internal computations use radians; limits are converted accordingly.
Sources¶
- Santosh Kumar Choudhary (2015). Design and Analysis of an Optimal Orbit Control for a Communication Satellite. INTERNATIONAL JOURNAL OF COMMUNICATIONS. Volume 9, 2015
Reward¶
The default reward function returns the negative absolute tracking error for the radial velocity:
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 ComSatEnv
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 signal for angular velocity control
reference_signals = unit_step(degree=0.1, tp=tp, time_step=10, output_rad=True).reshape(1, -1)
env = gym.make(
'ComSatEnv-v0',
number_time_steps=number_time_steps,
initial_state=[[6371.0], [0.0], [0.001]], # [rho (km), rho_dot (m/s), theta_dot (rad/s)]
reference_signal=reference_signals,
)
state, info = env.reset()
for _ in range(200):
action = np.array([[0.1]]) # Tangential thrust u2
state, reward, terminated, truncated, info = env.step(action)
if terminated or truncated:
break
import numpy as np
from tensoraerospace.aerospacemodel import ComSat
dt = 0.01
number_time_steps = 200
# Initial state: [rho (km), rho_dot (m/s), theta_dot (rad/s)]
x0 = np.array([6371.0, 0.0, 0.001])
model = ComSat(
x0=x0,
number_time_steps=number_time_steps,
selected_state_output=["rho", "rho_dot", "theta_dot"],
dt=dt,
)
for t in range(number_time_steps - 1):
u = np.array([[0.05]]) # Tangential thrust u2
x_next = model.run_step(u)
# Get state history
rho_history = model.get_state('rho')
rho_dot_history = model.get_state('rho_dot')
theta_dot_history = model.get_state('theta_dot')
Python API¶
ComSat(x0, number_time_steps, selected_state_output=None, t0=0, dt=0.01)
¶
Bases: ModelBase
Communication satellite 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
u2: tangential thrust (N) - positive accelerates satellite, negative decelerates
State space
rho: radial position - distance from Earth center [km] rho_dot: radial velocity [m/s] theta_dot: angular velocity [rad/s]
Output space
rho: radial position - distance from Earth center [km] rho_dot: radial velocity [m/s] theta_dot: angular velocity [rad/s]
Initialize ComSat 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()
¶
Load (set) stored linearized system matrices.
State vector: x = [x₁, x₃, x₄]ᵀ = [rho, rho_dot, theta_dot]ᵀ Control: u = u₂ (tangential thrust)
Equations: ẋ₁ = x₃ (radial position rate = radial velocity) ẋ₃ = 0.01036·x₁ + 0.7753·x₄ (radial acceleration) ẋ₄ = -0.01775·x₃ + 0.1513·u₂ (angular acceleration)
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 (e.g., |
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 name (e.g., |
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. |
ComSatEnv(initial_state, reference_signal, number_time_steps, tracking_states=None, state_space=None, control_space=None, output_space=None, reward_func=None, render_mode=None)
¶
Bases: Env
Gymnasium environment for a communication satellite longitudinal model.
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
|
Initialize communication satellite environment.
reward(state, ref_signal, ts)
staticmethod
¶
Compute tracking reward (negative absolute error).
step(action)
¶
Run one environment step (Gymnasium API).
reset(seed=None, options=None)
¶
Reset environment to the initial state (Gymnasium API).
render(mode=None)
¶
Render a lightweight telemetry snapshot.
The legacy ComSat environment does not ship a graphical viewer. Human
mode prints one concise state line; ansi returns it as a string for
tests and logging.