mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-28 08:53:26 +03:00
stop recalculating everything constantly
This commit is contained in:
parent
6354a09293
commit
6387853fa0
@ -2,69 +2,74 @@ use geom::{Acceleration, Distance, Duration, Speed};
|
|||||||
use map_model::{LaneID, Map, Traversable};
|
use map_model::{LaneID, Map, Traversable};
|
||||||
use sim::{CarID, CarState, DrawCarInput, VehicleType};
|
use sim::{CarID, CarState, DrawCarInput, VehicleType};
|
||||||
|
|
||||||
pub fn get_state(time: Duration, map: &Map) -> Vec<DrawCarInput> {
|
pub struct World {
|
||||||
let lane = map.get_l(LaneID(1250));
|
leader: Car,
|
||||||
let speed_limit = map.get_parent(lane.id).get_speed_limit();
|
follower: Car,
|
||||||
|
}
|
||||||
|
|
||||||
let mut leader = Car {
|
impl World {
|
||||||
id: CarID::tmp_new(0, VehicleType::Car),
|
pub fn new(map: &Map) -> World {
|
||||||
state: CarState::Moving,
|
let lane = map.get_l(LaneID(1250));
|
||||||
car_length: Distance::meters(5.0),
|
let speed_limit = map.get_parent(lane.id).get_speed_limit();
|
||||||
max_accel: Acceleration::meters_per_second_squared(2.5),
|
|
||||||
max_deaccel: Acceleration::meters_per_second_squared(-3.0),
|
|
||||||
intervals: Vec::new(),
|
|
||||||
start_dist: Distance::meters(5.0),
|
|
||||||
start_time: Duration::ZERO,
|
|
||||||
};
|
|
||||||
leader.accel_from_rest_to_speed_limit(0.5 * speed_limit);
|
|
||||||
leader.freeflow(Duration::seconds(10.0));
|
|
||||||
leader.deaccel_to_rest();
|
|
||||||
|
|
||||||
let mut follower = Car {
|
let mut leader = Car {
|
||||||
id: CarID::tmp_new(1, VehicleType::Car),
|
id: CarID::tmp_new(0, VehicleType::Car),
|
||||||
state: CarState::Stuck,
|
state: CarState::Moving,
|
||||||
car_length: Distance::meters(5.0),
|
car_length: Distance::meters(5.0),
|
||||||
max_accel: Acceleration::meters_per_second_squared(4.5),
|
max_accel: Acceleration::meters_per_second_squared(2.5),
|
||||||
max_deaccel: Acceleration::meters_per_second_squared(-2.0),
|
max_deaccel: Acceleration::meters_per_second_squared(-3.0),
|
||||||
intervals: Vec::new(),
|
intervals: Vec::new(),
|
||||||
start_dist: Distance::meters(5.0),
|
start_dist: Distance::meters(5.0),
|
||||||
start_time: Duration::seconds(4.0),
|
start_time: Duration::ZERO,
|
||||||
};
|
};
|
||||||
follower.accel_from_rest_to_speed_limit(speed_limit);
|
leader.accel_from_rest_to_speed_limit(0.5 * speed_limit);
|
||||||
follower.freeflow(Duration::seconds(10.0));
|
leader.freeflow(Duration::seconds(10.0));
|
||||||
follower.deaccel_to_rest();
|
leader.deaccel_to_rest();
|
||||||
|
|
||||||
for i in &leader.intervals {
|
let mut follower = Car {
|
||||||
println!(
|
id: CarID::tmp_new(1, VehicleType::Car),
|
||||||
"- Leader: {}->{} during {}->{} ({}->{})",
|
state: CarState::Stuck,
|
||||||
i.start_dist, i.end_dist, i.start_time, i.end_time, i.start_speed, i.end_speed
|
car_length: Distance::meters(5.0),
|
||||||
);
|
max_accel: Acceleration::meters_per_second_squared(4.5),
|
||||||
}
|
max_deaccel: Acceleration::meters_per_second_squared(-2.0),
|
||||||
for i in &follower.intervals {
|
intervals: Vec::new(),
|
||||||
println!(
|
start_dist: Distance::meters(5.0),
|
||||||
"- Follower: {}->{} during {}->{} ({}->{})",
|
start_time: Duration::seconds(4.0),
|
||||||
i.start_dist, i.end_dist, i.start_time, i.end_time, i.start_speed, i.end_speed
|
};
|
||||||
);
|
follower.accel_from_rest_to_speed_limit(speed_limit);
|
||||||
|
follower.freeflow(Duration::seconds(10.0));
|
||||||
|
follower.deaccel_to_rest();
|
||||||
|
|
||||||
|
for i in &leader.intervals {
|
||||||
|
println!(
|
||||||
|
"- Leader: {}->{} during {}->{} ({}->{})",
|
||||||
|
i.start_dist, i.end_dist, i.start_time, i.end_time, i.start_speed, i.end_speed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
println!("");
|
||||||
|
for i in &follower.intervals {
|
||||||
|
println!(
|
||||||
|
"- Follower: {}->{} during {}->{} ({}->{})",
|
||||||
|
i.start_dist, i.end_dist, i.start_time, i.end_time, i.start_speed, i.end_speed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
println!("");
|
||||||
|
|
||||||
|
follower.maybe_follow(&mut leader);
|
||||||
|
|
||||||
|
World { leader, follower }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Adjust the follower's intervals somehow.
|
pub fn get_draw_cars(&self, time: Duration, map: &Map) -> Vec<DrawCarInput> {
|
||||||
println!(
|
let mut draw = Vec::new();
|
||||||
"Collision (leader, follower) at {:?}",
|
if let Some(d) = self.leader.dist_at(time) {
|
||||||
leader.find_hit(&follower)
|
draw.push(draw_car(&self.leader, d, map));
|
||||||
);
|
}
|
||||||
println!(
|
if let Some(d) = self.follower.dist_at(time) {
|
||||||
"Collision (follower, leader) at {:?}",
|
draw.push(draw_car(&self.follower, d, map));
|
||||||
follower.find_hit(&leader)
|
}
|
||||||
);
|
draw
|
||||||
|
|
||||||
let mut draw = Vec::new();
|
|
||||||
if let Some(d) = leader.dist_at(time) {
|
|
||||||
draw.push(draw_car(&leader, d, map));
|
|
||||||
}
|
}
|
||||||
if let Some(d) = follower.dist_at(time) {
|
|
||||||
draw.push(draw_car(&follower, d, map));
|
|
||||||
}
|
|
||||||
draw
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_car(car: &Car, front: Distance, map: &Map) -> DrawCarInput {
|
fn draw_car(car: &Car, front: Distance, map: &Map) -> DrawCarInput {
|
||||||
@ -288,18 +293,35 @@ impl Car {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO Can we add in the following distance to our query?
|
// TODO Can we add in the following distance to our query?
|
||||||
// TODO Find "earliest" intersection... we could have intervals that wind up equivalent for a
|
// Returns interval indices too.
|
||||||
// stretch.
|
fn find_earliest_hit(&self, other: &Car) -> Option<(Duration, Distance, usize, usize)> {
|
||||||
fn find_hit(&self, other: &Car) -> Option<(Duration, Distance)> {
|
// TODO Do we ever have to worry about having the same intervals? I think this should
|
||||||
for i1 in &self.intervals {
|
// always find the earliest hit.
|
||||||
for i2 in &other.intervals {
|
// TODO A good unit test... Make sure find_hit is symmetric
|
||||||
if let Some(hit) = i1.intersection(i2) {
|
for (idx1, i1) in self.intervals.iter().enumerate() {
|
||||||
return Some(hit);
|
for (idx2, i2) in other.intervals.iter().enumerate() {
|
||||||
|
if let Some((time, dist)) = i1.intersection(i2) {
|
||||||
|
return Some((time, dist, idx1, idx2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn maybe_follow(&mut self, leader: &mut Car) {
|
||||||
|
let (time, dist, idx1, idx2) = match self.find_earliest_hit(leader) {
|
||||||
|
Some(hit) => hit,
|
||||||
|
None => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO Adjust the follower's intervals somehow.
|
||||||
|
println!(
|
||||||
|
"Collision at {}, {}. follower interval {}, leader interval {}",
|
||||||
|
time, dist, idx1, idx2
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn overlap<A: PartialOrd>((a_start, a_end): (A, A), (b_start, b_end): (A, A)) -> bool {
|
fn overlap<A: PartialOrd>((a_start, a_end): (A, A), (b_start, b_end): (A, A)) -> bool {
|
||||||
|
@ -5,11 +5,15 @@ use sim::{CarID, DrawCarInput, DrawPedestrianInput, GetDrawAgents, PedestrianID,
|
|||||||
|
|
||||||
pub struct SimpleModelController {
|
pub struct SimpleModelController {
|
||||||
current_tick: Option<Tick>,
|
current_tick: Option<Tick>,
|
||||||
|
world: Option<des_model::World>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimpleModelController {
|
impl SimpleModelController {
|
||||||
pub fn new() -> SimpleModelController {
|
pub fn new() -> SimpleModelController {
|
||||||
SimpleModelController { current_tick: None }
|
SimpleModelController {
|
||||||
|
current_tick: None,
|
||||||
|
world: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_active(&self) -> bool {
|
pub fn is_active(&self) -> bool {
|
||||||
@ -33,11 +37,17 @@ impl SimpleModelController {
|
|||||||
}
|
}
|
||||||
} else if ctx.input.action_chosen("start simple model") {
|
} else if ctx.input.action_chosen("start simple model") {
|
||||||
self.current_tick = Some(Tick::zero());
|
self.current_tick = Some(Tick::zero());
|
||||||
|
if self.world.is_none() {
|
||||||
|
self.world = Some(des_model::World::new(&ctx.primary.map));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_cars(&self, map: &Map) -> Vec<DrawCarInput> {
|
fn get_cars(&self, map: &Map) -> Vec<DrawCarInput> {
|
||||||
des_model::get_state(self.current_tick.unwrap().as_time(), map)
|
self.world
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.get_draw_cars(self.current_tick.unwrap().as_time(), map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user