From 323e3dfdac7e2941f3ee801d3efdcdb6aab4ba47 Mon Sep 17 00:00:00 2001 From: VALLONGOL Date: Wed, 22 Oct 2025 10:22:00 +0200 Subject: [PATCH] target rosso per real, target verde per simulato --- settings.json | 2 ++ target_simulator/gui/ppi_display.py | 28 ++++++++++++++++++++---- target_simulator/gui/sfp_debug_window.py | 16 ++++++++++++-- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/settings.json b/settings.json index cf70896..c4808e7 100644 --- a/settings.json +++ b/settings.json @@ -38,6 +38,8 @@ } } } + , + "ppi_trail_length": 100 }, "debug": { "enable_io_trace": true, diff --git a/target_simulator/gui/ppi_display.py b/target_simulator/gui/ppi_display.py index 51bd664..5310a70 100644 --- a/target_simulator/gui/ppi_display.py +++ b/target_simulator/gui/ppi_display.py @@ -26,7 +26,7 @@ class PPIDisplay(ttk.Frame): """ TRAIL_LENGTH = 100 # Number of historical points to show in a target's trail - def __init__(self, master, max_range_nm: int = 100, scan_limit_deg: int = 60): + def __init__(self, master, max_range_nm: int = 100, scan_limit_deg: int = 60, trail_length: int = None): super().__init__(master) self.max_range = max_range_nm self.scan_limit_deg = scan_limit_deg @@ -38,10 +38,14 @@ class PPIDisplay(ttk.Frame): self.real_trail_artists = [] self.target_label_artists = [] - # Data store for target trails + # Data store for target trails. Use a bounded deque per-target whose + # max length is configurable (via constructor). The widget no longer + # supports an unbounded "full trail" mode — use a sufficiently large + # trail_length if you need a longer history. + self.trail_length = trail_length or self.TRAIL_LENGTH self._trails = { - "simulated": collections.defaultdict(lambda: collections.deque(maxlen=self.TRAIL_LENGTH)), - "real": collections.defaultdict(lambda: collections.deque(maxlen=self.TRAIL_LENGTH)) + "simulated": collections.defaultdict(lambda: collections.deque(maxlen=self.trail_length)), + "real": collections.defaultdict(lambda: collections.deque(maxlen=self.trail_length)), } # Artists for trajectory preview @@ -156,6 +160,22 @@ class PPIDisplay(ttk.Frame): self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True) self._update_scan_lines() + def _init_trails(self): + """(Removed) kept for historical reasons but no longer used.""" + # This method is intentionally left as a no-op. Trails are initialized + # during construction and are always bounded by `trail_length`. + return + + def _on_full_trail_toggled(self): + """Toggle between bounded trail and full trail while preserving data. + + When switching modes we transfer existing points into the new structure + to avoid losing history unexpectedly. + """ + # Full-trail toggling has been removed. Keep the method present so + # callers won't fail if they still reference it, but do nothing. + return + def update_targets(self, targets_data: Union[List[Target], Dict[str, List[Target]]]): """ Updates the display with the current state of targets. diff --git a/target_simulator/gui/sfp_debug_window.py b/target_simulator/gui/sfp_debug_window.py index 8880034..7d3a590 100644 --- a/target_simulator/gui/sfp_debug_window.py +++ b/target_simulator/gui/sfp_debug_window.py @@ -415,7 +415,15 @@ class SfpDebugWindow(tk.Toplevel): paned.add(right, weight=2) # Create PPI widget inside ris_ppi_container but keep it hidden try: - self.ris_ppi_widget = PPIDisplay(self.ris_ppi_container, max_range_nm=100) + # Determine trail length from the configuration manager if available + gm = getattr(self.master, "config_manager", None) + trail_len = None + try: + general = gm.get_general_settings() if gm else {} + trail_len = general.get("ppi_trail_length") if isinstance(general, dict) else None + except Exception: + trail_len = None + self.ris_ppi_widget = PPIDisplay(self.ris_ppi_container, max_range_nm=100, trail_length=trail_len) self.ris_ppi_widget.pack(fill=tk.BOTH, expand=True) except Exception: self.ris_ppi_widget = None @@ -1331,7 +1339,11 @@ class SfpDebugWindow(tk.Toplevel): f"PPI target sample: id={getattr(pt, 'target_id', None)} r_nm={getattr(pt,'current_range_nm',None):.2f} az={getattr(pt,'current_azimuth_deg',None):.2f} hdg={getattr(pt,'current_heading_deg',None):.2f}", "DEBUG", ) - self.update_ppi_targets(ppi_targets) + # Mark these as server-sent 'real' targets so + # PPIDisplay will draw them using the 'real' + # styling (red). Use the dict form expected + # by PPIDisplay to distinguish origins. + self.update_ppi_targets({"real": ppi_targets}) except Exception: self.logger.exception( "Failed to push targets to PPI"