continue mode tree helper

This commit is contained in:
Robin Müller 2024-12-04 16:59:09 +01:00 committed by Robin Mueller
parent 1a211b073f
commit d5d3577af8
2 changed files with 77 additions and 18 deletions

View File

@ -129,6 +129,8 @@ pub struct TargetedModeRequest {
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ModeReply { pub enum ModeReply {
/// Mode information. Can be used to notify other components of changed modes.
ModeInfo(ModeAndSubmode),
/// Reply to a mode request to confirm the commanded mode was reached. /// Reply to a mode request to confirm the commanded mode was reached.
ModeReply(ModeAndSubmode), ModeReply(ModeAndSubmode),
// Can not reach the commanded mode. Contains a reason as a [ResultU16]. // Can not reach the commanded mode. Contains a reason as a [ResultU16].

View File

@ -58,24 +58,51 @@ pub enum TestComponentId {
pub type RequestSenderType = mpsc::SyncSender<GenericMessage<ModeRequest>>; pub type RequestSenderType = mpsc::SyncSender<GenericMessage<ModeRequest>>;
pub type ReplySenderType = mpsc::SyncSender<GenericMessage<ModeReply>>; pub type ReplySenderType = mpsc::SyncSender<GenericMessage<ModeReply>>;
#[derive(Debug)]
pub enum ModeTreeHelperState {
Idle,
TargetKeeping = 1,
SequenceCommanding = 2,
}
#[derive(Debug)]
pub enum ModeTreeHelperResult {
Idle,
TargetKeeping,
SequenceCommanding(SequenceHandlerResult),
}
impl From<SequenceHandlerResult> for ModeTreeHelperResult {
fn from(value: SequenceHandlerResult) -> Self {
Self::SequenceCommanding(value)
}
}
#[derive(Debug, thiserror::Error)]
pub enum ModeTreeHelperError {
#[error("generic targeted messaging error: {0}")]
Message(#[from] GenericTargetedMessagingError),
}
// TODO: // TODO:
// //
// 1. Fallback mode? // 1. Fallback mode? Needs to be a part of the target mode table..
// 2. State to determine whether we are in sequence execution mode or in target keeping mode. // 2. State to determine whether we are in sequence execution mode or in target keeping mode.
#[derive(Default)] pub struct ModeTreeCommandingHelper {
pub struct SubsystemHelper { pub state: ModeTreeHelperState,
pub children_mode_store: ModeStoreVec, pub children_mode_store: ModeStoreVec,
pub target_tables: TargetModeTables, pub target_tables: TargetModeTables,
pub sequence_tables: SequenceModeTables, pub sequence_tables: SequenceModeTables,
pub helper: SequenceExecutionHelper, pub helper: SequenceExecutionHelper,
} }
impl SubsystemHelper {
impl ModeTreeCommandingHelper {
pub fn new( pub fn new(
children_mode_store: ModeStoreVec, children_mode_store: ModeStoreVec,
target_tables: TargetModeTables, target_tables: TargetModeTables,
sequence_tables: SequenceModeTables, sequence_tables: SequenceModeTables,
) -> Self { ) -> Self {
Self { Self {
state: ModeTreeHelperState::Idle,
children_mode_store, children_mode_store,
target_tables, target_tables,
sequence_tables, sequence_tables,
@ -101,23 +128,53 @@ impl SubsystemHelper {
self.children_mode_store.set_mode(child, mode) self.children_mode_store.set_mode(child, mode)
} }
pub fn insert_mode_reply(&mut self, reply: &ModeReply) { pub fn handle_mode_reply(&mut self, reply: &GenericMessage<ModeReply>) {
// 1. Update child mode store (also, do we really need one?) let mut update_mode_store = |target_id, mode_and_submode| {
// 2. If a sequence is active, check whether this completes the sequence. How do we best if !self.children_mode_store.has_component(target_id) {
// do this? We would have to remember which IDs need a mode confirmation. We could return;
// extend the mode store for this. }
// 3. If no sequence is active and we are in target mode, we need to check whether the self.children_mode_store
// target mode table is violated. If it is, we need to command the fallback mode. .set_mode_for_contained_component(target_id, mode_and_submode);
// TODO:
// 1. If we are in IDLE Mode, we are done.
// 2. If we are in sequencing mode, check whether this completes the sequence. How do
// we best do this? We would have to remember which IDs need a mode confirmation.
// We could extend the mode store for this.
// 3. If we are in target keeping mode, we have to check whether the target keeping was
// violated.
};
match reply.message {
ModeReply::ModeInfo(mode_and_submode) => {
update_mode_store(reply.sender_id(), mode_and_submode);
}
ModeReply::ModeReply(mode_and_submode) => {
update_mode_store(reply.sender_id(), mode_and_submode);
}
ModeReply::CantReachMode(_) => (),
ModeReply::WrongMode { reached, .. } => {
update_mode_store(reply.sender_id(), reached);
}
};
} }
pub fn run( pub fn state_machine(
&mut self, &mut self,
opt_reply: Option<&GenericMessage<ModeReply>>,
req_sender: &impl ModeRequestSender, req_sender: &impl ModeRequestSender,
) -> Result<SequenceHandlerResult, GenericTargetedMessagingError> { ) -> Result<ModeTreeHelperResult, ModeTreeHelperError> {
//if self.helper.awaiting_check_success() { if let Some(reply) = opt_reply {
//self.check_current_sequence_against_mode_store(); self.handle_mode_reply(reply);
//} }
self.helper.run(&self.sequence_tables, req_sender) match self.state {
ModeTreeHelperState::Idle => todo!(),
ModeTreeHelperState::TargetKeeping => {
// TODO: Verify children modes against target table where applicable.
Ok(ModeTreeHelperResult::TargetKeeping)
}
ModeTreeHelperState::SequenceCommanding => {
Ok(self.helper.run(&self.sequence_tables, req_sender)?.into())
}
}
} }
//pub fn check_current_sequence_against_mode_store(&self) { //pub fn check_current_sequence_against_mode_store(&self) {
@ -247,7 +304,7 @@ struct AcsSubsystem {
pub mode_requestor_info: Option<MessageMetadata>, pub mode_requestor_info: Option<MessageMetadata>,
pub mode_and_submode: ModeAndSubmode, pub mode_and_submode: ModeAndSubmode,
pub target_mode_and_submode: Option<ModeAndSubmode>, pub target_mode_and_submode: Option<ModeAndSubmode>,
pub subsystem_helper: SubsystemHelper, pub subsystem_helper: ModeTreeCommandingHelper,
pub mode_req_handler_mock: ModeRequestHandlerMock, pub mode_req_handler_mock: ModeRequestHandlerMock,
pub mode_req_recvd: u32, pub mode_req_recvd: u32,
} }