hacking around bug where cars follow too closely.

This commit is contained in:
Dustin Carlino 2018-12-09 13:56:31 -08:00
parent 56d3c81d82
commit 897833e446
2 changed files with 44 additions and 21 deletions

View File

@ -359,35 +359,41 @@ pub struct SimQueue {
impl SimQueue {
fn new(
time: Tick,
id: Traversable,
map: &Map,
ids: Vec<CarID>,
cars: &BTreeMap<CarID, Car>,
cars: &mut BTreeMap<CarID, Car>,
) -> Result<SimQueue, Error> {
let capacity =
((id.length(map) / Vehicle::best_case_following_dist()).ceil() as usize).max(1);
let mut cars_queue: Vec<(Distance, CarID)> = ids
.into_iter()
.map(|id| (cars[&id].dist_along, id))
.collect();
if cars_queue.len() > capacity {
return Err(Error::new(format!(
"on {:?}, reset to {:?} broke, because capacity is just {}.",
id, cars_queue, capacity
)));
}
let mut cars_queue: Vec<(Distance, CarID)> =
ids.iter().map(|id| (cars[id].dist_along, *id)).collect();
// Sort descending.
cars_queue.sort_by_key(|(dist, _)| -NotNaN::new(dist.value_unsafe).unwrap());
// assert here we're not squished together too much
for slice in cars_queue.windows(2) {
let ((dist1, c1), (dist2, c2)) = (slice[0], slice[1]);
let capacity =
((id.length(map) / Vehicle::best_case_following_dist()).ceil() as usize).max(1);
if cars_queue.len() > capacity {
return Err(Error::new(format!(
"on {:?} at {}, reset to {:?} broke, because capacity is just {}.",
id, time, cars_queue, capacity
)));
}
// Make sure we're not squished together too much.
let mut adjusted_cars = 0;
for second_idx in 1..cars_queue.len() {
let ((dist1, c1), (dist2, c2)) = (cars_queue[second_idx - 1], cars_queue[second_idx]);
let dist_apart = dist1 - dist2 - cars[&c1].vehicle.length;
if dist_apart < kinematics::FOLLOWING_DISTANCE {
if dist_apart >= kinematics::FOLLOWING_DISTANCE {
continue;
}
// For now, hack around this problem by patching it up here.
if adjusted_cars == 0 {
let mut err = format!(
"On {:?}, {} and {} are {} apart -- that's {} too close\n",
"On {:?} at {}, {} and {} are {} apart -- that's {} too close\n",
id,
time,
c1,
c2,
dist_apart,
@ -398,8 +404,24 @@ impl SimQueue {
for (dist, id) in &cars_queue {
err.push_str(&format!("- {} at {}\n", id, dist));
}
return Err(Error::new(err));
error!("HACKING AROUND BUG: {}", err);
}
adjusted_cars += 1;
let fixed_dist = dist2 - (kinematics::FOLLOWING_DISTANCE - dist_apart);
if fixed_dist < 0.0 * si::M {
return Err(Error::new(format!("can't hack around bug where cars are too close on {:?}, because last car doesn't have room to be shifted back", id)));
}
cars.get_mut(&c2).unwrap().dist_along = fixed_dist;
cars_queue[second_idx] = (fixed_dist, c2);
}
if adjusted_cars > 1 {
error!(
"HACKING AROUND BUG: also had to correct {} more cars here",
adjusted_cars - 1
);
// Retry from scratch, just to be sure the fix worked.
return SimQueue::new(time, id, map, ids, cars);
}
Ok(SimQueue { cars_queue })
}
@ -666,7 +688,7 @@ impl DrivingSimState {
// Reset all queues -- only store ones with some agents present.
for (on, cars) in cars_per_traversable.into_iter() {
self.queues
.insert(on, SimQueue::new(on, map, cars, &self.cars)?);
.insert(on, SimQueue::new(time, on, map, cars, &mut self.cars)?);
}
Ok((finished_parking, vanished_at_border, done_biking))

View File

@ -193,6 +193,7 @@ impl TestRunner {
output_path,
debug_with_savestate: helper.debug_with_savestate,
};
// TODO If the "Running..." line actually took two lines, this breaks
print!("\r");
result.print(&self.flags);
self.results.push(result);