tests working again
This commit is contained in:
@@ -6,6 +6,7 @@ use spacepackets::{
|
||||
|
||||
pub mod ccsds;
|
||||
pub mod control;
|
||||
pub mod mgm;
|
||||
pub mod pcdu;
|
||||
|
||||
#[derive(
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
pub mod request {
|
||||
#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug)]
|
||||
pub enum Request {
|
||||
Ping,
|
||||
}
|
||||
}
|
||||
|
||||
pub mod response {
|
||||
use crate::Message;
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug)]
|
||||
pub enum Response {
|
||||
Ok,
|
||||
}
|
||||
|
||||
impl Message for Response {
|
||||
fn message_type(&self) -> crate::MessageType {
|
||||
match self {
|
||||
Response::Ok => crate::MessageType::Verification,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
use models::ccsds::{CcsdsTcPacketOwned, CcsdsTmPacketOwned};
|
||||
use models::pcdu::SwitchId;
|
||||
use models::ComponentId;
|
||||
use models::{mgm, ComponentId};
|
||||
use satrs::hk::{HkRequest, HkRequestVariant};
|
||||
use satrs::mode_tree::{ModeChild, ModeNode};
|
||||
use satrs::power::{PowerSwitchInfo, PowerSwitcherCommandSender};
|
||||
use satrs::spacepackets::CcsdsPacketIdAndPsc;
|
||||
use satrs_example::{DeviceMode, TimestampHelper};
|
||||
use satrs_minisim::acs::lis3mdl::{
|
||||
MgmLis3MdlReply, MgmLis3RawValues, FIELD_LSB_PER_GAUSS_4_SENS, GAUSS_TO_MICROTESLA_FACTOR,
|
||||
@@ -22,6 +22,7 @@ use satrs::mode::{
|
||||
use satrs::request::{GenericMessage, MessageMetadata};
|
||||
use satrs_example::config::components::NO_SENDER;
|
||||
|
||||
use crate::ccsds::pack_ccsds_tm_packet_for_now;
|
||||
use crate::eps::PowerSwitchHelper;
|
||||
use crate::spi::SpiInterface;
|
||||
|
||||
@@ -167,6 +168,7 @@ pub struct MgmHandlerLis3Mdl<ComInterface: SpiInterface> {
|
||||
}
|
||||
|
||||
impl<ComInterface: SpiInterface> MgmHandlerLis3Mdl<ComInterface> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
id: ComponentId,
|
||||
dev_str: &'static str,
|
||||
@@ -194,7 +196,7 @@ impl<ComInterface: SpiInterface> MgmHandlerLis3Mdl<ComInterface> {
|
||||
pub fn periodic_operation(&mut self) {
|
||||
self.stamp_helper.update_from_now();
|
||||
// Handle requests.
|
||||
self.handle_tc();
|
||||
self.handle_telecommands();
|
||||
self.handle_mode_requests();
|
||||
if let Some(target_mode_submode) = self.mode_helpers.target {
|
||||
self.handle_mode_transition(target_mode_submode);
|
||||
@@ -205,32 +207,53 @@ impl<ComInterface: SpiInterface> MgmHandlerLis3Mdl<ComInterface> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_tc(&mut self) {
|
||||
pub fn handle_telecommands(&mut self) {
|
||||
loop {
|
||||
//match self.tc_rx.try_recv() {
|
||||
/*
|
||||
Ok(ref msg) => match &msg.message {
|
||||
CompositeRequest::Hk(hk_request) => {
|
||||
self.handle_hk_request(&msg.requestor_info, hk_request)
|
||||
match self.tc_rx.try_recv() {
|
||||
Ok(packet) => {
|
||||
let tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&packet.sp_header);
|
||||
match postcard::from_bytes::<mgm::request::Request>(&packet.payload) {
|
||||
Ok(request) => {
|
||||
log::info!(
|
||||
"received request {:?} with TC ID {:#010x}",
|
||||
request,
|
||||
tc_id.raw()
|
||||
);
|
||||
match request {
|
||||
mgm::request::Request::Ping => {
|
||||
self.send_telemetry(Some(tc_id), mgm::response::Response::Ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("failed to deserialize request: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: This object does not have actions (yet).. Still send back completion failure
|
||||
// reply.
|
||||
CompositeRequest::Action(_action_req) => {}
|
||||
},
|
||||
Err(e) => match e {
|
||||
std::sync::mpsc::TryRecvError::Empty => break,
|
||||
std::sync::mpsc::TryRecvError::Disconnected => {
|
||||
log::warn!("packet sender disconnected")
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(e) => {
|
||||
if e != mpsc::TryRecvError::Empty {
|
||||
log::warn!(
|
||||
"{}: failed to receive composite request: {:?}",
|
||||
self.dev_str,
|
||||
e
|
||||
);
|
||||
} else {
|
||||
break;
|
||||
pub fn send_telemetry(
|
||||
&self,
|
||||
tc_id: Option<CcsdsPacketIdAndPsc>,
|
||||
response: mgm::response::Response,
|
||||
) {
|
||||
match pack_ccsds_tm_packet_for_now(self.id, tc_id, &response) {
|
||||
Ok(packet) => {
|
||||
if let Err(e) = self.tm_tx.send(packet) {
|
||||
log::warn!("failed to send TM packet: {}", e);
|
||||
}
|
||||
}
|
||||
*/
|
||||
//}
|
||||
Err(e) => {
|
||||
log::warn!("failed to pack TM packet: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,7 +500,7 @@ mod tests {
|
||||
};
|
||||
|
||||
use models::{
|
||||
pcdu::{SwitchRequest, SwitchStateBinary},
|
||||
pcdu::{SwitchRequest, SwitchState, SwitchStateBinary},
|
||||
ComponentId,
|
||||
};
|
||||
use satrs::{
|
||||
@@ -488,7 +511,7 @@ mod tests {
|
||||
};
|
||||
use satrs_minisim::acs::lis3mdl::MgmLis3RawValues;
|
||||
|
||||
use crate::eps::{pcdu::SharedSwitchSet, TestSwitchHelper};
|
||||
use crate::eps::pcdu::{SharedSwitchSet, SwitchMap, SwitchSet};
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -516,7 +539,7 @@ mod tests {
|
||||
#[allow(dead_code)]
|
||||
pub struct MgmTestbench {
|
||||
pub mode_request_tx: mpsc::SyncSender<GenericMessage<ModeRequest>>,
|
||||
pub mode_reply_rx_to_pus: mpsc::Receiver<GenericMessage<ModeReply>>,
|
||||
pub mode_reply_rx_to_ground: mpsc::Receiver<GenericMessage<ModeReply>>,
|
||||
pub mode_reply_rx_to_parent: mpsc::Receiver<GenericMessage<ModeReply>>,
|
||||
pub shared_switch_set: SharedSwitchSet,
|
||||
pub tc_tx: mpsc::SyncSender<CcsdsTcPacketOwned>,
|
||||
@@ -576,7 +599,10 @@ mod tests {
|
||||
let (_tm_tx, tm_rx) = mpsc::sync_channel(10);
|
||||
let (switcher_tx, switch_rx) = mpsc::sync_channel(10);
|
||||
let shared_mgm_set = Arc::default();
|
||||
let shared_switch_set = SharedSwitchSet::default();
|
||||
let mut switch_map = SwitchMap::new();
|
||||
switch_map.insert(SwitchId::Mgm0, SwitchState::Off);
|
||||
let switch_map = SwitchSet::new(switch_map);
|
||||
let shared_switch_set = SharedSwitchSet::new(Mutex::new(switch_map));
|
||||
let mut handler = MgmHandlerLis3Mdl::new(
|
||||
ComponentId::AcsMgm0,
|
||||
"TEST_MGM",
|
||||
@@ -591,7 +617,7 @@ mod tests {
|
||||
handler.add_mode_parent(ComponentId::AcsMgmAssembly as u32, reply_tx_to_parent);
|
||||
Self {
|
||||
mode_request_tx: request_tx,
|
||||
mode_reply_rx_to_pus: reply_rx_to_ground,
|
||||
mode_reply_rx_to_ground: reply_rx_to_ground,
|
||||
mode_reply_rx_to_parent: reply_rx_to_parent,
|
||||
shared_switch_set,
|
||||
switch_rx,
|
||||
@@ -642,26 +668,22 @@ mod tests {
|
||||
assert_eq!(testbench.handler.mode_and_submode().submode(), 0);
|
||||
|
||||
// Verify power switch handling.
|
||||
/*
|
||||
let mut switch_requests = testbench.handler.switch_helper.switch_requests.borrow_mut();
|
||||
assert_eq!(switch_requests.len(), 1);
|
||||
let switch_req = switch_requests.pop_front().expect("no switch request");
|
||||
assert_eq!(switch_req.target_state, SwitchStateBinary::On);
|
||||
assert_eq!(switch_req.switch_id, SwitchId::Mgm0);
|
||||
let mut switch_info_requests = testbench
|
||||
.handler
|
||||
.switch_helper
|
||||
.switch_info_requests
|
||||
.borrow_mut();
|
||||
assert_eq!(switch_info_requests.len(), 1);
|
||||
let switch_info_req = switch_info_requests.pop_front().expect("no switch request");
|
||||
*/
|
||||
let switch_req = testbench.switch_rx.try_recv().expect("no switch request");
|
||||
assert_eq!(switch_req.message.switch_id, SwitchId::Mgm0);
|
||||
assert_eq!(switch_req.message.target_state, SwitchStateBinary::On);
|
||||
|
||||
// This simulates one cycle for the power switch to update.
|
||||
testbench
|
||||
.shared_switch_set
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_switch_state(SwitchId::Mgm0, SwitchState::On);
|
||||
|
||||
// Now the power switch is updated and the mode request should be completed.
|
||||
testbench.handler.periodic_operation();
|
||||
|
||||
let mode_reply = testbench
|
||||
.mode_reply_rx_to_pus
|
||||
.mode_reply_rx_to_ground
|
||||
.try_recv()
|
||||
.expect("no mode reply generated");
|
||||
match mode_reply.message {
|
||||
@@ -672,7 +694,7 @@ mod tests {
|
||||
_ => panic!("unexpected mode reply"),
|
||||
}
|
||||
// The device should have been polled once.
|
||||
assert_eq!(testbench.handler.com_interface.call_count, 1);
|
||||
assert_eq!(testbench.handler.com_interface.call_count, 2);
|
||||
let mgm_set = *testbench.handler.shared_mgm_set.lock().unwrap();
|
||||
assert!(mgm_set.x < 0.001);
|
||||
assert!(mgm_set.y < 0.001);
|
||||
|
||||
@@ -20,6 +20,10 @@ impl Controller {
|
||||
}
|
||||
|
||||
pub fn periodic_operation(&mut self) {
|
||||
self.handle_telecommands();
|
||||
}
|
||||
|
||||
pub fn handle_telecommands(&mut self) {
|
||||
loop {
|
||||
match self.tc_rx.try_recv() {
|
||||
Ok(packet) => {
|
||||
@@ -32,9 +36,8 @@ impl Controller {
|
||||
tc_id.raw()
|
||||
);
|
||||
match request {
|
||||
control::request::Request::Ping => {
|
||||
self.send_tm(Some(tc_id), control::response::Response::Ok)
|
||||
}
|
||||
control::request::Request::Ping => self
|
||||
.send_telemetry(Some(tc_id), control::response::Response::Ok),
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -52,7 +55,7 @@ impl Controller {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_tm(
|
||||
pub fn send_telemetry(
|
||||
&self,
|
||||
tc_id: Option<CcsdsPacketIdAndPsc>,
|
||||
response: control::response::Response,
|
||||
|
||||
@@ -31,12 +31,34 @@ use strum::IntoEnumIterator as _;
|
||||
|
||||
use crate::ccsds::pack_ccsds_tm_packet_for_now;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SwitchSet {
|
||||
pub valid: bool,
|
||||
pub switch_map: SwitchMap,
|
||||
}
|
||||
|
||||
impl SwitchSet {
|
||||
pub fn new(switch_map: SwitchMap) -> Self {
|
||||
Self {
|
||||
valid: true,
|
||||
switch_map,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_init_switches_unknown() -> Self {
|
||||
let wrapper = SwitchMapWrapper::default();
|
||||
Self::new(wrapper.0)
|
||||
}
|
||||
|
||||
pub fn set_switch_state(&mut self, switch_id: SwitchId, state: SwitchState) -> bool {
|
||||
if !self.switch_map.contains_key(&switch_id) {
|
||||
return false;
|
||||
}
|
||||
*self.switch_map.get_mut(&switch_id).unwrap() = state;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub type SwitchMap = HashMap<SwitchId, SwitchState>;
|
||||
|
||||
pub struct SwitchMapWrapper(pub SwitchMap);
|
||||
@@ -375,19 +397,16 @@ impl<ComInterface: SerialInterface> PcduHandler<ComInterface> {
|
||||
pub fn handle_switch_requests(&mut self) {
|
||||
loop {
|
||||
match self.switch_request_rx.try_recv() {
|
||||
Ok(switch_req) => match SwitchId::try_from(switch_req.message.switch_id()) {
|
||||
Ok(pcdu_switch) => {
|
||||
let pcdu_req = PcduRequest::SwitchDevice {
|
||||
switch: pcdu_switch,
|
||||
state: switch_req.message.target_state(),
|
||||
};
|
||||
let pcdu_req_ser = serde_json::to_string(&pcdu_req).unwrap();
|
||||
self.com_interface
|
||||
.send(pcdu_req_ser.as_bytes())
|
||||
.expect("failed to send switch request to PCDU");
|
||||
}
|
||||
Err(e) => todo!("failed to convert switch ID {:?} to typed PCDU switch", e),
|
||||
},
|
||||
Ok(switch_req) => {
|
||||
let pcdu_req = PcduRequest::SwitchDevice {
|
||||
switch: switch_req.message.switch_id(),
|
||||
state: switch_req.message.target_state(),
|
||||
};
|
||||
let pcdu_req_ser = serde_json::to_string(&pcdu_req).unwrap();
|
||||
self.com_interface
|
||||
.send(pcdu_req_ser.as_bytes())
|
||||
.expect("failed to send switch request to PCDU");
|
||||
}
|
||||
Err(e) => match e {
|
||||
mpsc::TryRecvError::Empty => break,
|
||||
mpsc::TryRecvError::Disconnected => {
|
||||
@@ -581,7 +600,8 @@ mod tests {
|
||||
let (tc_tx, tc_rx) = mpsc::sync_channel(5);
|
||||
let (tm_tx, tm_rx) = mpsc::sync_channel(5);
|
||||
let (switch_request_tx, switch_reqest_rx) = mpsc::channel();
|
||||
let shared_switch_map = Arc::new(Mutex::new(SwitchSet::default()));
|
||||
let shared_switch_map =
|
||||
Arc::new(Mutex::new(SwitchSet::new_with_init_switches_unknown()));
|
||||
let mut handler = PcduHandler::new(
|
||||
mode_node,
|
||||
tc_rx,
|
||||
@@ -693,7 +713,7 @@ mod tests {
|
||||
))
|
||||
.expect("failed to send mode request");
|
||||
let switch_map_shared = testbench.handler.shared_switch_map.lock().unwrap();
|
||||
assert!(!switch_map_shared.valid);
|
||||
assert!(switch_map_shared.valid);
|
||||
drop(switch_map_shared);
|
||||
testbench.handler.periodic_operation(OpCode::RegularOp);
|
||||
testbench
|
||||
|
||||
@@ -38,6 +38,7 @@ use tmtc::{tc_source::TcSourceTask, tm_sink::TmSink};
|
||||
use crate::{
|
||||
acs::mgm::{MgmHandlerLis3Mdl, SpiDummyInterface, SpiSimInterface, SpiSimInterfaceWrapper},
|
||||
control::Controller,
|
||||
eps::pcdu::SwitchSet,
|
||||
interface::udp::UdpTmHandlerWithChannel,
|
||||
tmtc::tc_source::CcsdsDistributor,
|
||||
};
|
||||
@@ -46,7 +47,6 @@ mod acs;
|
||||
mod ccsds;
|
||||
mod control;
|
||||
mod eps;
|
||||
//mod hk;
|
||||
mod interface;
|
||||
mod logger;
|
||||
mod spi;
|
||||
@@ -125,7 +125,7 @@ fn main() {
|
||||
|
||||
let mut tm_sink = TmSink::new(sync_tm_tcp_source, tm_sink_rx, tm_server_tx);
|
||||
|
||||
let shared_switch_set = Arc::new(Mutex::default());
|
||||
let shared_switch_set = Arc::new(Mutex::new(SwitchSet::new_with_init_switches_unknown()));
|
||||
let (switch_request_tx, switch_request_rx) = mpsc::sync_channel(20);
|
||||
let switch_helper = PowerSwitchHelper::new(switch_request_tx, shared_switch_set.clone());
|
||||
|
||||
|
||||
@@ -162,8 +162,8 @@ impl TmSink {
|
||||
let zero_copy_writer =
|
||||
PusTmZeroCopyWriter::new(&mut tm_raw, MIN_CDS_FIELD_LEN, true)
|
||||
.expect("Creating TM zero copy writer failed");
|
||||
self.common.apply_packet_processing(zero_copy_writer);
|
||||
*/
|
||||
//self.common.apply_packet_processing(zero_copy_writer);
|
||||
self.common.sync_tm_tcp_source.add_tm(&tm.to_vec());
|
||||
self.tm_server_tx
|
||||
.send(tm)
|
||||
|
||||
Reference in New Issue
Block a user