mirror of
https://github.com/andrew-johnson-4/Hands-On-Functional-Programming-in-Rust
synced 2024-11-18 03:25:33 +00:00
add log to file capability for simulation
This commit is contained in:
parent
4d67bf5533
commit
7641809096
@ -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"
|
||||||
|
@ -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()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user