mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 23:15:24 +03:00
turns between sidewalks were getting conflated after the TurnID change; adding parent intersection fixes it. should fix ped warping problem.
This commit is contained in:
parent
ec38ccc11e
commit
890f6541af
@ -35,6 +35,7 @@
|
||||
|
||||
- savestating a sim has nondet output due to hashes; switching to btree is kind of weird
|
||||
- unit test that two savestates of same sim are equal
|
||||
- consider overriding encoding for TurnID and such, instead of remembering to stick maps everywhere
|
||||
- diffing two sim states is tedious no matter what; is there a nice macro-driven deep equals we could do instead?
|
||||
- will need programmatic diffs later for pointing out changes to players in A/B tests
|
||||
- consider refactoring car/ped sim
|
||||
|
@ -141,7 +141,7 @@ fn make_turns(
|
||||
// TODO if it's a multi-lane dead-end, ideally match up lanes or something
|
||||
|
||||
result.push(Turn {
|
||||
id: TurnID::new(*src, *dst),
|
||||
id: turn_id(parent, *src, *dst),
|
||||
parent,
|
||||
src: *src,
|
||||
dst: *dst,
|
||||
@ -172,7 +172,7 @@ fn make_crosswalks(i: &Intersection, m: &Map) -> Vec<Turn> {
|
||||
);
|
||||
|
||||
result.push(Turn {
|
||||
id: TurnID::new(src.id, dst.id),
|
||||
id: turn_id(i.id, src.id, dst.id),
|
||||
parent: i.id,
|
||||
src: src.id,
|
||||
dst: dst.id,
|
||||
@ -204,7 +204,7 @@ fn make_crosswalks(i: &Intersection, m: &Map) -> Vec<Turn> {
|
||||
}
|
||||
|
||||
result.push(Turn {
|
||||
id: TurnID::new(src.id, dst.id),
|
||||
id: turn_id(i.id, src.id, dst.id),
|
||||
parent: i.id,
|
||||
src: src.id,
|
||||
dst: dst.id,
|
||||
@ -216,3 +216,7 @@ fn make_crosswalks(i: &Intersection, m: &Map) -> Vec<Turn> {
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn turn_id(parent: IntersectionID, src: LaneID, dst: LaneID) -> TurnID {
|
||||
TurnID { parent, src, dst }
|
||||
}
|
||||
|
@ -136,6 +136,7 @@ impl Map {
|
||||
|
||||
for i in &m.intersections {
|
||||
for t in make::make_all_turns(i, &m) {
|
||||
assert!(!m.turns.contains_key(&t.id));
|
||||
m.turns.insert(t.id, t);
|
||||
}
|
||||
}
|
||||
|
@ -7,24 +7,24 @@ use std::fmt;
|
||||
use IntersectionID;
|
||||
use LaneID;
|
||||
|
||||
// Turns are uniquely identified by their (src, dst) lanes.
|
||||
// Turns are uniquely identified by their (src, dst) lanes and their parent intersection.
|
||||
// Intersection is needed to distinguish crosswalks that exist at two ends of a sidewalk.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct TurnID(LaneID, LaneID);
|
||||
|
||||
impl TurnID {
|
||||
pub(crate) fn new(src: LaneID, dst: LaneID) -> TurnID {
|
||||
TurnID(src, dst)
|
||||
}
|
||||
pub struct TurnID {
|
||||
pub parent: IntersectionID,
|
||||
pub src: LaneID,
|
||||
pub dst: LaneID,
|
||||
}
|
||||
|
||||
impl fmt::Display for TurnID {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "TurnID({0}, {1})", self.0, self.1)
|
||||
write!(f, "TurnID({0}, {1}, {2})", self.parent, self.src, self.dst)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Turn {
|
||||
// parent, src, dst are all encoded by id. TODO dedupe.
|
||||
pub id: TurnID,
|
||||
// src and dst must both belong to parent. No guarantees that src is incoming and dst is
|
||||
// outgoing for turns between sidewalks.
|
||||
|
@ -91,7 +91,7 @@ impl Car {
|
||||
let intersection_req_granted = match desired_on {
|
||||
// Already doing a turn, finish it!
|
||||
On::Lane(_) => true,
|
||||
On::Turn(id) => intersections.request_granted(Request::for_car(self.id, id), map),
|
||||
On::Turn(id) => intersections.request_granted(Request::for_car(self.id, id)),
|
||||
};
|
||||
if has_room_now && is_lead_vehicle && intersection_req_granted {
|
||||
Action::Goto(desired_on)
|
||||
@ -321,14 +321,14 @@ impl DrivingSimState {
|
||||
new_car_entered_this_step.insert(on);
|
||||
let c = self.cars.get_mut(&id).unwrap();
|
||||
if let On::Turn(t) = c.on {
|
||||
intersections.on_exit(Request::for_car(c.id, t), map);
|
||||
intersections.on_exit(Request::for_car(c.id, t));
|
||||
assert_eq!(c.path[0], map.get_t(t).dst);
|
||||
c.path.pop_front();
|
||||
}
|
||||
c.waiting_for = None;
|
||||
c.on = on;
|
||||
if let On::Turn(t) = c.on {
|
||||
intersections.on_enter(Request::for_car(c.id, t), map);
|
||||
intersections.on_enter(Request::for_car(c.id, t));
|
||||
}
|
||||
// TODO could calculate leftover (and deal with large timesteps, small
|
||||
// lanes)
|
||||
@ -339,7 +339,7 @@ impl DrivingSimState {
|
||||
self.cars.get_mut(&id).unwrap().waiting_for = Some(on);
|
||||
if let On::Turn(t) = on {
|
||||
// Note this is idempotent and does NOT grant the request.
|
||||
intersections.submit_request(Request::for_car(*id, t), time, map);
|
||||
intersections.submit_request(Request::for_car(*id, t), time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,8 @@ impl IntersectionSimState {
|
||||
}
|
||||
|
||||
// This is just an immutable query.
|
||||
pub fn request_granted(&self, req: Request, map: &Map) -> bool {
|
||||
let i = &self.intersections[map.get_t(req.turn).parent.0];
|
||||
pub fn request_granted(&self, req: Request) -> bool {
|
||||
let i = &self.intersections[req.turn.parent.0];
|
||||
i.accepted().get(&req.agent) == Some(&req.turn)
|
||||
}
|
||||
|
||||
@ -73,10 +73,8 @@ impl IntersectionSimState {
|
||||
// must be ready to enter the intersection (leader vehicle and at the end of the lane already).
|
||||
// The request may have been previously granted, but the agent might not have been able to
|
||||
// start the turn.
|
||||
pub fn submit_request(&mut self, req: Request, time: Tick, map: &Map) {
|
||||
let i = self.intersections
|
||||
.get_mut(map.get_t(req.turn).parent.0)
|
||||
.unwrap();
|
||||
pub fn submit_request(&mut self, req: Request, time: Tick) {
|
||||
let i = self.intersections.get_mut(req.turn.parent.0).unwrap();
|
||||
if let Some(t) = i.accepted().get(&req.agent) {
|
||||
assert_eq!(*t, req.turn);
|
||||
return;
|
||||
@ -106,15 +104,13 @@ impl IntersectionSimState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_enter(&self, req: Request, map: &Map) {
|
||||
let i = &self.intersections[map.get_t(req.turn).parent.0];
|
||||
pub fn on_enter(&self, req: Request) {
|
||||
let i = &self.intersections[req.turn.parent.0];
|
||||
assert!(i.accepted().contains_key(&req.agent));
|
||||
}
|
||||
|
||||
pub fn on_exit(&mut self, req: Request, map: &Map) {
|
||||
let i = self.intersections
|
||||
.get_mut(map.get_t(req.turn).parent.0)
|
||||
.unwrap();
|
||||
pub fn on_exit(&mut self, req: Request) {
|
||||
let i = self.intersections.get_mut(req.turn.parent.0).unwrap();
|
||||
assert!(i.accepted().contains_key(&req.agent));
|
||||
i.accepted_mut().remove(&req.agent);
|
||||
}
|
||||
@ -195,7 +191,7 @@ impl StopSign {
|
||||
let mut newly_accepted: Vec<Request> = Vec::new();
|
||||
for (req, started_waiting) in self.started_waiting_at.iter() {
|
||||
let (agent, turn) = (req.agent, req.turn);
|
||||
assert_eq!(map.get_t(turn).parent, self.id);
|
||||
assert_eq!(turn.parent, self.id);
|
||||
assert_eq!(self.accepted.contains_key(&agent), false);
|
||||
|
||||
if self.conflicts_with_accepted(turn, map) {
|
||||
|
@ -80,7 +80,7 @@ impl Pedestrian {
|
||||
let intersection_req_granted = match desired_on {
|
||||
// Already doing a turn, finish it!
|
||||
On::Lane(_) => true,
|
||||
On::Turn(id) => intersections.request_granted(Request::for_ped(self.id, id), map),
|
||||
On::Turn(id) => intersections.request_granted(Request::for_ped(self.id, id)),
|
||||
};
|
||||
if intersection_req_granted {
|
||||
Action::Goto(desired_on)
|
||||
@ -184,7 +184,7 @@ impl WalkingSimState {
|
||||
let p = self.peds.get_mut(&id).unwrap();
|
||||
let old_on = p.on.clone();
|
||||
if let On::Turn(t) = p.on {
|
||||
intersections.on_exit(Request::for_ped(p.id, t), map);
|
||||
intersections.on_exit(Request::for_ped(p.id, t));
|
||||
assert_eq!(p.path[0], map.get_t(t).dst);
|
||||
p.path.pop_front();
|
||||
}
|
||||
@ -194,7 +194,7 @@ impl WalkingSimState {
|
||||
p.contraflow = false;
|
||||
match p.on {
|
||||
On::Turn(t) => {
|
||||
intersections.on_enter(Request::for_ped(p.id, t), map);
|
||||
intersections.on_enter(Request::for_ped(p.id, t));
|
||||
}
|
||||
On::Lane(l) => {
|
||||
// Which end of the sidewalk are we entering?
|
||||
@ -218,7 +218,7 @@ impl WalkingSimState {
|
||||
self.peds.get_mut(&id).unwrap().waiting_for = Some(on);
|
||||
if let On::Turn(t) = on {
|
||||
// Note this is idempotent and does NOT grant the request.
|
||||
intersections.submit_request(Request::for_ped(*id, t), time, map);
|
||||
intersections.submit_request(Request::for_ped(*id, t), time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user