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 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;
|
||||||
|
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::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") {
|
||||||
|
@ -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.
|
||||||
|
@ -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(
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user