High-fidelity cislunar spacecraft simulation in pure Python — cross-validated against LightSail 2 mission data.
cislunar-sim is a Python library for simulating spacecraft trajectories from low Earth orbit through cislunar space. It provides a high-fidelity, validated physics engine and Q-law orbital guidance laws — without the XML configuration of GMAT or the Java dependency of Orekit.
- Validated: physics engine achieves < 0.05% SMA error against SGP4-propagated LightSail 2 states (bundled TLEs, reproducible from a fresh clone)
- Complete force environment: J2/J3 + GRAIL mascon lunar gravity, ion thruster, solar sail SRP, atmospheric drag, eclipse shadowing, attitude dynamics
- JPL-quality ephemeris: Sun and Moon positions from astropy DE430
- Minimal dependencies:
numpy,astropy, andnrlmsise00are the only runtime dependencies - Fast: adaptive RK4(5) integrator; 7-day GTO periapsis-raise and 5-day drag-decay demos each run in under 60 seconds
pip install cislunar-simRequirements: Python ≥ 3.11, numpy ≥ 1.24, astropy ≥ 5.3, nrlmsise00 ≥ 0.1
For TLE propagation and LightSail 2 telemetry replay, install the validation extra:
pip install "cislunar-sim[validation]" # adds sgp4>=2.22import numpy as np
from cislunar.guidance import ProgradeGuidance
from cislunar.physics import Action, make_lunar_craft
R_E = 6.371e6
MU = 3.986004418e14
r = R_E + 400e3
v_c = np.sqrt(MU / r)
sc = make_lunar_craft(
position_m=[r, 0.0, 0.0],
velocity_ms=[0.0, v_c, 0.0],
propellant_kg=0.5,
)
guidance = ProgradeGuidance()
for _ in range(60): # 1 hour at 60 s control steps
thrust_dir, throttle = guidance.steer(sc.state.position, sc.state.velocity)
sc.step(
Action(attitude_dir_cmd=thrust_dir, thrust_dir=thrust_dir, throttle=throttle),
dt_requested=60.0,
)
print(sc.state.time_s, np.linalg.norm(sc.state.position))The tested feature demos live in examples/:
examples/gto_periapsis_raise.py— ion-thruster GTO periapsis raise to a 1,000 km targetexamples/solar_sail_leo.py— solar-sail orbit raising from 585 km LEOexamples/drag_decay_leo.py— atmospheric drag driven SMA decay at 400 kmexamples/eclipse_power_gating.py— eclipse-aware power gating for ion thrustexamples/cislunar_transfer.py— combined ion + sail cislunar orbit raising
Adaptive RK4(5) Dormand-Prince integrator with:
| Force | Model |
|---|---|
| Earth gravity | Two-body + J2 oblateness |
| Lunar gravity | J2 + J3 + 8-mascon GRAIL model |
| Solar gravity | Third-body perturbation |
| Ion thruster | Hall-effect, 15 mN, iodine-fed, 60 s warmup |
| Solar sail | McInnes radiation pressure model with albedo |
| Atmospheric drag | NRLMSISE-00 proxy (F10.7 solar flux) |
| Eclipse | Earth/Moon umbra–penumbra; power/battery model |
| Attitude | Quaternion rigid-body + reaction wheels + RCS |
| Ephemeris | astropy DE430 (Sun + Moon positions) |
| Class | Description |
|---|---|
GVEPeriapsisGuidance |
GVE-optimal: maximise dr_p/dt |
GVEApogeeGuidance |
GVE-optimal: maximise dr_apo/dt |
GTOPeriapsisGuidance |
Periapsis burn gating for GTO |
GTOApogeeGuidance |
Apogee burn gating for GTO |
ProgradeGuidance |
Prograde burn with Oberth timing |
# Spot-check against McInnes, Wertz, JPL Horizons (19 benchmarks)
python -m cislunar.validation.physics_benchmark --extended
# Full LightSail 2 replay / telemetry validation
# Requires external mission files in validation/data/
make validate-externalThe orbit-replay test compares the physics engine against SGP4-propagated
state vectors derived from bundled LightSail 2 TLEs (5 historical epochs,
NORAD 44420). These run automatically via make test.
| Metric | Result | Reference | Reproducible |
|---|---|---|---|
| SMA error (1-day archival epoch) | < 0.05% | SGP4 propagation | ✓ from clone |
| Radial error | < 0.02% of orbital radius | SGP4 propagation | ✓ from clone |
| Sail force vs. McInnes (IKAROS params) | within 1% | McInnes (1999) Table 2.1 | ✓ from clone |
The along-track drift is drag-dominated and expected; see the validation record for details.
The B* swing analysis and eclipse/attitude comparisons use the full CelesTrak GP-history archive and SatNOGS beacon frames, neither of which is bundled in this repo.
| Metric | Result | Requires |
|---|---|---|
| B* swing ratio (sailing / passive) | 0.231 observed vs 0.228 predicted | CelesTrak GP archive |
| Eclipse timing (entry residuals) | mean +3.7 s, std 19.5 s | SatNOGS beacon data |
| Body-rate envelope | 0% of frames above model cap | SatNOGS beacon data |
See src/cislunar/validation/light_sail_2/VALIDATION_RECORD.md
for full methodology and validation/data/README.md
for acquisition instructions.
make validate-external # requires validation/data/ mission files (see that README)git clone https://github.com/arboreng/cislunar-sim.git
cd cislunar-sim
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pre-commit install
make test # physics + validation + example tests (~5 min)
make validate-external # requires validation/data/* mission files
make bench # spot-check benchmarksSee CONTRIBUTING.md.
See LICENSE. Copyright © 2026 Arbor Engineering Group.