From 5a2a070c481747347556bd57f1914ce7bd81ebc3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 12 May 2026 13:01:23 +0200 Subject: [PATCH] continue with subsystem --- satrs-example/client/src/main.rs | 6 +-- satrs-example/models/src/acs/ctrl.rs | 24 ++++++++- satrs-example/models/src/acs/mgm_assembly.rs | 18 +++---- satrs-example/models/src/acs/mgt.rs | 24 ++++++++- satrs-example/src/acs/mgm_assembly.rs | 52 ++++++++++---------- satrs-example/src/acs/subsystem.rs | 49 +++++++++++++----- 6 files changed, 120 insertions(+), 53 deletions(-) diff --git a/satrs-example/client/src/main.rs b/satrs-example/client/src/main.rs index 2820e61..178ead2 100644 --- a/satrs-example/client/src/main.rs +++ b/satrs-example/client/src/main.rs @@ -207,13 +207,13 @@ fn main() -> anyhow::Result<()> { if let Some(mode) = mgm_assembly_args.mode { let assembly_mode = match mode { AssemblyModeSelect::NoModeKeeping => { - models::acs::mgm_assembly::AssemblyMode::NoModeKeeping + models::acs::mgm_assembly::Mode::NoModeKeeping } AssemblyModeSelect::Off => { - models::acs::mgm_assembly::AssemblyMode::Device(models::DeviceMode::Off) + models::acs::mgm_assembly::Mode::Device(models::DeviceMode::Off) } AssemblyModeSelect::Normal => { - models::acs::mgm_assembly::AssemblyMode::Device( + models::acs::mgm_assembly::Mode::Device( models::DeviceMode::Normal, ) } diff --git a/satrs-example/models/src/acs/ctrl.rs b/satrs-example/models/src/acs/ctrl.rs index b13f7e7..9b901cb 100644 --- a/satrs-example/models/src/acs/ctrl.rs +++ b/satrs-example/models/src/acs/ctrl.rs @@ -1,6 +1,28 @@ #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq)] -pub enum ControllerMode { +pub enum Mode { Passive, Safe, Idle, } + +pub mod request { + use super::Mode; + + #[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] + pub enum ModeRequest { + SetMode(Mode), + ReadMode, + } +} + +pub mod response { + use super::Mode; + + #[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] + pub enum ModeReport { + /// Mode of the assembly. + Mode(super::Mode), + /// Children are in wrong mode after commanding. + WrongMode([Option; 2]), + } +} diff --git a/satrs-example/models/src/acs/mgm_assembly.rs b/satrs-example/models/src/acs/mgm_assembly.rs index a37293e..f96fd06 100644 --- a/satrs-example/models/src/acs/mgm_assembly.rs +++ b/satrs-example/models/src/acs/mgm_assembly.rs @@ -3,7 +3,7 @@ use core::str::FromStr; use crate::DeviceMode; #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq)] -pub enum AssemblyMode { +pub enum Mode { /// The assembly mode ressembles the modes of the devices it controls. It also tries to keep /// the children in the correct mode by re-commanding them into the correct mode. Device(DeviceMode), @@ -11,22 +11,22 @@ pub enum AssemblyMode { NoModeKeeping, } -impl FromStr for AssemblyMode { +impl FromStr for Mode { type Err = (); fn from_str(s: &str) -> Result { match s.to_lowercase().as_str() { - "off" => Ok(AssemblyMode::Device(DeviceMode::Off)), - "on" => Ok(AssemblyMode::Device(DeviceMode::On)), - "normal" => Ok(AssemblyMode::Device(DeviceMode::Normal)), - "no_mode_keeping" => Ok(AssemblyMode::NoModeKeeping), + "off" => Ok(Mode::Device(DeviceMode::Off)), + "on" => Ok(Mode::Device(DeviceMode::On)), + "normal" => Ok(Mode::Device(DeviceMode::Normal)), + "no_mode_keeping" => Ok(Mode::NoModeKeeping), _ => Err(()), } } } pub mod request { - use crate::{HkRequestType, Message, acs::mgm_assembly::AssemblyMode}; + use crate::{HkRequestType, Message, acs::mgm_assembly::Mode}; #[derive(Debug, PartialEq, Eq, Clone, Copy, serde::Serialize, serde::Deserialize)] pub enum HkId { @@ -35,7 +35,7 @@ pub mod request { #[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub enum ModeRequest { - SetMode(AssemblyMode), + SetMode(Mode), ReadMode, } @@ -77,7 +77,7 @@ pub mod response { #[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub enum ModeReport { /// Mode of the assembly. - Mode(super::AssemblyMode), + Mode(super::Mode), /// Timeout failure setting the children modes. SetModeTimeout([Option; 2]), /// Children are in wrong mode after commanding. diff --git a/satrs-example/models/src/acs/mgt.rs b/satrs-example/models/src/acs/mgt.rs index d15750b..1450214 100644 --- a/satrs-example/models/src/acs/mgt.rs +++ b/satrs-example/models/src/acs/mgt.rs @@ -1,5 +1,27 @@ #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq)] -pub enum MgtMode { +pub enum Mode { Off, Normal, } + +pub mod request { + use super::*; + + #[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] + pub enum ModeRequest { + SetMode(Mode), + ReadMode, + } +} + +pub mod response { + use super::*; + + #[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] + pub enum ModeReport { + /// Mode of the assembly. + Mode(super::Mode), + /// Children are in wrong mode after commanding. + WrongMode([Option; 2]), + } +} diff --git a/satrs-example/src/acs/mgm_assembly.rs b/satrs-example/src/acs/mgm_assembly.rs index fd63547..ebea489 100644 --- a/satrs-example/src/acs/mgm_assembly.rs +++ b/satrs-example/src/acs/mgm_assembly.rs @@ -2,7 +2,7 @@ use std::{sync::mpsc, time::Duration}; use models::{ ComponentId, DeviceMode, - acs::mgm_assembly::{AssemblyMode, request, response}, + acs::mgm_assembly::{Mode, request, response}, }; use satrs::spacepackets::CcsdsPacketIdAndPsc; use satrs_example::{ModeHelper, TmtcQueues}; @@ -35,7 +35,7 @@ pub struct MgmInfo { /// MGM assembly component. pub struct Assembly { - mode_helper: ModeHelper, + mode_helper: ModeHelper, /// This boolean is used for the distinction between transitions commanded by the parent /// or by ground, and transitions which were commanded autonomously as part of children /// mode keeping. @@ -56,7 +56,7 @@ impl Assembly { mode_timeout: Duration, ) -> Self { Self { - mode_helper: ModeHelper::new(AssemblyMode::NoModeKeeping, mode_timeout), + mode_helper: ModeHelper::new(Mode::NoModeKeeping, mode_timeout), mode_keeping_transition: false, tmtc_queues, mgm_modes: [MgmInfo::default(); 2], @@ -136,11 +136,11 @@ impl Assembly { match self.parent_queues.request_rx.try_recv() { Ok(request) => match request { request::ModeRequest::SetMode(assembly_mode) => match assembly_mode { - AssemblyMode::Device(_device_mode) => { + Mode::Device(_device_mode) => { self.start_transition(false, assembly_mode, None); } - AssemblyMode::NoModeKeeping => { - self.mode_helper.current = AssemblyMode::NoModeKeeping; + Mode::NoModeKeeping => { + self.mode_helper.current = Mode::NoModeKeeping; } }, request::ModeRequest::ReadMode => self @@ -191,7 +191,7 @@ impl Assembly { // Transition is active, check for completion. if self.mode_helper.transition_active() && self.mgm_modes.iter().all(|i| i.reply_received) - && let AssemblyMode::Device(device_mode) = self.mode_helper.target.unwrap() + && let Mode::Device(device_mode) = self.mode_helper.target.unwrap() { // If at least one child reached the correct mode, we are done. if self.mgm_modes.iter().any(|i| i.mode == Some(device_mode)) { @@ -207,7 +207,7 @@ impl Assembly { } // Mode keeping active: Check children modes. - if let AssemblyMode::Device(device_mode) = self.mode_helper.current + if let Mode::Device(device_mode) = self.mode_helper.current && self .mgm_modes .iter() @@ -226,8 +226,8 @@ impl Assembly { } let target = self.mode_helper.target.unwrap(); let device_mode = match target { - AssemblyMode::Device(device_mode) => device_mode, - AssemblyMode::NoModeKeeping => { + Mode::Device(device_mode) => device_mode, + Mode::NoModeKeeping => { self.handle_mode_reached(true); return; } @@ -283,7 +283,7 @@ impl Assembly { pub fn start_transition( &mut self, mode_keeping: bool, - target: AssemblyMode, + target: Mode, tc_id: Option, ) { self.mode_keeping_transition = mode_keeping; @@ -304,7 +304,7 @@ impl Assembly { } #[inline] - pub fn mode(&self) -> AssemblyMode { + pub fn mode(&self) -> Mode { self.mode_helper.current } @@ -411,7 +411,7 @@ mod tests { tb.assert_all_queues_empty(); tb.assembly.periodic_operation(); tb.assert_all_queues_empty(); - assert_eq!(tb.assembly.mode(), AssemblyMode::NoModeKeeping); + assert_eq!(tb.assembly.mode(), Mode::NoModeKeeping); } #[test] @@ -419,7 +419,7 @@ mod tests { let mut tb = Testbench::new(); tb.tc_tx .send(create_request_tc(mgm_assembly::request::Request::Mode( - request::ModeRequest::SetMode(AssemblyMode::Device(DeviceMode::Normal)), + request::ModeRequest::SetMode(Mode::Device(DeviceMode::Normal)), ))) .unwrap(); tb.assembly.periodic_operation(); @@ -443,7 +443,7 @@ mod tests { tb.assembly.periodic_operation(); assert!(!tb.assembly.mode_transition_active()); - assert_eq!(tb.assembly.mode(), AssemblyMode::Device(DeviceMode::Normal)); + assert_eq!(tb.assembly.mode(), Mode::Device(DeviceMode::Normal)); let response = tb.tm_rx.try_recv().unwrap(); assert_eq!(response.tm_header.sender_id, Assembly::ID); @@ -456,7 +456,7 @@ mod tests { fn test_parent_commanded_transition() { let mut tb = Testbench::new(); tb.subsystem_req_tx - .send(request::ModeRequest::SetMode(AssemblyMode::Device( + .send(request::ModeRequest::SetMode(Mode::Device( DeviceMode::Normal, ))) .unwrap(); @@ -481,12 +481,12 @@ mod tests { tb.assembly.periodic_operation(); assert!(!tb.assembly.mode_transition_active()); - assert_eq!(tb.assembly.mode(), AssemblyMode::Device(DeviceMode::Normal)); + assert_eq!(tb.assembly.mode(), Mode::Device(DeviceMode::Normal)); let report = tb.subsystem_report_rx.try_recv().unwrap(); assert_eq!( report, - response::ModeReport::Mode(AssemblyMode::Device(DeviceMode::Normal)) + response::ModeReport::Mode(Mode::Device(DeviceMode::Normal)) ); } @@ -494,7 +494,7 @@ mod tests { fn test_one_mgm_is_sufficient() { let mut tb = Testbench::new(); tb.subsystem_req_tx - .send(request::ModeRequest::SetMode(AssemblyMode::Device( + .send(request::ModeRequest::SetMode(Mode::Device( DeviceMode::Normal, ))) .unwrap(); @@ -523,12 +523,12 @@ mod tests { tb.assembly.periodic_operation(); assert!(!tb.assembly.mode_transition_active()); - assert_eq!(tb.assembly.mode(), AssemblyMode::Device(DeviceMode::Normal)); + assert_eq!(tb.assembly.mode(), Mode::Device(DeviceMode::Normal)); let report = tb.subsystem_report_rx.try_recv().unwrap(); assert_eq!( report, - response::ModeReport::Mode(AssemblyMode::Device(DeviceMode::Normal)) + response::ModeReport::Mode(Mode::Device(DeviceMode::Normal)) ); } @@ -536,7 +536,7 @@ mod tests { fn test_mode_commanding_fails() { let mut tb = Testbench::new(); tb.subsystem_req_tx - .send(request::ModeRequest::SetMode(AssemblyMode::Device( + .send(request::ModeRequest::SetMode(Mode::Device( DeviceMode::Normal, ))) .unwrap(); @@ -561,7 +561,7 @@ mod tests { tb.assembly.periodic_operation(); assert!(!tb.assembly.mode_transition_active()); - assert_eq!(tb.assembly.mode(), AssemblyMode::NoModeKeeping); + assert_eq!(tb.assembly.mode(), Mode::NoModeKeeping); let report = tb.subsystem_report_rx.try_recv().unwrap(); assert_eq!( @@ -574,7 +574,7 @@ mod tests { fn test_mode_keeping_fails() { let mut tb = Testbench::new(); tb.subsystem_req_tx - .send(request::ModeRequest::SetMode(AssemblyMode::Device( + .send(request::ModeRequest::SetMode(Mode::Device( DeviceMode::Normal, ))) .unwrap(); @@ -599,12 +599,12 @@ mod tests { tb.assembly.periodic_operation(); assert!(!tb.assembly.mode_transition_active()); - assert_eq!(tb.assembly.mode(), AssemblyMode::Device(DeviceMode::Normal)); + assert_eq!(tb.assembly.mode(), Mode::Device(DeviceMode::Normal)); let report = tb.subsystem_report_rx.try_recv().unwrap(); assert_eq!( report, - response::ModeReport::Mode(AssemblyMode::Device(DeviceMode::Normal)) + response::ModeReport::Mode(Mode::Device(DeviceMode::Normal)) ); for tx in tb.mgm_report_tx.iter() { diff --git a/satrs-example/src/acs/subsystem.rs b/satrs-example/src/acs/subsystem.rs index 539294e..07169e8 100644 --- a/satrs-example/src/acs/subsystem.rs +++ b/satrs-example/src/acs/subsystem.rs @@ -1,3 +1,5 @@ +use std::sync::mpsc::SyncSender; + use models::ComponentId; #[derive(Debug)] @@ -7,16 +9,16 @@ pub struct TransitionInfo { #[derive(Debug)] pub struct ChildModes { - mgm_assembly_mode: models::acs::mgm_assembly::AssemblyMode, - mgt_mode: models::acs::mgt::MgtMode, - controller_mode: models::acs::ctrl::ControllerMode, + mgm_assembly_mode: models::acs::mgm_assembly::Mode, + mgt_mode: models::acs::mgt::Mode, + controller_mode: models::acs::ctrl::Mode, } #[derive(Debug)] pub struct TransitionCommands { - mgm_assembly_mode: Option<(models::acs::mgm_assembly::AssemblyMode, TransitionInfo)>, - mgt_mode: Option<(models::acs::mgt::MgtMode, TransitionInfo)>, - controller_mode: Option<(models::acs::ctrl::ControllerMode, TransitionInfo)>, + mgm_assembly_mode: Option<(models::acs::mgm_assembly::Mode, TransitionInfo)>, + mgt_mode: Option<(models::acs::mgt::Mode, TransitionInfo)>, + controller_mode: Option<(models::acs::ctrl::Mode, TransitionInfo)>, } const OFF_SEQUENCE: [TransitionCommands; 2] = [ @@ -24,7 +26,7 @@ const OFF_SEQUENCE: [TransitionCommands; 2] = [ mgm_assembly_mode: None, mgt_mode: None, controller_mode: Some(( - models::acs::ctrl::ControllerMode::Passive, + models::acs::ctrl::Mode::Passive, TransitionInfo { check_mode_reached: true, }, @@ -32,13 +34,13 @@ const OFF_SEQUENCE: [TransitionCommands; 2] = [ }, TransitionCommands { mgm_assembly_mode: Some(( - models::acs::mgm_assembly::AssemblyMode::Device(models::DeviceMode::Off), + models::acs::mgm_assembly::Mode::Device(models::DeviceMode::Off), TransitionInfo { check_mode_reached: false, }, )), mgt_mode: Some(( - models::acs::mgt::MgtMode::Off, + models::acs::mgt::Mode::Off, TransitionInfo { check_mode_reached: false, }, @@ -50,13 +52,13 @@ const OFF_SEQUENCE: [TransitionCommands; 2] = [ const SAFE_SEQUENCE: [TransitionCommands; 2] = [ TransitionCommands { mgm_assembly_mode: Some(( - models::acs::mgm_assembly::AssemblyMode::Device(models::DeviceMode::Normal), + models::acs::mgm_assembly::Mode::Device(models::DeviceMode::Normal), TransitionInfo { check_mode_reached: false, }, )), mgt_mode: Some(( - models::acs::mgt::MgtMode::Normal, + models::acs::mgt::Mode::Normal, TransitionInfo { check_mode_reached: false, }, @@ -67,7 +69,7 @@ const SAFE_SEQUENCE: [TransitionCommands; 2] = [ mgm_assembly_mode: None, mgt_mode: None, controller_mode: Some(( - models::acs::ctrl::ControllerMode::Safe, + models::acs::ctrl::Mode::Safe, TransitionInfo { check_mode_reached: false, }, @@ -75,19 +77,40 @@ const SAFE_SEQUENCE: [TransitionCommands; 2] = [ }, ]; +#[derive(Debug)] +pub struct ModeRequestSenders { + mode_request_ctrl: SyncSender, + mode_request_assy: SyncSender, + mode_request_mgt: SyncSender, +} + +#[derive(Debug)] +pub struct ModeReportReceivers { + mode_response_ctrl: SyncSender, + mode_response_assy: SyncSender, + mode_response_mgt: SyncSender, +} + #[derive(Debug)] pub struct Subsystem { current_mode: models::acs::subsystem::Mode, current_child_modes: Option, + mode_request_senders: ModeRequestSenders, + mode_report_receivers: ModeReportReceivers, } impl Subsystem { pub const ID: ComponentId = ComponentId::AcsSubsystem; - pub fn new() -> Self { + pub fn new( + mode_request_senders: ModeRequestSenders, + mode_report_receivers: ModeReportReceivers, + ) -> Self { Self { current_mode: models::acs::subsystem::Mode::Off, current_child_modes: None, + mode_request_senders, + mode_report_receivers, } } }