visualize an agent's path

This commit is contained in:
Dustin Carlino 2018-08-30 15:15:37 -07:00
parent c685a80a98
commit c38c9d43ac
7 changed files with 89 additions and 3 deletions

View File

@ -6,6 +6,7 @@ pub mod geom_validation;
pub mod road_editor; pub mod road_editor;
pub mod search; pub mod search;
pub mod selection; pub mod selection;
pub mod show_route;
pub mod sim_controls; pub mod sim_controls;
pub mod steep; pub mod steep;
pub mod stop_sign_editor; pub mod stop_sign_editor;

View File

@ -0,0 +1,50 @@
use colors::{ColorScheme, Colors};
use ezgui::input::UserInput;
use graphics::types::Color;
use map_model::LaneID;
use piston::input::Key;
use sim::{AgentID, Sim};
use std::collections::HashSet;
pub enum ShowRouteState {
Empty,
Active(AgentID, HashSet<LaneID>),
}
impl ShowRouteState {
pub fn event(&mut self, input: &mut UserInput, sim: &Sim) -> bool {
let quit = match self {
ShowRouteState::Empty => false,
ShowRouteState::Active(agent, ref mut lanes) => {
if input.key_pressed(Key::Return, "stop showing route") {
true
} else {
match sim.get_current_route(*agent) {
Some(route) => {
lanes.clear();
lanes.extend(route);
false
}
None => true,
}
}
}
};
if quit {
*self = ShowRouteState::Empty;
}
quit
}
pub fn color_l(&self, l: LaneID, cs: &ColorScheme) -> Option<Color> {
let highlight = match self {
ShowRouteState::Empty => false,
ShowRouteState::Active(_, lanes) => lanes.contains(&l),
};
if highlight {
Some(cs.get(Colors::Queued))
} else {
None
}
}
}

View File

@ -26,6 +26,7 @@ use plugins::geom_validation::Validator;
use plugins::road_editor::RoadEditor; use plugins::road_editor::RoadEditor;
use plugins::search::SearchState; use plugins::search::SearchState;
use plugins::selection::{Hider, SelectionState, ID}; use plugins::selection::{Hider, SelectionState, ID};
use plugins::show_route::ShowRouteState;
use plugins::sim_controls::SimController; use plugins::sim_controls::SimController;
use plugins::steep::SteepnessVisualizer; use plugins::steep::SteepnessVisualizer;
use plugins::stop_sign_editor::StopSignEditor; use plugins::stop_sign_editor::StopSignEditor;
@ -34,8 +35,8 @@ use plugins::turn_colors::TurnColors;
use plugins::warp::WarpState; use plugins::warp::WarpState;
use render; use render;
use sim; use sim;
use sim::{CarID, CarState, PedestrianID}; use sim::{AgentID, CarID, CarState, PedestrianID};
use std::collections::HashMap; use std::collections::{HashMap, HashSet};
use std::process; use std::process;
// TODO ideally these would be tuned kind of dynamically based on rendering speed // TODO ideally these would be tuned kind of dynamically based on rendering speed
@ -65,6 +66,7 @@ pub struct UI {
current_search_state: SearchState, current_search_state: SearchState,
warp: WarpState, warp: WarpState,
follow: FollowState, follow: FollowState,
show_route: ShowRouteState,
floodfiller: Floodfiller, floodfiller: Floodfiller,
steepness_viz: SteepnessVisualizer, steepness_viz: SteepnessVisualizer,
osm_classifier: OsmClassifier, osm_classifier: OsmClassifier,
@ -137,6 +139,7 @@ impl UI {
current_search_state: SearchState::Empty, current_search_state: SearchState::Empty,
warp: WarpState::Empty, warp: WarpState::Empty,
follow: FollowState::Empty, follow: FollowState::Empty,
show_route: ShowRouteState::Empty,
floodfiller: Floodfiller::new(), floodfiller: Floodfiller::new(),
osm_classifier: OsmClassifier::new(), osm_classifier: OsmClassifier::new(),
traffic_signal_editor: TrafficSignalEditor::new(), traffic_signal_editor: TrafficSignalEditor::new(),
@ -281,6 +284,7 @@ impl UI {
// chaining is harder to read. :( // chaining is harder to read. :(
vec![ vec![
self.current_selection_state.color_l(l, &self.cs), self.current_selection_state.color_l(l, &self.cs),
self.show_route.color_l(l.id, &self.cs),
self.current_search_state.color_l(l, &self.map, &self.cs), self.current_search_state.color_l(l, &self.map, &self.cs),
self.floodfiller.color_l(l, &self.cs), self.floodfiller.color_l(l, &self.cs),
self.steepness_viz.color_l(&self.map, l), self.steepness_viz.color_l(&self.map, l),
@ -457,6 +461,7 @@ impl gui::GUI for UI {
self.follow self.follow
.event(input, &self.map, &self.sim_ctrl.sim, &mut self.canvas,) .event(input, &self.map, &self.sim_ctrl.sim, &mut self.canvas,)
); );
stop_if_done!(self.show_route.event(input, &self.sim_ctrl.sim));
stop_if_done!( stop_if_done!(
self.color_picker self.color_picker
.handle_event(input, &mut self.canvas, &mut self.cs) .handle_event(input, &mut self.canvas, &mut self.cs)
@ -544,12 +549,21 @@ impl gui::GUI for UI {
self.follow = FollowState::FollowingCar(id); self.follow = FollowState::FollowingCar(id);
return gui::EventLoopMode::InputOnly; return gui::EventLoopMode::InputOnly;
} }
if input.key_pressed(Key::R, "show this car's route") {
self.show_route = ShowRouteState::Active(AgentID::Car(id), HashSet::new());
return gui::EventLoopMode::InputOnly;
}
} }
SelectionState::SelectedPedestrian(id) => { SelectionState::SelectedPedestrian(id) => {
if input.key_pressed(Key::F, "follow this pedestrian") { if input.key_pressed(Key::F, "follow this pedestrian") {
self.follow = FollowState::FollowingPedestrian(id); self.follow = FollowState::FollowingPedestrian(id);
return gui::EventLoopMode::InputOnly; return gui::EventLoopMode::InputOnly;
} }
if input.key_pressed(Key::R, "show this pedestrian's route") {
self.show_route =
ShowRouteState::Active(AgentID::Pedestrian(id), HashSet::new());
return gui::EventLoopMode::InputOnly;
}
} }
SelectionState::SelectedLane(id, _) => { SelectionState::SelectedLane(id, _) => {
if input.key_pressed(Key::F, "start floodfilling from this lane") { if input.key_pressed(Key::F, "start floodfilling from this lane") {

View File

@ -842,6 +842,10 @@ impl DrivingSimState {
} }
view view
} }
pub fn get_current_route(&self, id: CarID) -> Option<Vec<LaneID>> {
self.routers.get(&id).map(|r| r.get_current_route())
}
} }
// The immutable view that cars see of other cars. // The immutable view that cars see of other cars.

View File

@ -163,6 +163,10 @@ impl Router {
self.path.push_back(choice); self.path.push_back(choice);
None None
} }
pub fn get_current_route(&self) -> Vec<LaneID> {
self.path.iter().map(|id| *id).collect()
}
} }
fn find_parking_spot( fn find_parking_spot(

View File

@ -18,7 +18,7 @@ use std::f64;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use transit::TransitSimState; use transit::TransitSimState;
use walking::WalkingSimState; use walking::WalkingSimState;
use {CarID, CarState, Event, InvariantViolated, PedestrianID, Tick, TIMESTEP}; use {AgentID, CarID, CarState, Event, InvariantViolated, PedestrianID, Tick, TIMESTEP};
#[derive(Serialize, Deserialize, Derivative)] #[derive(Serialize, Deserialize, Derivative)]
#[derivative(PartialEq, Eq)] #[derivative(PartialEq, Eq)]
@ -414,6 +414,13 @@ impl Sim {
)) ))
} }
} }
pub fn get_current_route(&self, id: AgentID) -> Option<Vec<LaneID>> {
match id {
AgentID::Car(car) => self.driving_state.get_current_route(car),
AgentID::Pedestrian(ped) => self.walking_state.get_current_route(ped),
}
}
} }
pub struct Benchmark { pub struct Benchmark {

View File

@ -504,6 +504,12 @@ impl WalkingSimState {
pub fn is_done(&self) -> bool { pub fn is_done(&self) -> bool {
self.peds.is_empty() self.peds.is_empty()
} }
pub fn get_current_route(&self, id: PedestrianID) -> Option<Vec<LaneID>> {
self.peds
.get(&id)
.map(|p| p.path.iter().map(|id| *id).collect())
}
} }
fn is_contraflow(map: &Map, from: LaneID, to: LaneID) -> bool { fn is_contraflow(map: &Map, from: LaneID, to: LaneID) -> bool {