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;