add log to file capability for simulation

master
Andrew Johnson 6 years ago
parent 4d67bf5533
commit 7641809096

@ -6,3 +6,6 @@ version = "1.0.0"
floating-duration = "0.1.2"
termion = "1.0"
timebomb = "0.1"
serde = "1.0"
serde_json = "1.0"
serde_derive = "1.0"

@ -4,6 +4,9 @@ mod motor;
use physics::{ElevatorSpecification, ElevatorState, MotorInput, simulate_elevator, DataRecorder, MotorController, MotorVoltage};
use motor::{SmoothMotorController};
#[macro_use] extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate floating_duration;
use std::time::Instant;
use std::env;
@ -53,6 +56,7 @@ struct SimpleDataRecorder<'a, W: 'a + Write>
termwidth: u64,
termheight: u64,
stdout: &'a mut raw::RawTerminal<W>,
log: File,
record_location: Vec<f64>,
record_velocity: Vec<f64>,
record_acceleration: Vec<f64>,
@ -62,10 +66,14 @@ impl<'a, W: Write> DataRecorder for SimpleDataRecorder<'a, W>
{
fn init(&mut self, esp: ElevatorSpecification, est: ElevatorState)
{
self.esp = esp;
self.esp = esp.clone();
self.log.write_all(serde_json::to_string(&esp.clone()).unwrap().as_bytes()).expect("write spec to log");
}
fn poll(&mut self, est: ElevatorState, dst: u64)
{
let datum = (est.clone(), dst);
self.log.write_all(serde_json::to_string(&datum).unwrap().as_bytes()).expect("write state to log");
//5.4. Print realtime statistics
print!("{}{}{}", clear::All, cursor::Goto(1, 1), cursor::Hide);
let carriage_floor = (est.location / self.esp.floor_height).floor();
@ -123,7 +131,7 @@ pub fn run_simulation()
//1. Store location, velocity, and acceleration state
//2. Store motor input voltage
let mut est = ElevatorState {
timestamp: Instant::now(),
timestamp: 0.0,
location: 0.0,
velocity: 0.0,
acceleration: 0.0,
@ -198,13 +206,14 @@ pub fn run_simulation()
termwidth: termsize.map(|(w,_)| w-2).expect("termwidth") as u64,
termheight: termsize.map(|(_,h)| h-2).expect("termheight") as u64,
stdout: &mut io::stdout().into_raw_mode().unwrap(),
log: File::create("simulation.log").expect("log file"),
record_location: Vec::new(),
record_velocity: Vec::new(),
record_acceleration: Vec::new(),
record_voltage: Vec::new()
};
let mut mc = SmoothMotorController {
timestamp: Instant::now(),
timestamp: 0.0,
esp: esp.clone()
};

@ -76,7 +76,7 @@ impl MotorController for SimpleMotorController
pub struct SmoothMotorController
{
pub esp: ElevatorSpecification,
pub timestamp: Instant
pub timestamp: f64
}
impl MotorController for SmoothMotorController
@ -130,8 +130,8 @@ impl MotorController for SmoothMotorController
let going_up = est.location < (dst as f64)*self.esp.floor_height;
//time elapsed since last poll
let dt = est.timestamp.duration_since(self.timestamp)
.as_fractional_secs();
let dt = est.timestamp - self.timestamp;
self.timestamp = est.timestamp;
//Do not exceed maximum velocity
if est.velocity.abs() >= MAX_VELOCITY {

@ -3,14 +3,14 @@ use std::time::Instant;
use floating_duration::{TimeAsFloat, TimeFormat};
use std::{thread, time};
#[derive(Clone)]
#[derive(Clone,Serialize,Deserialize)]
pub enum MotorInput
{
Up { voltage: f64 },
Down { voltage: f64 }
}
#[derive(Clone)]
#[derive(Clone,Serialize,Deserialize)]
pub struct ElevatorSpecification
{
pub floor_count: u64,
@ -18,10 +18,10 @@ pub struct ElevatorSpecification
pub carriage_weight: f64
}
#[derive(Clone)]
#[derive(Clone,Serialize,Deserialize)]
pub struct ElevatorState
{
pub timestamp: Instant,
pub timestamp: f64,
pub location: f64,
pub velocity: f64,
pub acceleration: f64,
@ -81,13 +81,15 @@ pub fn simulate_elevator<MC: MotorController, DR: DataRecorder>(esp: ElevatorSpe
dr.init(esp.clone(), est.clone());
//5. Loop while there are remaining floor requests
let original_ts = Instant::now();
while req.len() > 0
{
//5.1. Update location, velocity, and acceleration
let now = Instant::now();
let dt = now.duration_since(est.timestamp)
let ts = now.duration_since(original_ts)
.as_fractional_secs();
est.timestamp = now;
let dt = ts - est.timestamp;
est.timestamp = ts;
est.location = est.location + est.velocity * dt;
est.velocity = est.velocity + est.acceleration * dt;

Loading…
Cancel
Save