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}