From 17bd6fe71088011aabf440ec3192a18484b17587 Mon Sep 17 00:00:00 2001 From: AngusGMorrison Date: Tue, 2 Jan 2024 13:11:14 +0000 Subject: [PATCH] Calculate ERA using IAU 2000 --- crates/lox_core/src/earth.rs | 1 + crates/lox_core/src/earth/rotation_angle.rs | 56 +++++++++++++++++++++ crates/lox_core/src/time/intervals.rs | 2 + 3 files changed, 59 insertions(+) create mode 100644 crates/lox_core/src/earth/rotation_angle.rs diff --git a/crates/lox_core/src/earth.rs b/crates/lox_core/src/earth.rs index a429d4a0..f739fb1b 100644 --- a/crates/lox_core/src/earth.rs +++ b/crates/lox_core/src/earth.rs @@ -13,3 +13,4 @@ mod cio; mod cip; mod coordinate_transformations; mod nutation; +mod rotation_angle; diff --git a/crates/lox_core/src/earth/rotation_angle.rs b/crates/lox_core/src/earth/rotation_angle.rs new file mode 100644 index 00000000..cbd1eefa --- /dev/null +++ b/crates/lox_core/src/earth/rotation_angle.rs @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +//! Module rotation_angle exposes functions for calculating the Earth Rotation Angle (ERA). + +use crate::bodies::Earth; +use crate::time::intervals::UT1DaysSinceJ2000; +use crate::types::Radians; +use std::f64::consts::TAU; + +impl Earth { + /// Computes the Earth Rotation Angle (ERA) in radians using the IAU 2000 model. + pub fn rotation_angle_00(t: UT1DaysSinceJ2000) -> Radians { + let f = t.rem_euclid(1.0); // fractional part of t + TAU * (f + 0.7790572732640 + 0.00273781191135448 * t) % TAU + } +} + +#[cfg(test)] +mod tests { + use super::*; + use float_eq::assert_float_eq; + + #[test] + fn test_rotation_angle_00() { + struct TestCase { + t: UT1DaysSinceJ2000, + expected: Radians, + } + + [ + TestCase { + t: -123.45, + expected: 6.227104062035152, + }, + TestCase { + t: 0.0, + expected: 4.894961212823756, + }, + TestCase { + t: 123.45, + expected: 3.562818363612361, + }, + ] + .iter() + .for_each(|tc| { + let actual = Earth::rotation_angle_00(tc.t); + assert_float_eq!(tc.expected, actual, rel <= 1e-9); + }); + } +} diff --git a/crates/lox_core/src/time/intervals.rs b/crates/lox_core/src/time/intervals.rs index dd9c6d6c..ae3817eb 100644 --- a/crates/lox_core/src/time/intervals.rs +++ b/crates/lox_core/src/time/intervals.rs @@ -13,6 +13,8 @@ pub fn tdb_julian_centuries_since_j2000(epoch: Epoch) -> TDBJulianCenturiesSince } } +pub type UT1DaysSinceJ2000 = f64; + #[cfg(test)] mod epoch_tests { use float_eq::assert_float_eq;