melvin_ob/scheduling/task/base_task.rs
1use super::{
2 image_task::ImageTask,
3 switch_state_task::SwitchStateTask,
4 vel_change_task::VelocityChangeTask,
5};
6use crate::fatal;
7use crate::imaging::CameraAngle;
8use crate::util::Vec2D;
9use crate::flight_control::{FlightState, orbit::BurnSequence};
10use chrono::{DateTime, Utc};
11use std::fmt::{Display, Formatter};
12use strum_macros::Display;
13
14/// Represents a task with a specific type and associated time delay.
15/// Tasks can include image capture, state switching, or velocity changes.
16#[derive(Debug)]
17pub struct Task {
18 /// The specific type of the task.
19 task_type: BaseTask,
20 /// The pinned time delay associated with the task's execution.
21 t: DateTime<Utc>,
22}
23
24/// An enumeration representing different types of tasks.
25///
26/// It includes tasks for image capturing (`TakeImage`),
27/// switching flight states (`SwitchState`), and velocity changes (`ChangeVelocity`).
28#[derive(Display, Debug)]
29pub enum BaseTask {
30 /// Task to capture an image.
31 TakeImage(ImageTask),
32 /// Task to switch to a different flight state.
33 SwitchState(SwitchStateTask),
34 /// Task to change the velocity, represented by a burn sequence.
35 ChangeVelocity(VelocityChangeTask),
36}
37
38impl Display for Task {
39 /// Formats the task for display purposes.
40 ///
41 /// The formatted output includes the due time and the task's type.
42 /// For some task types, additional details are provided based on the task data.
43 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
44 let task_type_str = match &self.task_type {
45 BaseTask::TakeImage(_) => "Image Task",
46 BaseTask::SwitchState(task) => &*format!("Switch to {}", task.target_state()),
47 BaseTask::ChangeVelocity(task) => {
48 let res_vel = task.burn().sequence_vel().last().unwrap();
49 let res_pos = task.burn().sequence_pos().last().unwrap();
50 let angle_dev = task.burn().rem_angle_dev();
51 &*format!(
52 "Burn to velocity {res_vel} at pos {res_pos}, \
53 angle deviation will be {angle_dev}",
54 )
55 }
56 };
57 let end = self.t.format("%d %H:%M:%S").to_string();
58 write!(f, "Due: {end}, Task: {task_type_str}")
59 }
60}
61
62impl Task {
63 /// Creates a new task for switching to a target flight state.
64 ///
65 /// # Arguments
66 /// - `target_state`: The desired flight state to switch to.
67 /// - `t`: The time delay associated with the task's execution.
68 ///
69 /// # Returns
70 /// - A new [`Task`] instance representing the state switch task.
71 ///
72 /// # Panics
73 /// Panics if the provided `target_state` is invalid for switching.
74 pub fn switch_target(target_state: FlightState, t: DateTime<Utc>) -> Self {
75 Self {
76 task_type: BaseTask::SwitchState(
77 SwitchStateTask::new(target_state)
78 .unwrap_or_else(|| fatal!("Tried to schedule invalid state switch")),
79 ),
80 t,
81 }
82 }
83
84 /// Creates a new task for image capture.
85 ///
86 /// # Arguments
87 /// - `planned_pos`: The target position for capturing the image.
88 /// - `lens`: The camera lens configuration.
89 /// - `t`: The time delay associated with the task's execution.
90 ///
91 /// # Returns
92 /// - A new `Task` instance representing the image capture task.
93 pub fn image_task(planned_pos: Vec2D<u32>, lens: CameraAngle, t: DateTime<Utc>) -> Self {
94 Self { task_type: BaseTask::TakeImage(ImageTask::new(planned_pos, lens)), t }
95 }
96
97 /// Creates a new task for velocity change.
98 ///
99 /// # Arguments
100 /// - `burn`: The burn sequence for orbital adjustments.
101 /// - `t`: The time delay associated with the task's execution.
102 ///
103 /// # Returns
104 /// - A new `Task` instance representing the velocity change task.
105 pub fn vel_change_task(
106 burn: BurnSequence,
107 t: DateTime<Utc>,
108 ) -> Self {
109 Self { task_type: BaseTask::ChangeVelocity(VelocityChangeTask::new(burn)), t }
110 }
111 /// Returns an immutable reference to the task's time delay.
112 ///
113 /// # Returns
114 /// - An `DateTime<Utc>` representing the tasks due time.
115 pub fn t(&self) -> DateTime<Utc> { self.t }
116
117 /// Returns an immutable reference to the task's type.
118 ///
119 /// # Returns
120 /// - An immutable reference to the `BaseTask`.
121 pub fn task_type(&self) -> &BaseTask { &self.task_type }
122}