SimController ctor
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
use std::{sync::mpsc, time::Duration};
|
||||
use std::{
|
||||
sync::mpsc,
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
|
||||
use nexosim::{
|
||||
simulation::{Address, Simulation},
|
||||
simulation::{Address, Mailbox, SimInit, Simulation},
|
||||
time::{Clock, MonotonicTime, SystemClock},
|
||||
};
|
||||
use satrs_minisim::{
|
||||
@@ -22,51 +25,85 @@ const MGM_REQ_WIRETAPPING: bool = false;
|
||||
const PCDU_REQ_WIRETAPPING: bool = false;
|
||||
const MGT_REQ_WIRETAPPING: bool = false;
|
||||
|
||||
pub struct ModelAddrWrapper {
|
||||
mgm_0_addr: Address<MgmModel>,
|
||||
mgm_1_addr: Address<MgmModel>,
|
||||
pcdu_addr: Address<PcduModel>,
|
||||
mgt_addr: Address<MgtModel>,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ThreadingModel {
|
||||
Default = 0,
|
||||
Single = 1,
|
||||
}
|
||||
|
||||
struct ModelAddresses {
|
||||
mgm_0: Address<MgmModel>,
|
||||
mgm_1: Address<MgmModel>,
|
||||
pcdu: Address<PcduModel>,
|
||||
mgt: Address<MgtModel>,
|
||||
}
|
||||
|
||||
// The simulation controller processes requests and drives the simulation.
|
||||
pub struct SimController {
|
||||
pub sys_clock: SystemClock,
|
||||
pub request_receiver: mpsc::Receiver<SimRequestWithTime>,
|
||||
pub reply_sender: mpsc::Sender<SimReply>,
|
||||
sys_clock: SystemClock,
|
||||
request_receiver: mpsc::Receiver<SimRequestWithTime>,
|
||||
reply_sender: mpsc::Sender<SimReply>,
|
||||
pub simulation: Simulation,
|
||||
pub addr_wrapper: ModelAddrWrapper,
|
||||
addrs: ModelAddresses,
|
||||
}
|
||||
|
||||
impl ModelAddrWrapper {
|
||||
pub fn new(
|
||||
mgm_0_addr: Address<MgmModel>,
|
||||
mgm_1_addr: Address<MgmModel>,
|
||||
pcdu_addr: Address<PcduModel>,
|
||||
mgt_addr: Address<MgtModel>,
|
||||
) -> Self {
|
||||
Self {
|
||||
mgm_0_addr,
|
||||
mgm_1_addr,
|
||||
pcdu_addr,
|
||||
mgt_addr,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl SimController {
|
||||
pub fn new(
|
||||
sys_clock: SystemClock,
|
||||
request_receiver: mpsc::Receiver<SimRequestWithTime>,
|
||||
threading_model: ThreadingModel,
|
||||
start_time: MonotonicTime,
|
||||
reply_sender: mpsc::Sender<SimReply>,
|
||||
simulation: Simulation,
|
||||
addr_wrapper: ModelAddrWrapper,
|
||||
request_receiver: mpsc::Receiver<SimRequestWithTime>,
|
||||
) -> Self {
|
||||
let mgm_0_model = MgmModel::new(mgm::Id::Mgm0, reply_sender.clone());
|
||||
let mgm_1_model = MgmModel::new(mgm::Id::Mgm1, reply_sender.clone());
|
||||
let mut pcdu_model = PcduModel::new(reply_sender.clone());
|
||||
let mut mgt_model = MgtModel::new(reply_sender.clone());
|
||||
|
||||
let mgm_0_mailbox = Mailbox::new();
|
||||
let mgm_1_mailbox = Mailbox::new();
|
||||
let pcdu_mailbox = Mailbox::new();
|
||||
let mgt_mailbox = Mailbox::new();
|
||||
let addrs = ModelAddresses {
|
||||
mgm_0: mgm_0_mailbox.address(),
|
||||
mgm_1: mgm_1_mailbox.address(),
|
||||
pcdu: pcdu_mailbox.address(),
|
||||
mgt: mgt_mailbox.address(),
|
||||
};
|
||||
|
||||
pcdu_model
|
||||
.mgm_0_switch
|
||||
.connect(MgmModel::switch_device, &addrs.mgm_0);
|
||||
pcdu_model
|
||||
.mgm_1_switch
|
||||
.connect(MgmModel::switch_device, &addrs.mgm_1);
|
||||
pcdu_model
|
||||
.mgt_switch
|
||||
.connect(MgtModel::switch_device, &addrs.mgt);
|
||||
mgt_model
|
||||
.gen_magnetic_field
|
||||
.connect(MgmModel::apply_external_magnetic_field, &addrs.mgm_0);
|
||||
mgt_model
|
||||
.gen_magnetic_field
|
||||
.connect(MgmModel::apply_external_magnetic_field, &addrs.mgm_1);
|
||||
|
||||
let sim_init = if threading_model == ThreadingModel::Single {
|
||||
SimInit::with_num_threads(1)
|
||||
} else {
|
||||
SimInit::new()
|
||||
};
|
||||
let (simulation, _scheduler) = sim_init
|
||||
.add_model(mgm_0_model, mgm_0_mailbox, "MGM 0 model")
|
||||
.add_model(mgm_1_model, mgm_1_mailbox, "MGM 1 model")
|
||||
.add_model(pcdu_model, pcdu_mailbox, "PCDU model")
|
||||
.add_model(mgt_model, mgt_mailbox, "MGT model")
|
||||
.init(start_time)
|
||||
.unwrap();
|
||||
Self {
|
||||
sys_clock,
|
||||
sys_clock: SystemClock::from_system_time(start_time, SystemTime::now()),
|
||||
request_receiver,
|
||||
reply_sender,
|
||||
simulation,
|
||||
addr_wrapper,
|
||||
addrs,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,8 +162,8 @@ impl SimController {
|
||||
|
||||
fn handle_mgm_request(&mut self, mgm_id: mgm::Id, mgm_request: mgm::Request) {
|
||||
let addr = match mgm_id {
|
||||
mgm::Id::Mgm0 => &self.addr_wrapper.mgm_0_addr,
|
||||
mgm::Id::Mgm1 => &self.addr_wrapper.mgm_1_addr,
|
||||
mgm::Id::Mgm0 => &self.addrs.mgm_0,
|
||||
mgm::Id::Mgm1 => &self.addrs.mgm_1,
|
||||
};
|
||||
if MGM_REQ_WIRETAPPING {
|
||||
log::info!("received {mgm_id:?} request: {mgm_request:?}");
|
||||
@@ -153,20 +190,12 @@ impl SimController {
|
||||
match pcdu_request {
|
||||
PcduRequest::RequestSwitchInfo => {
|
||||
self.simulation
|
||||
.process_event(
|
||||
PcduModel::request_switch_info,
|
||||
(),
|
||||
&self.addr_wrapper.pcdu_addr,
|
||||
)
|
||||
.process_event(PcduModel::request_switch_info, (), &self.addrs.pcdu)
|
||||
.unwrap();
|
||||
}
|
||||
PcduRequest::SwitchDevice { switch, state } => {
|
||||
self.simulation
|
||||
.process_event(
|
||||
PcduModel::switch_device,
|
||||
(switch, state),
|
||||
&self.addr_wrapper.pcdu_addr,
|
||||
)
|
||||
.process_event(PcduModel::switch_device, (switch, state), &self.addrs.pcdu)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
@@ -179,19 +208,11 @@ impl SimController {
|
||||
match mgt_request {
|
||||
mgt::Request::ApplyTorque { duration, dipole } => self
|
||||
.simulation
|
||||
.process_event(
|
||||
MgtModel::apply_torque,
|
||||
(duration, dipole),
|
||||
&self.addr_wrapper.mgt_addr,
|
||||
)
|
||||
.process_event(MgtModel::apply_torque, (duration, dipole), &self.addrs.mgt)
|
||||
.unwrap(),
|
||||
mgt::Request::RequestHk => self
|
||||
.simulation
|
||||
.process_event(
|
||||
MgtModel::request_housekeeping_data,
|
||||
(),
|
||||
&self.addr_wrapper.mgt_addr,
|
||||
)
|
||||
.process_event(MgtModel::request_housekeeping_data, (), &self.addrs.mgt)
|
||||
.unwrap(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
use acs::{mgm::MgmModel, mgt::MgtModel};
|
||||
use controller::{ModelAddrWrapper, SimController};
|
||||
use eps::PcduModel;
|
||||
use nexosim::simulation::{Mailbox, SimInit};
|
||||
use nexosim::time::{MonotonicTime, SystemClock};
|
||||
use satrs_minisim::acs::mgm;
|
||||
use controller::{SimController, ThreadingModel};
|
||||
use nexosim::time::MonotonicTime;
|
||||
use satrs_minisim::udp::SIM_CTRL_PORT;
|
||||
use satrs_minisim::{SimReply, SimRequestWithTime};
|
||||
use std::sync::mpsc;
|
||||
use std::thread;
|
||||
use std::time::SystemTime;
|
||||
use udp::SimUdpServer;
|
||||
|
||||
mod acs;
|
||||
@@ -19,76 +13,12 @@ mod test_helpers;
|
||||
mod time;
|
||||
mod udp;
|
||||
|
||||
#[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<SimRequestWithTime>,
|
||||
) -> SimController {
|
||||
// Instantiate models and their mailboxes.
|
||||
let mgm_0_model = MgmModel::new(mgm::Id::Mgm0, reply_sender.clone());
|
||||
let mgm_1_model = MgmModel::new(mgm::Id::Mgm1, reply_sender.clone());
|
||||
|
||||
let mgm_0_mailbox = Mailbox::new();
|
||||
let mgm_0_addr = mgm_0_mailbox.address();
|
||||
let mgm_1_mailbox = Mailbox::new();
|
||||
let mgm_1_addr = mgm_1_mailbox.address();
|
||||
let pcdu_mailbox = Mailbox::new();
|
||||
let pcdu_addr = pcdu_mailbox.address();
|
||||
let mgt_mailbox = Mailbox::new();
|
||||
let mgt_addr = mgt_mailbox.address();
|
||||
|
||||
let mut pcdu_model = PcduModel::new(reply_sender.clone());
|
||||
pcdu_model
|
||||
.mgm_0_switch
|
||||
.connect(MgmModel::switch_device, &mgm_0_addr);
|
||||
pcdu_model
|
||||
.mgm_1_switch
|
||||
.connect(MgmModel::switch_device, &mgm_1_addr);
|
||||
|
||||
let mut mgt_model = MgtModel::new(reply_sender.clone());
|
||||
// Input connections.
|
||||
pcdu_model
|
||||
.mgt_switch
|
||||
.connect(MgtModel::switch_device, &mgt_addr);
|
||||
// Output connections.
|
||||
mgt_model
|
||||
.gen_magnetic_field
|
||||
.connect(MgmModel::apply_external_magnetic_field, &mgm_0_addr);
|
||||
mgt_model
|
||||
.gen_magnetic_field
|
||||
.connect(MgmModel::apply_external_magnetic_field, &mgm_1_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 addrs = ModelAddrWrapper::new(mgm_0_addr, mgm_1_addr, pcdu_addr, mgt_addr);
|
||||
let (simulation, _scheduler) = sim_init
|
||||
.add_model(mgm_0_model, mgm_0_mailbox, "MGM 0 model")
|
||||
.add_model(mgm_1_model, mgm_1_mailbox, "MGM 1 model")
|
||||
.add_model(pcdu_model, pcdu_mailbox, "PCDU model")
|
||||
.add_model(mgt_model, mgt_mailbox, "MGT model")
|
||||
.init(start_time)
|
||||
.unwrap();
|
||||
SimController::new(sys_clock, request_receiver, reply_sender, simulation, addrs)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
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);
|
||||
SimController::new(ThreadingModel::Default, t0, reply_sender, request_receiver);
|
||||
// Configure logger at runtime
|
||||
fern::Dispatch::new()
|
||||
// Perform allocation-free log formatting
|
||||
|
||||
@@ -7,7 +7,7 @@ use nexosim::{
|
||||
};
|
||||
use satrs_minisim::{SimReply, SimRequest, SimRequestWithTime};
|
||||
|
||||
use crate::{controller::SimController, create_sim_controller, ThreadingModel};
|
||||
use crate::controller::{SimController, ThreadingModel};
|
||||
|
||||
pub struct SimTestbench {
|
||||
pub sim_controller: SimController,
|
||||
@@ -21,7 +21,7 @@ impl SimTestbench {
|
||||
let (reply_sender, reply_receiver) = mpsc::channel();
|
||||
let t0 = MonotonicTime::EPOCH;
|
||||
let sim_ctrl =
|
||||
create_sim_controller(ThreadingModel::Single, t0, reply_sender, request_receiver);
|
||||
SimController::new(ThreadingModel::Single, t0, reply_sender, request_receiver);
|
||||
|
||||
Self {
|
||||
sim_controller: sim_ctrl,
|
||||
|
||||
Reference in New Issue
Block a user