nyx_space/md/events/
evaluators.rs1use anise::prelude::Almanac;
20use hifitime::Duration;
21use snafu::ResultExt;
22use std::sync::Arc;
23
24use super::{Event, EventEvaluator};
25use crate::errors::{EventAlmanacSnafu, EventError, EventPhysicsSnafu, EventStateSnafu};
26use crate::md::StateParameter;
27use crate::utils::between_pm_x;
28use crate::{Spacecraft, State};
29
30pub(crate) fn angled_value(cur_angle: f64, desired_angle: f64) -> f64 {
31 if between_pm_x(cur_angle, desired_angle) > 0.0 {
32 cur_angle - desired_angle
33 } else {
34 cur_angle + 2.0 * desired_angle
35 }
36}
37
38impl EventEvaluator<Spacecraft> for Event {
39 fn eval(&self, state: &Spacecraft, almanac: Arc<Almanac>) -> Result<f64, EventError> {
40 let state = if let Some(frame) = self.obs_frame {
41 if state.orbit.frame == frame {
42 *state
43 } else {
44 state.with_orbit(
45 almanac
46 .transform_to(state.orbit, frame, None)
47 .context(EventAlmanacSnafu)?,
48 )
49 }
50 } else {
51 *state
52 };
53
54 match self.parameter {
56 StateParameter::Apoapsis => Ok(angled_value(
57 state.orbit.ta_deg().context(EventPhysicsSnafu)?,
58 180.0,
59 )),
60 StateParameter::Periapsis => Ok(between_pm_x(
61 state.orbit.ta_deg().context(EventPhysicsSnafu)?,
62 180.0,
63 )),
64 StateParameter::PropMass => Ok(state.mass.prop_mass_kg - self.desired_value),
65 _ => Ok(state.value(self.parameter).context(EventStateSnafu {
66 param: self.parameter,
67 })? - self.desired_value),
68 }
69 }
70
71 #[allow(clippy::identity_op)]
72 fn epoch_precision(&self) -> Duration {
73 1 * self.epoch_precision
74 }
75
76 fn value_precision(&self) -> f64 {
77 self.value_precision
78 }
79
80 fn eval_string(
81 &self,
82 state: &Spacecraft,
83 _almanac: Arc<Almanac>,
84 ) -> Result<String, EventError> {
85 match self.parameter {
86 StateParameter::Apoapsis | StateParameter::Periapsis => {
87 Ok(format!("{}", self.parameter))
88 }
89 _ => {
90 let unit = if self.parameter.unit().is_empty() {
91 String::new()
92 } else {
93 format!(" ({})", self.parameter.unit())
94 };
95 let val = state.value(self.parameter).context(EventStateSnafu {
96 param: self.parameter,
97 })?;
98
99 Ok(format!("{}{} = {:.3}{}", self.parameter, unit, val, unit))
100 }
101 }
102 }
103}