Current section
Files
Jump to
Current section
Files
README.md
# sidereon[](https://hex.pm/packages/sidereon)[](https://hexdocs.pm/sidereon)[](https://livebook.dev/run?url=https://github.com/neilberkman/sidereon-ex/blob/main/sidereon.livemd)GNSS and astrodynamics for Elixir: propagate satellites, predict passes, solveprecise positions (SPP / RTK / PPP / DGNSS), screen for conjunctions, andconvert between coordinate frames and time scales.This is the Elixir interface to **sidereon**, a GNSS and astrodynamics enginewritten in Rust. The numerics run in that engine and ship to you as a[Rustler](https://github.com/rusterlium/rustler) **precompiled NIF**: adding thedependency downloads a prebuilt binary for your platform, so there is no Rusttoolchain to install and nothing to compile. You write ordinary Elixir, withplain `DateTime` and map structures in and typed structs out.The engine is reference-validated. The SGP4 propagator is a port of DavidVallado's reference implementation, bit-exact to it; frames and time are checkedagainst Skyfield and IERS; the positioning stack is checked against IGS products.## InstallAdd `:sidereon` to your dependencies in `mix.exs`:```elixirdef deps do [{:sidereon, "~> 0.10"}]end```Releases ship precompiled NIFs for common Linux, macOS, and Windows targets anddownload automatically, so no Rust build is needed. (Set `SIDEREON_BUILD=1` tocompile from source instead.)## Example: track a satelliteParse a two-line element set, run SGP4, and take a look angle from a groundstation. No data files and no setup: give it the elements and a station, and itreturns azimuth, elevation, and slant range.```elixirline1 = "1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9009"line2 = "2 25544 51.6400 208.8657 0002644 250.3037 109.7782 15.49560812999990"station = %{latitude: 51.5, longitude: -0.1, altitude_m: 10.0}with {:ok, tle} <- Sidereon.parse_tle(line1, line2), {:ok, look} <- Sidereon.look_angle(tle, ~U[2024-01-01 12:00:00Z], station) do look.azimuth # degrees look.elevation # degrees look.range_km # slant rangeend```The same parsed elements feed `Sidereon.propagate/2` (TEME position andvelocity), `Sidereon.geodetic/2` (the sub-satellite point), and`Sidereon.predict_passes/5` (every pass above a minimum elevation over a window).## Example: solve a positionThe positioning engine is the other half of the library. Feed it pseudorangesand a precise-ephemeris product and it returns a least-squares fix with ECEF andgeodetic positions plus geometry diagnostics.```elixir# GPS L1 pseudoranges (meters) for the satellites in view at the epoch.observations = [ {"G08", 23_825_519.8}, {"G10", 22_717_690.1}, {"G16", 20_478_653.4}, {"G18", 21_768_335.2}, {"G20", 21_248_327.7}, {"G21", 20_808_709.8}]# `sp3_data` is a precise SP3 ephemeris (a string, or load one with# `Sidereon.GNSS.SP3.load/1`).with {:ok, sp3} <- Sidereon.GNSS.SP3.parse(sp3_data), {:ok, solution} <- Sidereon.GNSS.Positioning.solve(sp3, observations, ~N[2020-06-24 12:00:00], initial_guess: [4_500_000.0, 500_000.0, 4_500_000.0, 0.0]) do solution.position # %{x_m, y_m, z_m} ITRF/IGS ECEF meters solution.geodetic # %{lat_rad, lon_rad, height_m} solution.rx_clock_s # receiver clock bias, seconds solution.dop.pdop # position dilution of precision solution.used_sats # satellites that contributed to the fixend````Sidereon.GNSS.RTK` and the PPP and DGNSS solvers follow the same shape:observations and a product in, a typed solution out.A runnable [`sidereon.livemd`](sidereon.livemd) walks through propagation,positioning, and conjunction screening; more notebooks live under[the examples directory](https://github.com/neilberkman/sidereon-ex/tree/main/examples).## What's in the box- **Orbit propagation** SGP4 / SDP4 from TLE and OMM, numerical propagation with a composable force model (spherical-harmonic geopotential to selectable degree and order, Sun/Moon third-body, solar radiation pressure, relativistic correction, atmospheric drag), orbital decay estimation with a post-decay validity latch, two-body Kepler propagation, ground track, sub-satellite point, eclipse, Sun and Moon angles, and Doppler. See `Sidereon`, `Sidereon.Propagator`, `Sidereon.SGP4`, `Sidereon.Drag`.- **GNSS positioning** single-point positioning (SPP), RTK (float, integer-fixed, fix-and-hold), PPP, DGNSS, robust Huber-reweighted solves, RAIM with fault detection and exclusion, SBAS and RTCM SSR / Galileo HAS corrections, dilution of precision, and receiver velocity from Doppler. See `Sidereon.GNSS.Positioning`, `Sidereon.GNSS.RTK`, `Sidereon.GNSS.PrecisePositioning`, `Sidereon.GNSS.DGNSS`, `Sidereon.GNSS.QC`, `Sidereon.GNSS.SBAS`, `Sidereon.GNSS.SSR`.- **Integrity and error bounds** multi-constellation ARAIM protection levels, SBAS protection levels (DO-229), per-observation reliability (minimal detectable bias, internal and external), observability classification of every solution (rank, redundancy, conditioning), and covariance-derived error metrics (CEP, R95, SEP, error ellipse) that report wide or flagged bounds for weak geometry rather than fabricated confidence. See `Sidereon.ARAIM`, `Sidereon.Reliability`, `Sidereon.ErrorMetrics`, `Sidereon.GNSS.SBAS`.- **Timing, estimation, and geodesy** Allan-family clock stability with power-law noise identification (IEEE 1139), scalar Kalman and alpha-beta trackers with innovation gating and CFAR thresholds, source localization (ToA/TDOA), robust station velocity (MIDAS) with trajectory fitting, step detection, and network motion fields, repeating-geometry (sidereal) filtering, geodesic direct and inverse problems (Karney), an epoch-aware terrestrial frame catalog (ITRF/ETRF Helmert sets), EGM2008 geoid grids, and batch least-squares orbit fitting against precise ephemerides (including terrestrial-frame SP3) with a per-satellite residual ledger. See `Sidereon.ClockStability`, `Sidereon.Estimation`, `Sidereon.SourceLocalization`, `Sidereon.GeodeticTimeSeries`, `Sidereon.Sidereal`, `Sidereon.OrbitDetermination`.- **GNSS data and observations** SP3 (read, multi-center merge, write), broadcast navigation (RINEX 3.x / 4.x), IONEX, ANTEX, CLK, satellite code biases (Bias-SINEX and CODE DCB with OSB / DSB lookup), uniform satellite-state sampling that treats precise and broadcast sources interchangeably, RINEX 3 observations with Hatanaka / CRINEX decoding, carrier-phase combinations, cycle-slip detection, Hatch smoothing, ionosphere-free combination, and GPS L1 C/A signal generation, acquisition, and LNAV decode. See `Sidereon.GNSS.SP3`, `Sidereon.GNSS.Broadcast`, `Sidereon.GNSS.Ephemeris`, `Sidereon.GNSS.Bias`, `Sidereon.GNSS.CarrierPhase`, `Sidereon.GNSS.RTCM`.- **Ephemeris and time** JPL SPK / `.bsp` kernels for Sun, Moon, and planets; TEME, GCRS, ITRS, geodetic, ECEF, and topocentric frames with IAU2000A nutation and IAU2006 precession; UTC / TAI / TT / TDB / UT1 scales. See `Sidereon.Ephemeris`, `Sidereon.Coordinates`, `Sidereon.GNSS.Time`.- **Geometry and events** pass prediction, look angles, conjunction and TCA screening, collision probability (Foster equal-area and numerical), CCSDS CDM parsing, covariance propagation, initial orbit determination (Gibbs, Herrick-Gibbs, Gauss angles-only), Lambert and Battin transfers, relative motion in RIC / RTN / LVLH frames with Clohessy-Wiltshire propagation, anomaly conversions, orbital element conversions including equinoctial and modified equinoctial forms, and angular geometry (angular separation, position angle, phase angle, beta angle). See `Sidereon.Passes`, `Sidereon.Conjunction`, `Sidereon.Collision`, `Sidereon.IOD`, `Sidereon.Lambert`, `Sidereon.OrbitalElements`, `Sidereon.Astro.Relative`, `Sidereon.Astro.Anomaly`, `Sidereon.Astro.Equinoctial`, `Sidereon.Angles`.- **Observation and almanac** apparent topocentric places (right ascension, declination, azimuth, elevation) for the Sun, Moon, and any SPK body; sub-solar and sub-observer points, terminator latitude, parallactic angle, and satellite visual magnitude; Moon rise / set, illumination, and meridian transits; seasons, moon phases, planetary events, and lunar / solar eclipses over a window. See `Sidereon.Astro.Observe`, `Sidereon.Astro.Almanac`, `Sidereon.Bodies`, `Sidereon.Observation`.- **Atmosphere** Klobuchar and Galileo NeQuick-G ionospheric delay, IONEX grids, tropospheric zenith delay and mapping, and NRLMSISE-00 neutral density. See `Sidereon.GNSS.Ionosphere`, `Sidereon.GNSS.Troposphere`, `Sidereon.Atmosphere`.- **RF link budget** free-space path loss, EIRP, C/N0, dish gain, and link margin. See `Sidereon.RF`.- **Terrain and data acquisition** DTED terrain elevation lookup, and cache-first download of GNSS products (SP3, CLK, NAV, IONEX) and DTED tiles from public archives, with canonical filenames and archive URLs for callers who fetch their own. See `Sidereon.Terrain`, `Sidereon.GNSS.Data`.- **Format parse and serialize** TLE and OMM (KVN, XML, JSON) parse and encode, CCSDS OPM / OEM / CDM / TDM, and the GNSS products above. See `Sidereon.Format.TLE`, `Sidereon.Format.OMM`, `Sidereon.CCSDS.OPM`, `Sidereon.CCSDS.OEM`, `Sidereon.CCSDS.TDM`.Every result is what the engine computes, returned as plain Elixir structs andmaps with `{:ok, _}` / `{:error, _}` tuples. Full signatures live on[HexDocs](https://hexdocs.pm/sidereon).## Other languagessidereon is one validated engine with first-class interfaces in severallanguages: Rust ([sidereon](https://github.com/neilberkman/sidereon)), Python([sidereon-python](https://github.com/neilberkman/sidereon-python)), C([sidereon-c](https://github.com/neilberkman/sidereon-c)), Elixir (thispackage), and WebAssembly([sidereon-wasm](https://github.com/neilberkman/sidereon-wasm)). The same numberscome out everywhere. See the live demo and docs at[sidereon.dev](https://sidereon.dev).## LicenseMIT. The engine's SGP4 propagation is a port of David Vallado's referenceimplementation (credit: David Vallado, AIAA 2006); see the core[sidereon](https://github.com/neilberkman/sidereon) crate for full attribution.