Skip to main content

sidereon_core/astro/
constants.rs

1//! Canonical physical and unit constants shared by the core crates.
2//!
3//! Values with different standards or parity sources are intentionally named
4//! distinctly in [`models`] or [`astro`] instead of being silently unified.
5
6/// Unit-conversion constants.
7pub mod units {
8    /// Meters per kilometer.
9    pub const M_PER_KM: f64 = 1_000.0;
10    /// Millimeters per meter.
11    pub const MM_PER_M: f64 = 1_000.0;
12    /// Kilometers to meters.
13    pub const KM_TO_M: f64 = M_PER_KM;
14    /// Microseconds to seconds.
15    pub const US_TO_S: f64 = 1.0e-6;
16    /// Microseconds per second.
17    pub const MICROSECONDS_PER_SECOND_I64: i64 = 1_000_000;
18    /// Microseconds per second, floating point. Used where a microsecond count
19    /// is divided or multiplied as an `f64`; kept distinct from [`US_TO_S`] so
20    /// the divide-by-`1_000_000.0` operation order is preserved bit-for-bit.
21    pub const MICROSECONDS_PER_SECOND: f64 = 1_000_000.0;
22    /// Nanoseconds to seconds.
23    pub const NS_TO_S: f64 = 1.0e-9;
24    /// Degrees to radians.
25    pub const DEG_TO_RAD: f64 = std::f64::consts::PI / 180.0;
26    /// Radians to degrees.
27    pub const RAD_TO_DEG: f64 = 180.0 / std::f64::consts::PI;
28    /// Degrees in one semicircle.
29    pub const DEGREES_PER_SEMICIRCLE: f64 = 180.0;
30    /// Degrees in one full circle.
31    pub const DEGREES_PER_CIRCLE: f64 = 360.0;
32    /// Arcseconds to radians.
33    #[allow(clippy::excessive_precision)]
34    pub const ARCSEC_TO_RAD: f64 = 4.848_136_811_095_359_935_899_141e-6;
35}
36
37/// Topocentric look-angle geometry tolerances.
38pub mod geometry {
39    /// Squared horizontal fraction of the unit line of sight below which the
40    /// topocentric azimuth is degenerate and is defined to be `0.0`.
41    ///
42    /// At (and arbitrarily near) the observer's zenith the east and north
43    /// components of the line of sight collapse to pure rounding residuals, so
44    /// `atan2(east, north)` carries no real bearing information. Following
45    /// RTKLIB's `satazel` (which sets `az = 0` when the squared horizontal
46    /// projection of the unit line-of-sight vector is `< 1e-12`), azimuth is
47    /// pinned to `0.0` inside this threshold rather than returning rounding
48    /// noise. The comparison is made in squared form
49    /// (`east^2 + north^2 < AZIMUTH_ZENITH_EPS * range^2`) so it is scale free
50    /// regardless of the units the line of sight is expressed in.
51    pub const AZIMUTH_ZENITH_EPS: f64 = 1e-12;
52}
53
54/// Time-scale and Julian-date constants.
55pub mod time {
56    use super::units::MICROSECONDS_PER_SECOND_I64;
57
58    /// Seconds per civil minute.
59    pub const SECONDS_PER_MINUTE: f64 = 60.0;
60    /// Seconds per civil hour.
61    pub const SECONDS_PER_HOUR: f64 = 3_600.0;
62    /// Seconds per civil day.
63    pub const SECONDS_PER_DAY: f64 = 86_400.0;
64    /// Seconds per civil day, integer form for calendar arithmetic.
65    pub const SECONDS_PER_DAY_I64: i64 = 86_400;
66    /// Microseconds per civil day.
67    pub const MICROSECONDS_PER_DAY_I64: i64 = SECONDS_PER_DAY_I64 * MICROSECONDS_PER_SECOND_I64;
68    /// Seconds per GNSS week.
69    pub const SECONDS_PER_WEEK: f64 = 604_800.0;
70    /// Julian Date of the J2000 epoch.
71    pub const J2000_JD: f64 = 2_451_545.0;
72    /// Days per Julian year.
73    pub const DAYS_PER_JULIAN_YEAR: f64 = 365.25;
74    /// Days per Julian century.
75    pub const DAYS_PER_JULIAN_CENTURY: f64 = 36_525.0;
76    /// TT - TAI, seconds.
77    pub const TT_MINUS_TAI_S: f64 = 32.184;
78    /// GPS/Galileo/QZSS system time minus TAI, seconds.
79    pub const GPST_MINUS_TAI_S: f64 = 19.0;
80    /// BeiDou time minus TAI, seconds.
81    pub const BDT_MINUS_TAI_S: f64 = 33.0;
82}
83
84/// WGS84 Earth constants.
85pub mod earth {
86    use super::units::M_PER_KM;
87
88    /// WGS84 geocentric gravitational constant (km^3/s^2).
89    pub const GM_EARTH_KM3_S2: f64 = 398_600.441_8;
90    /// WGS84 geocentric gravitational constant (m^3/s^2).
91    pub const GM_EARTH_M3_S2: f64 = GM_EARTH_KM3_S2 * 1.0e9;
92    /// WGS84 Earth equatorial radius (km).
93    pub const WGS84_A_KM: f64 = 6_378.137;
94    /// WGS84 Earth equatorial radius (m).
95    pub const WGS84_A_M: f64 = WGS84_A_KM * M_PER_KM;
96    /// Mean Earth radius used by spherical shell propagation and conical
97    /// shadow (eclipse) models (km).
98    pub const MEAN_EARTH_RADIUS_KM: f64 = 6_371.0;
99    /// Mean Earth radius used by spherical shell propagation and conical
100    /// shadow (eclipse) models (m).
101    pub const MEAN_EARTH_RADIUS_M: f64 = MEAN_EARTH_RADIUS_KM * M_PER_KM;
102    /// WGS84 flattening.
103    pub const WGS84_F: f64 = 1.0 / 298.257_223_563;
104    /// WGS84 first eccentricity squared.
105    pub const WGS84_E2: f64 = 2.0 * WGS84_F - WGS84_F * WGS84_F;
106    /// WGS84 Earth rotation rate used by GNSS Sagnac/transport terms (rad/s).
107    pub const OMEGA_E_DOT_RAD_S: f64 = 7.292_115_146_7e-5;
108    /// Earth's J2 coefficient used by the core force models.
109    pub const J2_EARTH: f64 = 1.082_626_68e-3;
110    /// Earth's J3 unnormalized zonal coefficient from EGM96.
111    pub const J3_EARTH: f64 = -2.532_656_485_332_235_5e-6;
112    /// Earth's J4 unnormalized zonal coefficient from EGM96.
113    pub const J4_EARTH: f64 = -1.619_621_591_367e-6;
114    /// Earth's J5 unnormalized zonal coefficient from EGM96.
115    pub const J5_EARTH: f64 = -2.272_960_828_686_982e-7;
116    /// Earth's J6 unnormalized zonal coefficient from EGM96.
117    pub const J6_EARTH: f64 = 5.406_812_391_070_848e-7;
118}
119
120/// Universal physical constants.
121pub mod physics {
122    /// Speed of light in vacuum (m/s), exact by SI definition (and the value
123    /// IS-GPS-200 fixes for GNSS ranging).
124    pub const SPEED_OF_LIGHT_M_S: f64 = 299_792_458.0;
125    /// Speed of light in vacuum (km/s), exact SI value converted to kilometers.
126    pub const SPEED_OF_LIGHT_KM_S: f64 = SPEED_OF_LIGHT_M_S / 1_000.0;
127}
128
129/// Astronomical constants.
130pub mod astro {
131    /// Astronomical unit in kilometers, matching Skyfield's AU convention.
132    pub const AU_KM: f64 = 149_597_870.700;
133    /// Astronomical unit in meters, matching [`AU_KM`].
134    pub const AU_M: f64 = AU_KM * 1_000.0;
135    /// Solar gravitational parameter (km^3/s^2), IAU 2015 Resolution B3.
136    pub const GM_SUN_KM3_S2: f64 = 132_712_440_041.939_38;
137    /// Lunar gravitational parameter (km^3/s^2), DE/IAU conventional value.
138    pub const GM_MOON_KM3_S2: f64 = 4_902.800_066;
139    /// Solar radiation pressure at 1 AU (N/m^2), the cannonball SRP convention.
140    pub const SOLAR_RADIATION_PRESSURE_N_M2: f64 = 4.56e-6;
141    /// AU value used by the Montenbruck-Gill analytic Sun/Moon series.
142    pub const MONTENBRUCK_AU_M: f64 = 149_597_870_691.0;
143    /// Solar photosphere radius (km), used by conical eclipse-shadow geometry.
144    pub const SOLAR_RADIUS_KM: f64 = 696_340.0;
145    /// Mean lunar radius (km), used by almanac eclipse geometry.
146    pub const MOON_RADIUS_KM: f64 = 1_737.4;
147}
148
149/// Model-specific constants that intentionally differ from WGS84.
150pub mod models {
151    pub mod pz90 {
152        /// Geocentric gravitational constant (m^3/s^2), PZ-90.11.
153        pub const GM_M3_S2: f64 = 3.986_004_4e14;
154        /// Second zonal harmonic of the geopotential, PZ-90.11.
155        pub const J2: f64 = 1.082_625_7e-3;
156        /// Earth rotation rate (rad/s), PZ-90.11.
157        pub const OMEGA_E_RAD_S: f64 = 7.292_115e-5;
158        /// Earth equatorial radius (m), PZ-90.11.
159        pub const A_M: f64 = 6_378_136.0;
160    }
161
162    pub mod iers {
163        /// Earth radius used by the Dehant solid Earth tide formulation (m).
164        pub const SOLID_TIDE_EARTH_RADIUS_M: f64 = 6_378_136.6;
165    }
166
167    pub mod proj {
168        /// PROJ-pinned WGS84 semi-major axis (m).
169        pub const WGS84_A_M: f64 = f64::from_bits(0x4158_54a6_4000_0000);
170        /// PROJ-pinned WGS84 semi-minor axis (m).
171        pub const WGS84_B_M: f64 = f64::from_bits(0x4158_3fc4_141c_97d0);
172        /// PROJ-pinned first eccentricity squared.
173        pub const WGS84_ES: f64 = f64::from_bits(0x3f7b_6b90_f1fe_94f0);
174        /// PROJ-pinned second eccentricity squared.
175        pub const WGS84_E2S: f64 = f64::from_bits(0x3f7b_9adf_e197_dcd1);
176        /// PROJ-pinned radian-to-degree multiplier.
177        pub const RAD_TO_DEG: f64 = f64::from_bits(0x404c_a5dc_1a63_c1f8);
178        /// PROJ-pinned half-pi value.
179        pub const HALF_PI: f64 = f64::from_bits(0x3ff9_21fb_5444_2d18);
180    }
181
182    pub mod broadcast {
183        /// GPS broadcast gravitational constant (m^3/s^2), IS-GPS-200.
184        pub const GPS_GM_M3_S2: f64 = 3.986_005_0e14;
185        /// GPS/Galileo broadcast Earth rotation rate (rad/s).
186        pub const GPS_GALILEO_OMEGA_E_RAD_S: f64 = 7.292_115_146_7e-5;
187        /// GPS broadcast relativistic clock constant (s/sqrt(m)).
188        pub const GPS_DTR_F: f64 = -0.000_000_000_444_280_763_339_306;
189        /// Galileo broadcast gravitational constant (m^3/s^2).
190        pub const GALILEO_GM_M3_S2: f64 = 3.986_004_418e14;
191        /// Galileo/BeiDou broadcast relativistic clock constant (s/sqrt(m)).
192        pub const GALILEO_BEIDOU_DTR_F: f64 = -0.000_000_000_444_280_730_904_397_75;
193        /// BeiDou broadcast Earth rotation rate (rad/s).
194        pub const BEIDOU_OMEGA_E_RAD_S: f64 = 7.292_115e-5;
195    }
196}
197
198/// Canonical Earth gravity-model constants: the (mu, Re, J2) triple in km units,
199/// used together by the two-body + J2 force model. Geodetic code instead uses the
200/// WGS84 ellipsoid parameters (earth::WGS84_A_KM with WGS84_E2/WGS84_F); RE_EARTH
201/// and WGS84_A_KM share a numeric value but name distinct concepts (gravity
202/// reference radius vs ellipsoid semi-major axis).
203pub const MU_EARTH: f64 = earth::GM_EARTH_KM3_S2;
204/// Earth reference equatorial radius for the gravity model (km).
205pub const RE_EARTH: f64 = earth::WGS84_A_KM;
206/// Earth J2 zonal harmonic for the gravity model.
207pub const J2_EARTH: f64 = earth::J2_EARTH;
208/// Earth J3 zonal harmonic for the gravity model.
209pub const J3_EARTH: f64 = earth::J3_EARTH;
210/// Earth J4 zonal harmonic for the gravity model.
211pub const J4_EARTH: f64 = earth::J4_EARTH;
212/// Earth J5 zonal harmonic for the gravity model.
213pub const J5_EARTH: f64 = earth::J5_EARTH;
214/// Earth J6 zonal harmonic for the gravity model.
215pub const J6_EARTH: f64 = earth::J6_EARTH;