use core::f64::consts::PI;
use crate::constants::C_M_S as C;
pub(crate) use crate::constants::F_L1_HZ as F_L1;
#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) struct KlobucharComponents {
pub psi: f64,
pub phi_i: f64,
pub lambda_i: f64,
pub phi_m: f64,
pub t: f64,
pub f: f64,
pub amp: f64,
pub per: f64,
pub x: f64,
pub t_iono: f64,
pub delay_l1_m: f64,
}
#[allow(clippy::manual_clamp)]
pub(crate) fn klobuchar_l1_components(
phi_u_deg: f64,
lambda_u_deg: f64,
azimuth_deg: f64,
elevation_deg: f64,
t_gps_s: f64,
alpha: [f64; 4],
beta: [f64; 4],
) -> KlobucharComponents {
let [a0, a1, a2, a3] = alpha;
let [b0, b1, b2, b3] = beta;
let phi_u = phi_u_deg / 180.0; let lambda_u = lambda_u_deg / 180.0; let a = azimuth_deg * PI / 180.0; let e = elevation_deg / 180.0;
let psi = 0.0137 / (e + 0.11) - 0.022;
let mut phi_i = phi_u + psi * a.cos();
if phi_i > 0.416 {
phi_i = 0.416;
}
if phi_i < -0.416 {
phi_i = -0.416;
}
let lambda_i = lambda_u + psi * a.sin() / (phi_i * PI).cos();
let phi_m = phi_i + 0.064 * ((lambda_i - 1.617) * PI).cos();
let mut t = 43200.0 * lambda_i + t_gps_s;
if t >= 86400.0 {
t -= 86400.0;
}
if t < 0.0 {
t += 86400.0;
}
let d = 0.53 - e;
let cube = d * d * d;
let f = 1.0 + 16.0 * cube;
let mut amp = a0 + phi_m * (a1 + phi_m * (a2 + phi_m * a3));
if amp < 0.0 {
amp = 0.0;
}
let mut per = b0 + phi_m * (b1 + phi_m * (b2 + phi_m * b3));
if per < 72000.0 {
per = 72000.0;
}
let x = 2.0 * PI * (t - 50400.0) / per;
let abs_x = if x < 0.0 { -x } else { x };
let t_iono = if abs_x < 1.57 {
let x2 = x * x;
let x4 = x2 * x2;
f * (5.0e-9 + amp * (1.0 - x2 / 2.0 + x4 / 24.0))
} else {
f * 5.0e-9
};
let delay_l1_m = C * t_iono;
KlobucharComponents {
psi,
phi_i,
lambda_i,
phi_m,
t,
f,
amp,
per,
x,
t_iono,
delay_l1_m,
}
}
#[cfg(test)]
mod tests;