Geostationary Satellite (GeoSat) — Longitudinal Dynamics¶
Geostationary satellites are spacecraft on geosationary orbits stationary relative to Earth’s surface. 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 GeoSat.
-
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 typical matrix structure is:
- ρ: altitude-to-Earth-radius ratio (dimensionless)
- θ: satellite position relative to the Earth frame, rad
- ω: angular velocity, rad/s
- η: control input (thrust)
- f1(ρ, ω) ≈ 0.01036 — derivative with respect to ρ
- f2(ρ, ω) ≈ 0.7757 — derivative with respect to ω in the θ̇ equation
- f3(ω, r) ≈ -0.1775 — derivative with respect to θ in the ω̇ equation
- g(r) ≈ 0.1513 — thrust influence on ω̇
Units
Angles and angular rates are in radians. API methods can output in degrees.
Mathematical model¶
Numerical matrices (example linearization):
Derivatives (numerical values)¶
- Matrix A (derivatives):
| Coefficient | Value |
|---|---|
| a_ρθ (∂ρ̇/∂θ) | 1.0 |
| a_θρ (∂θ̇/∂ρ) | 0.01036 |
| a_θω (∂θ̇/∂ω) | 0.7757 |
| a_ωθ (∂ω̇/∂θ) | -0.1775 |
- Input η (column B):
| Coefficient | Value |
|---|---|
| b_η→ω (∂ω̇/∂η) | 0.1513 |
Sources¶
- Tun, Hla & Mon, Lae & Lwin, Kyaw & Naing, Zaw. (2012). Implementation of Communication Satellite Orbit Controller Design Using State Space Techniques. ASEAN Journal on Science and Technology for Development. 29. 29‑49. 10.29037/ajstd.48.
Reward¶
The default reward function returns the negative absolute tracking error for the angular position:
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 GeoSatEnv
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(
'GeoSat-v0',
number_time_steps=number_time_steps,
initial_state=[[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 GeoSat
dt = 0.01
number_time_steps = 200
x0 = np.array([0.0, 0.0, 0.0]) # [rho, theta, omega]
model = GeoSat(
x0=x0,
number_time_steps=number_time_steps,
selected_state_output=["rho", "theta", "omega"],
dt=dt,
)
for t in range(number_time_steps - 1):
u = np.array([[0.05]])
x_next = model.run_step(u)
Python API¶
GeoSat(x0, number_time_steps, selected_state_output=None, t0=0, dt=0.01)
¶
Bases: ModelBase
Geostationary 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
thrust: engine thrust [N]
State space
rho: ratio of flight altitude to Earth radius theta: satellite position relative to Earth coordinate system [rad] omega: satellite angular velocity [rad/s]
Output space
rho: ratio of flight altitude to Earth radius theta: satellite position relative to Earth coordinate system [rad] omega: satellite angular velocity [rad/s]
Initialize GeoSat 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.
Values are taken from the authoritative Simulink reference model
tensoraerospace/aerospacemodel/simulinkModel/geosat/geosat_data.m,
which is the source of truth for this linearization.
NOTE: The Russian/English markdown docs under docs/**/model/geosat.md
currently list slightly different coefficients (0.7757, -0.1775, 0.1513).
Those values actually correspond to the ComSat model (see
simulinkModel/comsat/comsat_data.m) and the docs are likely a
copy/paste error. The Simulink .m reference is trusted here.
TODO: reconcile docs/**/model/geosat.md with the Simulink source.
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. |
GeoSatEnv(initial_state, reference_signal, number_time_steps, tracking_states=None, state_space=None, control_space=None, output_space=None, reward_func=None)
¶
Bases: Env
Gymnasium environment for geostationary satellite control.
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 geosationary satellite environment.
reward(state, ref_signal, ts)
staticmethod
¶
Evaluate control performance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
ndarray
|
Current state. |
required |
ref_signal
|
ndarray
|
Reference signal. |
required |
ts
|
int
|
Time step. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
Control evaluation reward (negative absolute error). |
step(action)
¶
Execute one simulation step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action
|
ndarray
|
Control signal array for selected actuators. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
tuple |
tuple[ndarray, float, bool, bool, dict[str, float]]
|
Tuple containing: - next_state (np.ndarray): Next state of the control object. - reward (np.ndarray): Evaluation of control algorithm actions. - done (bool): Simulation status, whether completed or not. - truncated (bool): Whether episode was truncated. - info (dict): Additional information. |
reset(seed=None, options=None)
¶
Reset simulation environment to initial conditions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed
|
int
|
Random seed. Defaults to None. |
None
|
options
|
dict
|
Additional initialization options. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
tuple |
tuple[ndarray, dict[str, float]]
|
Tuple containing: - observation (np.ndarray): Initial observation. - info (dict): Additional information. |
render()
¶
Visual rendering of actions in the environment. Work in progress.
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
Rendering is not yet implemented. |