aggiunta la visualizzazione ppi in debug

This commit is contained in:
VALLONGOL 2025-10-21 09:38:43 +02:00
parent c69de401e1
commit db645b13ce
5 changed files with 157 additions and 16 deletions

View File

@ -2,7 +2,7 @@
"general": {
"scan_limit": 60,
"max_range": 100,
"geometry": "1200x1024+85+163",
"geometry": "1200x1024+501+367",
"last_selected_scenario": "scenario2",
"connection": {
"target": {
@ -76,8 +76,10 @@
"maneuver_type": "Fly to Point",
"duration_s": 10.0,
"target_range_nm": 10.0,
"target_azimuth_deg": 1.0,
"target_azimuth_deg": -3.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 0.0,
"target_heading_deg": 0.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,

View File

@ -75,6 +75,14 @@ def build_tgtset_selective(target_id: int, updates: Dict[str, Any]) -> str:
]
params = [str(updates.get(key, "*")) for key in param_order]
command_parts = ["tgtset", str(target_id)] + params
qualifiers = []
if "active" in updates:
qualifiers.append("/s" if updates["active"] else "/-s")
if "traceable" in updates:
qualifiers.append("/t" if updates["traceable"] else "/-t")
command_parts.extend(qualifiers)
full_command = " ".join(command_parts)
logger.debug(f"Built selective command: {full_command!r}")
return full_command

View File

@ -24,9 +24,10 @@ class PPIDisplay(ttk.Frame):
super().__init__(master)
self.max_range = max_range_nm
self.scan_limit_deg = scan_limit_deg
# Artists for dynamic target display
# Artists for dynamic target display (dots, lines)
self.target_artists = []
# Artists for numeric labels next to targets
self.target_label_artists = []
self.active_targets: List[Target] = []
# Artists for trajectory preview display
@ -147,22 +148,51 @@ class PPIDisplay(ttk.Frame):
def update_targets(self, targets: List[Target]):
"""Updates the display with the current state of active targets."""
# Keep only active targets
self.active_targets = [t for t in targets if t.active]
# Clear previous target artists
for artist in self.target_artists:
artist.remove()
self.target_artists.clear()
# Clear previous numeric label artists (avoid label accumulation)
for l in getattr(self, "target_label_artists", []):
try:
l.remove()
except Exception:
pass
self.target_label_artists.clear()
vector_len_nm = self.range_var.get() / 20.0 # Length of heading vector
vector_len_nm = max(1.0, self.range_var.get() / 20.0) # Length of heading vector
# Ensure plot radial limit matches selected range
try:
current_range = self.range_var.get()
self.ax.set_ylim(0, current_range)
self._update_scan_lines()
except Exception:
pass
# Diagnostic logging (kept lightweight)
try:
import logging
logger = logging.getLogger(__name__)
logger.debug("PPIDisplay.update_targets: received %d active target(s)", len(self.active_targets))
for t in self.active_targets:
try:
logger.debug("PPIDisplay target id=%s r_nm=%.2f az=%.2f hdg=%.2f", getattr(t, 'target_id', None), getattr(t, 'current_range_nm', 0.0), getattr(t, 'current_azimuth_deg', 0.0), getattr(t, 'current_heading_deg', 0.0))
except Exception:
pass
except Exception:
pass
for target in self.active_targets:
# Target's polar coordinates
r_nm = target.current_range_nm
theta_rad = np.deg2rad(target.current_azimuth_deg)
# Draw the target dot
(dot,) = self.ax.plot(theta_rad, r_nm, "o", markersize=6, color="red")
# Draw the target dot (slightly larger for visibility)
(dot,) = self.ax.plot(theta_rad, r_nm, "o", markersize=8, color="red")
self.target_artists.append(dot)
# Draw the heading vector
@ -182,7 +212,25 @@ class PPIDisplay(ttk.Frame):
)
self.target_artists.append(line)
# Add numeric label near the dot showing target id (if available)
try:
tid = getattr(target, "target_id", None)
if tid is not None:
# place label slightly outward from the dot
label_r = r_nm + (vector_len_nm * 0.7)
txt = self.ax.text(theta_rad, label_r, f"{tid}", color="white", fontsize=8, ha="center", va="center")
self.target_label_artists.append(txt)
except Exception:
pass
# Force immediate redraw to make sure UI shows the changes
try:
self.canvas.draw()
except Exception:
try:
self.canvas.draw_idle()
except Exception:
pass
def draw_trajectory_preview(self, waypoints: List[Waypoint], use_spline: bool):
"""

View File

@ -180,8 +180,8 @@ class SfpDebugWindow(tk.Toplevel):
self.logger.exception("Toggle PPI failed")
def update_ppi_targets(self, targets):
if self._ppi_visible:
try:
if self.ris_ppi_widget:
self.ris_ppi_widget.update_targets(targets)
except Exception:
self.logger.exception("Failed to update RIS PPI targets")
@ -203,6 +203,7 @@ class SfpDebugWindow(tk.Toplevel):
t.current_azimuth_deg = math.degrees(math.atan2(ris_tgt.x, ris_tgt.y))
t.current_altitude_ft = ris_tgt.z
t.current_heading_deg = getattr(ris_tgt, 'heading', 0.0)
t.active = True
targets.append(t)
self.update_ppi_targets(targets)
@ -1000,6 +1001,89 @@ class SfpDebugWindow(tk.Toplevel):
self.ris_tree.insert("", tk.END, values=(None, None, str(t.get("heading")), str(t.get("x")), str(t.get("y")), str(t.get("z"))))
except Exception:
pass
# --- Update PPI with active targets that fit the current PPI scale/sector ---
try:
# Only proceed if we have a PPI widget available
ppi = getattr(self, "ris_ppi_widget", None)
if ppi is not None:
ppi_targets = []
METERS_PER_NM = 1852.0
# Determine current display range from the PPI widget
current_range = ppi.range_var.get() if hasattr(ppi, "range_var") else ppi.max_range
# Debug: show parsed target count and sample raw values
try:
self._log_to_widget(f"PPI: parsed {len(targets)} JSON target(s); current_range={current_range}", "DEBUG")
for i, tt in enumerate(targets[:6]):
try:
fx = tt.get('flags', None)
tx = tt.get('x', None)
ty = tt.get('y', None)
tz = tt.get('z', None)
# compute derived quantities
try:
xm = float(tx)
ym = float(ty)
zm = float(tz)
rng_m = (xm * xm + ym * ym) ** 0.5
rng_nm = rng_m / 1852.0
az_deg = math.degrees(math.atan2(xm, ym))
# elevation from z and slant range
elev_rad = math.atan2(zm, rng_m) if rng_m > 0 else 0.0
elev_deg = math.degrees(elev_rad)
except Exception:
rng_m = rng_nm = az_deg = elev_deg = None
msg = f"PPI RAW[{i}]: flags={fx} x={tx} y={ty} z={tz} | range_m={rng_m:.1f} range_nm={rng_nm:.2f} az={az_deg:.2f}° elev={elev_deg:.2f}°" if rng_m is not None else f"PPI RAW[{i}]: flags={fx} x={tx} y={ty} z={tz}"
self._log_to_widget(msg, "DEBUG")
except Exception:
pass
except Exception:
pass
for t in targets:
raw_flags = t.get("flags", 0)
# Only show enabled/active targets (non-zero flags)
if int(raw_flags) == 0:
continue
x = float(t.get("x", 0.0))
y = float(t.get("y", 0.0))
z = float(t.get("z", 0.0))
# Compute range in NM assuming x/y are meters
range_nm = ((x ** 2 + y ** 2) ** 0.5) / METERS_PER_NM
if range_nm > current_range:
continue
# Compute azimuth in degrees using same convention as PPIDisplay
az_deg = math.degrees(math.atan2(x, y))
# Heading in JSON is in radians -> convert to degrees
heading = t.get("heading", 0.0)
try:
hdg_deg = float(heading) * (180.0 / math.pi)
except Exception:
hdg_deg = 0.0
tgt = Target(target_id=int(t.get("index", 0)), trajectory=[], active=True, traceable=True)
tgt.current_range_nm = range_nm
tgt.current_azimuth_deg = az_deg
tgt.current_heading_deg = hdg_deg
# convert altitude from meters to feet
try:
tgt.current_altitude_ft = float(z) * 3.280839895
except Exception:
tgt.current_altitude_ft = 0.0
tgt.active = True
ppi_targets.append(tgt)
# Push to PPI (log debug info)
try:
self._log_to_widget(f"PPI: prepared {len(ppi_targets)} target(s) for display", "DEBUG")
if ppi_targets:
for pt in ppi_targets[:5]:
self._log_to_widget(
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)
except Exception:
self.logger.exception("Failed to push targets to PPI")
except Exception:
self.logger.exception("Error while preparing RIS targets for PPI")
except Exception:
pass
self.after(self.GUI_POLL_INTERVAL_MS, self._process_latest_payloads)

View File

@ -3,13 +3,12 @@
## bachi
quando faccio la traiettoria ad alti 9 sbaglia a disegnare la curva, rivedere il caso specifico ed anche con o senza spline
La traiettoria a 9 g viene reindirizzataa scatti invece che con una curva
## sviluppi
fare in modo di aggiornare la label della simulazione per evitare la scia.
girare le label sulla ppi a sinistra sono gli azimuth positivi, a destra i negativi
leggere le informazioni dell'antenna del messaggio di stato
leggere la flag per capire se il target è attivo
scomporre il campo flag in bit per avere le informazioni dello stato del target (attivo, tracable)
fare simulazione con moviumento dell'aereo letto da protocollo
visualizzare informaizoni dinamiche dell'areo durante la simulazione