-
-
Notifications
You must be signed in to change notification settings - Fork 346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make leader agents call ahead before starting a turn, and stop cutting #900
base: main
Are you sure you want to change the base?
Conversation
Not ready after all... there are cases where everyone stalls at a stop sign and seem to never retry a turn that was blocked by an approaching vehicle. |
Before the clock strikes 12... bug was lane-changing, of course. Agent could change their mind about what lane to target between sending their first ETA and starting the turn. Fixed. Will validate and push in the AM, then see if this combined with downgraded crossings produces better behavior. |
sim/src/mechanics/intersection.rs
Outdated
if other_turn.conflicts_with(turn) { | ||
// Now we need to prioritize between the two. First use the stop sign priority | ||
let their_priority = sign.get_priority(other_req.turn, map); | ||
let should_yield = if our_priority < their_priority { | ||
true | ||
} else if our_priority > their_priority { | ||
false | ||
} else { | ||
// Same priority by the stop sign, so check turn types | ||
let turn_type_ranks = if map.get_config().driving_side == DrivingSide::Right { | ||
vec![TurnType::Straight, TurnType::Right, TurnType::Left] | ||
} else { | ||
vec![TurnType::Straight, TurnType::Left, TurnType::Right] | ||
}; | ||
|
||
// Other turn types (U-turns and pedestrian crossings) always lose. That | ||
// should probably be configurable | ||
let our_rank = turn_type_ranks | ||
.iter() | ||
.position(|x| *x == turn.turn_type) | ||
.unwrap_or(3); | ||
let their_rank = turn_type_ranks | ||
.iter() | ||
.position(|x| *x == other_turn.turn_type) | ||
.unwrap_or(3); | ||
// 0 is the highest rank here | ||
// If all the priorities are equal, we should go -- we're ready to start; | ||
// they're still approaching. | ||
our_rank > their_rank |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool. You get to encode the driver's interpretations of the road rules and priority. Even let them take risks (like following a leader into an intersection, hoping traffic will keep flowing until you get out).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discrete events mean these decisions only happen at a few moments, and it's important to "wake everyone up" anytime there's a potential decision to make. And the complication this PR is exposing is the difference between people at the intersection already waiting, and those approaching it. But in principle, yes, one place to decide this ordering.
|
I found a gridlock at one intersection that's pretty rare -- leaders send an ETA, but if somebody new exits a driveway and appears in front, they become the new leader. The old one never deregistered, so people were yielding to agents who weren't the leader and couldn't proceed. So then I made leaders be keyed by origin lane and get overwritten in this case. That problem solved, but then it exposed a problem where the nice ordering of agents based on stop sign priority and straight > right > left turns was relying on ETAs that now don't seem to get filled out as often, and so I tried adding back the logic to also look at agents that're ready to start their turn. But then the SMP scenario breaks utterly; pedestrians keep streaming across crosswalks and cutting off vehicles unrealistically. So I don't think I'll be able to merge this PR until I detangle the entire mess there. So hard to make incremental steps. :( |
Looking at how the discrete event interactions at intersections work again, I think the whole protocol is backwards. Agents ask to start turns, go to sleep when denied, get woken up in very particular orders, then ask again, and now there's all this complicated ordering during that decision. And it's definitely a load of wasted computation in gridlock scenarios, as everyone keeps asking only to get denied. I want to invert things. Agents still send ETAs and say when they arrive at an intersection. But then intersections should be able to directly tell an agent when to start their turn. Not just wake them up and have them call maybe_start_turn again, but actually do the "are they blocked?" calculation and tell them to start. |
Alright, digging out of the rabbit hole a bit -- 4b446c7 has no behavioral changes, just gets the ETA plumbing done. I urgentlyish need to fix a particular situation in one map, and it has nothing to do with approaching agents; the ordering at a stop sign between waiting agents isn't realistic: screencast.mp4So for the moment, will set aside this PR and the ideas for rethinking intersection protocol |
off approaching vehicles at stop signs. #517
This reminds me of an idea that has stuck with me for years ever since reading it in the Citybound design doc:
I am interested to see how it applies to the A/B Street simulation, as I learn more about the implementation and as you iterate. |
off approaching vehicles at stop signs. #517
Why did the chicken cross the road? Because it was only checking for higher priority traffic right at the edge of the intersection, not a meter away. This PR makes vehicles at the front of their queue "call ahead" and send the ETA when they'd try to start their turn. Then other agents have the opportunity to see if they might cut off an approaching vehicle.
Net results are much more reasonable ordering at stop signs. North/south traffic has priority here, but watch the utter anarchy before this change:
before.mp4
With this PR, things get better, though the northbound left turner still seems a little hesitant:
after.mp4
I'm not yet attempting similar logic at traffic signals. Both stop signs and signals have some weird logic, previously motivated by trying to resolve gridlock -- use the scheduler to let higher-priority agents go first, and don't do so many checks when trying to start a turn. Honestly all of this needs a full overhaul and more careful tests, but just making small steps forward.
The original purpose behind this work is to get more realistic pedestrian/vehicle interactions. That actually comes down to whether crosswalks are marked or unmarked. I'll follow up with some ideas to set those values more realistically.