abstreet/sim/tests/physics.rs

59 lines
1.8 KiB
Rust
Raw Normal View History

extern crate dimensioned;
extern crate geom;
extern crate sim;
use dimensioned::si;
use geom::EPSILON_DIST;
use sim::kinematics::{results_of_accel_for_one_tick, Vehicle, EPSILON_SPEED};
use sim::{CarID, Distance, Speed};
// TODO table driven test style?
#[test]
fn test_accel_to_stop_in_dist_easy() {
test_accel_to_stop_in_dist(23.554161711896512 * si::M, 8.5817572532688 * si::MPS)
}
#[test]
fn test_accel_to_stop_in_dist_hard() {
test_accel_to_stop_in_dist(4.543071997281501 * si::M, 0.003911613164279909 * si::MPS);
}
fn test_accel_to_stop_in_dist(orig_dist_left: Distance, orig_speed: Speed) {
let vehicle = Vehicle {
id: CarID(0),
length: 3.0 * si::M,
max_accel: 2.7 * si::MPS2,
max_deaccel: -2.7 * si::MPS2,
};
// Can we successfully stop in a certain distance from some initial conditions?
let mut speed = orig_speed;
let mut dist_left = orig_dist_left;
for step in 0..100 {
let desired_accel = vehicle.accel_to_stop_in_dist(speed, dist_left).unwrap();
let accel = vehicle.clamp_accel(desired_accel);
println!(
"Step {}: speed {}, dist_left {}, want accel {} but doing {}",
step, speed, dist_left, desired_accel, accel
);
let (dist_covered, new_speed) = results_of_accel_for_one_tick(speed, accel);
speed = new_speed;
dist_left -= dist_covered;
println!(" Result: speed {}, dist_left {}", speed, dist_left);
if dist_left < -EPSILON_DIST {
panic!("We overshot too much!");
}
if dist_left <= EPSILON_DIST {
if speed > EPSILON_SPEED {
panic!("Finished, but going too fast");
}
return;
}
}
panic!("Didn't finish; only covered {}", orig_dist_left - dist_left);
}