sidereon
GNSS and astrodynamics for Rust: propagate satellites, predict passes, solve precise positions (SPP / RTK / PPP), and convert between coordinate frames and time scales, checked against the references the field trusts (Vallado, Skyfield, IGS, IERS).
It's a pure-Rust engine, fast and #![forbid(unsafe_code)] at the surface, with
one ergonomic crate that re-exports the whole stack. You just cargo add sidereon.
Install
cargo add sidereon
Quickstart: when does the ISS fly over you?
No data files, no setup: give it a two-line element set and a ground station, and ask when the satellite is above the horizon.
use ;
use ;
use Satellite;
A typical run prints something like:
08:30 UTC | 6.8 min | peak 88 deg
15:01 UTC | 6.6 min | peak 56 deg
16:39 UTC | 3.5 min | peak 14 deg
Each [SatellitePass] gives you acquisition (aos), loss (los), culmination
time, and peak elevation. The same sidereon::passes module has look_angle
(azimuth / elevation / range to a satellite at an instant), ground_track, and
propagate_teme_arc for raw state vectors; Satellite from sidereon::sgp4 is
the propagator behind all of it.
Precise positioning
The positioning engine is the other half of the library: feed it pseudoranges and a precise-ephemeris (SP3) product and it returns a least-squares fix.
use ;
use ;
let sp3 = load_sp3?;
let inputs = SolveInputs ;
let fix = solve_spp?;
println!; // ItrfPositionM: ECEF metres
println!; // Some(Wgs84Geodetic): lat / lon / height
println!; // the satellites that contributed
solve_rtk_float_with, solve_rtk_fixed_with, solve_ppp_float_with, and
solve_ppp_fixed_with follow the same pattern: a typed config in, a result struct
with ECEF/geodetic position, residuals, DOP, and status out. One [Error] enum
unifies every product-parse and solve failure, and solve_spp_batch fans a fleet
of epochs across a rayon pool, bit-identical to the serial path.
What's in the box
- Orbits: SGP4/TLE and OMM, numerical propagation with atmospheric drag and decay/reentry prediction, Kepler and anomaly conversions, classical and equinoctial elements, passes, look angles, ground tracks
- Frames, time & geodesy: TEME ↔ GCRS ↔ ITRS, GMST/GAST, geodetic ↔ ECEF, topocentric coordinates, UTC/TT/TDB/UT1, EGM96/EGM2008 geoid grids, PROJ EGM96 GTX loading with explicit fused or separately rounded interpolation, DTED terrain elevation
- Bodies & almanac: Sun/Moon/planet apparent places (geocentric or topocentric RA/Dec and az/el), Sun and Moon rise/set, Moon illumination, seasons, moon phases, eclipses, planetary transits, plus JPL SPK (DAF/.bsp) kernels
- Observation geometry: angular separation and position angle, phase/beta/parallactic angles, sub-solar and sub-observer points, terminator, satellite visual magnitude
- Positioning: SPP, RINEX observation to SPP assembly and solve helpers, RTK (float/fixed), PPP (float/fixed), DOP, velocity, robust fault detection and exclusion
- GNSS/INS fusion: loose and tight updates, inertial checkpoint serialization, RTS smoothing, outage velocity matching, stationary and non-holonomic pseudo-updates
- GNSS data: SP3, RINEX (obs/nav/clock), CRINEX encode/decode, ANTEX, broadcast ephemeris, Bias-SINEX / CODE DCB biases, source-agnostic ephemeris sampling
- Corrections: SBAS, RTCM SSR and Galileo HAS orbit/clock/bias correction stores
- Space situational awareness: conjunction/TCA screening, collision probability, CDM, covariance, relative motion (RIC/RTN/LVLH, Clohessy-Wiltshire)
- RF: link budget (FSPL, EIRP, C/N0, antenna gain)
The product parsers, CRINEX encoder, Sun/Moon sky helpers, look-angle,
ground-track, geodetic/topocentric, Doppler, and propagation shortcuts live at
the crate root (load_sp3, encode_crinex, solve_spp, passes, sgp4,
tle, tca, relative, almanac, InertialFilter,
velocity_match_outage_to_state); the full astrodynamics tree is under sidereon::astro. Lower-level RTK/PPP internals stay
behind the explicit sidereon::raw escape hatch so the ergonomic surface stays
small.
The Bias-SINEX and CODE DCB convenience path loaders treat .gz files as
complete RFC 1952 member series and validate every member header and trailer.
They cap local archives at 64 MiB and cumulative output at 500 MiB. Consumers
with a different I/O policy can decode bytes externally and pass them to the
existing parse_bias_sinex* or parse_code_dcb* functions.
Other languages
sidereon is one validated engine with first-class interfaces in Rust, Python, C, Elixir, and WebAssembly: same numbers everywhere. See the live demo and docs at sidereon.dev.
How it's validated
The SGP4 propagator is a Rust port of David Vallado's reference implementation, bit-exact to it. Frames and time are checked against Skyfield and IERS; the positioning stack is checked against IGS products.
MIT licensed. The engine's SGP4 propagation credits David Vallado (AIAA 2006);
see the sidereon-core crate for full attribution.