Skip to content

Commit

Permalink
continue
Browse files Browse the repository at this point in the history
  • Loading branch information
robamu committed Nov 21, 2024
1 parent c5fa195 commit 9db7acf
Show file tree
Hide file tree
Showing 4 changed files with 422 additions and 51 deletions.
5 changes: 3 additions & 2 deletions satrs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,16 @@ pub mod pus;
pub mod queue;
pub mod request;
pub mod res_code;
pub mod time;
pub mod tmtc;
#[cfg(feature = "alloc")]
pub mod scheduling;
pub mod time;
pub mod tmtc;

pub mod action;
pub mod hk;
pub mod mode;
pub mod params;
pub mod subsystem;

pub use spacepackets;

Expand Down
159 changes: 152 additions & 7 deletions satrs/src/mode_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,168 @@ pub enum TableEntryType {
Sequence,
}

pub struct ModeTableEntry {
/// Common fields required for both target and sequence table entries.
///
/// The most important parameters here are the target ID which this entry belongs to, and the mode
/// and submode the entry either will be commanded to for sequence table entries or which will be
/// monitored for target table entries.
#[derive(Debug, Copy, Clone)]
pub struct ModeTableEntryCommon {
/// Name of respective table entry.
pub name: &'static str,
/// Target channel ID.
pub channel_id: ComponentId,
/// Target component ID.
pub target_id: ComponentId,
/// Has a different meaning depending on whether this is a sequence table or a target table.
///
/// - For sequence tables, this denotes the mode which will be commanded
/// - For target tables, this is the mode which the target children should have and which
/// might be monitored depending on configuration.
pub mode_submode: ModeAndSubmode,
/// This mask allows to specify multiple allowed submodes for a given mode.
pub allowed_submode_mask: Option<Submode>,
pub check_success: bool,
}

pub struct ModeTableMapValue {
impl ModeTableEntryCommon {
pub fn set_allowed_submode_mask(&mut self, mask: Submode) {
self.allowed_submode_mask = Some(mask);
}

pub fn allowed_submode_mask(&self) -> Option<Submode> {
self.allowed_submode_mask
}
}

/// An entry for the target tables.
#[derive(Debug)]
pub struct TargetTableEntry {
pub common: ModeTableEntryCommon,
pub monitor_state: bool,
}

impl TargetTableEntry {
pub fn new(
name: &'static str,
target_id: ComponentId,
mode_submode: ModeAndSubmode,
monitor_state: bool,
) -> Self {
Self {
common: ModeTableEntryCommon {
name,
target_id,
mode_submode,
allowed_submode_mask: None,
},
monitor_state,
}
}

delegate::delegate! {
to self.common {
pub fn set_allowed_submode_mask(&mut self, mask: Submode);
pub fn allowed_submode_mask(&self) -> Option<Submode>;
}
}
}

#[derive(Debug)]
pub struct TargetTableMapValue {
/// Name for a given mode table entry.
pub name: &'static str,
pub entries: Vec<ModeTableEntry>,
/// These are the rows of the a target table.
pub entries: Vec<TargetTableEntry>,
}

impl TargetTableMapValue {
pub fn new(name: &'static str) -> Self {
Self {
name,
entries: Default::default(),
}
}

pub fn add_entry(&mut self, entry: TargetTableEntry) {
self.entries.push(entry);
}
}

/// An entry for the sequence tables.
///
/// The `check_success` field instructs the mode sequence executor to verify that the
/// target mode was actually reached before executing the next sequence.
pub struct SequenceTableEntry {
pub common: ModeTableEntryCommon,
pub check_success: bool,
}

impl SequenceTableEntry {
pub fn new(
name: &'static str,
target_id: ComponentId,
mode_submode: ModeAndSubmode,
check_success: bool,
) -> Self {
Self {
common: ModeTableEntryCommon {
name,
target_id,
mode_submode,
allowed_submode_mask: None,
},
check_success,
}
}

delegate::delegate! {
to self.common {
pub fn set_allowed_submode_mask(&mut self, mask: Submode);
pub fn allowed_submode_mask(&self) -> Option<Submode>;
}
}
}

pub struct SequenceTableMapTable {
/// Name for a given mode sequence.
pub name: &'static str,
/// These are the rows of the a sequence table.
pub entries: Vec<SequenceTableEntry>,
}

impl SequenceTableMapTable {
pub fn new(name: &'static str) -> Self {
Self {
name,
entries: Default::default(),
}
}

pub fn add_entry(&mut self, entry: SequenceTableEntry) {
self.entries.push(entry);
}
}

pub struct SequenceTableMapValue {
/// Name for a given mode sequence.
pub name: &'static str,
/// Each sequence can consists of multiple sequences that are executed consecutively.
pub entries: Vec<SequenceTableMapTable>,
}

impl SequenceTableMapValue {
pub fn new(name: &'static str) -> Self {
Self {
name,
entries: Default::default(),
}
}

pub fn add_sequence_table(&mut self, entry: SequenceTableMapTable) {
self.entries.push(entry);
}
}

pub type ModeTable = HashMap<Mode, ModeTableMapValue>;
pub struct TargetModeTable(pub HashMap<Mode, TargetTableMapValue>);
pub struct SequenceModeTable(pub HashMap<Mode, SequenceTableMapValue>);

#[cfg(test)]
mod tests {}
134 changes: 134 additions & 0 deletions satrs/src/subsystem.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use crate::{
mode::{Mode, ModeAndSubmode, ModeRequest, ModeRequestSender},
mode_tree::{SequenceModeTable, SequenceTableMapTable, SequenceTableMapValue},
queue::GenericTargetedMessagingError,
request::RequestId,
ComponentId,
};

#[derive(Debug, PartialEq, Eq)]
pub enum SequenceExecutionHelperStates {
Idle,
AwaitingCheckSuccess,
Done,
}

#[derive(Debug)]
pub struct SequenceExecutionHelper {
target_mode: Mode,
state: SequenceExecutionHelperStates,
request_id: RequestId,
current_sequence_index: Option<usize>,
}

pub trait CheckSuccessProvider {
fn mode_request_requires_success_check(
&mut self,
target_id: ComponentId,
target_mode: ModeAndSubmode,
);
}

#[derive(Debug)]
pub enum SequenceHandlerResult {
SequenceDone,
SequenceStepDone,
AwaitingSuccessCheck,
}

impl SequenceExecutionHelper {
pub fn new(
mode: Mode,
request_id: RequestId,
sequence_table: &SequenceModeTable,
) -> Option<Self> {
if !sequence_table.0.contains_key(&mode) {
return None;
}
Some(Self {
target_mode: mode,
state: SequenceExecutionHelperStates::Idle,
request_id,
current_sequence_index: None,
})
}

pub fn confirm_sequence_done(&mut self) {
if let SequenceExecutionHelperStates::AwaitingCheckSuccess = self.state {
self.state = SequenceExecutionHelperStates::Idle;
}
}

pub fn run(
&mut self,
table: &SequenceModeTable,
sender: &impl ModeRequestSender,
) -> Result<SequenceHandlerResult, GenericTargetedMessagingError> {
if self.state == SequenceExecutionHelperStates::AwaitingCheckSuccess {
return Ok(SequenceHandlerResult::AwaitingSuccessCheck);
}
match self.current_sequence_index {
Some(idx) => {
// Execute the sequence.
let seq_table_value = table.0.get(&self.target_mode).unwrap();
self.execute_sequence_and_map_to_result(seq_table_value, idx, sender)
}
None => {
// Find the first sequence
let seq_table_value = table.0.get(&self.target_mode).unwrap();
if seq_table_value.entries.is_empty() {
Ok(SequenceHandlerResult::SequenceDone)
} else {
self.current_sequence_index = Some(0);
self.execute_sequence_and_map_to_result(seq_table_value, 0, sender)
}
}
}
}

pub fn execute_sequence_and_map_to_result(
&mut self,
seq_table_value: &SequenceTableMapValue,
sequence_idx: usize,
sender: &impl ModeRequestSender,
) -> Result<SequenceHandlerResult, GenericTargetedMessagingError> {
if Self::execute_sequence(
self.request_id,
&seq_table_value.entries[sequence_idx],
sender,
)? {
self.state = SequenceExecutionHelperStates::AwaitingCheckSuccess;
Ok(SequenceHandlerResult::AwaitingSuccessCheck)
} else if seq_table_value.entries.len() - 1 == sequence_idx {
return Ok(SequenceHandlerResult::SequenceDone);
} else {
self.current_sequence_index = Some(sequence_idx + 1);
return Ok(SequenceHandlerResult::SequenceStepDone);
}
}

pub fn execute_sequence(
request_id: RequestId,
map_table: &SequenceTableMapTable,
//sequence_idx: usize,
sender: &impl ModeRequestSender,
) -> Result<bool, GenericTargetedMessagingError> {
let mut some_succes_check_required = false;
for entry in &map_table.entries {
sender.send_mode_request(
request_id,
entry.common.target_id,
ModeRequest::SetMode(entry.common.mode_submode),
)?;
if entry.check_success {
some_succes_check_required = true;
}
}
Ok(some_succes_check_required)
}
}

#[cfg(test)]
mod tests {
pub struct SatSystem {}
}
Loading

0 comments on commit 9db7acf

Please sign in to comment.