melvin_ob/flight_control/
flight_state.rs1use crate::{DT_0, fatal};
2use chrono::TimeDelta;
3use fixed::types::I32F32;
4use num::Zero;
5use std::{collections::HashMap, sync::LazyLock, time::Duration};
6use strum_macros::Display;
7
8#[derive(Debug, Display, PartialEq, Eq, Clone, Copy, Hash)]
22pub enum FlightState {
23 Charge = 0,
24 Acquisition = 1,
25 Deployment,
26 Transition,
27 Comms,
28 Safe,
29}
30
31impl FlightState {
32 pub const ACQ_ACC_ADDITION: I32F32 = I32F32::lit("-0.05");
34
35 pub fn get_charge_rate(self) -> I32F32 {
44 match self {
45 FlightState::Deployment => I32F32::lit("-0.025"),
46 FlightState::Transition => I32F32::zero(),
47 FlightState::Acquisition => I32F32::lit("-0.1"),
48 FlightState::Charge => I32F32::lit("0.1"),
49 FlightState::Comms => I32F32::lit("-0.008"),
50 FlightState::Safe => I32F32::lit("0.025"),
51 }
52 }
53
54 pub fn from_dp_usize(i: usize) -> Self {
56 match i {
57 1 => FlightState::Acquisition,
58 0 => FlightState::Charge,
59 _ => panic!("Invalid state"),
60 }
61 }
62
63 pub fn to_dp_usize(self) -> usize {
65 match self {
66 FlightState::Charge => 0,
67 FlightState::Acquisition => 1,
68 FlightState::Comms => 2,
69 _ => panic!("Invalid state"),
70 }
71 }
72
73 pub fn dt_to(self, other: Self) -> Duration {
75 *TRANS_DEL
76 .get(&(self, other))
77 .unwrap_or_else(|| fatal!("({self}, {other}) not in TRANSITION_DELAY_LOOKUP"))
78 }
79
80 pub fn td_dt_to(self, other: Self) -> TimeDelta {
81 TimeDelta::from_std(*TRANS_DEL.get(&(self, other)).unwrap_or_else(|| {
82 fatal!("({self}, {other}) not in TRANSITION_DELAY_LOOKUP")
83 }))
84 .unwrap_or(DT_0)
85 }
86}
87
88impl From<&str> for FlightState {
89 fn from(value: &str) -> Self {
99 match value.to_lowercase().as_str() {
100 "deployment" => FlightState::Deployment,
101 "transition" => FlightState::Transition,
102 "acquisition" => FlightState::Acquisition,
103 "charge" => FlightState::Charge,
104 "communication" => FlightState::Comms,
105 "safe" => FlightState::Safe,
106 _ => panic!("Couldn't convert flight_state string"),
107 }
108 }
109}
110
111impl From<FlightState> for &'static str {
112 fn from(value: FlightState) -> Self {
121 match value {
122 FlightState::Deployment => "deployment",
123 FlightState::Transition => "transition",
124 FlightState::Acquisition => "acquisition",
125 FlightState::Charge => "charge",
126 FlightState::Comms => "communication",
127 FlightState::Safe => "safe",
128 }
129 }
130}
131
132static TRANS_DEL: LazyLock<HashMap<(FlightState, FlightState), Duration>> = LazyLock::new(|| {
137 let mut lookup = HashMap::new();
138 let transition_times = vec![
139 (
141 FlightState::Deployment,
142 FlightState::Acquisition,
143 Duration::from_secs(180),
144 ),
145 (
146 FlightState::Deployment,
147 FlightState::Charge,
148 Duration::from_secs(180),
149 ),
150 (
151 FlightState::Deployment,
152 FlightState::Comms,
153 Duration::from_secs(180),
154 ),
155 (
157 FlightState::Acquisition,
158 FlightState::Deployment,
159 Duration::from_secs(180),
160 ),
161 (
162 FlightState::Acquisition,
163 FlightState::Charge,
164 Duration::from_secs(180),
165 ),
166 (
167 FlightState::Acquisition,
168 FlightState::Comms,
169 Duration::from_secs(180),
170 ),
171 (
173 FlightState::Charge,
174 FlightState::Deployment,
175 Duration::from_secs(180),
176 ),
177 (
178 FlightState::Charge,
179 FlightState::Acquisition,
180 Duration::from_secs(180),
181 ),
182 (
183 FlightState::Charge,
184 FlightState::Comms,
185 Duration::from_secs(180),
186 ),
187 (
189 FlightState::Comms,
190 FlightState::Deployment,
191 Duration::from_secs(180),
192 ),
193 (
194 FlightState::Comms,
195 FlightState::Acquisition,
196 Duration::from_secs(180),
197 ),
198 (
199 FlightState::Comms,
200 FlightState::Charge,
201 Duration::from_secs(180),
202 ),
203 (
205 FlightState::Safe,
206 FlightState::Deployment,
207 Duration::from_secs(1200),
208 ),
209 (
210 FlightState::Safe,
211 FlightState::Acquisition,
212 Duration::from_secs(1200),
213 ),
214 (
215 FlightState::Safe,
216 FlightState::Charge,
217 Duration::from_secs(1200),
218 ),
219 ];
220
221 for (from, to, duration) in transition_times {
222 lookup.insert((from, to), duration);
223 }
224 lookup
225});