cislunar-sim
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 as a library you import — not an application you drive with mission scripts, like GMAT, or a JVM you host from Python, like Orekit.
Why cislunar-sim?
- 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
Installation
pip install cislunar-sim
Requirements: 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.22
Quick start
import 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))
Examples
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
What's included
Physics engine (cislunar.physics)
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) |
Guidance laws (cislunar.guidance)
| 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 |
Validation (cislunar.validation)
# 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-external
Validation record
Reproducible from a fresh clone
The 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.
Envelope
Validated against external data: 579–717 km — the band the bundled LightSail 2 epochs span, and the only place results are compared against something outside this repository.
Exercised with sanity checks from about 185 km upward — the atmosphere model is tested from 200 to 1500 km and the examples run at 400 km and a 185 km periapsis, but those tests check direction and order of magnitude, not accuracy. Below 579 km the engine runs and behaves plausibly; it has not been checked against truth, and drag error grows quickly as altitude falls.
See VALIDATION_RECORD.md.
Requires external mission files
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 (early / late window) | 0.231 observed vs 0.228 predicted — confounded, see note | 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 |
On the B* swing: the two windows differ in solar activity and altitude as well as sail behaviour, and the sail was never furled — it deployed in July 2019 and stayed deployed until reentry. The agreement is suggestive, not confirming. VALIDATION_RECORD.md §2 explains what would be needed to make it a controlled test.
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)
Development setup
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 benchmarks
Contributing
See CONTRIBUTING.md.
License
See LICENSE. Copyright © 2026 Arbor Engineering Group.
Metadata
Release files for cislunar-sim 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cislunar_sim-1.0.1.tar.gz | 264.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cislunar_sim-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 472.3 kB
Release files / cislunar_sim-1.0.1.tar.gz
| Download URL | cislunar_sim-1.0.1.tar.gz |
|---|---|
| Size | 264.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f41e58a0519dbb7f5b56d867650a31f22fb1efffe361798f36dbde6d07f0486c
|
|
BLAKE2b-256 checksum How to use checksums |
86f0bb898ce515c2478f7496b8de930a67a25b065f180d92bb8cebe7d8a96709
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / cislunar_sim-1.0.1-py3-none-any.whl
| Download URL | cislunar_sim-1.0.1-py3-none-any.whl |
|---|---|
| Size | 207.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ebd4754ee74acd78d5925c1e5a43ef5f33296640ed32b692f446197af240e7a9
|
|
BLAKE2b-256 checksum How to use checksums |
a246b7e3155bd5aae87b2e8a93e4f44e63e3d52e6ddc11a9e24152e7d1c0d51e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency log