continuing the simulation
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-06 14:16:40 +01:00
parent b622e83731
commit 0a41de5e70
Signed by: muellerr
GPG Key ID: A649FB78196E3849
2 changed files with 47 additions and 28 deletions

View File

@ -6,10 +6,15 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
asynchronix = "0.2"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
log = "0.4" log = "0.4"
[dependencies.asynchronix]
version = "0.2"
path = "../../asynchronix/asynchronix"
# git = "https://github.com/us-irs/asynchronix.git"
# branch = "clock-not-sendable"
[dependencies.satrs] [dependencies.satrs]
path = "../satrs" path = "../satrs"

View File

@ -1,6 +1,6 @@
use asynchronix::model::{Model, Output}; use asynchronix::model::{Model, Output};
use asynchronix::simulation::{EventSlot, Mailbox, SimInit}; use asynchronix::simulation::{EventSlot, Mailbox, SimInit, Simulation};
use asynchronix::time::{MonotonicTime, Scheduler}; use asynchronix::time::{MonotonicTime, Scheduler, SystemClock};
use log::{info, warn}; use log::{info, warn};
use satrs::power::{SwitchState, SwitchStateBinary}; use satrs::power::{SwitchState, SwitchStateBinary};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -8,7 +8,7 @@ use std::f64::consts::PI;
use std::future::Future; use std::future::Future;
use std::net::{SocketAddr, UdpSocket}; use std::net::{SocketAddr, UdpSocket};
use std::sync::{mpsc, Arc, Mutex}; use std::sync::{mpsc, Arc, Mutex};
use std::time::Duration; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use std::{io, thread}; use std::{io, thread};
// Normally, small magnetometers generate their output as a signed 16 bit raw format or something // Normally, small magnetometers generate their output as a signed 16 bit raw format or something
@ -219,17 +219,11 @@ impl MagnetorquerModel {
impl Model for MagnetorquerModel {} impl Model for MagnetorquerModel {}
// A UDP server which handles all TC received by a client application.
pub struct UdpTcServer {
socket: UdpSocket,
last_sender: Arc<Mutex<Option<SocketAddr>>>,
}
// A helper object which sends back all replies to the UDP client. // A helper object which sends back all replies to the UDP client.
// //
// This helper is scheduled separately to minimize the delay between the requests and replies. // This helper is scheduled separately to minimize the delay between the requests and replies.
pub struct UdpTmSender { pub struct UdpTmSender {
reply_receiver: mpsc::Receiver<ValueReply>, reply_receiver: mpsc::Receiver<SimReply>,
last_sender: Arc<Mutex<Option<SocketAddr>>>, last_sender: Arc<Mutex<Option<SocketAddr>>>,
} }
@ -247,21 +241,30 @@ pub struct SimRequest {
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct ValueReply { pub struct SimReply {
device: SimDevice, device: SimDevice,
reply: String, reply: String,
} }
struct ReplyHandler { pub type SharedSocketAddr = Arc<Mutex<Option<SocketAddr>>>;
reply_sender: mpsc::Sender<ValueReply>,
// A UDP server which handles all TC received by a client application.
pub struct UdpTcServer {
socket: UdpSocket,
request_sender: mpsc::Sender<SimRequest>,
last_sender: SharedSocketAddr,
} }
impl UdpTcServer { impl UdpTcServer {
pub fn new(reply_receiver: mpsc::Receiver<ValueReply>) -> io::Result<Self> { pub fn new(
request_sender: mpsc::Sender<SimRequest>,
last_sender: SharedSocketAddr,
) -> io::Result<Self> {
let socket = UdpSocket::bind("0.0.0.0:7303")?; let socket = UdpSocket::bind("0.0.0.0:7303")?;
Ok(Self { Ok(Self {
socket, socket,
// reply_receiver, request_sender,
last_sender,
}) })
} }
@ -288,6 +291,9 @@ impl UdpTcServer {
); );
continue; continue;
} }
self.request_sender.send(sim_req.unwrap()).unwrap();
self.last_sender.lock().unwrap().replace(src);
/*
let sim_req = sim_req.unwrap(); let sim_req = sim_req.unwrap();
match sim_req.device { match sim_req.device {
SimDevice::Mgm => { SimDevice::Mgm => {
@ -298,6 +304,7 @@ impl UdpTcServer {
self.handle_pcdu_request(&src, &sim_req); self.handle_pcdu_request(&src, &sim_req);
} }
} }
*/
} }
} }
@ -327,11 +334,23 @@ impl UdpTcServer {
} }
} }
// The simulation controller processes requests and drives the simulation.
// TODO: How do we process requests and drive the simulation at the same time?
pub struct SimController {
pub request_receiver: mpsc::Receiver<SimRequest>,
pub simulation: Simulation,
}
impl SimController {}
pub fn current_millis(time: MonotonicTime) -> u64 { pub fn current_millis(time: MonotonicTime) -> u64 {
(time.as_secs() as u64 * 1000) + (time.subsec_nanos() as u64 / 1_000_000) (time.as_secs() as u64 * 1000) + (time.subsec_nanos() as u64 / 1_000_000)
} }
fn main() { fn main() {
let shared_socket_addr = SharedSocketAddr::default();
let (req_sender, req_receiver) = mpsc::channel();
// Instantiate models and their mailboxes. // Instantiate models and their mailboxes.
let mut mgm_sim = MagnetometerModel::new(Duration::from_millis(50)); let mut mgm_sim = MagnetometerModel::new(Duration::from_millis(50));
@ -339,24 +358,19 @@ fn main() {
let mgm_input_addr = mgm_mailbox.address(); let mgm_input_addr = mgm_mailbox.address();
// Keep handles to the main input and output. // Keep handles to the main input and output.
let output_slot = mgm_sim.sensor_values.connect_slot().0; // let output_slot = mgm_sim.sensor_values.connect_slot().0;
// let output_slot_2 = mgm_sim.sensor_values.connect_slot().0; // let output_slot_2 = mgm_sim.sensor_values.connect_slot().0;
let t0 = MonotonicTime::EPOCH;
let clock = SystemClock::from_system_time(t0, SystemTime::now());
// Instantiate the simulator // Instantiate the simulator
let t0 = MonotonicTime::EPOCH; // arbitrary start time let mut simu = SimInit::new()
let mut simu = SimInit::new().add_model(mgm_sim, mgm_mailbox).init(t0); .add_model(mgm_sim, mgm_mailbox)
.init_with_clock(t0, clock);
// This thread schedules the simulator. // This thread schedules the simulator.
let sim_thread = thread::spawn(move || { let sim_thread = thread::spawn(move || {
// The magnetometer will schedule itself at fixed intervals. // The magnetometer will schedule itself at fixed intervals.
simu.send_event(MagnetometerModel::start, (), &mgm_input_addr); simu.send_event(MagnetometerModel::start, (), &mgm_input_addr);
/*
for _ in 0..100 {
simu.step();
let tuple = output_slot_2.take().expect("expected output");
println!("output at {:?}: {tuple:?}", simu.time());
}
*/
loop { loop {
simu.step(); simu.step();
} }
@ -364,7 +378,7 @@ fn main() {
// This thread manages the simulator UDP server. // This thread manages the simulator UDP server.
let udp_thread = thread::spawn(move || { let udp_thread = thread::spawn(move || {
let mut server = UdpTcServer::new(output_slot).unwrap(); let mut server = UdpTcServer::new(req_sender, shared_socket_addr).unwrap();
server.run(); server.run();
}); });