sidereon_core/spp/source.rs
1//! Ephemeris-source abstraction for SPP.
2
3use crate::id::GnssSatelliteId;
4use crate::sp3::Sp3;
5
6/// A source of satellite position and clock at a transmit epoch.
7///
8/// The SPP pipeline is written against this trait rather than a concrete product
9/// so it can run on either a precise SP3 ephemeris or a broadcast navigation
10/// message. The contract is exactly what the transmit-time iteration needs: the
11/// ECEF position (meters) and the satellite clock offset (seconds) at a given
12/// J2000 second, or `None` if the source has no usable ephemeris for that
13/// satellite at that instant.
14pub trait EphemerisSource {
15 /// ECEF position (m) and satellite clock offset (s) for `sat` at `t_j2000_s`.
16 fn position_clock_at_j2000_s(
17 &self,
18 sat: GnssSatelliteId,
19 t_j2000_s: f64,
20 ) -> Option<([f64; 3], f64)>;
21}
22
23impl EphemerisSource for Sp3 {
24 fn position_clock_at_j2000_s(
25 &self,
26 sat: GnssSatelliteId,
27 t_j2000_s: f64,
28 ) -> Option<([f64; 3], f64)> {
29 let state = self.position_at_j2000_seconds(sat, t_j2000_s).ok()?;
30 let clk = state.clock_s?;
31 Some((state.position.as_array(), clk))
32 }
33}