From 9beec6db3e2b8cbd395aa9aa0e083ab92ab79d67 Mon Sep 17 00:00:00 2001 From: Charlie Date: Thu, 13 Feb 2025 14:26:35 -0500 Subject: [PATCH 01/20] reordered UI frames and added scrollable section to btree --- SimTraffic.py | 12 +++-- dash/Dashboard.py | 126 ++++++++++++++++++++++++---------------------- 2 files changed, 74 insertions(+), 64 deletions(-) diff --git a/SimTraffic.py b/SimTraffic.py index df7dfa9a..626a035f 100644 --- a/SimTraffic.py +++ b/SimTraffic.py @@ -7,6 +7,7 @@ # dashboard (debug), and external Simulator (Unreal or alternative Graphics engine) # -------------------------------------------- +import multiprocessing from multiprocessing import Manager, Array import numpy as np import glog as log @@ -27,6 +28,7 @@ class SimTraffic(object): def __init__(self, laneletmap, sim_config): + #multiprocessing.set_start_method('forkserver', force=True) self.lanelet_map = laneletmap self.sim_config = sim_config @@ -52,6 +54,8 @@ def __init__(self, laneletmap, sim_config): self.log_file = '' self.vehicles_log = {} + self.flag = None + def add_vehicle(self, v:Vehicle): self.vehicles[v.id] = v v.sim_traffic = self @@ -80,6 +84,7 @@ def add_static_obect(self, oid, x,y): def start(self): + self.flag = True #Optional CARLA co-sim if CARLA_COSIMULATION: self.carla_sync = CarlaSync() @@ -90,12 +95,12 @@ def start(self): self.write_traffic_state(0 , 0.0, 0.0) #If cosimulation, hold start waiting for first client state - if self.cosimulation == True and self.simconfig.wait_for_client: + if self.cosimulation == True and self.sim_config.wait_for_client: log.warn("GSServer is running in co-simulation. Waiting for client state in SEM:{} KEY:{}...".format(CS_SEM_KEY, CS_SHM_KEY)) while(True): header, vstates, _, _, _ = self.sim_client_shm.read_client_state(len(self.vehicles), len(self.pedestrians)) if len(vstates)>0: - break; + break time.sleep(0.5) #Start SDV Planners @@ -109,6 +114,7 @@ def start(self): pedestrian.start_planner() def stop_all(self): + self.flag = False if self.carla_sync: self.carla_sync.quit() @@ -208,7 +214,7 @@ def create_traffic_state_shm(self): def write_traffic_state(self, tick_count, delta_time, sim_time): if not self.traffic_state_sharr: return - + nv = len(self.vehicles) np = len(self.pedestrians) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 2a407740..6327297e 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -9,7 +9,7 @@ import matplotlib from matplotlib import pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from multiprocessing import Process +from multiprocessing import Process, set_start_method from TickSync import TickSync import tkinter as tk from tkinter import ttk @@ -26,6 +26,7 @@ from TrafficLight import * from sp.Pedestrian import * from mapping.LaneletMap import get_line_format +from threading import Thread class Dashboard(object): MAP_FIG_ID = 1 @@ -40,8 +41,10 @@ def __init__(self, sim_traffic:SimTraffic, sim_config:SimConfig): self.window = None self.center_pedestrian = False self.lanelet_map:LaneletMap = None + self.thread = None + self.maneuver = None - def start(self): + def start(self, traffic): """ Start dashboard in subprocess. global constant SHOW_DASHBOARD must be true Traffic must have started, otherwise the shared array is not ready @@ -56,24 +59,18 @@ def start(self): return self.lanelet_map = self.sim_traffic.lanelet_map - self._process = Process(target=self.run_dash_process, - args=(self.sim_traffic.traffic_state_sharr, self.sim_traffic.debug_shdata), - daemon=True) - self._process.start() - - def run_dash_process(self, traffic_state_sharr, debug_shdata): + self.run_dash_process(self.sim_traffic.traffic_state_sharr, self.sim_traffic.debug_shdata, traffic) + def run_dash_process(self, traffic_state_sharr, debug_shdata, traffic): + self.window = self.create_gui() - sync_dash = TickSync(DASH_RATE, realtime=True, block=True, verbose=False, label="DP") + sync_dash = TickSync(DASH_RATE, realtime=False, block=True, verbose=False, label="DP") while sync_dash.tick(): - if not self.window: + if not self.window or not traffic.flag: return - - #clear + self.clear_vehicle_charts() - self.tree_msg.configure(text= "") - #get new data header, vehicles, pedestrians, traffic_lights, static_objects = self.sim_traffic.read_traffic_state(traffic_state_sharr, False) tickcount, delta_time, sim_time = header[0:3] @@ -97,7 +94,6 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata): #find valid vehicle to focus plots and btree (if available) vid = None - if (type(self.center_id) == str): if self.center_id[0] == 'p': self.center_pedestrian = True @@ -118,8 +114,9 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata): self.plot_frenet_chart(vid, planner_state, ref_path, traj, cand, unf, traj_s_shift) if VEH_TRAJ_CHART: #vehicle traj plot self.plot_vehicle_sd(traj, cand) - #behavior tree - self.tree_msg.configure(text="==== Behavior Tree. Vehicle {} ====\n\n {} ".format(vid, btree_snapshot)) + #behavior tree update + self.tree_msg.delete("1.0", "end") + self.tree_msg.insert("1.0", "==== Behavior Tree. Vehicle {} ====\n\n {} ".format(vid, btree_snapshot)) else: #vehicles without planner: self.plot_cartesian_chart(vid, vehicles, pedestrians) @@ -135,9 +132,10 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata): if SHOW_MPLOT: self.map_canvas.draw() self.window.update() - + def quit(self): - self._process.terminate() + self.window.destroy() + # self._process.terminate() def change_tab_focus(self, event): focus = self.tab.focus() @@ -171,7 +169,6 @@ def update_pedestrian_table(self, pedestrians): sp = ['p' + str(pid)] + [sim_state] + sp self.tab.insert('','end', 'p' + str(pid), values=(sp)) - def plot_map_chart(self, vehicles,pedestrians,traffic_light_states,static_objects): #-Global Map cartesian plot fig = plt.figure(Dashboard.MAP_FIG_ID, frameon=False) @@ -721,47 +718,65 @@ def plot_curve(coef, T, title, ylabel, xlabel, color="black"): def create_gui(self): #Window window = tk.Tk() + window.configure(bg="white") + screen_width = window.winfo_screenwidth() + screen_height = window.winfo_screenheight() + + window.geometry(f"{screen_width}x{screen_height}") # Main containers: # title frame # stats frame # global frame [ map | table ] # vehicle frame [ cart | frenet | btree ] - title_frame = tk.Frame(window, width = 1200, height = 50, bg = "black") - title_frame.grid(row=0, sticky="nsew") - #tk.ttk.Separator(window,orient=tk.HORIZONTAL).grid(row=1, column=0, sticky='ew' ) - stats_frame = tk.Frame(window, width = 1200, height = 50, bg = "white") - stats_frame.grid(row=2, sticky="nsew") - tk.ttk.Separator(window,orient=tk.HORIZONTAL).grid(row=3, column=0, sticky='ew' ) + #title and stats + title_frame = tk.Frame(window, bg = "black") + title_frame.place(relx=0, rely=0, relwidth=1.0, relheight=0.05) - global_frame = tk.Frame(window, width = 1200, height = 300, bg = "white") - global_frame.grid(row=4, sticky="nsew") - tk.ttk.Separator(window,orient=tk.HORIZONTAL).grid(row=5, column=0, sticky='ew' ) + stats_frame = tk.Frame(window, bg = "white") + stats_frame.place(relx=0, rely=0.05, relwidth=1.0, relheight=0.05) + + #map and cartesian + map_frame = tk.Frame(window, bg = "white") + map_frame.place(relx=0, rely=0.1, relwidth=0.35, relheight=0.4) + #tk.ttk.Separator(window,orient=tk.HORIZONTAL).grid(row=6, column=0, sticky='ew' ) - vehicle_frame = tk.Frame(window, width = 1200, height = 300, bg = "white") - vehicle_frame.grid(row=6, sticky="nsew") + cart_frame = tk.Frame(window, bg = "white") + cart_frame.place(relx=0.35, rely=0.1, relwidth=0.35, relheight=0.4) - #global sub containers - if SHOW_MPLOT: - map_frame = tk.Frame(global_frame, width = 600, height = 300, bg = "red") #create - map_frame.grid(row=0, column=1, sticky="nsew") #set pos + fren_frame = tk.Frame(window, bg="white") + fren_frame.place(relx=0.01, rely=0.51, relwidth=0.69, relheight=0.29) + + tab_frame = tk.Frame(window, bg="white") + tab_frame.place(relx=0, rely=0.8, relwidth=0.7, relheight=0.2) + + canvas = tk.Canvas(window) + canvas.place(relx=0.7, rely=0.1, relwidth=0.3, relheight=0.9) + + # Add a vertical scrollbar + scrollbar = tk.Scrollbar(window, orient="vertical", command=canvas.yview) + scrollbar.place(relx=0.99, rely=0.1, relwidth=0.01, relheight=0.9) - tab_frame = tk.Frame(global_frame, width = 1000, height = 300, bg = "blue") - tab_frame.grid(row=0, column=2, sticky="nsew") + canvas.configure(yscrollcommand=scrollbar.set) + + # Create the bt_frame inside the canvas + bt_frame = tk.Frame(canvas, bg="white") + + # Add the bt_frame to the canvas + canvas.create_window((0, 0), window=bt_frame, anchor="nw", width=500) + + # Update the scrollregion whenever bt_frame is resize + + bt_frame.bind( + "", + lambda e: canvas.configure( + scrollregion=canvas.bbox("all") # Adjust scroll region based on content size + ) + ) #vehicle sub containers - cart_frame = tk.Frame(vehicle_frame if SHOW_MPLOT else global_frame, width = 300, height = 300, bg = "white") - fren_frame = tk.Frame(vehicle_frame, width = 300, height = 300, bg = "white") - bt_frame = tk.Frame(vehicle_frame, width = 300, height = 300, bg = "white") - traj_frame = tk.Frame(vehicle_frame, width = 300, height = 300, bg = "white") - - # Show enabled plots (left justified) - c = 0 - for cframe, visible in zip([cart_frame, fren_frame, bt_frame], [SHOW_CPLOT, SHOW_FFPLOT, SHOW_BTREE]): - if visible: - cframe.grid(row=0, column=c, sticky="nsew") - c += 1 + traj_frame = tk.Frame(bt_frame, bg = "white") # Content: window.title = 'GeoScenario Server' @@ -785,12 +800,6 @@ def create_gui(self): scenario_config_lb.pack(side = 'left') self.scenario_config_lb = scenario_config_lb - #scenario_stats_lb = tk.Label(stats_frame, bg='white', text='Loading \n scenario...', font=('OpenSans', 12), anchor="e", justify=tk.RIGHT) - #scenario_stats_lb.pack(side = 'right') - #self.scenario_stats_lb = scenario_stats_lb - - # global container: - # map if SHOW_MPLOT: fig_map = plt.figure(Dashboard.MAP_FIG_ID) @@ -816,9 +825,6 @@ def create_gui(self): tab.pack(fill='both', expand=True) #x and y self.tab = tab - - # vehicle container: - # vehicle cart fig_cart = plt.figure(Dashboard.CART_FIG_ID) if not SHOW_MPLOT: @@ -840,12 +846,10 @@ def create_gui(self): self.traj_canvas = FigureCanvasTkAgg(fig_traj, traj_frame) self.traj_canvas.get_tk_widget().pack() - tree_msg= tk.Message(bt_frame,text='', anchor='s', - width=300, - bg='white',foreground='black') + tree_msg = tk.Text(bt_frame, height=65, spacing2=1, bg="white", fg="black", wrap="word") self.tree_msg = tree_msg tree_msg.grid(row=0,column=0, sticky='nsew') - + #General plot Layout matplotlib.rc('font', size=8) matplotlib.rc('axes', titlesize=8) From 76a72631b9683e25a41e32729c55c82d3539d85d Mon Sep 17 00:00:00 2001 From: Charlie Date: Thu, 13 Feb 2025 15:00:55 -0500 Subject: [PATCH 02/20] reordered UI and added btree scroll --- dash/Dashboard.py | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 6327297e..364042a0 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -9,7 +9,7 @@ import matplotlib from matplotlib import pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from multiprocessing import Process, set_start_method +from multiprocessing import Process from TickSync import TickSync import tkinter as tk from tkinter import ttk @@ -26,7 +26,6 @@ from TrafficLight import * from sp.Pedestrian import * from mapping.LaneletMap import get_line_format -from threading import Thread class Dashboard(object): MAP_FIG_ID = 1 @@ -41,10 +40,8 @@ def __init__(self, sim_traffic:SimTraffic, sim_config:SimConfig): self.window = None self.center_pedestrian = False self.lanelet_map:LaneletMap = None - self.thread = None - self.maneuver = None - def start(self, traffic): + def start(self): """ Start dashboard in subprocess. global constant SHOW_DASHBOARD must be true Traffic must have started, otherwise the shared array is not ready @@ -59,18 +56,24 @@ def start(self, traffic): return self.lanelet_map = self.sim_traffic.lanelet_map - self.run_dash_process(self.sim_traffic.traffic_state_sharr, self.sim_traffic.debug_shdata, traffic) + self._process = Process(target=self.run_dash_process, + args=(self.sim_traffic.traffic_state_sharr, self.sim_traffic.debug_shdata), + daemon=True) + self._process.start() + + def run_dash_process(self, traffic_state_sharr, debug_shdata): - def run_dash_process(self, traffic_state_sharr, debug_shdata, traffic): - self.window = self.create_gui() - sync_dash = TickSync(DASH_RATE, realtime=False, block=True, verbose=False, label="DP") + sync_dash = TickSync(DASH_RATE, realtime=True, block=True, verbose=False, label="DP") while sync_dash.tick(): - if not self.window or not traffic.flag: + if not self.window: return - + + #clear self.clear_vehicle_charts() + self.tree_msg.configure(text= "") + #get new data header, vehicles, pedestrians, traffic_lights, static_objects = self.sim_traffic.read_traffic_state(traffic_state_sharr, False) tickcount, delta_time, sim_time = header[0:3] @@ -94,6 +97,7 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata, traffic): #find valid vehicle to focus plots and btree (if available) vid = None + if (type(self.center_id) == str): if self.center_id[0] == 'p': self.center_pedestrian = True @@ -114,9 +118,9 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata, traffic): self.plot_frenet_chart(vid, planner_state, ref_path, traj, cand, unf, traj_s_shift) if VEH_TRAJ_CHART: #vehicle traj plot self.plot_vehicle_sd(traj, cand) - #behavior tree update + #behavior tree self.tree_msg.delete("1.0", "end") - self.tree_msg.insert("1.0", "==== Behavior Tree. Vehicle {} ====\n\n {} ".format(vid, btree_snapshot)) + self.tree_msg.insert("1.0", "==== Behavior Tree. Vehicle {} ====\n\n {} ".format(vid, btree_snapshot)) else: #vehicles without planner: self.plot_cartesian_chart(vid, vehicles, pedestrians) @@ -132,10 +136,9 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata, traffic): if SHOW_MPLOT: self.map_canvas.draw() self.window.update() - + def quit(self): - self.window.destroy() - # self._process.terminate() + self._process.terminate() def change_tab_focus(self, event): focus = self.tab.focus() @@ -169,6 +172,7 @@ def update_pedestrian_table(self, pedestrians): sp = ['p' + str(pid)] + [sim_state] + sp self.tab.insert('','end', 'p' + str(pid), values=(sp)) + def plot_map_chart(self, vehicles,pedestrians,traffic_light_states,static_objects): #-Global Map cartesian plot fig = plt.figure(Dashboard.MAP_FIG_ID, frameon=False) @@ -859,4 +863,4 @@ def create_gui(self): matplotlib.rc('legend', fontsize=8) matplotlib.rc('figure', titlesize=8) - return window + return window \ No newline at end of file From ff1f6a97f2b2c677c130026c13e730fc13813888 Mon Sep 17 00:00:00 2001 From: Charlie Date: Thu, 13 Feb 2025 15:33:05 -0500 Subject: [PATCH 03/20] UI updates and btree scroll added --- SimTraffic.py | 10 ---------- dash/Dashboard.py | 18 +++--------------- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/SimTraffic.py b/SimTraffic.py index 626a035f..4fdb84ce 100644 --- a/SimTraffic.py +++ b/SimTraffic.py @@ -7,7 +7,6 @@ # dashboard (debug), and external Simulator (Unreal or alternative Graphics engine) # -------------------------------------------- -import multiprocessing from multiprocessing import Manager, Array import numpy as np import glog as log @@ -28,7 +27,6 @@ class SimTraffic(object): def __init__(self, laneletmap, sim_config): - #multiprocessing.set_start_method('forkserver', force=True) self.lanelet_map = laneletmap self.sim_config = sim_config @@ -54,8 +52,6 @@ def __init__(self, laneletmap, sim_config): self.log_file = '' self.vehicles_log = {} - self.flag = None - def add_vehicle(self, v:Vehicle): self.vehicles[v.id] = v v.sim_traffic = self @@ -262,8 +258,6 @@ def write_traffic_state(self, tick_count, delta_time, sim_time): if self.carla_sync: self.carla_sync.write_server_state(tick_count, delta_time, self.vehicles) - - def detect_collisions(self,tick_count, delta_time, sim_time): for id_va, va in self.vehicles.items(): if va.sim_state is not ActorSimState.ACTIVE: @@ -284,8 +278,6 @@ def detect_collisions(self,tick_count, delta_time, sim_time): return True return False - - def log_sim_state(self, client_vehicle_states, disabled_vehicles): log.info("Collision between vehicles {}".format(disabled_vehicles)) state_str = "GSS crash report:\n" @@ -306,7 +298,6 @@ def log_sim_state(self, client_vehicle_states, disabled_vehicles): ) log.info(state_str) - def log_trajectories(self,tick_count,delta_time,sim_time): if WRITE_TRAJECTORIES: for vid, vehicle in sorted(self.vehicles.items()): @@ -333,7 +324,6 @@ def write_log_trajectories(self): for line in vlog: csv_writer.writerow(line) - #For independent processes: def read_traffic_state(self, traffic_state_sharr, actives_only = True): ''' diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 364042a0..05df1a15 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -72,7 +72,6 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata): #clear self.clear_vehicle_charts() - self.tree_msg.configure(text= "") #get new data header, vehicles, pedestrians, traffic_lights, static_objects = self.sim_traffic.read_traffic_state(traffic_state_sharr, False) @@ -97,7 +96,6 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata): #find valid vehicle to focus plots and btree (if available) vid = None - if (type(self.center_id) == str): if self.center_id[0] == 'p': self.center_pedestrian = True @@ -368,8 +366,6 @@ def plot_vehicles(self,vehicles,x_min,x_max,y_min,y_max, show_arrow = False): vy = -vy plt.arrow(x, y, vx/2, vy/2, head_width=1, head_length=1, color=colorcode, zorder=10) - - def plot_pedestrians(self, pedestrians, x_min, x_max, y_min, y_max, show_arrow=True): if pedestrians: for pid, pedestrian in pedestrians.items(): @@ -399,7 +395,6 @@ def plot_pedestrians(self, pedestrians, x_min, x_max, y_min, y_max, show_arrow=T plt.plot(x_goal, y_goal, 'r.' ,markersize=2, zorder=10) plt.gca().text(x_goal+1, y_goal+1, "p{} goal".format(pid), style='italic', zorder=10) - def plot_frenet_chart(self, center_id, traffic_state:TrafficState, debug_ref_path, traj, cand, unf, traj_s_shift): #Frenet Frame plot fig = plt.figure(Dashboard.FRE_FIG_ID) @@ -441,7 +436,6 @@ def plot_frenet_chart(self, center_id, traffic_state:TrafficState, debug_ref_pat x, y = lane_config.stopline_pos plt.axvline(x, color= 'r', linestyle='-', zorder=1) - #road_occupancy if SHOW_OCCUPANCY and traffic_state.road_occupancy is not None: road_occupancy:RoadOccupancy = traffic_state.road_occupancy @@ -476,7 +470,6 @@ def plot_frenet_chart(self, center_id, traffic_state:TrafficState, debug_ref_pat gca.text(anchorx, anchory, y_label) gca.text(anchorx, anchory + cellsize, i_label) - #junction #size = 3 #intersections = traffic_state.intersections @@ -486,7 +479,6 @@ def plot_frenet_chart(self, center_id, traffic_state:TrafficState, debug_ref_pat # if isinstance(intersection, sv.SDVTrafficState.AllWayStopIntersection): # intersection. - # Regulatory Elements if (regulatory_elements is not None): for re in regulatory_elements: @@ -563,9 +555,6 @@ def plot_frenet_chart(self, center_id, traffic_state:TrafficState, debug_ref_pat # update lane config based on current (possibly outdated) reference frame #lane_config = self.read_map(vehicle_state, self.reference_path) - - - def get_color_by_type(self,actor,a_type,sim_state = None, name = ''): #color colorcode = 'k' #black @@ -614,7 +603,6 @@ def clear_vehicle_charts(self): fig = plt.figure(Dashboard.TRAJ_FIG_ID) plt.cla() - @staticmethod def plot_trajectory(s_coef, d_coef, T, traj_s_shift, tcolor='grey'): s_eq = to_equation(s_coef) @@ -742,9 +730,9 @@ def create_gui(self): stats_frame.place(relx=0, rely=0.05, relwidth=1.0, relheight=0.05) #map and cartesian - map_frame = tk.Frame(window, bg = "white") - map_frame.place(relx=0, rely=0.1, relwidth=0.35, relheight=0.4) - #tk.ttk.Separator(window,orient=tk.HORIZONTAL).grid(row=6, column=0, sticky='ew' ) + if SHOW_MPLOT: + map_frame = tk.Frame(window, bg = "white") + map_frame.place(relx=0, rely=0.1, relwidth=0.35, relheight=0.4) cart_frame = tk.Frame(window, bg = "white") cart_frame.place(relx=0.35, rely=0.1, relwidth=0.35, relheight=0.4) From 598b1e66966e6e7a56cbce43a4318a088e84005c Mon Sep 17 00:00:00 2001 From: Charlie Date: Thu, 13 Feb 2025 16:40:19 -0500 Subject: [PATCH 04/20] changed UI and added btree scroll --- dash/Dashboard.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 05df1a15..1c3386ac 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -118,7 +118,7 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata): self.plot_vehicle_sd(traj, cand) #behavior tree self.tree_msg.delete("1.0", "end") - self.tree_msg.insert("1.0", "==== Behavior Tree. Vehicle {} ====\n\n {} ".format(vid, btree_snapshot)) + self.tree_msg.insert("1.0", btree_snapshot) else: #vehicles without planner: self.plot_cartesian_chart(vid, vehicles, pedestrians) @@ -711,10 +711,7 @@ def create_gui(self): #Window window = tk.Tk() window.configure(bg="white") - screen_width = window.winfo_screenwidth() - screen_height = window.winfo_screenheight() - - window.geometry(f"{screen_width}x{screen_height}") + window.configure("-fullscreen", True) # Main containers: # title frame From 180e95656c3cfcd11867dbcfa2c5d7948a98940c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Antkiewicz?= Date: Fri, 14 Feb 2025 11:38:43 -0500 Subject: [PATCH 05/20] use attributes(-zoomed, True) to maximize the window --- dash/Dashboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 1c3386ac..d5c55d13 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -711,7 +711,7 @@ def create_gui(self): #Window window = tk.Tk() window.configure(bg="white") - window.configure("-fullscreen", True) + window.attributes("-zoomed", True) # Main containers: # title frame From 0a95f4216005c05c93d38b67997eb8a22f838861 Mon Sep 17 00:00:00 2001 From: Charlie Date: Fri, 14 Feb 2025 11:38:51 -0500 Subject: [PATCH 06/20] added UI changes and btree scroll --- SimTraffic.py | 9 ++++----- dash/Dashboard.py | 10 ++++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/SimTraffic.py b/SimTraffic.py index 4fdb84ce..9b91db7c 100644 --- a/SimTraffic.py +++ b/SimTraffic.py @@ -51,6 +51,7 @@ def __init__(self, laneletmap, sim_config): #Traffic Log self.log_file = '' self.vehicles_log = {} + self.traffic_running = False def add_vehicle(self, v:Vehicle): self.vehicles[v.id] = v @@ -78,9 +79,8 @@ def add_pedestrian(self, p:Pedestrian): def add_static_obect(self, oid, x,y): self.static_objects[oid] = StaticObject(oid,x,y) - def start(self): - self.flag = True + self.traffic_running = True #Optional CARLA co-sim if CARLA_COSIMULATION: self.carla_sync = CarlaSync() @@ -110,7 +110,7 @@ def start(self): pedestrian.start_planner() def stop_all(self): - self.flag = False + self.traffic_running = False if self.carla_sync: self.carla_sync.quit() @@ -165,7 +165,6 @@ def tick(self, tick_count, delta_time, sim_time): if self.vehicles[vid].type is Vehicle.EV_TYPE and vid in vstates: self.vehicles[vid].update_sim_state(vstates[vid], delta_time) #client_delta_time - #tick vehicles (all types) for vid in self.vehicles: self.vehicles[vid].tick(tick_count, delta_time, sim_time) @@ -388,4 +387,4 @@ def read_traffic_state(self, traffic_state_sharr, actives_only = True): # should be automatically thread-safe static_objects = copy(self.static_objects) - return header, vehicles, pedestrians, traffic_light_states, static_objects + return header, vehicles, pedestrians, traffic_light_states, static_objects \ No newline at end of file diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 1c3386ac..26d9fb08 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -646,7 +646,7 @@ def plot_vehicle_sd(trajectory, cand): s_vel_coef = differentiate(s_coef) Dashboard.plot_curve(s_vel_coef,T,'Long Vel (m/s)', '', 'T (s)') - # # S Acc(t) curve + #S Acc(t) curve i+=1 s_acc_coef = differentiate(s_vel_coef) plt.subplot(nrows,ncols,i) @@ -711,8 +711,10 @@ def create_gui(self): #Window window = tk.Tk() window.configure(bg="white") - window.configure("-fullscreen", True) + screen_height = window.winfo_screenheight() + screen_width = window.winfo_screenwidth() + window.geometry(f"{screen_width}x{screen_height}") # Main containers: # title frame # stats frame @@ -753,7 +755,7 @@ def create_gui(self): bt_frame = tk.Frame(canvas, bg="white") # Add the bt_frame to the canvas - canvas.create_window((0, 0), window=bt_frame, anchor="nw", width=500) + canvas.create_window((0, 0), window=bt_frame, anchor="nw", width=screen_width*0.3) # Update the scrollregion whenever bt_frame is resize @@ -767,7 +769,7 @@ def create_gui(self): #vehicle sub containers traj_frame = tk.Frame(bt_frame, bg = "white") - # Content: + #Content: window.title = 'GeoScenario Server' str_title = ' GeoScenario Server ' img_logos = ImageTk.PhotoImage(Image.open(ROOT_DIR + "/dash/img/logos.png").resize((380, 50))) From bcccc2f3ac1ea4377b292af93f3bec379e99b11f Mon Sep 17 00:00:00 2001 From: Charlie Date: Fri, 14 Feb 2025 11:58:56 -0500 Subject: [PATCH 07/20] UI changes and added btree scroll --- SimTraffic.py | 1 - dash/Dashboard.py | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/SimTraffic.py b/SimTraffic.py index 9b91db7c..3a1e09d3 100644 --- a/SimTraffic.py +++ b/SimTraffic.py @@ -23,7 +23,6 @@ except: log.warning("Carla API not found") - class SimTraffic(object): def __init__(self, laneletmap, sim_config): diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 26d9fb08..5d6a75eb 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -714,7 +714,11 @@ def create_gui(self): screen_height = window.winfo_screenheight() screen_width = window.winfo_screenwidth() - window.geometry(f"{screen_width}x{screen_height}") + try: + window.attributes("-zoomed", True) + except: + window.state("zoomed") + # Main containers: # title frame # stats frame From 78087ac1373e024d219c7f38daec02d2159eb4fd Mon Sep 17 00:00:00 2001 From: Charlie Date: Fri, 14 Feb 2025 12:17:09 -0500 Subject: [PATCH 08/20] window maximization for mac and linux --- dash/Dashboard.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 5d6a75eb..dcc2521c 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -715,8 +715,10 @@ def create_gui(self): screen_width = window.winfo_screenwidth() try: + #linux window.attributes("-zoomed", True) except: + #mac window.state("zoomed") # Main containers: From 1cd1de56bbee496a8815a59955e95973c8f552e7 Mon Sep 17 00:00:00 2001 From: Charlie Date: Fri, 14 Feb 2025 12:27:48 -0500 Subject: [PATCH 09/20] UI changes and added btree scroll --- dash/Dashboard.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index dcc2521c..cb7d5a51 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -170,7 +170,6 @@ def update_pedestrian_table(self, pedestrians): sp = ['p' + str(pid)] + [sim_state] + sp self.tab.insert('','end', 'p' + str(pid), values=(sp)) - def plot_map_chart(self, vehicles,pedestrians,traffic_light_states,static_objects): #-Global Map cartesian plot fig = plt.figure(Dashboard.MAP_FIG_ID, frameon=False) @@ -209,7 +208,6 @@ def plot_pedestrian_cartesian_chart(self, center_id, vehicles, pedestrians, traf y_min = pedestrians[center_id].state.y - (CPLOT_SIZE/2) y_max = pedestrians[center_id].state.y + (CPLOT_SIZE/2) - self.plot_road(x_min,x_max,y_min,y_max,traffic_lights) self.plot_static_objects(static_objects, x_min,x_max,y_min,y_max) @@ -237,7 +235,6 @@ def plot_cartesian_chart(self, center_id, vehicles, pedestrians, reference_path y_min = vehicles[center_id].state.y - (CPLOT_SIZE/2) y_max = vehicles[center_id].state.y + (CPLOT_SIZE/2) - self.plot_road(x_min,x_max,y_min,y_max,traffic_lights) self.plot_static_objects(static_objects, x_min,x_max,y_min,y_max) if REFERENCE_PATH and reference_path is not None: @@ -258,7 +255,6 @@ def plot_cartesian_chart(self, center_id, vehicles, pedestrians, reference_path plt.margins(0,0) plt.subplots_adjust(bottom=0.05,top=0.95,left=0.05,right=0.95,hspace=0,wspace=0) - def plot_road(self,x_min,x_max,y_min,y_max,traffic_light_states = None): #road lines: @@ -292,7 +288,6 @@ def plot_road(self,x_min,x_max,y_min,y_max,traffic_light_states = None): #for stop_line in stop_lines: #plt.plot([pt.x for pt in stop_line], [pt.y for pt in stop_line], 'r-') #red - #lights (must be drawn after other stop lines) if traffic_light_states: for lid,state in traffic_light_states.items(): @@ -761,7 +756,7 @@ def create_gui(self): bt_frame = tk.Frame(canvas, bg="white") # Add the bt_frame to the canvas - canvas.create_window((0, 0), window=bt_frame, anchor="nw", width=screen_width*0.3) + canvas.create_window((0, 0), window=bt_frame, anchor="nw", width=screen_width*0.3, height=screen_height) # Update the scrollregion whenever bt_frame is resize From 423a0d23d80b699a36ee66da5a6e3f77cb6cfedd Mon Sep 17 00:00:00 2001 From: Charlie Date: Tue, 18 Feb 2025 14:40:05 -0500 Subject: [PATCH 10/20] added resolution scaling --- dash/Dashboard.py | 142 +++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 70 deletions(-) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index cb7d5a51..86c95222 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -706,81 +706,82 @@ def create_gui(self): #Window window = tk.Tk() window.configure(bg="white") + + screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() - screen_width = window.winfo_screenwidth() - - try: - #linux - window.attributes("-zoomed", True) - except: - #mac - window.state("zoomed") - - # Main containers: - # title frame - # stats frame - # global frame [ map | table ] - # vehicle frame [ cart | frenet | btree ] - - #title and stats - title_frame = tk.Frame(window, bg = "black") - title_frame.place(relx=0, rely=0, relwidth=1.0, relheight=0.05) - - stats_frame = tk.Frame(window, bg = "white") - stats_frame.place(relx=0, rely=0.05, relwidth=1.0, relheight=0.05) + window.geometry(f"{screen_width}x{screen_height}") - #map and cartesian - if SHOW_MPLOT: - map_frame = tk.Frame(window, bg = "white") - map_frame.place(relx=0, rely=0.1, relwidth=0.35, relheight=0.4) + vis_scaling = 1 + txt_scaling = 1 + + if screen_height >= 1440 and screen_width >= 2560: + vis_scaling = 3 + txt_scaling = 1.5 + elif screen_height >= 1080 and screen_width >= 1920: + vis_scaling = 2 + txt_scaling = 1.2 + + window.minsize("1512x982") + + # Configure row and column weights for dynamic resizing + window.columnconfigure(0, weight=1) # Left section (70% width) + window.columnconfigure(1, weight=1) # Right section (30% width) + window.columnconfigure(2, weight=1) # Scrollable content + window.rowconfigure(0, weight=1) # Title row + window.rowconfigure(1, weight=1) # Stats row + window.rowconfigure(2, weight=3) # Map/cartesian row + window.rowconfigure(3, weight=3) # Fren frame + window.rowconfigure(4, weight=3) # Tab frame + #window.rowconfigure(5, weight=4) # Scrollable content + + # # Frames + title_frame = tk.Frame(window, bg="black") + title_frame.grid(row=1, column=0, columnspan=3, sticky="nsew") + + stats_frame = tk.Frame(window, bg="white") + stats_frame.grid(row=2, column=0, columnspan=3, sticky="nsew") + + map_frame = tk.Frame(window, bg="white") + map_frame.grid(row=3, column=0, sticky="nsew") - cart_frame = tk.Frame(window, bg = "white") - cart_frame.place(relx=0.35, rely=0.1, relwidth=0.35, relheight=0.4) + cart_frame = tk.Frame(window, bg="white") + cart_frame.grid(row=3, column=1, sticky="nsew") fren_frame = tk.Frame(window, bg="white") - fren_frame.place(relx=0.01, rely=0.51, relwidth=0.69, relheight=0.29) + fren_frame.grid(row=4, column=0, columnspan=2, sticky="nsew") tab_frame = tk.Frame(window, bg="white") - tab_frame.place(relx=0, rely=0.8, relwidth=0.7, relheight=0.2) + tab_frame.grid(row=5, column=0, columnspan=2, sticky="nsew") - canvas = tk.Canvas(window) - canvas.place(relx=0.7, rely=0.1, relwidth=0.3, relheight=0.9) + # Scrollable Right Section + canvas = tk.Canvas(window, bg="white") + canvas.grid(row=2, column=2, rowspan=4, sticky="nsew") - # Add a vertical scrollbar scrollbar = tk.Scrollbar(window, orient="vertical", command=canvas.yview) - scrollbar.place(relx=0.99, rely=0.1, relwidth=0.01, relheight=0.9) + scrollbar.grid(row=2, column=2, rowspan=4, sticky="nse") # Align right edge of the column canvas.configure(yscrollcommand=scrollbar.set) - # Create the bt_frame inside the canvas bt_frame = tk.Frame(canvas, bg="white") + canvas.create_window((0, 0), window=bt_frame, anchor="nw") - # Add the bt_frame to the canvas - canvas.create_window((0, 0), window=bt_frame, anchor="nw", width=screen_width*0.3, height=screen_height) + # Make widgets inside bt_frame expand + bt_frame.bind("", lambda e: canvas.configure(scrollregion=canvas.bbox("all"))) - # Update the scrollregion whenever bt_frame is resize - - bt_frame.bind( - "", - lambda e: canvas.configure( - scrollregion=canvas.bbox("all") # Adjust scroll region based on content size - ) - ) - - #vehicle sub containers + # #vehicle sub containers traj_frame = tk.Frame(bt_frame, bg = "white") - #Content: + # Content: window.title = 'GeoScenario Server' str_title = ' GeoScenario Server ' - img_logos = ImageTk.PhotoImage(Image.open(ROOT_DIR + "/dash/img/logos.png").resize((380, 50))) + img_logos = ImageTk.PhotoImage(Image.open(ROOT_DIR + "/dash/img/logos.png").resize((int(380*vis_scaling), int(50*vis_scaling)))) img_gs = pimg = ImageTk.PhotoImage(Image.open(ROOT_DIR + "/dash/img/icons/gs.png").resize((40, 40))) img_veh = ImageTk.PhotoImage(Image.open(ROOT_DIR + "/dash/img/icons/vehicle.png").resize((100, 47))) img_ego = ImageTk.PhotoImage(Image.open(ROOT_DIR + "/dash/img/icons/vehicle_ego.png").resize((80, 30))) # Widgets # title - lb = tk.Label(title_frame, text=str_title, bg = "black", fg="white",font=('OpenSans', 30)) + lb = tk.Label(title_frame, text=str_title, bg = "black", fg="white",font=('OpenSans', int(30*txt_scaling))) # needs scaling lb.pack(side = 'left') lb_logos = tk.Label(title_frame, image=img_logos) @@ -788,16 +789,16 @@ def create_gui(self): lb_logos.pack(side='right') # stats container: - scenario_config_lb = tk.Label(stats_frame, bg='white', text='Loading \n scenario...', font=('OpenSans', 10), anchor="w", justify=tk.LEFT) + scenario_config_lb = tk.Label(stats_frame, bg='white', text='Loading \n scenario...', font=('OpenSans', int(12*txt_scaling)), anchor="w", justify=tk.LEFT) scenario_config_lb.pack(side = 'left') self.scenario_config_lb = scenario_config_lb # map if SHOW_MPLOT: fig_map = plt.figure(Dashboard.MAP_FIG_ID) - fig_map.set_size_inches(5, 5, forward=True) + fig_map.set_size_inches(2*vis_scaling, 2*vis_scaling, forward=True) # needs to be scaled self.map_canvas = FigureCanvasTkAgg(fig_map, map_frame) - self.map_canvas.get_tk_widget().pack() + self.map_canvas.get_tk_widget().pack(expand=True, fill="both") # vehicle table tab = ttk.Treeview(tab_frame, show=['headings']) @@ -811,7 +812,7 @@ def create_gui(self): ) for col in tab['columns']: tab.heading(col, text=col, anchor='center') - tab.column(col, anchor='center', width=65, minwidth=65) + tab.column(col, anchor='center', width=1, minwidth=1) tab.bind('<>', self.change_tab_focus) #tab.grid(row=0,column=0, sticky='nsew') tab.pack(fill='both', expand=True) #x and y @@ -820,35 +821,36 @@ def create_gui(self): # vehicle cart fig_cart = plt.figure(Dashboard.CART_FIG_ID) if not SHOW_MPLOT: - fig_cart.set_size_inches(7, 7, forward=True) + fig_cart.set_size_inches(4, 4, forward=True) # needs to be scaled else: - fig_cart.set_size_inches(6, 6, forward=True) + fig_cart.set_size_inches(2*vis_scaling, 2*vis_scaling, forward=True) # needs to be scaled self.cart_canvas = FigureCanvasTkAgg(fig_cart, cart_frame) - self.cart_canvas.get_tk_widget().pack() + self.cart_canvas.get_tk_widget().pack(expand=True, fill="both") # vehicle frenet fig_fren = plt.figure(Dashboard.FRE_FIG_ID) - #fig_fren.set_size_inches(6,4,forward=True) + fig_fren.set_size_inches(1*vis_scaling,1*vis_scaling,forward=True) # needs to be scaled self.fren_canvas = FigureCanvasTkAgg(fig_fren, fren_frame) - self.fren_canvas.get_tk_widget().pack() + self.fren_canvas.get_tk_widget().pack(expand=True, fill="both", padx=5*vis_scaling, pady=5*vis_scaling) # vehicle traj fig_traj = plt.figure(Dashboard.TRAJ_FIG_ID) - fig_traj.set_size_inches(4,4,forward=True) + fig_traj.set_size_inches(2*vis_scaling,2*vis_scaling,forward=True) # needs to be scaled self.traj_canvas = FigureCanvasTkAgg(fig_traj, traj_frame) - self.traj_canvas.get_tk_widget().pack() - - tree_msg = tk.Text(bt_frame, height=65, spacing2=1, bg="white", fg="black", wrap="word") + self.traj_canvas.get_tk_widget().pack(expand=True, fill="both") + + tree_msg = tk.Text(bt_frame, height=int(65*txt_scaling), width=int(60*txt_scaling), spacing2=1, bg="white", fg="black", wrap="word", font=("Arial", int(12*txt_scaling))) self.tree_msg = tree_msg tree_msg.grid(row=0,column=0, sticky='nsew') #General plot Layout - matplotlib.rc('font', size=8) - matplotlib.rc('axes', titlesize=8) - matplotlib.rc('axes', labelsize=8) - matplotlib.rc('xtick', labelsize=6) - matplotlib.rc('ytick', labelsize=6) - matplotlib.rc('legend', fontsize=8) - matplotlib.rc('figure', titlesize=8) - + matplotlib.rc('font', size=int(8*txt_scaling)) # needs to be scaled + matplotlib.rc('lines', linewidth=2*vis_scaling) #needs to be scaled + matplotlib.rc('axes', titlesize=8*vis_scaling) + matplotlib.rc('axes', labelsize=8*vis_scaling) + matplotlib.rc('xtick', labelsize=6*vis_scaling) + matplotlib.rc('ytick', labelsize=6*vis_scaling) + matplotlib.rc('legend', fontsize=8*vis_scaling) + matplotlib.rc('figure', titlesize=8*vis_scaling) + return window \ No newline at end of file From 72ed87a647d97691f05f2d415a04d846e1276f87 Mon Sep 17 00:00:00 2001 From: Charlie Date: Tue, 18 Feb 2025 14:45:45 -0500 Subject: [PATCH 11/20] UI layout change and added resolution scaling --- dash/Dashboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 86c95222..a7bd2942 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -721,7 +721,7 @@ def create_gui(self): vis_scaling = 2 txt_scaling = 1.2 - window.minsize("1512x982") + window.minsize(1512, 982) # Configure row and column weights for dynamic resizing window.columnconfigure(0, weight=1) # Left section (70% width) From 9afe0a8d3e657533424f6935213c8ee54a634910 Mon Sep 17 00:00:00 2001 From: Charlie Date: Tue, 18 Feb 2025 15:28:55 -0500 Subject: [PATCH 12/20] Ui changes and resolution scaling --- dash/Dashboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index a7bd2942..7aaa7940 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -789,7 +789,7 @@ def create_gui(self): lb_logos.pack(side='right') # stats container: - scenario_config_lb = tk.Label(stats_frame, bg='white', text='Loading \n scenario...', font=('OpenSans', int(12*txt_scaling)), anchor="w", justify=tk.LEFT) + scenario_config_lb = tk.Label(stats_frame, bg='white', text='Loading \n scenario...', font=('OpenSans', int(10*txt_scaling)), anchor="w", justify=tk.LEFT) scenario_config_lb.pack(side = 'left') self.scenario_config_lb = scenario_config_lb From c388ec5d8530d109c50a11985b16c99c739b3e09 Mon Sep 17 00:00:00 2001 From: Charlie Date: Tue, 18 Feb 2025 15:40:34 -0500 Subject: [PATCH 13/20] UI changes --- dash/Dashboard.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 7aaa7940..fe242ee9 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -816,6 +816,8 @@ def create_gui(self): tab.bind('<>', self.change_tab_focus) #tab.grid(row=0,column=0, sticky='nsew') tab.pack(fill='both', expand=True) #x and y + style = ttk.Style() + style.configure("Treeview", font=("Arial", int(12*txt_scaling))) # needs to be scaled self.tab = tab # vehicle cart From 56643b0b4bd8191d9d3aa996804f7671fc8d577d Mon Sep 17 00:00:00 2001 From: Charlie Date: Wed, 19 Feb 2025 11:13:32 -0500 Subject: [PATCH 14/20] added ability to set screen position on launch --- GSServer.py | 24 +++++++------------- dash/Dashboard.py | 56 +++++++++++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 42 deletions(-) mode change 100755 => 100644 GSServer.py diff --git a/GSServer.py b/GSServer.py old mode 100755 new mode 100644 index 4e524a5b..9159d635 --- a/GSServer.py +++ b/GSServer.py @@ -37,6 +37,8 @@ def start_server(args, m=MVelKeepConfig()): btree_locations = [base_btree_location] log.info ("Btree search locations set (in order) as: " + str(btree_locations)) + traffic = SimTraffic(lanelet_map, sim_config) + if args.verify_map != "": verify_map_file(args.verify_map, lanelet_map) return @@ -44,15 +46,6 @@ def start_server(args, m=MVelKeepConfig()): if args.no_dash: sim_config.show_dashboard = False - if args.wait_for_input: - sim_config.wait_for_input = True - - if args.wait_for_client: - sim_config.wait_for_client = True - - # use sim_config after all modifications - traffic = SimTraffic(lanelet_map, sim_config) - # SCENARIO SETUP if args.gsfiles: if all(['.osm' in file for file in args.gsfiles]): @@ -74,9 +67,6 @@ def start_server(args, m=MVelKeepConfig()): sync_global = TickSync(rate=sim_config.traffic_rate, realtime=True, block=True, verbose=False, label="EX") sync_global.set_timeout(sim_config.timeout) - if sim_config.wait_for_input: - input("Press [ENTER] to start...") - #SIM EXECUTION START log.info('SIMULATION START') traffic.start() @@ -84,10 +74,13 @@ def start_server(args, m=MVelKeepConfig()): #GUI / Debug screen dashboard = Dashboard(traffic, sim_config) if sim_config.show_dashboard: - dashboard.start() + dashboard.start(args.dash_pos) else: log.warn("Dashboard will not start") + if WAIT_FOR_INPUT: + input("waiting for [ENTER]...") + while sync_global.tick(): if sim_config.show_dashboard and not dashboard._process.is_alive(): # might/might not be wanted break @@ -127,11 +120,10 @@ def verify_map_file(map_file, lanelet_map:LaneletMap): parser.add_argument("-s", "--scenario", dest="gsfiles", nargs='*', metavar="FILE", default="", help="GeoScenario file. If no file is provided, the GSServer will load a scenario from code") parser.add_argument("--verify_map", dest="verify_map", metavar="FILE", default="", help="Lanelet map file") parser.add_argument("-q", "--quiet", dest="verbose", default=True, help="don't print messages to stdout") - parser.add_argument("-n", "--no-dash", dest="no_dash", action="store_true", help="run without the dashboard") + parser.add_argument("-n", "--no_dash", dest="no_dash", action="store_true", help="run without the dashboard") parser.add_argument("-m", "--map-path", dest="map_path", default="", help="Set the prefix to append to the value of the attribute `globalconfig->lanelet`") parser.add_argument("-b", "--btree-locations", dest="btree_locations", default="", help="Add higher priority locations to search for btrees by agent btypes") - parser.add_argument("-wi", "--wait-for-input", dest="wait_for_input", action="store_true", help="Wait for the user to press [ENTER] to start the simulation") - parser.add_argument("-wc", "--wait-for-client", dest="wait_for_client", action="store_true", help="Wait for a valid client state to start the simulation") + parser.add_argument("--dash-pos", default=[0,0,0,0], dest="dash_pos", type=float, nargs=4, help="Set the position of the dashboard window (x y width height)") args = parser.parse_args() start_server(args) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index fe242ee9..1fdbf708 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -9,7 +9,7 @@ import matplotlib from matplotlib import pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from multiprocessing import Process +from multiprocessing import Process, set_start_method from TickSync import TickSync import tkinter as tk from tkinter import ttk @@ -26,6 +26,7 @@ from TrafficLight import * from sp.Pedestrian import * from mapping.LaneletMap import get_line_format +from threading import Thread class Dashboard(object): MAP_FIG_ID = 1 @@ -40,8 +41,10 @@ def __init__(self, sim_traffic:SimTraffic, sim_config:SimConfig): self.window = None self.center_pedestrian = False self.lanelet_map:LaneletMap = None + self.thread = None + self.maneuver = None - def start(self): + def start(self, traffic, pos): """ Start dashboard in subprocess. global constant SHOW_DASHBOARD must be true Traffic must have started, otherwise the shared array is not ready @@ -56,23 +59,17 @@ def start(self): return self.lanelet_map = self.sim_traffic.lanelet_map - self._process = Process(target=self.run_dash_process, - args=(self.sim_traffic.traffic_state_sharr, self.sim_traffic.debug_shdata), - daemon=True) - self._process.start() + self.run_dash_process(self.sim_traffic.traffic_state_sharr, self.sim_traffic.debug_shdata, traffic, pos) - def run_dash_process(self, traffic_state_sharr, debug_shdata): - - self.window = self.create_gui() - sync_dash = TickSync(DASH_RATE, realtime=True, block=True, verbose=False, label="DP") + def run_dash_process(self, traffic_state_sharr, debug_shdata, traffic, pos): + self.window = self.create_gui(pos) + sync_dash = TickSync(DASH_RATE, realtime=False, block=True, verbose=False, label="DP") while sync_dash.tick(): - if not self.window: + if not self.window or not traffic.traffic_running: return - - #clear + self.clear_vehicle_charts() - #get new data header, vehicles, pedestrians, traffic_lights, static_objects = self.sim_traffic.read_traffic_state(traffic_state_sharr, False) tickcount, delta_time, sim_time = header[0:3] @@ -116,9 +113,9 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata): self.plot_frenet_chart(vid, planner_state, ref_path, traj, cand, unf, traj_s_shift) if VEH_TRAJ_CHART: #vehicle traj plot self.plot_vehicle_sd(traj, cand) - #behavior tree + #behavior tree update self.tree_msg.delete("1.0", "end") - self.tree_msg.insert("1.0", btree_snapshot) + self.tree_msg.insert("1.0", btree_snapshot) else: #vehicles without planner: self.plot_cartesian_chart(vid, vehicles, pedestrians) @@ -134,9 +131,10 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata): if SHOW_MPLOT: self.map_canvas.draw() self.window.update() - + def quit(self): - self._process.terminate() + self.window.destroy() + # self._process.terminate() def change_tab_focus(self, event): focus = self.tab.focus() @@ -235,6 +233,7 @@ def plot_cartesian_chart(self, center_id, vehicles, pedestrians, reference_path y_min = vehicles[center_id].state.y - (CPLOT_SIZE/2) y_max = vehicles[center_id].state.y + (CPLOT_SIZE/2) + self.plot_road(x_min,x_max,y_min,y_max,traffic_lights) self.plot_static_objects(static_objects, x_min,x_max,y_min,y_max) if REFERENCE_PATH and reference_path is not None: @@ -641,7 +640,7 @@ def plot_vehicle_sd(trajectory, cand): s_vel_coef = differentiate(s_coef) Dashboard.plot_curve(s_vel_coef,T,'Long Vel (m/s)', '', 'T (s)') - #S Acc(t) curve + # # S Acc(t) curve i+=1 s_acc_coef = differentiate(s_vel_coef) plt.subplot(nrows,ncols,i) @@ -702,14 +701,21 @@ def plot_curve(coef, T, title, ylabel, xlabel, color="black"): t += 0.25 plt.plot(X,Y,color=color) - def create_gui(self): + def create_gui(self, pos): #Window window = tk.Tk() window.configure(bg="white") screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() - window.geometry(f"{screen_width}x{screen_height}") + + x, y, w, h = pos + if set(pos) == {0}: + x, y, w, h = 0, 0, screen_width, screen_height + else: + x, y, w, h = pos + + window.geometry("%dx%d+%d+%d" % (w, h, x, y)) vis_scaling = 1 txt_scaling = 1 @@ -720,8 +726,6 @@ def create_gui(self): elif screen_height >= 1080 and screen_width >= 1920: vis_scaling = 2 txt_scaling = 1.2 - - window.minsize(1512, 982) # Configure row and column weights for dynamic resizing window.columnconfigure(0, weight=1) # Left section (70% width) @@ -817,7 +821,7 @@ def create_gui(self): #tab.grid(row=0,column=0, sticky='nsew') tab.pack(fill='both', expand=True) #x and y style = ttk.Style() - style.configure("Treeview", font=("Arial", int(12*txt_scaling))) # needs to be scaled + style.configure("Treeview", font=("Arial", int(12*txt_scaling))) self.tab = tab # vehicle cart @@ -833,7 +837,7 @@ def create_gui(self): fig_fren = plt.figure(Dashboard.FRE_FIG_ID) fig_fren.set_size_inches(1*vis_scaling,1*vis_scaling,forward=True) # needs to be scaled self.fren_canvas = FigureCanvasTkAgg(fig_fren, fren_frame) - self.fren_canvas.get_tk_widget().pack(expand=True, fill="both", padx=5*vis_scaling, pady=5*vis_scaling) + self.fren_canvas.get_tk_widget().pack(expand=True, fill="both", padx=3*vis_scaling, pady=3*vis_scaling) # vehicle traj fig_traj = plt.figure(Dashboard.TRAJ_FIG_ID) @@ -846,8 +850,8 @@ def create_gui(self): tree_msg.grid(row=0,column=0, sticky='nsew') #General plot Layout + matplotlib.rcParams['lines.linewidth'] = 2*vis_scaling matplotlib.rc('font', size=int(8*txt_scaling)) # needs to be scaled - matplotlib.rc('lines', linewidth=2*vis_scaling) #needs to be scaled matplotlib.rc('axes', titlesize=8*vis_scaling) matplotlib.rc('axes', labelsize=8*vis_scaling) matplotlib.rc('xtick', labelsize=6*vis_scaling) From 95ae14a8715a7dc7b6fa92a03ac06519be38b480 Mon Sep 17 00:00:00 2001 From: Charlie Date: Wed, 19 Feb 2025 11:14:57 -0500 Subject: [PATCH 15/20] added ability to change dash size on launch --- dash/Dashboard.py | 52 +++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 1fdbf708..a378c0da 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -9,7 +9,7 @@ import matplotlib from matplotlib import pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from multiprocessing import Process, set_start_method +from multiprocessing import Process from TickSync import TickSync import tkinter as tk from tkinter import ttk @@ -26,7 +26,6 @@ from TrafficLight import * from sp.Pedestrian import * from mapping.LaneletMap import get_line_format -from threading import Thread class Dashboard(object): MAP_FIG_ID = 1 @@ -41,10 +40,8 @@ def __init__(self, sim_traffic:SimTraffic, sim_config:SimConfig): self.window = None self.center_pedestrian = False self.lanelet_map:LaneletMap = None - self.thread = None - self.maneuver = None - def start(self, traffic, pos): + def start(self, dash_pos): """ Start dashboard in subprocess. global constant SHOW_DASHBOARD must be true Traffic must have started, otherwise the shared array is not ready @@ -59,17 +56,23 @@ def start(self, traffic, pos): return self.lanelet_map = self.sim_traffic.lanelet_map - self.run_dash_process(self.sim_traffic.traffic_state_sharr, self.sim_traffic.debug_shdata, traffic, pos) + self._process = Process(target=self.run_dash_process, + args=(self.sim_traffic.traffic_state_sharr, self.sim_traffic.debug_shdata, dash_pos), + daemon=True) + self._process.start() - def run_dash_process(self, traffic_state_sharr, debug_shdata, traffic, pos): - self.window = self.create_gui(pos) - sync_dash = TickSync(DASH_RATE, realtime=False, block=True, verbose=False, label="DP") + def run_dash_process(self, traffic_state_sharr, debug_shdata, dash_pos): + + self.window = self.create_gui(dash_pos) + sync_dash = TickSync(DASH_RATE, realtime=True, block=True, verbose=False, label="DP") while sync_dash.tick(): - if not self.window or not traffic.traffic_running: + if not self.window: return - + + #clear self.clear_vehicle_charts() + #get new data header, vehicles, pedestrians, traffic_lights, static_objects = self.sim_traffic.read_traffic_state(traffic_state_sharr, False) tickcount, delta_time, sim_time = header[0:3] @@ -113,9 +116,9 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata, traffic, pos): self.plot_frenet_chart(vid, planner_state, ref_path, traj, cand, unf, traj_s_shift) if VEH_TRAJ_CHART: #vehicle traj plot self.plot_vehicle_sd(traj, cand) - #behavior tree update + #behavior tree self.tree_msg.delete("1.0", "end") - self.tree_msg.insert("1.0", btree_snapshot) + self.tree_msg.insert("1.0", btree_snapshot) else: #vehicles without planner: self.plot_cartesian_chart(vid, vehicles, pedestrians) @@ -131,10 +134,9 @@ def run_dash_process(self, traffic_state_sharr, debug_shdata, traffic, pos): if SHOW_MPLOT: self.map_canvas.draw() self.window.update() - + def quit(self): - self.window.destroy() - # self._process.terminate() + self._process.terminate() def change_tab_focus(self, event): focus = self.tab.focus() @@ -233,7 +235,6 @@ def plot_cartesian_chart(self, center_id, vehicles, pedestrians, reference_path y_min = vehicles[center_id].state.y - (CPLOT_SIZE/2) y_max = vehicles[center_id].state.y + (CPLOT_SIZE/2) - self.plot_road(x_min,x_max,y_min,y_max,traffic_lights) self.plot_static_objects(static_objects, x_min,x_max,y_min,y_max) if REFERENCE_PATH and reference_path is not None: @@ -640,7 +641,7 @@ def plot_vehicle_sd(trajectory, cand): s_vel_coef = differentiate(s_coef) Dashboard.plot_curve(s_vel_coef,T,'Long Vel (m/s)', '', 'T (s)') - # # S Acc(t) curve + #S Acc(t) curve i+=1 s_acc_coef = differentiate(s_vel_coef) plt.subplot(nrows,ncols,i) @@ -701,7 +702,7 @@ def plot_curve(coef, T, title, ylabel, xlabel, color="black"): t += 0.25 plt.plot(X,Y,color=color) - def create_gui(self, pos): + def create_gui(self, dash_pos): #Window window = tk.Tk() window.configure(bg="white") @@ -709,11 +710,11 @@ def create_gui(self, pos): screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() - x, y, w, h = pos - if set(pos) == {0}: + x, y, w, h = dash_pos + if set(dash_pos) == {0}: x, y, w, h = 0, 0, screen_width, screen_height else: - x, y, w, h = pos + x, y, w, h = dash_pos window.geometry("%dx%d+%d+%d" % (w, h, x, y)) @@ -736,7 +737,6 @@ def create_gui(self, pos): window.rowconfigure(2, weight=3) # Map/cartesian row window.rowconfigure(3, weight=3) # Fren frame window.rowconfigure(4, weight=3) # Tab frame - #window.rowconfigure(5, weight=4) # Scrollable content # # Frames title_frame = tk.Frame(window, bg="black") @@ -821,7 +821,7 @@ def create_gui(self, pos): #tab.grid(row=0,column=0, sticky='nsew') tab.pack(fill='both', expand=True) #x and y style = ttk.Style() - style.configure("Treeview", font=("Arial", int(12*txt_scaling))) + style.configure("Treeview", font=("Arial", int(12*txt_scaling))) # needs to be scaled self.tab = tab # vehicle cart @@ -837,7 +837,7 @@ def create_gui(self, pos): fig_fren = plt.figure(Dashboard.FRE_FIG_ID) fig_fren.set_size_inches(1*vis_scaling,1*vis_scaling,forward=True) # needs to be scaled self.fren_canvas = FigureCanvasTkAgg(fig_fren, fren_frame) - self.fren_canvas.get_tk_widget().pack(expand=True, fill="both", padx=3*vis_scaling, pady=3*vis_scaling) + self.fren_canvas.get_tk_widget().pack(expand=True, fill="both", padx=5*vis_scaling, pady=5*vis_scaling) # vehicle traj fig_traj = plt.figure(Dashboard.TRAJ_FIG_ID) @@ -850,8 +850,8 @@ def create_gui(self, pos): tree_msg.grid(row=0,column=0, sticky='nsew') #General plot Layout - matplotlib.rcParams['lines.linewidth'] = 2*vis_scaling matplotlib.rc('font', size=int(8*txt_scaling)) # needs to be scaled + matplotlib.rc('lines', linewidth=2*vis_scaling) #needs to be scaled matplotlib.rc('axes', titlesize=8*vis_scaling) matplotlib.rc('axes', labelsize=8*vis_scaling) matplotlib.rc('xtick', labelsize=6*vis_scaling) From cbfb30c4acdd1f3a8af554f948c6c0cf56c18f25 Mon Sep 17 00:00:00 2001 From: Charlie Date: Wed, 19 Feb 2025 14:37:54 -0500 Subject: [PATCH 16/20] made UI changes and font changes --- GSServer.py | 23 ++++++++++++++++------- dash/Dashboard.py | 4 ++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/GSServer.py b/GSServer.py index 9159d635..8734e876 100644 --- a/GSServer.py +++ b/GSServer.py @@ -37,8 +37,6 @@ def start_server(args, m=MVelKeepConfig()): btree_locations = [base_btree_location] log.info ("Btree search locations set (in order) as: " + str(btree_locations)) - traffic = SimTraffic(lanelet_map, sim_config) - if args.verify_map != "": verify_map_file(args.verify_map, lanelet_map) return @@ -46,6 +44,15 @@ def start_server(args, m=MVelKeepConfig()): if args.no_dash: sim_config.show_dashboard = False + if args.wait_for_input: + sim_config.wait_for_input = True + + if args.wait_for_client: + sim_config.wait_for_client = True + + # use sim_config after all modifications + traffic = SimTraffic(lanelet_map, sim_config) + # SCENARIO SETUP if args.gsfiles: if all(['.osm' in file for file in args.gsfiles]): @@ -67,6 +74,9 @@ def start_server(args, m=MVelKeepConfig()): sync_global = TickSync(rate=sim_config.traffic_rate, realtime=True, block=True, verbose=False, label="EX") sync_global.set_timeout(sim_config.timeout) + if sim_config.wait_for_input: + input("Press [ENTER] to start...") + #SIM EXECUTION START log.info('SIMULATION START') traffic.start() @@ -78,9 +88,6 @@ def start_server(args, m=MVelKeepConfig()): else: log.warn("Dashboard will not start") - if WAIT_FOR_INPUT: - input("waiting for [ENTER]...") - while sync_global.tick(): if sim_config.show_dashboard and not dashboard._process.is_alive(): # might/might not be wanted break @@ -120,10 +127,12 @@ def verify_map_file(map_file, lanelet_map:LaneletMap): parser.add_argument("-s", "--scenario", dest="gsfiles", nargs='*', metavar="FILE", default="", help="GeoScenario file. If no file is provided, the GSServer will load a scenario from code") parser.add_argument("--verify_map", dest="verify_map", metavar="FILE", default="", help="Lanelet map file") parser.add_argument("-q", "--quiet", dest="verbose", default=True, help="don't print messages to stdout") - parser.add_argument("-n", "--no_dash", dest="no_dash", action="store_true", help="run without the dashboard") + parser.add_argument("-n", "--no-dash", dest="no_dash", action="store_true", help="run without the dashboard") parser.add_argument("-m", "--map-path", dest="map_path", default="", help="Set the prefix to append to the value of the attribute `globalconfig->lanelet`") parser.add_argument("-b", "--btree-locations", dest="btree_locations", default="", help="Add higher priority locations to search for btrees by agent btypes") + parser.add_argument("-wi", "--wait-for-input", dest="wait_for_input", action="store_true", help="Wait for the user to press [ENTER] to start the simulation") + parser.add_argument("-wc", "--wait-for-client", dest="wait_for_client", action="store_true", help="Wait for a valid client state to start the simulation") parser.add_argument("--dash-pos", default=[0,0,0,0], dest="dash_pos", type=float, nargs=4, help="Set the position of the dashboard window (x y width height)") args = parser.parse_args() - start_server(args) + start_server(args) \ No newline at end of file diff --git a/dash/Dashboard.py b/dash/Dashboard.py index a378c0da..93f816fd 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -821,7 +821,7 @@ def create_gui(self, dash_pos): #tab.grid(row=0,column=0, sticky='nsew') tab.pack(fill='both', expand=True) #x and y style = ttk.Style() - style.configure("Treeview", font=("Arial", int(12*txt_scaling))) # needs to be scaled + style.configure("Treeview", font=("TkDefaultFont", int(12*txt_scaling))) # needs to be scaled self.tab = tab # vehicle cart @@ -845,7 +845,7 @@ def create_gui(self, dash_pos): self.traj_canvas = FigureCanvasTkAgg(fig_traj, traj_frame) self.traj_canvas.get_tk_widget().pack(expand=True, fill="both") - tree_msg = tk.Text(bt_frame, height=int(65*txt_scaling), width=int(60*txt_scaling), spacing2=1, bg="white", fg="black", wrap="word", font=("Arial", int(12*txt_scaling))) + tree_msg = tk.Text(bt_frame, height=int(65*txt_scaling), width=int(60*txt_scaling), spacing2=1, bg="white", fg="black", wrap="word", font=("TkDefaultFont", int(12*txt_scaling))) self.tree_msg = tree_msg tree_msg.grid(row=0,column=0, sticky='nsew') From 3478ec68dd65ffdb1a71ff656a88c21246dd0c33 Mon Sep 17 00:00:00 2001 From: Charlie Zheng <72936974+zhengc84@users.noreply.github.com> Date: Wed, 19 Feb 2025 14:44:18 -0500 Subject: [PATCH 17/20] changed default input of --dash-pos to [] --- GSServer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GSServer.py b/GSServer.py index 8734e876..2050b99e 100644 --- a/GSServer.py +++ b/GSServer.py @@ -132,7 +132,7 @@ def verify_map_file(map_file, lanelet_map:LaneletMap): parser.add_argument("-b", "--btree-locations", dest="btree_locations", default="", help="Add higher priority locations to search for btrees by agent btypes") parser.add_argument("-wi", "--wait-for-input", dest="wait_for_input", action="store_true", help="Wait for the user to press [ENTER] to start the simulation") parser.add_argument("-wc", "--wait-for-client", dest="wait_for_client", action="store_true", help="Wait for a valid client state to start the simulation") - parser.add_argument("--dash-pos", default=[0,0,0,0], dest="dash_pos", type=float, nargs=4, help="Set the position of the dashboard window (x y width height)") + parser.add_argument("--dash-pos", default=[], dest="dash_pos", type=float, nargs=4, help="Set the position of the dashboard window (x y width height)") args = parser.parse_args() - start_server(args) \ No newline at end of file + start_server(args) From 638a1351d806262f91a03352908a982d4fa8909b Mon Sep 17 00:00:00 2001 From: Charlie Zheng <72936974+zhengc84@users.noreply.github.com> Date: Wed, 19 Feb 2025 14:52:09 -0500 Subject: [PATCH 18/20] fixed setting --dash-pos --- dash/Dashboard.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 93f816fd..5a5d979c 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -710,11 +710,10 @@ def create_gui(self, dash_pos): screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() - x, y, w, h = dash_pos - if set(dash_pos) == {0}: - x, y, w, h = 0, 0, screen_width, screen_height - else: + if dash_pos: x, y, w, h = dash_pos + else: + x, y, w, h = 0, 0, screen_width, screen_height window.geometry("%dx%d+%d+%d" % (w, h, x, y)) @@ -859,4 +858,4 @@ def create_gui(self, dash_pos): matplotlib.rc('legend', fontsize=8*vis_scaling) matplotlib.rc('figure', titlesize=8*vis_scaling) - return window \ No newline at end of file + return window From 74d22624ec5790e09a32d80fa859be5d9f02450e Mon Sep 17 00:00:00 2001 From: Michal Antkiewicz Date: Wed, 19 Feb 2025 15:43:25 -0500 Subject: [PATCH 19/20] remove conda-forge tk and use the one from pip to support TrueType fonts --- scripts/conda-environment.yml | 2 +- scripts/setup-conda-forge-env.bash | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/conda-environment.yml b/scripts/conda-environment.yml index a2240258..d8aa65ed 100644 --- a/scripts/conda-environment.yml +++ b/scripts/conda-environment.yml @@ -9,10 +9,10 @@ dependencies: - matplotlib - numpy - scipy - - tk - pip: - antlr-denter - glog - lanelet2 - py_trees==0.7.6 - sysv-ipc + - tk diff --git a/scripts/setup-conda-forge-env.bash b/scripts/setup-conda-forge-env.bash index 7c331c02..857407a6 100644 --- a/scripts/setup-conda-forge-env.bash +++ b/scripts/setup-conda-forge-env.bash @@ -45,7 +45,8 @@ fi if ! $MAMBA_EXE env list | grep -q gss; then echo "Creating conda forge 'gss' environment..." $MAMBA_EXE env create --yes --quiet --file ${SCRIPT_DIR}/conda-environment.yml - if [[ $? == 0 ]]; then + if [[ $? == 0 ]]; then + $MAMBA_EXE -n gss remove --force --yes --quiet tk echo "The environment created successfully." else echo "Environment not created. Exiting..." From 2de607541ae1b98d3cededdaa2413b0fc452055f Mon Sep 17 00:00:00 2001 From: Michal Antkiewicz Date: Wed, 19 Feb 2025 16:01:39 -0500 Subject: [PATCH 20/20] tiny cleanup --- GSServer.py | 2 +- SimTraffic.py | 5 +++-- dash/Dashboard.py | 6 +++--- scripts/setup-conda-forge-env.bash | 2 ++ 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/GSServer.py b/GSServer.py index 2050b99e..634f6060 100644 --- a/GSServer.py +++ b/GSServer.py @@ -75,7 +75,7 @@ def start_server(args, m=MVelKeepConfig()): sync_global.set_timeout(sim_config.timeout) if sim_config.wait_for_input: - input("Press [ENTER] to start...") + input("Press [ENTER] to start...") #SIM EXECUTION START log.info('SIMULATION START') diff --git a/SimTraffic.py b/SimTraffic.py index 3a1e09d3..08486884 100644 --- a/SimTraffic.py +++ b/SimTraffic.py @@ -208,7 +208,7 @@ def create_traffic_state_shm(self): def write_traffic_state(self, tick_count, delta_time, sim_time): if not self.traffic_state_sharr: return - + nv = len(self.vehicles) np = len(self.pedestrians) @@ -386,4 +386,5 @@ def read_traffic_state(self, traffic_state_sharr, actives_only = True): # should be automatically thread-safe static_objects = copy(self.static_objects) - return header, vehicles, pedestrians, traffic_light_states, static_objects \ No newline at end of file + return header, vehicles, pedestrians, traffic_light_states, static_objects + \ No newline at end of file diff --git a/dash/Dashboard.py b/dash/Dashboard.py index 5a5d979c..c37130ef 100644 --- a/dash/Dashboard.py +++ b/dash/Dashboard.py @@ -784,7 +784,7 @@ def create_gui(self, dash_pos): # Widgets # title - lb = tk.Label(title_frame, text=str_title, bg = "black", fg="white",font=('OpenSans', int(30*txt_scaling))) # needs scaling + lb = tk.Label(title_frame, text=str_title, bg = "black", fg="white",font=('TkHeadingFont', int(30*txt_scaling))) # needs scaling lb.pack(side = 'left') lb_logos = tk.Label(title_frame, image=img_logos) @@ -792,7 +792,7 @@ def create_gui(self, dash_pos): lb_logos.pack(side='right') # stats container: - scenario_config_lb = tk.Label(stats_frame, bg='white', text='Loading \n scenario...', font=('OpenSans', int(10*txt_scaling)), anchor="w", justify=tk.LEFT) + scenario_config_lb = tk.Label(stats_frame, bg='white', text='Loading \n scenario...', font=('TkHeadingFont', int(10*txt_scaling)), anchor="w", justify=tk.LEFT) scenario_config_lb.pack(side = 'left') self.scenario_config_lb = scenario_config_lb @@ -847,7 +847,7 @@ def create_gui(self, dash_pos): tree_msg = tk.Text(bt_frame, height=int(65*txt_scaling), width=int(60*txt_scaling), spacing2=1, bg="white", fg="black", wrap="word", font=("TkDefaultFont", int(12*txt_scaling))) self.tree_msg = tree_msg tree_msg.grid(row=0,column=0, sticky='nsew') - + #General plot Layout matplotlib.rc('font', size=int(8*txt_scaling)) # needs to be scaled matplotlib.rc('lines', linewidth=2*vis_scaling) #needs to be scaled diff --git a/scripts/setup-conda-forge-env.bash b/scripts/setup-conda-forge-env.bash index 857407a6..04c8c49c 100644 --- a/scripts/setup-conda-forge-env.bash +++ b/scripts/setup-conda-forge-env.bash @@ -46,6 +46,8 @@ if ! $MAMBA_EXE env list | grep -q gss; then echo "Creating conda forge 'gss' environment..." $MAMBA_EXE env create --yes --quiet --file ${SCRIPT_DIR}/conda-environment.yml if [[ $? == 0 ]]; then + # conda-forge tk does not support TrueType fonts + # remove it so that we can use the one from pip $MAMBA_EXE -n gss remove --force --yes --quiet tk echo "The environment created successfully." else