add log to file capability for simulation

This commit is contained in:
Andrew Johnson 2018-04-07 14:17:35 -06:00
parent 4d67bf5533
commit 7641809096
4 changed files with 26 additions and 12 deletions

View File

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

View File

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

View File

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

View File

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