mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-23 17:07:12 +03:00
Prevent pedestrians from endlessly cutting off cars at a stop sign by
limiting how long a crowd can enter a crosswalk. #517 Removing Tehran from prebaking; it starts gridlocking. I didn't investigate why; making SMP realistic unfortunately takes priority right now.
This commit is contained in:
parent
ae8d6f6cf2
commit
738f50f5b8
@ -53,7 +53,8 @@ pub fn prebake_all() {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Started gridlocking with more realistic pedestrian crossing behavior
|
||||
if false {
|
||||
let tehran_map = map_model::Map::load_synchronously(
|
||||
MapName::new("ir", "tehran", "parliament").path(),
|
||||
&mut timer,
|
||||
|
@ -169,6 +169,10 @@ impl AgentID {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_pedestrian(&self) -> bool {
|
||||
matches!(self, AgentID::Pedestrian(_))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AgentID {
|
||||
|
@ -847,7 +847,7 @@ impl IntersectionSimState {
|
||||
req: &Request,
|
||||
map: &Map,
|
||||
sign: &ControlStopSign,
|
||||
_speed: Speed,
|
||||
speed: Speed,
|
||||
now: Time,
|
||||
scheduler: &mut Scheduler,
|
||||
) -> bool {
|
||||
@ -881,6 +881,37 @@ impl IntersectionSimState {
|
||||
// TODO Make sure we can optimistically finish this turn before an approaching
|
||||
// higher-priority vehicle wants to begin.
|
||||
|
||||
// If a pedestrian is going to cut off a car, check how long the car has been waiting and
|
||||
// maybe yield (regardless of stop sign priority). This is a very rough start to more
|
||||
// realistic "batching" of pedestrians to cross a street. Without this, if there's one
|
||||
// pedestrian almost clear of a crosswalk, cars are totally stopped for them, and so a new
|
||||
// pedestrian arriving will win.
|
||||
if req.agent.is_pedestrian() {
|
||||
let our_turn = map.get_t(req.turn);
|
||||
let time_to_cross = our_turn.geom.length() / speed;
|
||||
for (other_req, (other_time, _)) in &self.state[&req.turn.parent].waiting {
|
||||
if matches!(other_req.agent, AgentID::Car(_)) {
|
||||
if our_turn.conflicts_with(map.get_t(other_req.turn)) {
|
||||
let our_waiting = now - our_time;
|
||||
let other_waiting = now - *other_time;
|
||||
// We can't tell if a car has been waiting for a while due to pedestrians
|
||||
// crossing, or due to a blockage in their destination queue. Always let
|
||||
// pedestrians muscle their way in eventually.
|
||||
if our_waiting > other_waiting {
|
||||
continue;
|
||||
}
|
||||
// Intuition: another pedestrian trying to enter a crosswalk has a 3s
|
||||
// buffer to "join" the first pedestrian who started crossing and caused
|
||||
// cars to stop. We're using the time for _this_ pedestrian to cross _this_
|
||||
// turn, so it's a very rough definition.
|
||||
if other_waiting > time_to_cross + Duration::seconds(3.0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -4,27 +4,20 @@
|
||||
"scenario": "weekday",
|
||||
"finished_trips": 76640,
|
||||
"cancelled_trips": 0,
|
||||
"total_trip_duration_seconds": 43681790.01100022
|
||||
"total_trip_duration_seconds": 43931256.87820016
|
||||
},
|
||||
{
|
||||
"map": "montlake (in seattle (us))",
|
||||
"scenario": "weekday",
|
||||
"finished_trips": 36710,
|
||||
"cancelled_trips": 86,
|
||||
"total_trip_duration_seconds": 18533522.79990011
|
||||
},
|
||||
{
|
||||
"map": "parliament (in tehran (ir))",
|
||||
"scenario": "random people going to and from work",
|
||||
"finished_trips": 29350,
|
||||
"cancelled_trips": 16734,
|
||||
"total_trip_duration_seconds": 40298148.80850012
|
||||
"total_trip_duration_seconds": 18533435.094100088
|
||||
},
|
||||
{
|
||||
"map": "sao_miguel_paulista (in sao_paulo (br))",
|
||||
"scenario": "Full",
|
||||
"finished_trips": 122948,
|
||||
"cancelled_trips": 33043,
|
||||
"total_trip_duration_seconds": 102103184.10710092
|
||||
"total_trip_duration_seconds": 86387963.54580107
|
||||
}
|
||||
]
|
Loading…
Reference in New Issue
Block a user