pub const MU: f64 = 3.9860044e14;
pub const J2: f64 = 1.0826257e-3;
pub const OMEGA_E: f64 = 7.292115e-5;
pub const R_E: f64 = 6378136.0;
pub const TSTEP_S: f64 = 60.0;
const TOL_S: f64 = 1.0e-9;
pub(crate) fn deq(s: &[f64; 6], acc: &[f64; 3]) -> [f64; 6] {
let (x, y, z, vx, vy, vz) = (s[0], s[1], s[2], s[3], s[4], s[5]);
let r2 = x * x + y * y + z * z;
let r = r2.sqrt();
let r3 = r2 * r;
let a = 1.5 * J2 * MU * (R_E * R_E) / (r2 * r3);
let b = 5.0 * z * z / r2;
let c = -MU / r3 - a * (1.0 - b);
let omg2 = OMEGA_E * OMEGA_E;
let ax = (c + omg2) * x + 2.0 * OMEGA_E * vy + acc[0];
let ay = (c + omg2) * y - 2.0 * OMEGA_E * vx + acc[1];
let az = (c - 2.0 * a) * z + acc[2];
[vx, vy, vz, ax, ay, az]
}
#[allow(clippy::needless_range_loop)] pub(crate) fn glorbit(step: f64, s: &[f64; 6], acc: &[f64; 3]) -> [f64; 6] {
let k1 = deq(s, acc);
let mut w = [0.0_f64; 6];
for i in 0..6 {
w[i] = s[i] + k1[i] * step / 2.0;
}
let k2 = deq(&w, acc);
for i in 0..6 {
w[i] = s[i] + k2[i] * step / 2.0;
}
let k3 = deq(&w, acc);
for i in 0..6 {
w[i] = s[i] + k3[i] * step;
}
let k4 = deq(&w, acc);
let mut out = [0.0_f64; 6];
for i in 0..6 {
out[i] = s[i] + (k1[i] + 2.0 * k2[i] + 2.0 * k3[i] + k4[i]) * step / 6.0;
}
out
}
pub fn propagate(state0: [f64; 6], acc: [f64; 3], tk: f64) -> [f64; 6] {
let mut state = state0;
let mut tt = tk;
while tt.abs() > TOL_S {
let step = if tt.abs() < TSTEP_S {
tt
} else if tt > 0.0 {
TSTEP_S
} else {
-TSTEP_S
};
state = glorbit(step, &state, &acc);
tt -= step;
}
state
}
pub fn clock_offset_s(clk_bias: f64, gamma_n: f64, tk: f64) -> f64 {
let mut t = tk;
for _ in 0..2 {
t -= clk_bias + gamma_n * t;
}
clk_bias + gamma_n * t
}
#[cfg(test)]
mod tests;