mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-25 03:41:09 +03:00
visualize an agent's path
This commit is contained in:
parent
c685a80a98
commit
c38c9d43ac
@ -6,6 +6,7 @@ pub mod geom_validation;
|
||||
pub mod road_editor;
|
||||
pub mod search;
|
||||
pub mod selection;
|
||||
pub mod show_route;
|
||||
pub mod sim_controls;
|
||||
pub mod steep;
|
||||
pub mod stop_sign_editor;
|
||||
|
50
editor/src/plugins/show_route.rs
Normal file
50
editor/src/plugins/show_route.rs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ use plugins::geom_validation::Validator;
|
||||
use plugins::road_editor::RoadEditor;
|
||||
use plugins::search::SearchState;
|
||||
use plugins::selection::{Hider, SelectionState, ID};
|
||||
use plugins::show_route::ShowRouteState;
|
||||
use plugins::sim_controls::SimController;
|
||||
use plugins::steep::SteepnessVisualizer;
|
||||
use plugins::stop_sign_editor::StopSignEditor;
|
||||
@ -34,8 +35,8 @@ use plugins::turn_colors::TurnColors;
|
||||
use plugins::warp::WarpState;
|
||||
use render;
|
||||
use sim;
|
||||
use sim::{CarID, CarState, PedestrianID};
|
||||
use std::collections::HashMap;
|
||||
use sim::{AgentID, CarID, CarState, PedestrianID};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::process;
|
||||
|
||||
// TODO ideally these would be tuned kind of dynamically based on rendering speed
|
||||
@ -65,6 +66,7 @@ pub struct UI {
|
||||
current_search_state: SearchState,
|
||||
warp: WarpState,
|
||||
follow: FollowState,
|
||||
show_route: ShowRouteState,
|
||||
floodfiller: Floodfiller,
|
||||
steepness_viz: SteepnessVisualizer,
|
||||
osm_classifier: OsmClassifier,
|
||||
@ -137,6 +139,7 @@ impl UI {
|
||||
current_search_state: SearchState::Empty,
|
||||
warp: WarpState::Empty,
|
||||
follow: FollowState::Empty,
|
||||
show_route: ShowRouteState::Empty,
|
||||
floodfiller: Floodfiller::new(),
|
||||
osm_classifier: OsmClassifier::new(),
|
||||
traffic_signal_editor: TrafficSignalEditor::new(),
|
||||
@ -281,6 +284,7 @@ impl UI {
|
||||
// chaining is harder to read. :(
|
||||
vec![
|
||||
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.floodfiller.color_l(l, &self.cs),
|
||||
self.steepness_viz.color_l(&self.map, l),
|
||||
@ -457,6 +461,7 @@ impl gui::GUI for UI {
|
||||
self.follow
|
||||
.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!(
|
||||
self.color_picker
|
||||
.handle_event(input, &mut self.canvas, &mut self.cs)
|
||||
@ -544,12 +549,21 @@ impl gui::GUI for UI {
|
||||
self.follow = FollowState::FollowingCar(id);
|
||||
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) => {
|
||||
if input.key_pressed(Key::F, "follow this pedestrian") {
|
||||
self.follow = FollowState::FollowingPedestrian(id);
|
||||
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, _) => {
|
||||
if input.key_pressed(Key::F, "start floodfilling from this lane") {
|
||||
|
@ -842,6 +842,10 @@ impl DrivingSimState {
|
||||
}
|
||||
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.
|
||||
|
@ -163,6 +163,10 @@ impl Router {
|
||||
self.path.push_back(choice);
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_current_route(&self) -> Vec<LaneID> {
|
||||
self.path.iter().map(|id| *id).collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn find_parking_spot(
|
||||
|
@ -18,7 +18,7 @@ use std::f64;
|
||||
use std::time::{Duration, Instant};
|
||||
use transit::TransitSimState;
|
||||
use walking::WalkingSimState;
|
||||
use {CarID, CarState, Event, InvariantViolated, PedestrianID, Tick, TIMESTEP};
|
||||
use {AgentID, CarID, CarState, Event, InvariantViolated, PedestrianID, Tick, TIMESTEP};
|
||||
|
||||
#[derive(Serialize, Deserialize, Derivative)]
|
||||
#[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 {
|
||||
|
@ -504,6 +504,12 @@ impl WalkingSimState {
|
||||
pub fn is_done(&self) -> bool {
|
||||
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 {
|
||||
|
Loading…
Reference in New Issue
Block a user