A dual language library for GEO spacecraft propulsion optimisation and orbital mechanics. The same physics; Hohmann transfers, J2 secular perturbations, electric thruster trade space optimisation, is implemented in both Python and MATLAB so that results can be cross verified at every step of the mission design cycle.
This library bridges the gap between rapid research workflows (Python) and flight-software simulation environments (MATLAB/Simulink). Every physical equation is implemented identically in both languages, test-verified against published reference values, and documented with LaTeX mathematics.
Aerospace engineering workflows typically span two toolchains:
| Phase | Preferred Environment |
|---|---|
| π¬ Rapid research & algorithm development | Python (NumPy, SciPy, Astropy) |
| π°οΈ Flight-software simulation & heritage tools | MATLAB / Simulink |
| β Verification & cross-check | Both |
Maintaining a single source of truth across both languages means:
- π Results produced in Python can be independently validated in MATLAB before they appear in a flight-software simulation
- π MATLAB Simulink models can import the same thruster parameters that were optimised in Python
- π€ Engineers can work in whichever language they know without losing access to the validated physics kernel
geo_optimization/
β
βββ π python/ Python package
β βββ pyproject.toml PEP 517/518 build configuration
β βββ src/geo_opt/
β βββ __init__.py Package root (version, metadata)
β βββ constants.py Physical & orbital constants (astropy.units)
β βββ dynamics/
β β βββ __init__.py Convenience re-exports for short imports
β β βββ keplerian.py Vis-viva, circular velocity, Hohmann transfer
β β βββ perturbations.py J2 RAAN & Ο drift, station-keeping budget
β βββ propulsion/
β β βββ __init__.py Convenience re-exports for short imports
β β βββ thruster.py Generic rocket eqn + Pydantic config
β β βββ het.py Hall-Effect Thruster model
β β βββ ion.py Gridded Ion Thruster model
β βββ optimization/
β βββ solvers.py Grid-search & SciPy L-BFGS-B solvers
β
βββ πΆ matlab/ MATLAB package (+geo_opt namespace)
β βββ startup.m Adds library paths β run once per session
β βββ +geo_opt/
β β βββ constants.m Returns authoritative constant struct
β β βββ +dynamics/
β β β βββ circular_velocity.m
β β β βββ vis_viva.m
β β β βββ hohmann_transfer.m
β β β βββ orbital_period.m
β β β βββ j2_raan_drift.m
β β β βββ j2_argperigee_drift.m
β β βββ +propulsion/
β β β βββ calculate_thrust.m
β β β βββ estimate_power.m
β β β βββ thrust_to_power_ratio.m
β β β βββ tsiolkovsky_dv.m
β β β βββ het_performance.m
β β β βββ ion_performance.m
β β βββ +optimization/
β β βββ grid_search.m Exhaustive mesh optimiser
β β βββ fmincon_optimizer.m fmincon continuous solver
β βββ tests/
β βββ test_dynamics.m
β βββ test_propulsion.m
β βββ test_optimization.m
β
βββ π .gitignore
βββ π LICENSE
βββ π README.md
# Install from the python/ subdirectory
pip install -e "python/[dev]"
# Run all tests
cd python && pytestfrom astropy import units as u
from geo_opt.constants import R_LEO, R_GEO
# β¨ Convenience imports β short form (recommended)
from geo_opt.dynamics import hohmann_transfer
from geo_opt.propulsion import ThrusterConfig, HETModel
# π¦ Fully qualified imports also work
# from geo_opt.dynamics.keplerian import hohmann_transfer
# from geo_opt.propulsion.thruster import ThrusterConfig
# from geo_opt.propulsion.het import HETModel
from geo_opt.optimization.solvers import grid_search_optimizer
# --- πΈ Hohmann Transfer: LEO β GEO ---
result = hohmann_transfer(R_LEO, R_GEO)
print(f"Total ΞV = {result['dv_total'].to('km/s'):.4f}")
# Total ΞV = 3.8933 km / s
# --- β‘ HET Performance ---
cfg = ThrusterConfig(name="SPT-100", isp_s=1600, efficiency=0.50,
mass_flow_kg_s=5e-6)
het = HETModel(cfg)
perf = het.performance()
print(f"Thrust = {perf['thrust_mN']:.3f} | Power = {perf['input_power_W']:.1f}")
# --- π― Thruster Optimisation ---
opt = grid_search_optimizer(isp_range=(1000, 4000), efficiency=0.55)
print(f"Optimal F/P = {opt.thrust_to_power.to('mN/W'):.4f}")% From the MATLAB command window, run startup once:
run('matlab/startup.m')
% πΈ Hohmann Transfer: LEO β GEO
C = geo_opt.constants();
result = geo_opt.dynamics.hohmann_transfer(C.R_LEO, C.R_GEO);
fprintf('Total dV = %.4f km/s\n', result.dv_total/1e3);
% Total dV = 3.8933 km/s
% β‘ HET Performance
perf = geo_opt.propulsion.het_performance(1600, 5e-6, 0.50);
fprintf('Thrust = %.3f mN | Power = %.1f W\n', perf.thrust_mN, perf.power_W);
% π― Thruster Optimisation
opt = geo_opt.optimization.grid_search([1000 4000], [5e-5 1e-3], 0.55);
fprintf('Optimal F/P = %.4f mN/W\n', opt.thrust_to_power * 1e3);
% β
Run tests
results = runtests('tests/test_dynamics');
disp(table(results))| Model | Equation |
|---|---|
| Circular velocity | |
| Vis-viva | |
| Hohmann ΞVβ | |
| Hohmann ΞVβ | |
| J2 RAAN drift | |
| J2 Ο drift |
| Model | Equation |
|---|---|
| Thrust | |
| Input power | |
| Thrust-to-power | |
| Rocket equation |
| Type |
|
Efficiency | Application |
|---|---|---|---|
| β‘ Hall-Effect (HET) | 1 200 β 3 500 | 45 β 65 % | GEO station-keeping, orbit raising |
| π¬ Gridded Ion | 2 500 β 10 000 | 55 β 80 % | Deep-space, high-ΞV GEO |
| Symbol | Value | Unit | Source |
|---|---|---|---|
| 9.80665 | m sβ»Β² | ISO 80000-3 | |
| 3.986 004 418 Γ 10ΒΉβ΄ | mΒ³ sβ»Β² | WGS-84 | |
| 6 378 137 | m | WGS-84 | |
| 1.082 626 68 Γ 10β»Β³ | β | IERS 2010 | |
| 42 164 137 | m | derived |
π Python
cd python
pip install -e ".[dev]"
pytest -vπΆ MATLAB
run('matlab/startup.m')
runtests('matlab/tests/test_dynamics')
runtests('matlab/tests/test_propulsion')
runtests('matlab/tests/test_optimization')- β Specific Impulse Range: 1 000 β 10 000 seconds
- β Mass Flow Rate Range: 0.00005 β 0.001 kg/s
- β Customisable efficiency parameters
- β Real-time thrust and power calculations
- β Multi-objective optimisation support
- β Gravity-assist multiplier support
- β All reference values anchored to Vallado (2013) & Curtis (2020)
- β
Python tests use
astropy.unitsfor unit-safe comparisons - β
MATLAB tests use
functiontestswithRelTol/AbsToltolerances - β Cross-language parity verified: LEOβGEO ΞV = 3.893 km/s in both
- β
Pydantic
ThrusterConfigenforces physical bounds (Isp, efficiency, mass flow) - β Consistent input guards across all propulsion functions (positive Isp, positive mass flow, 0 < Ξ· β€ 1)
@misc{ATaylor_GEOOptimization_2026,
author = {A. Taylor},
title = {GEO Optimization \& Orbital Dynamics β Dual-Language Library},
year = {2026},
url = {https://github.com/ATaylorAerospace/geo_optimization}
}Have questions, ideas, or want to collaborate? Reach out to A Taylor directly:
