moving agent stepping code to be owned by each agent

This commit is contained in:
Dustin Carlino 2018-08-04 13:58:00 -07:00
parent 676e076ae1
commit 474215d478
3 changed files with 92 additions and 72 deletions

View File

@ -81,6 +81,22 @@ impl Car {
Action::WaitFor(desired_on)
}
}
fn step_goto(&mut self, on: On, map: &Map, intersections: &mut IntersectionSimState) {
if let On::Turn(t) = self.on {
intersections.on_exit(Request::for_car(self.id, t));
assert_eq!(self.path[0], map.get_t(t).dst);
self.path.pop_front();
}
self.waiting_for = None;
self.on = on;
if let On::Turn(t) = self.on {
intersections.on_enter(Request::for_car(self.id, t));
}
// TODO could calculate leftover (and deal with large timesteps, small
// lanes)
self.dist_along = 0.0 * si::M;
}
}
#[derive(Serialize, Deserialize, PartialEq, Eq)]
@ -283,19 +299,7 @@ impl DrivingSimState {
} else {
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));
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));
}
// TODO could calculate leftover (and deal with large timesteps, small
// lanes)
c.dist_along = 0.0 * si::M;
c.step_goto(on, map, intersections);
}
}
Action::WaitFor(on) => {

View File

@ -20,8 +20,6 @@ use {CarID, CarState, On, Tick, SPEED_LIMIT};
// This represents an actively driving car, not a parked one
#[derive(Clone, Serialize, Deserialize)]
struct Car {
// TODO might be going back to something old here, but an enum with parts of the state grouped
// could be more clear.
id: CarID,
on: On,
// When did the car start the current On?
@ -93,6 +91,28 @@ impl Car {
}
}
fn step_goto(
&mut self,
on: On,
time: Tick,
map: &Map,
intersections: &mut IntersectionSimState,
) {
if let On::Turn(t) = self.on {
intersections.on_exit(Request::for_car(self.id, t));
assert_eq!(self.path[0], map.get_t(t).dst);
self.path.pop_front();
}
self.waiting_for = None;
self.on = on;
if let On::Turn(t) = self.on {
intersections.on_enter(Request::for_car(self.id, t));
}
// TODO could calculate leftover (and deal with large timesteps, small
// lanes)
self.started_at = time;
}
// Returns the angle and the dist along the lane/turn too
fn get_best_case_pos(&self, time: Tick, map: &Map) -> (Pt2D, Angle, si::Meter<f64>) {
let mut dist = SPEED_LIMIT * (time - self.started_at).as_time();
@ -361,19 +381,7 @@ impl DrivingSimState {
} else {
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));
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));
}
// TODO could calculate leftover (and deal with large timesteps, small
// lanes)
c.started_at = time;
c.step_goto(on, time, map, intersections);
}
}
Action::WaitFor(on) => {

View File

@ -81,6 +81,56 @@ impl Pedestrian {
Action::WaitFor(desired_on)
}
}
fn step_continue(&mut self, delta_time: si::Second<f64>, map: &Map) {
let new_dist: si::Meter<f64> = delta_time * SPEED;
if self.contraflow {
self.dist_along -= new_dist;
if self.dist_along < 0.0 * si::M {
self.dist_along = 0.0 * si::M;
}
} else {
self.dist_along += new_dist;
let max_dist = self.on.length(map);
if self.dist_along > max_dist {
self.dist_along = max_dist;
}
}
}
fn step_goto(&mut self, on: On, map: &Map, intersections: &mut IntersectionSimState) {
let old_on = self.on.clone();
if let On::Turn(t) = self.on {
intersections.on_exit(Request::for_ped(self.id, t));
assert_eq!(self.path[0], map.get_t(t).dst);
self.path.pop_front();
}
self.waiting_for = None;
self.on = on;
self.dist_along = 0.0 * si::M;
self.contraflow = false;
match self.on {
On::Turn(t) => {
intersections.on_enter(Request::for_ped(self.id, t));
}
On::Lane(l) => {
// Which end of the sidewalk are we entering?
// TODO are there cases where we should enter a new sidewalk and
// immediately enter a different turn, instead of always going to the
// other side of the sidealk? or are there enough turns to make that
// unnecessary?
let turn = map.get_t(old_on.as_turn());
let lane = map.get_l(l);
if turn.parent == lane.dst_i {
self.contraflow = true;
self.dist_along = lane.length();
}
}
}
// TODO could calculate leftover (and deal with large timesteps, small
// lanes)
}
}
#[derive(Serialize, Deserialize, Derivative, PartialEq, Eq)]
@ -149,53 +199,11 @@ impl WalkingSimState {
}
Action::Continue => {
let p = self.peds.get_mut(&id).unwrap();
let new_dist: si::Meter<f64> = delta_time * SPEED;
if p.contraflow {
p.dist_along -= new_dist;
if p.dist_along < 0.0 * si::M {
p.dist_along = 0.0 * si::M;
}
} else {
p.dist_along += new_dist;
let max_dist = p.on.length(map);
if p.dist_along > max_dist {
p.dist_along = max_dist;
}
}
p.step_continue(delta_time, map);
}
Action::Goto(on) => {
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));
assert_eq!(p.path[0], map.get_t(t).dst);
p.path.pop_front();
}
p.waiting_for = None;
p.on = on;
p.dist_along = 0.0 * si::M;
p.contraflow = false;
match p.on {
On::Turn(t) => {
intersections.on_enter(Request::for_ped(p.id, t));
}
On::Lane(l) => {
// Which end of the sidewalk are we entering?
// TODO are there cases where we should enter a new sidewalk and
// immediately enter a different turn, instead of always going to the
// other side of the sidealk? or are there enough turns to make that
// unnecessary?
let turn = map.get_t(old_on.as_turn());
let lane = map.get_l(l);
if turn.parent == lane.dst_i {
p.contraflow = true;
p.dist_along = lane.length();
}
}
}
// TODO could calculate leftover (and deal with large timesteps, small
// lanes)
p.step_goto(on, map, intersections);
}
Action::WaitFor(on) => {
self.peds.get_mut(&id).unwrap().waiting_for = Some(on);