aggiunta la visualizzazione ppi in debug
This commit is contained in:
parent
c69de401e1
commit
db645b13ce
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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):
|
||||
"""
|
||||
|
||||
@ -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)
|
||||
|
||||
7
todo.md
7
todo.md
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user