continue mode tree execution helper
This commit is contained in:
parent
d4339f3ea3
commit
a42aefff87
@ -110,6 +110,7 @@ impl PusReplyHandler<ActivePusRequestStd, ModeReply> for ModeReplyHandler {
|
|||||||
),
|
),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
ModeReply::ModeInfo(_mode_and_submode) => (),
|
||||||
};
|
};
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,9 @@ pub struct ModeAndSubmode {
|
|||||||
submode: Submode,
|
submode: Submode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const INVALID_MODE: ModeAndSubmode = ModeAndSubmode::new(u32::MAX, 0);
|
||||||
|
pub const UNKNOWN_MODE: ModeAndSubmode = ModeAndSubmode::new(u32::MAX - 1, 0);
|
||||||
|
|
||||||
impl ModeAndSubmode {
|
impl ModeAndSubmode {
|
||||||
pub const RAW_LEN: usize = size_of::<Mode>() + size_of::<Submode>();
|
pub const RAW_LEN: usize = size_of::<Mode>() + size_of::<Submode>();
|
||||||
|
|
||||||
|
@ -105,7 +105,6 @@ impl TargetTableEntry {
|
|||||||
name: &'static str,
|
name: &'static str,
|
||||||
target_id: ComponentId,
|
target_id: ComponentId,
|
||||||
mode_submode: ModeAndSubmode,
|
mode_submode: ModeAndSubmode,
|
||||||
monitor_state: bool,
|
|
||||||
allowed_submode_mask: Option<Submode>,
|
allowed_submode_mask: Option<Submode>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -115,7 +114,7 @@ impl TargetTableEntry {
|
|||||||
mode_submode,
|
mode_submode,
|
||||||
allowed_submode_mask,
|
allowed_submode_mask,
|
||||||
},
|
},
|
||||||
monitor_state,
|
monitor_state: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +122,6 @@ impl TargetTableEntry {
|
|||||||
name: &'static str,
|
name: &'static str,
|
||||||
target_id: ComponentId,
|
target_id: ComponentId,
|
||||||
mode_submode: ModeAndSubmode,
|
mode_submode: ModeAndSubmode,
|
||||||
monitor_state: bool,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
common: ModeTableEntryCommon {
|
common: ModeTableEntryCommon {
|
||||||
@ -132,7 +130,7 @@ impl TargetTableEntry {
|
|||||||
mode_submode,
|
mode_submode,
|
||||||
allowed_submode_mask: None,
|
allowed_submode_mask: None,
|
||||||
},
|
},
|
||||||
monitor_state,
|
monitor_state: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,14 +212,17 @@ pub mod alloc_mod {
|
|||||||
pub struct TargetTablesMapValue {
|
pub struct TargetTablesMapValue {
|
||||||
/// Name for a given mode table entry.
|
/// Name for a given mode table entry.
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
|
/// Optional fallback mode if the target mode can not be kept.
|
||||||
|
pub fallback_mode: Option<Mode>,
|
||||||
/// These are the rows of the a target table.
|
/// These are the rows of the a target table.
|
||||||
pub entries: Vec<TargetTableEntry>,
|
pub entries: Vec<TargetTableEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TargetTablesMapValue {
|
impl TargetTablesMapValue {
|
||||||
pub fn new(name: &'static str) -> Self {
|
pub fn new(name: &'static str, fallback_mode: Option<Mode>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
|
fallback_mode,
|
||||||
entries: Default::default(),
|
entries: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,24 +279,49 @@ pub mod alloc_mod {
|
|||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct SequenceModeTables(pub HashMap<Mode, SequenceTablesMapValue>);
|
pub struct SequenceModeTables(pub HashMap<Mode, SequenceTablesMapValue>);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ModeStoreVecValue {
|
||||||
|
id: ComponentId,
|
||||||
|
mode_and_submode: ModeAndSubmode,
|
||||||
|
pub awaiting_reply: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModeStoreVecValue {
|
||||||
|
pub fn new(id: ComponentId, mode_and_submode: ModeAndSubmode) -> Self {
|
||||||
|
Self {
|
||||||
|
id,
|
||||||
|
mode_and_submode,
|
||||||
|
awaiting_reply: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id(&self) -> ComponentId {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mode_and_submode(&self) -> ModeAndSubmode {
|
||||||
|
self.mode_and_submode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ModeStoreVec(pub alloc::vec::Vec<(ComponentId, ModeAndSubmode)>);
|
pub struct ModeStoreVec(pub alloc::vec::Vec<ModeStoreVecValue>);
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ModeStoreMap(pub hashbrown::HashMap<ComponentId, ModeAndSubmode>);
|
pub struct ModeStoreMap(pub hashbrown::HashMap<ComponentId, ModeAndSubmode>);
|
||||||
|
|
||||||
impl ModeStoreProvider for ModeStoreVec {
|
impl ModeStoreProvider for ModeStoreVec {
|
||||||
fn add_component(&mut self, target_id: ComponentId, mode: ModeAndSubmode) {
|
fn add_component(&mut self, target_id: ComponentId, mode: ModeAndSubmode) {
|
||||||
self.0.push((target_id, mode));
|
self.0.push(ModeStoreVecValue::new(target_id, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_component(&self, target_id: ComponentId) -> bool {
|
fn has_component(&self, target_id: ComponentId) -> bool {
|
||||||
self.0.iter().any(|(id, _)| *id == target_id)
|
self.0.iter().any(|val| val.id == target_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mode(&self, target_id: ComponentId) -> Option<ModeAndSubmode> {
|
fn get_mode(&self, target_id: ComponentId) -> Option<ModeAndSubmode> {
|
||||||
self.0.iter().find_map(|(id, mode)| {
|
self.0.iter().find_map(|val| {
|
||||||
if *id == target_id {
|
if val.id == target_id {
|
||||||
return Some(*mode);
|
return Some(val.mode_and_submode);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
@ -306,9 +332,9 @@ pub mod alloc_mod {
|
|||||||
target_id: ComponentId,
|
target_id: ComponentId,
|
||||||
mode_to_set: ModeAndSubmode,
|
mode_to_set: ModeAndSubmode,
|
||||||
) {
|
) {
|
||||||
self.0.iter_mut().for_each(|(id, mode)| {
|
self.0.iter_mut().for_each(|val| {
|
||||||
if *id == target_id {
|
if val.id == target_id {
|
||||||
*mode = mode_to_set;
|
val.mode_and_submode = mode_to_set;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ mod tests {
|
|||||||
use crate::{
|
use crate::{
|
||||||
mode::{
|
mode::{
|
||||||
ModeAndSubmode, ModeReply, ModeReplySender, ModeRequest, ModeRequestSender,
|
ModeAndSubmode, ModeReply, ModeReplySender, ModeRequest, ModeRequestSender,
|
||||||
ModeRequestorAndHandlerOneParentMpsc, ModeRequestorOneChildMpsc,
|
ModeRequestorAndHandlerMpsc, ModeRequestorOneChildMpsc,
|
||||||
},
|
},
|
||||||
request::{GenericMessage, MessageMetadata},
|
request::{GenericMessage, MessageMetadata},
|
||||||
};
|
};
|
||||||
@ -90,7 +90,7 @@ mod tests {
|
|||||||
|
|
||||||
let (request_sender_to_channel_1, request_receiver_channel_1) = mpsc::channel();
|
let (request_sender_to_channel_1, request_receiver_channel_1) = mpsc::channel();
|
||||||
//let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
//let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
||||||
let mut mode_connector = ModeRequestorAndHandlerOneParentMpsc::new(
|
let mut mode_connector = ModeRequestorAndHandlerMpsc::new(
|
||||||
TEST_COMPONENT_ID_0,
|
TEST_COMPONENT_ID_0,
|
||||||
request_receiver_of_connector,
|
request_receiver_of_connector,
|
||||||
reply_receiver_of_connector,
|
reply_receiver_of_connector,
|
||||||
@ -129,7 +129,7 @@ mod tests {
|
|||||||
let (_request_sender_to_connector, request_receiver_of_connector) = mpsc::channel();
|
let (_request_sender_to_connector, request_receiver_of_connector) = mpsc::channel();
|
||||||
|
|
||||||
let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
||||||
let mut mode_connector = ModeRequestorAndHandlerOneParentMpsc::new(
|
let mut mode_connector = ModeRequestorAndHandlerMpsc::new(
|
||||||
TEST_COMPONENT_ID_0,
|
TEST_COMPONENT_ID_0,
|
||||||
request_receiver_of_connector,
|
request_receiver_of_connector,
|
||||||
reply_receiver_of_connector,
|
reply_receiver_of_connector,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
mode::{Mode, ModeAndSubmode, ModeRequest, ModeRequestSender},
|
mode::{Mode, ModeAndSubmode, ModeRequest, ModeRequestSender},
|
||||||
mode_tree::{SequenceModeTables, SequenceTableMapTable, SequenceTablesMapValue},
|
mode_tree::{ModeStoreVec, SequenceModeTables, SequenceTableMapTable, SequenceTablesMapValue},
|
||||||
queue::GenericTargetedMessagingError,
|
queue::GenericTargetedMessagingError,
|
||||||
request::RequestId,
|
request::RequestId,
|
||||||
ComponentId,
|
ComponentId,
|
||||||
@ -21,6 +21,12 @@ pub trait CheckSuccessProvider {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum TargetKeepingResult {
|
||||||
|
Ok,
|
||||||
|
Violated { fallback_mode: Option<Mode> },
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SequenceHandlerResult {
|
pub enum SequenceHandlerResult {
|
||||||
SequenceDone,
|
SequenceDone,
|
||||||
@ -92,6 +98,7 @@ impl SequenceExecutionHelper {
|
|||||||
&mut self,
|
&mut self,
|
||||||
table: &SequenceModeTables,
|
table: &SequenceModeTables,
|
||||||
sender: &impl ModeRequestSender,
|
sender: &impl ModeRequestSender,
|
||||||
|
mode_store_vec: &mut ModeStoreVec,
|
||||||
) -> Result<SequenceHandlerResult, GenericTargetedMessagingError> {
|
) -> Result<SequenceHandlerResult, GenericTargetedMessagingError> {
|
||||||
if self.state == SequenceExecutionHelperStates::AwaitingCheckSuccess {
|
if self.state == SequenceExecutionHelperStates::AwaitingCheckSuccess {
|
||||||
return Ok(SequenceHandlerResult::AwaitingSuccessCheck);
|
return Ok(SequenceHandlerResult::AwaitingSuccessCheck);
|
||||||
@ -100,7 +107,12 @@ impl SequenceExecutionHelper {
|
|||||||
Some(idx) => {
|
Some(idx) => {
|
||||||
// Execute the sequence.
|
// Execute the sequence.
|
||||||
let seq_table_value = table.0.get(&self.target_mode).unwrap();
|
let seq_table_value = table.0.get(&self.target_mode).unwrap();
|
||||||
self.execute_sequence_and_map_to_result(seq_table_value, idx, sender)
|
self.execute_sequence_and_map_to_result(
|
||||||
|
seq_table_value,
|
||||||
|
idx,
|
||||||
|
sender,
|
||||||
|
mode_store_vec,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Find the first sequence
|
// Find the first sequence
|
||||||
@ -109,7 +121,12 @@ impl SequenceExecutionHelper {
|
|||||||
Ok(SequenceHandlerResult::SequenceDone)
|
Ok(SequenceHandlerResult::SequenceDone)
|
||||||
} else {
|
} else {
|
||||||
self.current_sequence_index = Some(0);
|
self.current_sequence_index = Some(0);
|
||||||
self.execute_sequence_and_map_to_result(seq_table_value, 0, sender)
|
self.execute_sequence_and_map_to_result(
|
||||||
|
seq_table_value,
|
||||||
|
0,
|
||||||
|
sender,
|
||||||
|
mode_store_vec,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,11 +137,13 @@ impl SequenceExecutionHelper {
|
|||||||
seq_table_value: &SequenceTablesMapValue,
|
seq_table_value: &SequenceTablesMapValue,
|
||||||
sequence_idx: usize,
|
sequence_idx: usize,
|
||||||
sender: &impl ModeRequestSender,
|
sender: &impl ModeRequestSender,
|
||||||
|
mode_store_vec: &mut ModeStoreVec,
|
||||||
) -> Result<SequenceHandlerResult, GenericTargetedMessagingError> {
|
) -> Result<SequenceHandlerResult, GenericTargetedMessagingError> {
|
||||||
if Self::execute_sequence(
|
if Self::execute_sequence(
|
||||||
self.request_id,
|
self.request_id,
|
||||||
&seq_table_value.entries[sequence_idx],
|
&seq_table_value.entries[sequence_idx],
|
||||||
sender,
|
sender,
|
||||||
|
mode_store_vec,
|
||||||
)? {
|
)? {
|
||||||
self.state = SequenceExecutionHelperStates::AwaitingCheckSuccess;
|
self.state = SequenceExecutionHelperStates::AwaitingCheckSuccess;
|
||||||
Ok(SequenceHandlerResult::AwaitingSuccessCheck)
|
Ok(SequenceHandlerResult::AwaitingSuccessCheck)
|
||||||
@ -140,6 +159,7 @@ impl SequenceExecutionHelper {
|
|||||||
request_id: RequestId,
|
request_id: RequestId,
|
||||||
map_table: &SequenceTableMapTable,
|
map_table: &SequenceTableMapTable,
|
||||||
sender: &impl ModeRequestSender,
|
sender: &impl ModeRequestSender,
|
||||||
|
mode_store_vec: &mut ModeStoreVec,
|
||||||
) -> Result<bool, GenericTargetedMessagingError> {
|
) -> Result<bool, GenericTargetedMessagingError> {
|
||||||
let mut some_succes_check_required = false;
|
let mut some_succes_check_required = false;
|
||||||
for entry in &map_table.entries {
|
for entry in &map_table.entries {
|
||||||
@ -148,6 +168,11 @@ impl SequenceExecutionHelper {
|
|||||||
entry.common.target_id,
|
entry.common.target_id,
|
||||||
ModeRequest::SetMode(entry.common.mode_submode),
|
ModeRequest::SetMode(entry.common.mode_submode),
|
||||||
)?;
|
)?;
|
||||||
|
mode_store_vec.0.iter_mut().for_each(|val| {
|
||||||
|
if val.id() == entry.common.target_id {
|
||||||
|
val.awaiting_reply = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
if entry.check_success {
|
if entry.check_success {
|
||||||
some_succes_check_required = true;
|
some_succes_check_required = true;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@ use core::cell::Cell;
|
|||||||
use satrs::mode::{
|
use satrs::mode::{
|
||||||
Mode, ModeError, ModeProvider, ModeReplyReceiver, ModeReplySender, ModeRequestHandler,
|
Mode, ModeError, ModeProvider, ModeReplyReceiver, ModeReplySender, ModeRequestHandler,
|
||||||
ModeRequestHandlerMpscBounded, ModeRequestReceiver, ModeRequestSender,
|
ModeRequestHandlerMpscBounded, ModeRequestReceiver, ModeRequestSender,
|
||||||
ModeRequestorAndHandlerMpscBounded, ModeRequestorOneChildBoundedMpsc,
|
ModeRequestorAndHandlerMpscBounded, ModeRequestorOneChildBoundedMpsc, INVALID_MODE,
|
||||||
|
UNKNOWN_MODE,
|
||||||
};
|
};
|
||||||
use satrs::mode_tree::{
|
use satrs::mode_tree::{
|
||||||
connect_mode_nodes, ModeChild, ModeNode, ModeParent, ModeStoreProvider, SequenceTableEntry,
|
connect_mode_nodes, ModeChild, ModeNode, ModeParent, ModeStoreProvider, SequenceTableEntry,
|
||||||
@ -13,7 +14,7 @@ use satrs::mode_tree::{
|
|||||||
TargetTablesMapValue,
|
TargetTablesMapValue,
|
||||||
};
|
};
|
||||||
use satrs::request::MessageMetadata;
|
use satrs::request::MessageMetadata;
|
||||||
use satrs::subsystem::{SequenceExecutionHelper, SequenceHandlerResult};
|
use satrs::subsystem::{SequenceExecutionHelper, SequenceHandlerResult, TargetKeepingResult};
|
||||||
use satrs::{
|
use satrs::{
|
||||||
mode::{ModeAndSubmode, ModeReply, ModeRequest},
|
mode::{ModeAndSubmode, ModeReply, ModeRequest},
|
||||||
queue::GenericTargetedMessagingError,
|
queue::GenericTargetedMessagingError,
|
||||||
@ -25,9 +26,6 @@ use std::collections::VecDeque;
|
|||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
use std::{println, sync::mpsc};
|
use std::{println, sync::mpsc};
|
||||||
|
|
||||||
const INVALID_MODE: ModeAndSubmode = ModeAndSubmode::new(0xffffffff, 0);
|
|
||||||
const UNKNOWN_MODE: ModeAndSubmode = ModeAndSubmode::new(0xffffffff - 1, 0);
|
|
||||||
|
|
||||||
pub enum DefaultMode {
|
pub enum DefaultMode {
|
||||||
OFF = 0,
|
OFF = 0,
|
||||||
ON = 1,
|
ON = 1,
|
||||||
@ -58,8 +56,9 @@ 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)]
|
#[derive(Debug, Default)]
|
||||||
pub enum ModeTreeHelperState {
|
pub enum ModeTreeHelperState {
|
||||||
|
#[default]
|
||||||
Idle,
|
Idle,
|
||||||
TargetKeeping = 1,
|
TargetKeeping = 1,
|
||||||
SequenceCommanding = 2,
|
SequenceCommanding = 2,
|
||||||
@ -68,10 +67,16 @@ pub enum ModeTreeHelperState {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ModeTreeHelperResult {
|
pub enum ModeTreeHelperResult {
|
||||||
Idle,
|
Idle,
|
||||||
TargetKeeping,
|
TargetKeeping(TargetKeepingResult),
|
||||||
SequenceCommanding(SequenceHandlerResult),
|
SequenceCommanding(SequenceHandlerResult),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<TargetKeepingResult> for ModeTreeHelperResult {
|
||||||
|
fn from(value: TargetKeepingResult) -> Self {
|
||||||
|
Self::TargetKeeping(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<SequenceHandlerResult> for ModeTreeHelperResult {
|
impl From<SequenceHandlerResult> for ModeTreeHelperResult {
|
||||||
fn from(value: SequenceHandlerResult) -> Self {
|
fn from(value: SequenceHandlerResult) -> Self {
|
||||||
Self::SequenceCommanding(value)
|
Self::SequenceCommanding(value)
|
||||||
@ -82,12 +87,16 @@ impl From<SequenceHandlerResult> for ModeTreeHelperResult {
|
|||||||
pub enum ModeTreeHelperError {
|
pub enum ModeTreeHelperError {
|
||||||
#[error("generic targeted messaging error: {0}")]
|
#[error("generic targeted messaging error: {0}")]
|
||||||
Message(#[from] GenericTargetedMessagingError),
|
Message(#[from] GenericTargetedMessagingError),
|
||||||
|
#[error("current mode {0} is not contained in target table")]
|
||||||
|
CurrentModeNotInTargetTable(Mode),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
//
|
//
|
||||||
// 1. Fallback mode? Needs to be a part of the target mode table..
|
// 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.
|
||||||
pub struct ModeTreeCommandingHelper {
|
pub struct ModeTreeCommandingHelper {
|
||||||
|
pub current_mode: ModeAndSubmode,
|
||||||
pub state: ModeTreeHelperState,
|
pub state: ModeTreeHelperState,
|
||||||
pub children_mode_store: ModeStoreVec,
|
pub children_mode_store: ModeStoreVec,
|
||||||
pub target_tables: TargetModeTables,
|
pub target_tables: TargetModeTables,
|
||||||
@ -95,6 +104,19 @@ pub struct ModeTreeCommandingHelper {
|
|||||||
pub helper: SequenceExecutionHelper,
|
pub helper: SequenceExecutionHelper,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ModeTreeCommandingHelper {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
current_mode: UNKNOWN_MODE,
|
||||||
|
state: Default::default(),
|
||||||
|
children_mode_store: Default::default(),
|
||||||
|
target_tables: Default::default(),
|
||||||
|
sequence_tables: Default::default(),
|
||||||
|
helper: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ModeTreeCommandingHelper {
|
impl ModeTreeCommandingHelper {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
children_mode_store: ModeStoreVec,
|
children_mode_store: ModeStoreVec,
|
||||||
@ -102,6 +124,7 @@ impl ModeTreeCommandingHelper {
|
|||||||
sequence_tables: SequenceModeTables,
|
sequence_tables: SequenceModeTables,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
current_mode: UNKNOWN_MODE,
|
||||||
state: ModeTreeHelperState::Idle,
|
state: ModeTreeHelperState::Idle,
|
||||||
children_mode_store,
|
children_mode_store,
|
||||||
target_tables,
|
target_tables,
|
||||||
@ -135,13 +158,24 @@ impl ModeTreeCommandingHelper {
|
|||||||
}
|
}
|
||||||
self.children_mode_store
|
self.children_mode_store
|
||||||
.set_mode_for_contained_component(target_id, mode_and_submode);
|
.set_mode_for_contained_component(target_id, mode_and_submode);
|
||||||
// TODO:
|
match self.state {
|
||||||
// 1. If we are in IDLE Mode, we are done.
|
ModeTreeHelperState::Idle => (),
|
||||||
// 2. If we are in sequencing mode, check whether this completes the sequence. How do
|
ModeTreeHelperState::TargetKeeping => {}
|
||||||
// we best do this? We would have to remember which IDs need a mode confirmation.
|
ModeTreeHelperState::SequenceCommanding => {
|
||||||
// We could extend the mode store for this.
|
let mut still_awating_replies = false;
|
||||||
// 3. If we are in target keeping mode, we have to check whether the target keeping was
|
self.children_mode_store.0.iter_mut().for_each(|val| {
|
||||||
// violated.
|
if val.id() == target_id {
|
||||||
|
val.awaiting_reply = false;
|
||||||
|
}
|
||||||
|
if val.awaiting_reply {
|
||||||
|
still_awating_replies = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if !still_awating_replies {
|
||||||
|
self.helper.confirm_sequence_done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
match reply.message {
|
match reply.message {
|
||||||
ModeReply::ModeInfo(mode_and_submode) => {
|
ModeReply::ModeInfo(mode_and_submode) => {
|
||||||
@ -166,22 +200,49 @@ impl ModeTreeCommandingHelper {
|
|||||||
self.handle_mode_reply(reply);
|
self.handle_mode_reply(reply);
|
||||||
}
|
}
|
||||||
match self.state {
|
match self.state {
|
||||||
ModeTreeHelperState::Idle => todo!(),
|
ModeTreeHelperState::Idle => Ok(ModeTreeHelperResult::Idle),
|
||||||
ModeTreeHelperState::TargetKeeping => {
|
ModeTreeHelperState::TargetKeeping => {
|
||||||
// TODO: Verify children modes against target table where applicable.
|
// We check whether the current mode is modelled by a target table first.
|
||||||
Ok(ModeTreeHelperResult::TargetKeeping)
|
if let Some(target_table) = self.target_tables.0.get(&self.current_mode.mode()) {
|
||||||
}
|
for entry in &target_table.entries {
|
||||||
ModeTreeHelperState::SequenceCommanding => {
|
if !entry.monitor_state {
|
||||||
Ok(self.helper.run(&self.sequence_tables, req_sender)?.into())
|
continue;
|
||||||
|
}
|
||||||
|
let mut target_mode_violated = false;
|
||||||
|
self.children_mode_store.0.iter().for_each(|val| {
|
||||||
|
if val.id() == entry.common.target_id {
|
||||||
|
target_mode_violated = if let Some(allowed_submode_mask) =
|
||||||
|
entry.allowed_submode_mask()
|
||||||
|
{
|
||||||
|
let fixed_bits = !allowed_submode_mask;
|
||||||
|
(val.mode_and_submode().mode()
|
||||||
|
!= entry.common.mode_submode.mode())
|
||||||
|
&& (val.mode_and_submode().submode() & fixed_bits
|
||||||
|
!= entry.common.mode_submode.submode() & fixed_bits)
|
||||||
|
} else {
|
||||||
|
val.mode_and_submode() != entry.common.mode_submode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Target keeping violated. Report violation and fallback mode to user.
|
||||||
|
return Ok(TargetKeepingResult::Violated {
|
||||||
|
fallback_mode: None,
|
||||||
|
}
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
Ok(ModeTreeHelperResult::TargetKeeping(TargetKeepingResult::Ok))
|
||||||
}
|
}
|
||||||
|
ModeTreeHelperState::SequenceCommanding => Ok(self
|
||||||
|
.helper
|
||||||
|
.run(
|
||||||
|
&self.sequence_tables,
|
||||||
|
req_sender,
|
||||||
|
&mut self.children_mode_store,
|
||||||
|
)?
|
||||||
|
.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn check_current_sequence_against_mode_store(&self) {
|
|
||||||
// TODO: Check whether current sequence requires success checks and if some are required,
|
|
||||||
// check mode store content against the sequence target mode.
|
|
||||||
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
@ -266,6 +327,9 @@ impl ModeRequestHandler for ModeRequestHandlerMock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct ModeReplyHandlerMock {}
|
||||||
|
|
||||||
struct PusModeService {
|
struct PusModeService {
|
||||||
pub request_id_counter: Cell<u32>,
|
pub request_id_counter: Cell<u32>,
|
||||||
pub mode_node: ModeRequestorOneChildBoundedMpsc,
|
pub mode_node: ModeRequestorOneChildBoundedMpsc,
|
||||||
@ -316,7 +380,7 @@ impl AcsSubsystem {
|
|||||||
mode_requestor_info: None,
|
mode_requestor_info: None,
|
||||||
mode_and_submode: UNKNOWN_MODE,
|
mode_and_submode: UNKNOWN_MODE,
|
||||||
target_mode_and_submode: None,
|
target_mode_and_submode: None,
|
||||||
subsystem_helper: Default::default(),
|
subsystem_helper: ModeTreeCommandingHelper::default(),
|
||||||
mode_req_handler_mock: Default::default(),
|
mode_req_handler_mock: Default::default(),
|
||||||
mode_req_recvd: 0,
|
mode_req_recvd: 0,
|
||||||
}
|
}
|
||||||
@ -506,6 +570,7 @@ impl MgmAssembly {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_mode_replies(&mut self) -> Result<(), GenericTargetedMessagingError> {
|
pub fn check_mode_replies(&mut self) -> Result<(), GenericTargetedMessagingError> {
|
||||||
|
// TODO: Call mode reply handler mock.
|
||||||
if let Some(reply_and_id) = self.mode_node.try_recv_mode_reply()? {
|
if let Some(reply_and_id) = self.mode_node.try_recv_mode_reply()? {
|
||||||
match reply_and_id.message {
|
match reply_and_id.message {
|
||||||
ModeReply::ModeReply(reply) => {
|
ModeReply::ModeReply(reply) => {
|
||||||
@ -524,6 +589,7 @@ impl MgmAssembly {
|
|||||||
expected
|
expected
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
ModeReply::ModeInfo(_mode_and_submode) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1136,12 +1202,11 @@ impl TreeTestbench {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ACS subsystem tables
|
// ACS subsystem tables
|
||||||
let mut target_table_safe = TargetTablesMapValue::new("SAFE_TARGET_TBL");
|
let mut target_table_safe = TargetTablesMapValue::new("SAFE_TARGET_TBL", None);
|
||||||
target_table_safe.add_entry(TargetTableEntry::new(
|
target_table_safe.add_entry(TargetTableEntry::new(
|
||||||
"CTRL_SAFE",
|
"CTRL_SAFE",
|
||||||
TestComponentId::AcsController as u64,
|
TestComponentId::AcsController as u64,
|
||||||
ModeAndSubmode::new(AcsMode::SAFE as u32, 0),
|
ModeAndSubmode::new(AcsMode::SAFE as u32, 0),
|
||||||
true,
|
|
||||||
// All submodes allowed.
|
// All submodes allowed.
|
||||||
Some(0xffff),
|
Some(0xffff),
|
||||||
));
|
));
|
||||||
@ -1149,13 +1214,11 @@ impl TreeTestbench {
|
|||||||
"MGM_A_NML",
|
"MGM_A_NML",
|
||||||
TestComponentId::MagnetometerAssembly as u64,
|
TestComponentId::MagnetometerAssembly as u64,
|
||||||
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
||||||
true,
|
|
||||||
));
|
));
|
||||||
target_table_safe.add_entry(TargetTableEntry::new_with_precise_submode(
|
target_table_safe.add_entry(TargetTableEntry::new_with_precise_submode(
|
||||||
"MGT_MAN_NML",
|
"MGT_MAN_NML",
|
||||||
TestComponentId::MgtDevManager as u64,
|
TestComponentId::MgtDevManager as u64,
|
||||||
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
||||||
true,
|
|
||||||
));
|
));
|
||||||
let mut sequence_tbl_safe_0 = SequenceTableMapTable::new("SAFE_SEQ_0_TBL");
|
let mut sequence_tbl_safe_0 = SequenceTableMapTable::new("SAFE_SEQ_0_TBL");
|
||||||
sequence_tbl_safe_0.add_entry(SequenceTableEntry::new(
|
sequence_tbl_safe_0.add_entry(SequenceTableEntry::new(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user