unittests are working well
Some checks failed
Rust/sat-rs/pipeline/pr-main There was a failure building this commit

This commit is contained in:
Robin Müller 2024-03-07 17:11:24 +01:00
parent c9f71125a3
commit 3dd6ad6155
Signed by: muellerr
GPG Key ID: A649FB78196E3849
6 changed files with 168 additions and 62 deletions

View File

@ -4,7 +4,7 @@ use asynchronix::{
model::{Model, Output},
time::Scheduler,
};
use satrs::power::SwitchState;
use satrs::power::{SwitchState, SwitchStateBinary};
use satrs_minisim::{
acs::{MgmSensorValues, MgtDipole, MGT_GEN_MAGNETIC_FIELD},
SimDevice, SimReply,
@ -32,7 +32,7 @@ const PHASE_Z: f32 = 0.2;
/// a general purpose OS, but self self-sampling at a relatively high rate (20-40 ms) might
/// stil lbe possible.
pub struct MagnetometerModel {
pub switch_state: SwitchState,
pub switch_state: SwitchStateBinary,
pub periodicity: Duration,
pub external_mag_field: Option<MgmSensorValues>,
pub reply_sender: mpsc::Sender<SimReply>,
@ -41,14 +41,14 @@ pub struct MagnetometerModel {
impl MagnetometerModel {
pub fn new(periodicity: Duration, reply_sender: mpsc::Sender<SimReply>) -> Self {
Self {
switch_state: SwitchState::Off,
switch_state: SwitchStateBinary::Off,
periodicity,
external_mag_field: None,
reply_sender,
}
}
pub async fn switch_device(&mut self, switch_state: SwitchState) {
pub async fn switch_device(&mut self, switch_state: SwitchStateBinary) {
self.switch_state = switch_state;
}
@ -72,7 +72,7 @@ impl MagnetometerModel {
}
fn calculate_current_mgm_tuple(&mut self, time_ms: u64) -> MgmSensorValues {
if let SwitchState::On = self.switch_state {
if SwitchStateBinary::On == self.switch_state {
if let Some(ext_field) = self.external_mag_field {
return ext_field;
}

View File

@ -1,7 +1,10 @@
use std::{sync::mpsc, time::Duration};
use std::{
sync::mpsc,
time::{Duration, SystemTime},
};
use asynchronix::{
simulation::{Address, Simulation},
simulation::{Address, Mailbox, SimInit, Simulation},
time::{Clock, MonotonicTime, SystemClock},
};
use satrs_minisim::{acs::MgmRequest, SimRequest};
@ -21,6 +24,22 @@ pub struct SimController {
}
impl SimController {
pub fn new(
sys_clock: SystemClock,
request_receiver: mpsc::Receiver<SimRequest>,
simulation: Simulation,
mgm_addr: Address<MagnetometerModel>,
pcdu_addr: Address<PcduModel>,
) -> Self {
Self {
sys_clock,
request_receiver,
simulation,
mgm_addr,
pcdu_addr,
}
}
pub fn run(&mut self, start_time: MonotonicTime) {
let mut t = start_time + Duration::from_millis(1);
self.sys_clock.synchronize(t);
@ -39,10 +58,10 @@ impl SimController {
pub fn handle_sim_requests(&mut self) {
loop {
match self.request_receiver.try_recv() {
Ok(request) => match request.device {
satrs_minisim::SimDevice::Mgm => self.handle_mgm_request(&request.request),
satrs_minisim::SimDevice::Mgt => self.handle_mgt_request(&request.request),
satrs_minisim::SimDevice::Pcdu => self.handle_pcdu_request(&request.request),
Ok(request) => match request.device() {
satrs_minisim::SimDevice::Mgm => self.handle_mgm_request(request.request()),
satrs_minisim::SimDevice::Mgt => self.handle_mgt_request(request.request()),
satrs_minisim::SimDevice::Pcdu => self.handle_pcdu_request(request.request()),
},
Err(e) => match e {
mpsc::TryRecvError::Empty => break,
@ -83,6 +102,7 @@ impl SimController {
let pcdu_request = pcdu_request.unwrap();
match pcdu_request {
PcduRequest::RequestSwitchInfo => todo!(),
PcduRequest::SwitchDevice => todo!(),
}
}

View File

@ -1,10 +1,19 @@
use asynchronix::model::{Model, Output};
use satrs::power::{SwitchState, SwitchStateBinary};
use std::{sync::mpsc, time::Duration};
use asynchronix::{
model::{Model, Output},
time::Scheduler,
};
use satrs::power::SwitchStateBinary;
use satrs_minisim::{SimDevice, SimReply};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct PcduTuple {}
pub const SWITCH_INFO_DELAY_MS: u64 = 10;
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct SwitchInfo(Vec<SwitchStateBinary>);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum PcduSwitches {
Mgm = 0,
Mgt = 1,
@ -12,17 +21,45 @@ pub enum PcduSwitches {
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum PcduRequest {
SwitchDevice,
RequestSwitchInfo,
}
pub struct PcduModel {
pub switcher_list: Output<Vec<SwitchStateBinary>>,
pub mgm_switch: Output<SwitchState>,
pub mgt_switch: Output<SwitchState>,
pub current_switch_info: Vec<SwitchStateBinary>,
pub mgm_switch: Output<SwitchStateBinary>,
pub mgt_switch: Output<SwitchStateBinary>,
pub reply_sender: mpsc::Sender<SimReply>,
}
impl PcduModel {
pub async fn switch_device(&mut self, switch: PcduSwitches, switch_state: SwitchState) {
pub fn new(reply_sender: mpsc::Sender<SimReply>) -> Self {
Self {
current_switch_info: vec![SwitchStateBinary::Off; 2],
mgm_switch: Output::new(),
mgt_switch: Output::new(),
reply_sender,
}
}
pub async fn request_switch_info(&mut self, _: (), scheduler: &Scheduler<Self>) {
scheduler
.schedule_event(
Duration::from_millis(SWITCH_INFO_DELAY_MS),
Self::send_switch_info,
(),
)
.expect("requesting switch info failed");
}
pub fn send_switch_info(&mut self) {
let switch_info = SwitchInfo(self.current_switch_info.clone());
let reply = SimReply::new(SimDevice::Pcdu, switch_info);
self.reply_sender.send(reply).unwrap();
}
pub async fn switch_device(&mut self, switch: PcduSwitches, switch_state: SwitchStateBinary) {
self.current_switch_info[switch as usize] = switch_state;
match switch {
PcduSwitches::Mgm => {
self.mgm_switch.send(switch_state).await;

View File

@ -9,8 +9,25 @@ pub enum SimDevice {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimRequest {
pub device: SimDevice,
pub request: String,
device: SimDevice,
request: String,
}
impl SimRequest {
pub fn new<T: Serialize>(device: SimDevice, reply: T) -> Self {
Self {
device,
request: serde_json::to_string(&reply).unwrap(),
}
}
pub fn device(&self) -> SimDevice {
self.device
}
pub fn request(&self) -> &String {
&self.request
}
}
#[derive(Serialize, Deserialize)]
@ -19,6 +36,19 @@ pub struct SimReply {
pub reply: String,
}
impl SimReply {
pub fn new<T: Serialize>(device: SimDevice, reply: T) -> Self {
Self {
device,
reply: serde_json::to_string(&reply).unwrap(),
}
}
pub fn reply(&self) -> &String {
&self.reply
}
}
pub mod acs {
use super::*;

View File

@ -2,6 +2,8 @@ use acs::MagnetometerModel;
use asynchronix::simulation::{Mailbox, SimInit};
use asynchronix::time::{MonotonicTime, SystemClock};
use controller::SimController;
use eps::PcduModel;
use satrs_minisim::{SimReply, SimRequest};
use std::sync::mpsc;
use std::thread;
use std::time::{Duration, SystemTime};
@ -13,35 +15,57 @@ mod eps;
mod time;
mod udp;
fn main() {
let shared_socket_addr = SharedSocketAddr::default();
let (request_sender, request_receiver) = mpsc::channel();
let (reply_sender, reply_receiver) = mpsc::channel();
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ThreadingModel {
Default = 0,
Single = 1,
}
fn create_sim_controller(
threading_model: ThreadingModel,
start_time: MonotonicTime,
reply_sender: mpsc::Sender<SimReply>,
request_receiver: mpsc::Receiver<SimRequest>,
) -> SimController {
// Instantiate models and their mailboxes.
let mgm_sim = MagnetometerModel::new(Duration::from_millis(50), reply_sender.clone());
let mgm_model = MagnetometerModel::new(Duration::from_millis(50), reply_sender.clone());
let mgm_mailbox = Mailbox::new();
let mgm_addr = mgm_mailbox.address();
let pcdu_mailbox = Mailbox::new();
let pcdu_addr = pcdu_mailbox.address();
// Instantiate the simulator
let t0 = MonotonicTime::EPOCH;
let sys_clock = SystemClock::from_system_time(t0, SystemTime::now());
let simulation = SimInit::new().add_model(mgm_sim, mgm_mailbox).init(t0);
let mut pcdu_model = PcduModel::new(reply_sender.clone());
let mut sim_controller = SimController {
sys_clock,
request_receiver,
simulation,
mgm_addr,
pcdu_addr,
pcdu_model
.mgm_switch
.connect(MagnetometerModel::switch_device, &mgm_addr);
// Instantiate the simulator
let sys_clock = SystemClock::from_system_time(start_time, SystemTime::now());
let sim_init = if threading_model == ThreadingModel::Single {
SimInit::with_num_threads(1)
} else {
SimInit::new()
};
let simulation = sim_init
.add_model(mgm_model, mgm_mailbox)
.add_model(pcdu_model, pcdu_mailbox)
.init(start_time);
SimController::new(sys_clock, request_receiver, simulation, mgm_addr, pcdu_addr)
}
fn main() {
let shared_socket_addr = SharedSocketAddr::default();
let (request_sender, request_receiver) = mpsc::channel();
let (reply_sender, reply_receiver) = mpsc::channel();
let t0 = MonotonicTime::EPOCH;
let mut sim_ctrl =
create_sim_controller(ThreadingModel::Default, t0, reply_sender, request_receiver);
// This thread schedules the simulator.
let sim_thread = thread::spawn(move || {
sim_controller.run(t0);
sim_ctrl.run(t0);
});
let mut server = UdpTcServer::new(request_sender, shared_socket_addr.clone()).unwrap();
@ -69,6 +93,8 @@ mod tests {
SimDevice, SimReply, SimRequest,
};
use crate::eps::PcduRequest;
use super::*;
struct SimTestbench {
@ -81,29 +107,12 @@ mod tests {
fn new() -> Self {
let (request_sender, request_receiver) = mpsc::channel();
let (reply_sender, reply_receiver) = mpsc::channel();
// Instantiate models and their mailboxes.
let mgm_sim = MagnetometerModel::new(Duration::from_millis(50), reply_sender.clone());
let mgm_mailbox = Mailbox::new();
let mgm_addr = mgm_mailbox.address();
let pcdu_mailbox = Mailbox::new();
let pcdu_addr = pcdu_mailbox.address();
// Instantiate the simulator
let t0 = MonotonicTime::EPOCH;
let sys_clock = SystemClock::from_system_time(t0, SystemTime::now());
let simulation = SimInit::with_num_threads(1)
.add_model(mgm_sim, mgm_mailbox)
.init(t0);
let sim_ctrl =
create_sim_controller(ThreadingModel::Single, t0, reply_sender, request_receiver);
Self {
sim_controller: SimController {
sys_clock,
request_receiver,
simulation,
mgm_addr,
pcdu_addr,
},
sim_controller: sim_ctrl,
reply_receiver,
request_sender,
}
@ -140,10 +149,7 @@ mod tests {
fn test_basic_mgm_request() {
let mut sim_testbench = SimTestbench::new();
let mgm_request = MgmRequest::RequestSensorData;
let request = SimRequest {
device: SimDevice::Mgm,
request: serde_json::to_string(&mgm_request).unwrap(),
};
let request = SimRequest::new(SimDevice::Mgm, mgm_request);
sim_testbench
.send_request(request)
.expect("sending MGM request failed");
@ -161,5 +167,9 @@ mod tests {
}
#[test]
fn test_basic_mgm_request_switched_on() {}
fn test_basic_mgm_request_switched_on() {
let mut sim_testbench = SimTestbench::new();
let pcdu_request = PcduRequest::RequestSwitchInfo;
let request = SimRequest::new(SimDevice::Pcdu, pcdu_request);
}
}

View File

@ -42,6 +42,15 @@ impl TryFrom<SwitchState> for SwitchStateBinary {
}
}
impl<T: Into<u64>> From<T> for SwitchStateBinary {
fn from(value: T) -> Self {
if value.into() == 0 {
return SwitchStateBinary::Off;
}
SwitchStateBinary::On
}
}
impl From<SwitchStateBinary> for SwitchState {
fn from(value: SwitchStateBinary) -> Self {
match value {