Skip wakeup_waiting while we're handling live map edits. Based on the

order of vehicle deletion, we try to ask about stop sign and traffic
signal movements that may be deleted and would be irrelevant anyway if a
different deletion order happened. #312

We should really defer wakeup_waiting until after all cleanup is done,
but for now, willing to risk some stuckness at a stop sign...
This commit is contained in:
Dustin Carlino 2020-10-23 12:15:51 -07:00
parent 3db8fe6669
commit 9dbb156058
4 changed files with 27 additions and 31 deletions

View File

@ -118,19 +118,18 @@ impl ControlStopSign {
}
/// Get the priority of a turn according to the stop sign -- either protected or yield, never
/// banned. The result is None if the turn doesn't exist -- this can happen in the middle of
/// resolving live map edits.
/// banned.
// TODO Or cache
pub fn get_priority(&self, turn: TurnID, map: &Map) -> Option<TurnPriority> {
match map.maybe_get_t(turn)?.turn_type {
TurnType::SharedSidewalkCorner => Some(TurnPriority::Protected),
pub fn get_priority(&self, turn: TurnID, map: &Map) -> TurnPriority {
match map.get_t(turn).turn_type {
TurnType::SharedSidewalkCorner => TurnPriority::Protected,
// TODO This actually feels like a policy bit that should be flippable.
TurnType::Crosswalk => Some(TurnPriority::Protected),
TurnType::Crosswalk => TurnPriority::Protected,
_ => {
if self.roads[&map.get_l(turn.src).parent].must_stop {
Some(TurnPriority::Yield)
TurnPriority::Yield
} else {
Some(TurnPriority::Protected)
TurnPriority::Protected
}
}
}

View File

@ -658,8 +658,10 @@ impl DrivingSimState {
Traversable::Lane(l) => ctx.map.get_l(l).src_i,
Traversable::Turn(t) => t.parent,
};
ctx.intersections
.space_freed(now, i, ctx.scheduler, ctx.map);
if !ctx.handling_live_edits {
ctx.intersections
.space_freed(now, i, ctx.scheduler, ctx.map);
}
}
ctx.intersections.vehicle_gone(car.vehicle.id);
@ -788,16 +790,19 @@ impl DrivingSimState {
t,
ctx.scheduler,
ctx.map,
ctx.handling_live_edits,
);
}
Traversable::Lane(l) => {
old_queue.free_reserved_space(car);
ctx.intersections.space_freed(
now,
ctx.map.get_l(l).src_i,
ctx.scheduler,
ctx.map,
);
if !ctx.handling_live_edits {
ctx.intersections.space_freed(
now,
ctx.map.get_l(l).src_i,
ctx.scheduler,
ctx.map,
);
}
}
}

View File

@ -116,17 +116,12 @@ impl IntersectionSimState {
turn: TurnID,
scheduler: &mut Scheduler,
map: &Map,
handling_live_edits: bool,
) {
let state = self.state.get_mut(&turn.parent).unwrap();
assert!(state.accepted.remove(&Request { agent, turn }));
state.reserved.remove(&Request { agent, turn });
// maybe_get_t to handle live edits; an agent could be deleted in the middle of a deleted
// turn.
if map
.maybe_get_t(turn)
.map(|t| t.turn_type != TurnType::SharedSidewalkCorner)
.unwrap_or(true)
{
if !handling_live_edits && map.get_t(turn).turn_type != TurnType::SharedSidewalkCorner {
self.wakeup_waiting(now, turn.parent, scheduler, map);
}
if self.break_turn_conflict_cycles {
@ -205,17 +200,13 @@ impl IntersectionSimState {
} else if let Some(ref sign) = map.maybe_get_stop_sign(i) {
for (req, _) in all {
match sign.get_priority(req.turn, map) {
Some(TurnPriority::Protected) => {
TurnPriority::Protected => {
protected.push(req);
}
Some(TurnPriority::Yield) => {
TurnPriority::Yield => {
yielding.push(req);
}
Some(TurnPriority::Banned) => unreachable!(),
// This may happen in the middle of resolving live edits. delete_car calls
// space_freed, which gets here. Depending on the order we delete cars, we hit
// this case.
None => {}
TurnPriority::Banned => unreachable!(),
}
}
} else {
@ -601,7 +592,7 @@ impl IntersectionSimState {
now: Time,
scheduler: &mut Scheduler,
) -> bool {
let our_priority = sign.get_priority(req.turn, map).unwrap();
let our_priority = sign.get_priority(req.turn, map);
assert!(our_priority != TurnPriority::Banned);
let our_time = self.state[&req.turn.parent].waiting[req];

View File

@ -211,6 +211,7 @@ impl WalkingSimState {
t,
ctx.scheduler,
ctx.map,
false,
);
}