data recorder

master
Andrew Johnson 6 years ago
parent 7f4a5b6c03
commit ef518e5dd6

@ -8,6 +8,18 @@ pub trait Building
fn get_floor_heights(&self) -> Vec<f64>;
fn get_carriage_weight(&self) -> f64;
fn clone(&self) -> Box<Building>;
fn serialize(&self) -> u64;
}
pub fn deserialize(n: u64) -> Box<Building>
{
if n==1 {
Box::new(Building1)
} else if n==2 {
Box::new(Building2)
} else {
Box::new(Building3)
}
}
pub struct Building1;
@ -31,6 +43,10 @@ impl Building for Building1 {
fn clone(&self) -> Box<Building> {
Box::new(Building1)
}
fn serialize(&self) -> u64
{
2
}
}
pub struct Building2;
@ -54,6 +70,10 @@ impl Building for Building2 {
fn clone(&self) -> Box<Building> {
Box::new(Building2)
}
fn serialize(&self) -> u64
{
2
}
}
pub struct Building3;
@ -77,4 +97,8 @@ impl Building for Building3 {
fn clone(&self) -> Box<Building> {
Box::new(Building3)
}
fn serialize(&self) -> u64
{
3
}
}

@ -1,113 +1,86 @@
use buildings::{Building};
use physics::{ElevatorState};
pub trait DataRecorder
{
fn init(&mut self, esp: Box<Building>, est: ElevatorState);
fn poll(&mut self, est: ElevatorState, dst: u64);
fn summary(&mut self);
}
pub struct SimpleDataRecorder;
pub fn newSimpleDataRecorder() -> SimpleDataRecorder
{
SimpleDataRecorder
}
/*
use physics::{ElevatorSpecification, ElevatorState, MotorInput, SimpleMotorInput, simulate_elevator, DataRecorder, MotorController, MotorVoltage,
ElevatorStateClone, ElevatorSpecificationClone, Motor, SimpleMotor};
use motor::{SmoothMotorController, SimpleMotorController};
#[macro_use] extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate floating_duration;
use std::time::Instant;
use std::env;
use std::fs::File;
use std::io::{self, Read, Write};
use std::io::prelude::*;
extern crate termion;
use termion;
use termion::{clear, cursor, style};
use termion::raw;
use termion::raw::IntoRawMode;
use termion::input::TermRead;
use termion::event::Key;
use std::cmp;
fn variable_summary<W: Write>(stdout: &mut raw::RawTerminal<W>, vname: String, data: &Vec<f64>) {
let (avg, dev) = variable_summary_stats(data);
variable_summary_print(stdout, vname, avg, dev);
}
fn variable_summary_stats(data: &Vec<f64>) -> (f64, f64)
{
//calculate statistics
let N = data.len();
let sum = data.clone().into_iter()
.fold(0.0, |a, b| a+b);
let avg = sum / (N as f64);
let dev = (
data.clone().into_iter()
.map(|v| (v - avg).powi(2))
.fold(0.0, |a, b| a+b)
/ (N as f64)
).sqrt();
(avg, dev)
}
use serde_json;
fn variable_summary_print<W: Write>(stdout: &mut raw::RawTerminal<W>, vname: String, avg: f64, dev: f64)
pub trait DataRecorder
{
//print formatted output
write!(stdout, "Average of {:25}{:.6}\r\n", vname, avg);
write!(stdout, "Standard deviation of {:14}{:.6}\r\n", vname, dev);
write!(stdout, "\r\n");
fn init(&mut self, esp: Box<Building>, est: ElevatorState);
fn poll(&mut self, est: ElevatorState, dst: u64);
fn summary(&mut self);
}
struct SimpleDataRecorder<'a, W: 'a + Write>
struct SimpleDataRecorder<W: Write>
{
esp: ElevatorSpecification,
esp: Box<Building>,
termwidth: u64,
termheight: u64,
stdout: &'a mut raw::RawTerminal<W>,
stdout: raw::RawTerminal<W>,
log: File,
record_location: Vec<f64>,
record_velocity: Vec<f64>,
record_acceleration: Vec<f64>,
record_voltage: Vec<f64>,
record_force: Vec<f64>,
}
pub fn newSimpleDataRecorder(esp: Box<Building>) -> Box<DataRecorder>
{
let termsize = termion::terminal_size().ok();
Box::new(SimpleDataRecorder {
esp: esp.clone(),
termwidth: termsize.map(|(w,_)| w-2).expect("termwidth") as u64,
termheight: termsize.map(|(_,h)| h-2).expect("termheight") as u64,
stdout: 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_force: Vec::new()
})
}
impl<'a, W: Write> DataRecorder for SimpleDataRecorder<'a, W>
fn getCarriageFloor(floorHeights: Vec<f64>, height: f64) -> u64
{
0
}
impl<W: Write> DataRecorder for SimpleDataRecorder<W>
{
fn init(&mut self, esp: ElevatorSpecification, est: ElevatorState)
fn init(&mut self, esp: Box<Building>, est: ElevatorState)
{
self.esp = esp.clone();
self.log.write_all(serde_json::to_string(&esp.clone().dump()).unwrap().as_bytes()).expect("write spec to log");
self.log.write_all(serde_json::to_string(&esp.serialize()).unwrap().as_bytes()).expect("write spec to log");
self.log.write_all(b"\r\n").expect("write spec to log");
}
fn poll(&mut self, est: ElevatorState, dst: u64)
{
let datum = (est.clone().dump(), dst);
self.log.write_all(serde_json::to_string(&datum).unwrap().as_bytes()).expect("write state to log");
let datum = serde_json::to_string(&(est.clone(), dst)).unwrap();
self.log.write_all(datum.as_bytes()).expect("write state to log");
self.log.write_all(b"\r\n").expect("write state to log");
self.record_location.push(est.location);
self.record_velocity.push(est.velocity);
self.record_acceleration.push(est.acceleration);
self.record_voltage.push(est.motor_input.voltage());
self.record_force.push(est.motor_input);
//5.4. Print realtime statistics
print!("{}{}{}", clear::All, cursor::Goto(1, 1), cursor::Hide);
let carriage_floor = (est.location / self.esp.floor_height).floor();
let carriage_floor = if carriage_floor < 1.0 { 0 } else { carriage_floor as u64 };
let carriage_floor = cmp::min(carriage_floor, self.esp.floor_count-1);
let carriage_floor = getCarriageFloor(self.esp.get_floor_heights(), est.location);
let floor_count = self.esp.get_floor_heights().len() as u64;
let mut terminal_buffer = vec![' ' as u8; (self.termwidth*self.termheight) as usize];
for ty in 0..self.esp.floor_count
for ty in 0..floor_count
{
terminal_buffer[ (ty*self.termwidth + 0) as usize ] = '[' as u8;
terminal_buffer[ (ty*self.termwidth + 1) as usize ] =
if (ty as u64)==((self.esp.floor_count-1)-carriage_floor) { 'X' as u8 }
if (ty as u64)==((floor_count-1)-carriage_floor) { 'X' as u8 }
else { ' ' as u8 };
terminal_buffer[ (ty*self.termwidth + 2) as usize ] = ']' as u8;
terminal_buffer[ (ty*self.termwidth + self.termwidth-2) as usize ] = '\r' as u8;
@ -118,7 +91,7 @@ impl<'a, W: Write> DataRecorder for SimpleDataRecorder<'a, W>
format!("Location {:.06}", est.location),
format!("Velocity {:.06}", est.velocity),
format!("Acceleration {:.06}", est.acceleration),
format!("Voltage [up-down] {:.06}", est.motor_input.voltage()),
format!("Force [up-down] {:.06}", est.motor_input),
];
for sy in 0..stats.len()
{
@ -130,8 +103,6 @@ impl<'a, W: Write> DataRecorder for SimpleDataRecorder<'a, W>
write!(self.stdout, "{}", String::from_utf8(terminal_buffer).ok().unwrap());
self.stdout.flush().unwrap();
}
}
impl<'a, W: Write> DataRecorderSummary for SimpleDataRecorder<'a, W> {
fn summary(&mut self)
{
//6 Calculate and print summary statistics
@ -139,9 +110,36 @@ impl<'a, W: Write> DataRecorderSummary for SimpleDataRecorder<'a, W> {
variable_summary(&mut self.stdout, "location".to_string(), &self.record_location);
variable_summary(&mut self.stdout, "velocity".to_string(), &self.record_velocity);
variable_summary(&mut self.stdout, "acceleration".to_string(), &self.record_acceleration);
variable_summary(&mut self.stdout, "voltage".to_string(), &self.record_voltage);
variable_summary(&mut self.stdout, "force".to_string(), &self.record_force);
self.stdout.flush().unwrap();
}
}
*/
fn variable_summary<W: Write>(stdout: &mut raw::RawTerminal<W>, vname: String, data: &Vec<f64>) {
let (avg, dev) = variable_summary_stats(data);
variable_summary_print(stdout, vname, avg, dev);
}
fn variable_summary_stats(data: &Vec<f64>) -> (f64, f64)
{
//calculate statistics
let N = data.len();
let sum = data.clone().into_iter()
.fold(0.0, |a, b| a+b);
let avg = sum / (N as f64);
let dev = (
data.clone().into_iter()
.map(|v| (v - avg).powi(2))
.fold(0.0, |a, b| a+b)
/ (N as f64)
).sqrt();
(avg, dev)
}
fn variable_summary_print<W: Write>(stdout: &mut raw::RawTerminal<W>, vname: String, avg: f64, dev: f64)
{
//print formatted output
write!(stdout, "Average of {:25}{:.6}\r\n", vname, avg);
write!(stdout, "Standard deviation of {:14}{:.6}\r\n", vname, dev);
write!(stdout, "\r\n");
}

@ -2,6 +2,7 @@ extern crate libc;
#[macro_use] extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate termion;
pub mod motor_controllers;
pub mod elevator_drivers;

@ -1,4 +1,4 @@
use physics::{ElevatorState};
use physics::{ElevatorState, MAX_JERK, MAX_ACCELERATION, MAX_VELOCITY};
use buildings::{Building};
pub trait MotionController
@ -35,10 +35,6 @@ impl MotionController for SmoothMotionController
{
//5.3. Adjust motor control to process next floor request
let MAX_JERK = 0.2;
let MAX_ACCELERATION = 2.0;
let MAX_VELOCITY = 5.0;
//it will take t seconds to reach max from max
let t_accel = MAX_ACCELERATION / MAX_JERK;
let t_veloc = MAX_VELOCITY / MAX_ACCELERATION;

@ -7,3 +7,7 @@ pub struct ElevatorState {
pub acceleration: f64,
pub motor_input: f64
}
pub const MAX_JERK: f64 = 0.2;
pub const MAX_ACCELERATION: f64 = 2.0;
pub const MAX_VELOCITY: f64 = 5.0;

@ -108,7 +108,7 @@ pub fn run_simulation()
}
}
let mut dr = newSimpleDataRecorder();
let mut dr = newSimpleDataRecorder(esp.clone());
let mut mc = SmoothMotionController {
timestamp: 0.0,
esp: esp.clone()

Loading…
Cancel
Save