42 releases (13 breaking)
| 0.16.2 | Apr 13, 2026 |
|---|---|
| 0.15.0 | Mar 29, 2026 |
| 0.8.3 | Nov 12, 2025 |
| 0.5.6 | Apr 6, 2025 |
| 0.2.5 |
|
#72 in Algorithms
8,899 downloads per month
1MB
15K
SLoC
satkit
Satellite astrodynamics in Rust, with full Python bindings.
Satkit is a high-performance orbital mechanics library written in Rust with complete Python bindings via PyO3. It handles coordinate transforms, orbit propagation, time systems, gravity models, atmospheric density, and JPL ephemerides -- everything needed for satellite astrodynamics work.
Documentation and tutorials (Python examples, but the concepts and API apply equally to Rust) | Rust API reference
[!NOTE] Version 0.16.0 introduces several breaking changes:
Frame::RICis renamed to the canonicalFrame::RTN(withRIC/RSWremaining as aliases, so existing code still compiles); a newFrame::NTW(velocity-aligned) is added;LVLHis now accepted as a maneuver/thrust frame; the uncertainty API is unified intoset_pos_uncertainty(sigma, frame)/set_vel_uncertainty(sigma, frame)(the four old per-frame methods are removed, not deprecated);PropSettings::default()now usesGravityModel::EGM96instead ofJGM3; the Gauss-Jackson 8 fixed-step multistep integrator is available for long-duration propagation; andPropSettings::max_stepsis now configurable. SeeCHANGELOG.mdfor the full list.
Installation
Rust:
cargo add satkit
Python:
pip install satkit
Pre-built wheels are available for Linux, macOS, and Windows on Python 3.10--3.14.
After installing, download the required data files (gravity models, ephemerides, Earth orientation parameters):
import satkit as sk
sk.utils.update_datafiles() # one-time download; re-run periodically for fresh EOP/space weather
Quick Examples
SGP4 propagation (Python)
import satkit as sk
tle = sk.TLE.from_lines([
"ISS (ZARYA)",
"1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9003",
"2 25544 51.6432 351.4697 0007417 130.5364 329.6482 15.48915330299357"
])
pos, vel = sk.sgp4(tle, sk.time(2024, 1, 2))
High-precision propagation (Python)
import satkit as sk
import numpy as np
r0 = 6378e3 + 500e3 # 500 km altitude
v0 = np.sqrt(sk.consts.mu_earth / r0)
settings = sk.propsettings(
gravity_model=sk.gravmodel.egm96, # default; also jgm3, jgm2, itugrace16
gravity_degree=8,
integrator=sk.integrator.rkv98, # default; also rkv87, rkv65, rkts54,
# gauss_jackson8 (fixed-step multistep)
)
result = sk.propagate(
np.array([r0, 0, 0, 0, v0, 0]),
sk.time(2024, 1, 1),
end=sk.time(2024, 1, 1) + sk.duration.from_days(1),
propsettings=settings,
)
state = result.interp(sk.time(2024, 1, 1) + sk.duration.from_hours(6))
Coordinate transforms (Python)
import satkit as sk
time = sk.time(2024, 1, 1, 12, 0, 0)
coord = sk.itrfcoord(latitude_deg=42.0, longitude_deg=-71.0, altitude=100.0)
q = sk.frametransform.qitrf2gcrf(time)
gcrf_pos = q * coord.vector
Planetary ephemerides (Rust)
use satkit::{Instant, SolarSystem, jplephem};
let time = Instant::from_datetime(2024, 1, 1, 0, 0, 0.0)?;
let (pos, vel) = jplephem::geocentric_state(SolarSystem::Moon, &time)?;
Features
Coordinate Frames
Full IERS 2010 Conventions reduction (IAU 2006/2000A precession-nutation) with Earth orientation parameters:
| Frame | Description |
|---|---|
| ITRF | International Terrestrial Reference Frame (Earth-fixed) |
| GCRF | Geocentric Celestial Reference Frame (inertial) |
| TEME | True Equator Mean Equinox (SGP4 output frame) |
| CIRS | Celestial Intermediate Reference System |
| TIRS | Terrestrial Intermediate Reference System |
| Geodetic | Latitude / longitude / altitude (WGS-84) |
Plus ENU, NED, and geodesic distance (Vincenty) utilities.
Orbit Propagation
- Numerical -- Selectable adaptive Runge-Kutta integrators (9(8), 8(7), 6(5), 5(4)) plus RODAS4 (stiff) and Gauss-Jackson 8 (fixed-step multistep for high-precision long-duration propagation), with dense output, state transition matrix, and configurable force models
- SGP4 -- Standard TLE/OMM propagator with TLE fitting from precision states
- Keplerian -- Analytical two-body propagation
Orbit Maneuvers
- Impulsive maneuvers -- Instantaneous delta-v applied at a scheduled time during propagation. Supported frames: GCRF (inertial), RTN (radial/tangential/normal — the CCSDS OEM convention, also exposed as
RSWandRICaliases), NTW (velocity-aligned — natural for prograde burns on eccentric orbits, where a pure +T delta-v adds exactly Δv to |v|), and LVLH (Local Vertical / Local Horizontal). Ergonomic helpersadd_prograde/add_retrograde/add_radial/add_normalfor common scalar-magnitude burns. - Continuous thrust -- Constant-acceleration thrust arcs over time windows in any of the frames above, integrated directly into the force model
- Automatic segmentation -- Propagation through maneuver sequences is handled transparently, including backward propagation
Force Models
- Earth gravity: JGM2, JGM3, EGM96, ITU GRACE16 (spherical harmonics up to degree/order 360)
- Third-body gravity: Sun and Moon via JPL DE440/441 ephemerides
- Atmospheric drag: NRLMSISE-00 with automatic space weather data
- Solar radiation pressure: Cannonball model with shadow function
Time Systems
Seamless conversion between UTC, TAI, TT, TDB, UT1, and GPS time scales with full leap-second handling.
Solar System
- JPL DE440/DE441 ephemerides for all planets, Sun, Moon, and barycenters
- Fast analytical Sun/Moon models for lower-precision work
- Sunrise/sunset and Moon phase calculations
Linear Algebra
SatKit uses numeris for all linear algebra (vectors, matrices, quaternions, ODE integration). If you also use nalgebra in your project, enable the nalgebra feature on numeris for zero-cost From/Into conversions between types:
numeris = { version = "0.5.7", features = ["nalgebra"] }
Cargo Features
| Feature | Default | Description |
|---|---|---|
omm-xml |
yes | XML OMM deserialization via quick-xml |
chrono |
no | TimeLike impl for chrono::DateTime |
Data Files
Satkit needs external data for gravity models, ephemerides, and Earth orientation. Call update_datafiles() to download them automatically.
Downloaded once: JPL DE440/441 (~100 MB), gravity model coefficients, IERS nutation tables
Update periodically: Space weather indices (F10.7, Ap) and Earth orientation parameters (polar motion, UT1-UTC) -- both sourced from Celestrak.
Testing and Validation
The library is validated against:
- Vallado test cases for SGP4, coordinate transforms, and Keplerian elements
- JPL test vectors for DE440/441 ephemeris interpolation (10,000+ cases)
- ICGEM reference values for gravity field calculations
- GPS SP3 precise ephemerides for multi-day numerical propagation
157 Rust tests and 81 Python tests run on every commit across Linux, macOS, and Windows.
Running Tests Locally
Tests require two sets of external data: the astro-data files (gravity models, ephemerides, etc.) and the test vectors (reference outputs for validation). Download both before running:
# Install the download helper
pip install requests
# Download test vectors
python python/test/download_testvecs.py
Then run tests with the environment variables pointing to the downloaded directories:
# Rust tests
SATKIT_DATA=astro-data SATKIT_TESTVEC_ROOT=satkit-testvecs cargo test
# Python tests
SATKIT_DATA=astro-data SATKIT_TESTVEC_ROOT=satkit-testvecs pytest python/test/
Documentation
- Rust: docs.rs/satkit
- Python: satkit.dev -- tutorials, Jupyter notebooks, and API reference
References
- D. Vallado, Fundamentals of Astrodynamics and Applications, 4th ed., 2013
- O. Montenbruck & E. Gill, Satellite Orbits: Models, Methods, Applications, 2000
- J. Verner, Runge-Kutta integration coefficients
License
MIT
Dependencies
~12–24MB
~401K SLoC