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
[dependencies]
asynchronix = "0.2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
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]
path = "../satrs"

View File

@ -1,6 +1,6 @@
use asynchronix::model::{Model, Output};
use asynchronix::simulation::{EventSlot, Mailbox, SimInit};
use asynchronix::time::{MonotonicTime, Scheduler};
use asynchronix::simulation::{EventSlot, Mailbox, SimInit, Simulation};
use asynchronix::time::{MonotonicTime, Scheduler, SystemClock};
use log::{info, warn};
use satrs::power::{SwitchState, SwitchStateBinary};
use serde::{Deserialize, Serialize};
@ -8,7 +8,7 @@ use std::f64::consts::PI;
use std::future::Future;
use std::net::{SocketAddr, UdpSocket};
use std::sync::{mpsc, Arc, Mutex};
use std::time::Duration;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use std::{io, thread};
// 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 {}
// 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.
//
// This helper is scheduled separately to minimize the delay between the requests and replies.
pub struct UdpTmSender {
reply_receiver: mpsc::Receiver<ValueReply>,
reply_receiver: mpsc::Receiver<SimReply>,
last_sender: Arc<Mutex<Option<SocketAddr>>>,
}
@ -247,21 +241,30 @@ pub struct SimRequest {
}
#[derive(Serialize, Deserialize)]
pub struct ValueReply {
pub struct SimReply {
device: SimDevice,
reply: String,
}
struct ReplyHandler {
reply_sender: mpsc::Sender<ValueReply>,
pub type SharedSocketAddr = Arc<Mutex<Option<SocketAddr>>>;
// 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 {
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")?;
Ok(Self {
socket,
// reply_receiver,
request_sender,
last_sender,
})
}
@ -288,6 +291,9 @@ impl UdpTcServer {
);
continue;
}
self.request_sender.send(sim_req.unwrap()).unwrap();
self.last_sender.lock().unwrap().replace(src);
/*
let sim_req = sim_req.unwrap();
match sim_req.device {
SimDevice::Mgm => {
@ -298,6 +304,7 @@ impl UdpTcServer {
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 {
(time.as_secs() as u64 * 1000) + (time.subsec_nanos() as u64 / 1_000_000)
}
fn main() {
let shared_socket_addr = SharedSocketAddr::default();
let (req_sender, req_receiver) = mpsc::channel();
// Instantiate models and their mailboxes.
let mut mgm_sim = MagnetometerModel::new(Duration::from_millis(50));
@ -339,24 +358,19 @@ fn main() {
let mgm_input_addr = mgm_mailbox.address();
// 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 t0 = MonotonicTime::EPOCH;
let clock = SystemClock::from_system_time(t0, SystemTime::now());
// Instantiate the simulator
let t0 = MonotonicTime::EPOCH; // arbitrary start time
let mut simu = SimInit::new().add_model(mgm_sim, mgm_mailbox).init(t0);
let mut simu = SimInit::new()
.add_model(mgm_sim, mgm_mailbox)
.init_with_clock(t0, clock);
// This thread schedules the simulator.
let sim_thread = thread::spawn(move || {
// The magnetometer will schedule itself at fixed intervals.
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 {
simu.step();
}
@ -364,7 +378,7 @@ fn main() {
// This thread manages the simulator UDP server.
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();
});