use crate::prelude::{Epoch, SP3, SV};
use anise::{
astro::AzElRange,
math::Vector6,
prelude::{Almanac, Frame, Orbit},
};
#[cfg(feature = "anise")]
#[cfg_attr(docsrs, doc(cfg(feature = "anise")))]
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct SatelliteOrbitalState {
pub epoch: Epoch,
pub satellite: SV,
pub orbit: Orbit,
pub maneuver: bool,
}
#[cfg(feature = "anise")]
#[cfg_attr(docsrs, doc(cfg(feature = "anise")))]
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct SatelliteOrbitalAttitude {
pub satellite: SV,
pub maneuver: bool,
pub azelrange: AzElRange,
}
impl SP3 {
#[cfg(feature = "anise")]
#[cfg_attr(docsrs, doc(cfg(feature = "anise")))]
pub fn satellites_orbit_iter(
&self,
frame: Frame,
) -> Box<dyn Iterator<Item = SatelliteOrbitalState> + '_> {
Box::new(self.data.iter().filter_map(move |(k, v)| {
let (x_km, y_km, z_km) = v.position_km;
let (vx_km_s, vy_km_s, vz_km_s) = match v.velocity_km_s {
Some((vx_km_s, vy_km_s, vz_km_s)) => (vx_km_s, vy_km_s, vz_km_s),
None => (0.0, 0.0, 0.0),
};
let pos_vel = Vector6::new(x_km, y_km, z_km, vx_km_s, vy_km_s, vz_km_s);
let orbit = Orbit::from_cartesian_pos_vel(pos_vel, k.epoch, frame);
Some(SatelliteOrbitalState {
orbit,
epoch: k.epoch,
satellite: k.sv,
maneuver: v.maneuver,
})
}))
}
#[cfg(feature = "anise")]
#[cfg_attr(docsrs, doc(cfg(feature = "anise")))]
pub fn satellites_attitude_iter(
&self,
almanac: Almanac,
frame: Frame,
rx_orbit: Orbit,
) -> Box<dyn Iterator<Item = SatelliteOrbitalAttitude> + '_> {
Box::new(self.satellites_orbit_iter(frame).filter_map(move |state| {
if let Ok(azelrange) =
almanac.azimuth_elevation_range_sez(rx_orbit, state.orbit, None, None)
{
Some(SatelliteOrbitalAttitude {
azelrange,
maneuver: state.maneuver,
satellite: state.satellite,
})
} else {
None
}
}))
}
}