#[derive(Debug, Clone)]
pub struct MissionElapsedTime {
pub epoch_offset: f64,
pub seconds: f64,
pub hold: bool,
was_held: bool,
held_at_parent: f64,
}
impl MissionElapsedTime {
pub fn new(parent_seconds_at_epoch: f64) -> Self {
Self {
epoch_offset: parent_seconds_at_epoch,
seconds: 0.0,
hold: false,
was_held: false,
held_at_parent: 0.0,
}
}
pub fn update(&mut self, parent_seconds: f64) {
if self.hold {
if !self.was_held {
self.was_held = true;
self.held_at_parent = parent_seconds;
}
} else if self.was_held {
let hold_duration = parent_seconds - self.held_at_parent;
self.epoch_offset += hold_duration;
self.was_held = false;
self.seconds = parent_seconds - self.epoch_offset;
} else {
self.seconds = parent_seconds - self.epoch_offset;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn met_basic() {
let mut met = MissionElapsedTime::new(1000.0);
assert_eq!(met.seconds, 0.0);
met.update(1100.0);
assert!((met.seconds - 100.0).abs() < 1e-15);
met.update(2000.0);
assert!((met.seconds - 1000.0).abs() < 1e-15);
}
#[test]
fn met_hold_and_release() {
let mut met = MissionElapsedTime::new(0.0);
met.update(100.0);
assert!((met.seconds - 100.0).abs() < 1e-15);
met.hold = true;
met.update(100.0); let frozen = met.seconds;
met.update(200.0); assert_eq!(met.seconds, frozen);
met.hold = false;
met.update(200.0);
assert!(
(met.seconds - 100.0).abs() < 1e-15,
"After hold release, MET should be 100, got {}",
met.seconds
);
met.update(300.0);
assert!(
(met.seconds - 200.0).abs() < 1e-15,
"After 100 more parent seconds, MET should be 200, got {}",
met.seconds
);
}
#[test]
fn met_from_nonzero_epoch() {
let mut met = MissionElapsedTime::new(5000.0);
met.update(5000.0);
assert!(met.seconds.abs() < 1e-15);
met.update(5060.0);
assert!((met.seconds - 60.0).abs() < 1e-15);
}
}