use nalgebra::Vector3;
use crate::math::{SMatrix3, SVector6};
use crate::time::Epoch;
use super::gcrf_itrf::{
position_gcrf_to_itrf, position_itrf_to_gcrf, rotation_gcrf_to_itrf, rotation_itrf_to_gcrf,
state_gcrf_to_itrf, state_itrf_to_gcrf,
};
pub fn rotation_eci_to_ecef(epc: Epoch) -> SMatrix3 {
rotation_gcrf_to_itrf(epc)
}
pub fn rotation_ecef_to_eci(epc: Epoch) -> SMatrix3 {
rotation_itrf_to_gcrf(epc)
}
pub fn position_eci_to_ecef(epc: Epoch, x: Vector3<f64>) -> Vector3<f64> {
position_gcrf_to_itrf(epc, x)
}
pub fn position_ecef_to_eci(epc: Epoch, x: Vector3<f64>) -> Vector3<f64> {
position_itrf_to_gcrf(epc, x)
}
pub fn state_eci_to_ecef(epc: Epoch, x_eci: SVector6) -> SVector6 {
state_gcrf_to_itrf(epc, x_eci)
}
pub fn state_ecef_to_eci(epc: Epoch, x_ecef: SVector6) -> SVector6 {
state_itrf_to_gcrf(epc, x_ecef)
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use approx::assert_abs_diff_eq;
use nalgebra::Vector3;
use serial_test::serial;
use crate::constants::{DEGREES, R_EARTH};
use crate::coordinates::state_koe_to_eci;
use crate::frames::*;
use crate::math::vector6_from_array;
use crate::time::{Epoch, TimeSystem};
use crate::utils::testing::setup_global_test_eop;
#[test]
#[serial]
#[allow(non_snake_case)]
fn test_rotation_eci_to_ecef() {
use crate::constants::AS2RAD;
use crate::eop::{StaticEOPProvider, set_global_eop_provider};
use crate::time::TimeSystem;
let pm_x = 0.0349282 * AS2RAD;
let pm_y = 0.4833163 * AS2RAD;
let ut1_utc = -0.072073685;
let dX = 0.0001750 * AS2RAD * 1.0e-3;
let dY = -0.0002259 * AS2RAD * 1.0e-3;
let eop = StaticEOPProvider::from_values((pm_x, pm_y, ut1_utc, dX, dY, 0.0));
set_global_eop_provider(eop);
let epc = Epoch::from_datetime(2007, 4, 5, 12, 0, 0.0, 0.0, TimeSystem::UTC);
let r = rotation_eci_to_ecef(epc);
let tol = 1.0e-8;
assert_abs_diff_eq!(r[(0, 0)], 0.973104317697535, epsilon = tol);
assert_abs_diff_eq!(r[(0, 1)], 0.230363826239128, epsilon = tol);
assert_abs_diff_eq!(r[(0, 2)], -0.000703163482198, epsilon = tol);
assert_abs_diff_eq!(r[(1, 0)], -0.230363800456037, epsilon = tol);
assert_abs_diff_eq!(r[(1, 1)], 0.973104570632801, epsilon = tol);
assert_abs_diff_eq!(r[(1, 2)], 0.000118545366625, epsilon = tol);
assert_abs_diff_eq!(r[(2, 0)], 0.000711560162668, epsilon = tol);
assert_abs_diff_eq!(r[(2, 1)], 0.000046626403995, epsilon = tol);
assert_abs_diff_eq!(r[(2, 2)], 0.999999745754024, epsilon = tol);
}
#[test]
#[serial]
#[allow(non_snake_case)]
fn test_rotation_ecef_to_eci() {
use crate::constants::AS2RAD;
use crate::eop::{StaticEOPProvider, set_global_eop_provider};
use crate::time::TimeSystem;
let pm_x = 0.0349282 * AS2RAD;
let pm_y = 0.4833163 * AS2RAD;
let ut1_utc = -0.072073685;
let dX = 0.0001750 * AS2RAD * 1.0e-3;
let dY = -0.0002259 * AS2RAD * 1.0e-3;
let eop = StaticEOPProvider::from_values((pm_x, pm_y, ut1_utc, dX, dY, 0.0));
set_global_eop_provider(eop);
let epc = Epoch::from_datetime(2007, 4, 5, 12, 0, 0.0, 0.0, TimeSystem::UTC);
let r = rotation_ecef_to_eci(epc);
let tol = 1.0e-8;
assert_abs_diff_eq!(r[(0, 0)], 0.973104317697535, epsilon = tol);
assert_abs_diff_eq!(r[(0, 1)], -0.230363800456037, epsilon = tol);
assert_abs_diff_eq!(r[(0, 2)], 0.000711560162668, epsilon = tol);
assert_abs_diff_eq!(r[(1, 0)], 0.230363826239128, epsilon = tol);
assert_abs_diff_eq!(r[(1, 1)], 0.973104570632801, epsilon = tol);
assert_abs_diff_eq!(r[(1, 2)], 0.000046626403995, epsilon = tol);
assert_abs_diff_eq!(r[(2, 0)], -0.000703163482198, epsilon = tol);
assert_abs_diff_eq!(r[(2, 1)], 0.000118545366625, epsilon = tol);
assert_abs_diff_eq!(r[(2, 2)], 0.999999745754024, epsilon = tol);
}
#[test]
#[serial]
fn test_position_eci_to_ecef() {
setup_global_test_eop();
let epc = Epoch::from_datetime(2022, 4, 5, 0, 0, 0.0, 0.0, TimeSystem::UTC);
let p_eci = Vector3::new(R_EARTH + 500e3, 0.0, 0.0);
let p_ecef = position_eci_to_ecef(epc, p_eci);
assert_ne!(p_eci[0], p_ecef[0]);
assert_ne!(p_eci[1], p_ecef[1]);
assert_ne!(p_eci[2], p_ecef[2]);
}
#[test]
#[serial]
fn test_position_ecef_to_eci() {
setup_global_test_eop();
let epc = Epoch::from_datetime(2022, 4, 5, 0, 0, 0.0, 0.0, TimeSystem::UTC);
let p_ecef = Vector3::new(R_EARTH + 500e3, 0.0, 0.0);
let p_eci = position_ecef_to_eci(epc, p_ecef);
assert_ne!(p_eci[0], p_ecef[0]);
assert_ne!(p_eci[1], p_ecef[1]);
assert_ne!(p_eci[2], p_ecef[2]);
}
#[test]
#[serial]
fn test_state_eci_to_ecef_circular() {
setup_global_test_eop();
let epc = Epoch::from_datetime(2022, 4, 5, 0, 0, 0.0, 0.0, TimeSystem::UTC);
let oe = vector6_from_array([R_EARTH + 500e3, 1e-3, 97.8, 75.0, 25.0, 45.0]);
let eci = state_koe_to_eci(oe, DEGREES);
let ecef = state_eci_to_ecef(epc, eci);
let eci2 = state_ecef_to_eci(epc, ecef);
let ecef2 = state_eci_to_ecef(epc, eci2);
let tol = 1e-6;
assert_abs_diff_eq!(eci2[0], eci[0], epsilon = tol);
assert_abs_diff_eq!(eci2[1], eci[1], epsilon = tol);
assert_abs_diff_eq!(eci2[2], eci[2], epsilon = tol);
assert_abs_diff_eq!(eci2[3], eci[3], epsilon = tol);
assert_abs_diff_eq!(eci2[4], eci[4], epsilon = tol);
assert_abs_diff_eq!(eci2[5], eci[5], epsilon = tol);
assert_abs_diff_eq!(ecef2[0], ecef[0], epsilon = tol);
assert_abs_diff_eq!(ecef2[1], ecef[1], epsilon = tol);
assert_abs_diff_eq!(ecef2[2], ecef[2], epsilon = tol);
assert_abs_diff_eq!(ecef2[3], ecef[3], epsilon = tol);
assert_abs_diff_eq!(ecef2[4], ecef[4], epsilon = tol);
assert_abs_diff_eq!(ecef2[5], ecef[5], epsilon = tol);
}
#[test]
#[serial]
fn test_eci_ecef_gcrf_itrf_equivalence() {
setup_global_test_eop();
let epc = Epoch::from_datetime(2022, 4, 5, 0, 0, 0.0, 0.0, TimeSystem::UTC);
let oe = vector6_from_array([R_EARTH + 500e3, 1e-3, 97.8, 75.0, 25.0, 45.0]);
let eci = state_koe_to_eci(oe, DEGREES);
let ecef = state_eci_to_ecef(epc, eci);
let itrf = state_gcrf_to_itrf(epc, eci);
let eci2 = state_ecef_to_eci(epc, ecef);
let gcrf = state_itrf_to_gcrf(epc, itrf);
let tol = 1e-6;
assert_abs_diff_eq!(ecef[0], itrf[0], epsilon = tol);
assert_abs_diff_eq!(ecef[1], itrf[1], epsilon = tol);
assert_abs_diff_eq!(ecef[2], itrf[2], epsilon = tol);
assert_abs_diff_eq!(ecef[3], itrf[3], epsilon = tol);
assert_abs_diff_eq!(ecef[4], itrf[4], epsilon = tol);
assert_abs_diff_eq!(ecef[5], itrf[5], epsilon = tol);
assert_abs_diff_eq!(gcrf[0], eci2[0], epsilon = tol);
assert_abs_diff_eq!(gcrf[1], eci2[1], epsilon = tol);
assert_abs_diff_eq!(gcrf[2], eci2[2], epsilon = tol);
assert_abs_diff_eq!(gcrf[3], eci2[3], epsilon = tol);
assert_abs_diff_eq!(gcrf[4], eci2[4], epsilon = tol);
assert_abs_diff_eq!(gcrf[5], eci2[5], epsilon = tol);
}
}