mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 23:15:24 +03:00
Make the blocked-by graph used for debugging and the API detect problems
from somebody about to start an uber-turn.
This commit is contained in:
parent
ad37d612b4
commit
5dba8f5896
@ -40,7 +40,7 @@ impl Game {
|
||||
.expect(&format!("can't find {}", config.start));
|
||||
let player = Player::new(ctx, app, start);
|
||||
|
||||
let state = GamehState::new(ctx, app, config);
|
||||
let state = GameState::new(ctx, app, config);
|
||||
|
||||
let panel = Panel::new(Widget::col(vec![
|
||||
Widget::row(vec![
|
||||
|
@ -8,7 +8,7 @@ use abstutil::{
|
||||
use geom::{Duration, Time};
|
||||
use map_model::{
|
||||
ControlStopSign, ControlTrafficSignal, Intersection, IntersectionID, LaneID, Map, PhaseType,
|
||||
Traversable, TurnID, TurnPriority, TurnType,
|
||||
Traversable, TurnID, TurnPriority, TurnType, UberTurn,
|
||||
};
|
||||
|
||||
use crate::mechanics::car::Car;
|
||||
@ -640,12 +640,15 @@ impl IntersectionSimState {
|
||||
queues: &HashMap<Traversable, Queue>,
|
||||
) {
|
||||
// Don't use self.blocked_by -- that gets complicated with uber-turns and such.
|
||||
//
|
||||
// This also assumes default values for handle_uber_turns, disable_turn_conflicts, etc!
|
||||
for state in self.state.values() {
|
||||
for (req, started_at) in &state.waiting {
|
||||
let turn = map.get_t(req.turn);
|
||||
// In the absence of other explanations, the agent must be pausing at a stop sign
|
||||
// or before making an unprotected movement, aka, in the middle of
|
||||
// WAIT_AT_STOP_SIGN or WAIT_BEFORE_YIELD_AT_TRAFFIC_SIGNAL.
|
||||
// WAIT_AT_STOP_SIGN or WAIT_BEFORE_YIELD_AT_TRAFFIC_SIGNAL. Or they're waiting for
|
||||
// a signal to change.
|
||||
let mut cause = DelayCause::Intersection(state.id);
|
||||
if let Some(other) = state.accepted.iter().find(|other| {
|
||||
turn.conflicts_with(map.get_t(other.turn)) || turn.id == other.turn
|
||||
@ -653,16 +656,36 @@ impl IntersectionSimState {
|
||||
cause = DelayCause::Agent(other.agent);
|
||||
} else if let AgentID::Car(car) = req.agent {
|
||||
let queue = &queues[&Traversable::Lane(req.turn.dst)];
|
||||
if !queue.room_for_car(cars.get(&car).unwrap()) {
|
||||
let car = cars.get(&car).unwrap();
|
||||
if !queue.room_for_car(car) {
|
||||
// TODO Or it's reserved due to an uber turn or something
|
||||
let blocker = queue.cars.back().cloned().or(queue.laggy_head).unwrap();
|
||||
cause = DelayCause::Agent(AgentID::Car(blocker));
|
||||
} else if let Some(ut) = car.router.get_path().about_to_start_ut() {
|
||||
if let Some(blocker) = self.check_for_conflicts_before_uber_turn(ut, map) {
|
||||
cause = DelayCause::Agent(blocker);
|
||||
}
|
||||
}
|
||||
}
|
||||
graph.insert(req.agent, (now - *started_at, cause));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// See if any agent is currently performing a turn that conflicts with an uber-turn. Doesn't
|
||||
/// check for room on the queues.
|
||||
fn check_for_conflicts_before_uber_turn(&self, ut: &UberTurn, map: &Map) -> Option<AgentID> {
|
||||
for t in &ut.path {
|
||||
let turn = map.get_t(*t);
|
||||
let state = &self.state[&turn.id.parent];
|
||||
for other in state.accepted.iter().chain(state.reserved.iter()) {
|
||||
if map.get_t(other.turn).conflicts_with(turn) {
|
||||
return Some(other.agent);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// Stuff to support maybe_start_turn
|
||||
|
Loading…
Reference in New Issue
Block a user