sistemata visualizzazione target e scenario, aggiunta visualizzazione raw e semplificata
This commit is contained in:
parent
42f019e0a1
commit
ea7a2533c1
@ -208,7 +208,7 @@ class RisScenario(ctypes.Structure):
|
||||
("longitude", ctypes.c_float),
|
||||
("ant_nav_az", ctypes.c_float),
|
||||
("ant_nav_el", ctypes.c_float),
|
||||
("spare2", ctypes.c_uint32 * 7),
|
||||
("spare2", ctypes.c_uint32 * 8),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@ -66,6 +66,38 @@ class SfpDebugWindow(tk.Toplevel):
|
||||
self.ip_var = tk.StringVar(value="127.0.0.1")
|
||||
self.port_var = tk.StringVar(value="60002")
|
||||
|
||||
# Master mode names (from C++ enum ordering) — used to display readable mode
|
||||
# NOTE: keep in sync with the C++ enum if it changes
|
||||
self._master_mode_names = [
|
||||
"idle_master_mode",
|
||||
"int_bit_master_mode",
|
||||
"gm_master_mode",
|
||||
"dbs_master_mode",
|
||||
"rws_master_mode",
|
||||
"vs_master_mode",
|
||||
"acm_master_mode",
|
||||
"tws_master_mode",
|
||||
"sea_low_master_mode",
|
||||
"sea_high_master_mode",
|
||||
"gmti_master_mode",
|
||||
"bcn_master_mode",
|
||||
"sam_master_mode",
|
||||
"ta_master_mode",
|
||||
"wa_master_mode",
|
||||
"stt_master_mode",
|
||||
"dtt_master_mode",
|
||||
"sstt_master_mode",
|
||||
"acq_master_mode",
|
||||
"ftt_master_mode",
|
||||
"agr_master_mode",
|
||||
"sar_master_mode",
|
||||
"invalid_master_mode_",
|
||||
"xtst_dummy_mode",
|
||||
"xtst_hw_validation_mode",
|
||||
"boot_master_mode",
|
||||
"master_mode_id_cardinality_",
|
||||
]
|
||||
|
||||
# --- Connection Frame (IP / Port / Connect controls) ---
|
||||
conn_frame = ttk.Frame(self)
|
||||
conn_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=(5, 2))
|
||||
@ -611,6 +643,27 @@ class SfpDebugWindow(tk.Toplevel):
|
||||
import json
|
||||
|
||||
struct = json.loads(payload.decode("utf-8")) if isinstance(payload, (bytes, bytearray)) else payload
|
||||
# Debug: log keys and a short sample of the payload to help
|
||||
# diagnose any label/value mismatches coming from the server.
|
||||
try:
|
||||
if isinstance(struct, dict):
|
||||
scenario_preview = struct.get("scenario")
|
||||
#self.logger.debug("RIS payload keys: %s", list(struct.keys()))
|
||||
#if isinstance(scenario_preview, dict):
|
||||
#self.logger.debug("RIS scenario keys: %s", list(scenario_preview.keys()))
|
||||
targets_preview = struct.get("targets")
|
||||
if isinstance(targets_preview, list):
|
||||
sample_keys = [list(t.keys()) for t in targets_preview[:3] if isinstance(t, dict)]
|
||||
#self.logger.debug("RIS targets sample keys (first 3): %s", sample_keys)
|
||||
# Also put a concise message in the Raw Log widget for convenience
|
||||
try:
|
||||
msg = f"RIS JSON: scenario_keys={len(scenario_preview) if isinstance(scenario_preview, dict) else 0}, targets={len(targets_preview) if isinstance(targets_preview, list) else 0}"
|
||||
#self._log_to_widget(msg, "DEBUG")
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
# Never raise from debug logging
|
||||
pass
|
||||
# scenario table (field, value)
|
||||
for iid in self.scenario_tree.get_children():
|
||||
self.scenario_tree.delete(iid)
|
||||
@ -671,6 +724,15 @@ class SfpDebugWindow(tk.Toplevel):
|
||||
except Exception:
|
||||
return str(v)
|
||||
|
||||
def try_float(v):
|
||||
"""Attempt to convert value to float; return None on failure."""
|
||||
try:
|
||||
return float(v)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
# collect rows first so we can log the exact label->value mapping
|
||||
scenario_rows = []
|
||||
for label, key, unit in order:
|
||||
if key in scenario:
|
||||
val = scenario.get(key)
|
||||
@ -691,33 +753,38 @@ class SfpDebugWindow(tk.Toplevel):
|
||||
else:
|
||||
# simplified view: show converted value and unit adjacent to number
|
||||
if key in ("platform_azimuth", "true_heading"):
|
||||
if isinstance(val, (int, float)):
|
||||
conv = to_deg(val)
|
||||
fv = try_float(val)
|
||||
if fv is not None:
|
||||
conv = to_deg(fv)
|
||||
display_val = fmt_simplified_number(conv, "°", dec_simp)
|
||||
else:
|
||||
display_val = str(val)
|
||||
elif key in ("ant_nav_az", "ant_nav_el"):
|
||||
if isinstance(val, (int, float)):
|
||||
conv = to_deg(val)
|
||||
fv = try_float(val)
|
||||
if fv is not None:
|
||||
conv = to_deg(fv)
|
||||
display_val = fmt_simplified_number(conv, "°", dec_simp)
|
||||
else:
|
||||
display_val = str(val)
|
||||
elif key in ("vx", "vy", "vz"):
|
||||
if isinstance(val, (int, float)):
|
||||
conv = m_s_to_ft_s(val)
|
||||
fv = try_float(val)
|
||||
if fv is not None:
|
||||
conv = m_s_to_ft_s(fv)
|
||||
display_val = fmt_simplified_number(conv, "ft/s", dec_simp)
|
||||
else:
|
||||
display_val = str(val)
|
||||
elif key == "baro_altitude":
|
||||
if isinstance(val, (int, float)):
|
||||
conv = m_to_ft(val)
|
||||
fv = try_float(val)
|
||||
if fv is not None:
|
||||
conv = m_to_ft(fv)
|
||||
display_val = fmt_simplified_number(conv, "ft", dec_simp)
|
||||
else:
|
||||
display_val = str(val)
|
||||
elif key in ("latitude", "longitude"):
|
||||
if isinstance(val, (int, float)):
|
||||
fv = try_float(val)
|
||||
if fv is not None:
|
||||
# show decimal degrees with higher precision per request
|
||||
display_val = f"{float(val):.{8}f} °"
|
||||
display_val = f"{fv:.{8}f} °"
|
||||
else:
|
||||
display_val = str(val)
|
||||
elif key == "flags":
|
||||
@ -726,12 +793,41 @@ class SfpDebugWindow(tk.Toplevel):
|
||||
except Exception:
|
||||
display_val = str(val)
|
||||
elif key == "mode":
|
||||
display_val = str(int(val)) if isinstance(val, (int, float)) else str(val)
|
||||
# Map numeric mode to human-friendly short name
|
||||
try:
|
||||
midx = int(val)
|
||||
if 0 <= midx < len(self._master_mode_names):
|
||||
name = self._master_mode_names[midx]
|
||||
# strip trailing parts like '_master_mode' or '_mode' or trailing underscores
|
||||
short = name
|
||||
for suffix in ("_master_mode", "_mode", "_master_mode_", "_"):
|
||||
if short.endswith(suffix):
|
||||
short = short[: -len(suffix)]
|
||||
# also remove any remaining 'master' parts
|
||||
short = short.replace("master", "").strip("_")
|
||||
display_val = short
|
||||
else:
|
||||
display_val = str(midx)
|
||||
except Exception:
|
||||
display_val = str(val)
|
||||
else:
|
||||
display_val = str(val)
|
||||
|
||||
# Show label without unit; unit is appended to the value in simplified view
|
||||
self.scenario_tree.insert("", tk.END, values=(f"{label}", display_val))
|
||||
# collect the pair for logging and insertion
|
||||
scenario_rows.append((label, display_val))
|
||||
|
||||
# Log the label->value pairs for diagnosis (concise)
|
||||
try:
|
||||
preview = ", ".join(f"{l}={v}" for l, v in scenario_rows)
|
||||
#self.logger.debug("Scenario label->value: %s", preview)
|
||||
# also write a shorter message to Raw Log for visibility
|
||||
#self._log_to_widget(f"Scenario preview: {preview}", "DEBUG")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Now insert collected rows into the Treeview
|
||||
for l, v in scenario_rows:
|
||||
self.scenario_tree.insert("", tk.END, values=(f"{l}", v))
|
||||
|
||||
# targets
|
||||
for iid in self.ris_tree.get_children():
|
||||
@ -751,28 +847,37 @@ class SfpDebugWindow(tk.Toplevel):
|
||||
view_mode = self.scenario_view_mode.get() if hasattr(self, "scenario_view_mode") else "simplified"
|
||||
dec_simp = int(self.simplified_decimals.get() if hasattr(self, "simplified_decimals") else 4)
|
||||
for t in targets:
|
||||
try:
|
||||
# normalize index (accept common aliases)
|
||||
idx = t.get("index")
|
||||
if idx is None:
|
||||
idx = t.get("idx")
|
||||
if idx is None:
|
||||
idx = t.get("#")
|
||||
|
||||
# normalize flags and format consistently
|
||||
raw_flags = t.get("flags", t.get("flag", 0))
|
||||
try:
|
||||
flags_val = int(raw_flags)
|
||||
flags_display = f"{flags_val} (0x{flags_val:X})"
|
||||
except Exception:
|
||||
flags_display = str(raw_flags)
|
||||
|
||||
if view_mode == "raw":
|
||||
# format raw with reasonable precision
|
||||
try:
|
||||
heading_raw = float(t.get("heading"))
|
||||
heading_val = f"{heading_raw:.6f}"
|
||||
except Exception:
|
||||
heading_val = str(t.get("heading"))
|
||||
try:
|
||||
x_raw = float(t.get("x"))
|
||||
y_raw = float(t.get("y"))
|
||||
z_raw = float(t.get("z"))
|
||||
x_val = f"{x_raw:.6f}"
|
||||
y_val = f"{y_raw:.6f}"
|
||||
z_val = f"{z_raw:.6f}"
|
||||
except Exception:
|
||||
x_val = t.get("x")
|
||||
y_val = t.get("y")
|
||||
z_val = t.get("z")
|
||||
# format raw with reasonable precision using try_float
|
||||
hfv = try_float(t.get("heading"))
|
||||
heading_val = f"{hfv:.6f}" if hfv is not None else str(t.get("heading"))
|
||||
|
||||
xfv = try_float(t.get("x"))
|
||||
yfv = try_float(t.get("y"))
|
||||
zfv = try_float(t.get("z"))
|
||||
x_val = f"{xfv:.6f}" if xfv is not None else t.get("x")
|
||||
y_val = f"{yfv:.6f}" if yfv is not None else t.get("y")
|
||||
z_val = f"{zfv:.6f}" if zfv is not None else t.get("z")
|
||||
|
||||
vals = (
|
||||
t.get("index"),
|
||||
t.get("flags"),
|
||||
idx,
|
||||
flags_display,
|
||||
heading_val,
|
||||
x_val,
|
||||
y_val,
|
||||
@ -780,34 +885,44 @@ class SfpDebugWindow(tk.Toplevel):
|
||||
)
|
||||
else:
|
||||
# simplified: converted values with units next to number
|
||||
try:
|
||||
heading = float(t.get("heading"))
|
||||
heading_deg = heading * (180.0 / 3.141592653589793)
|
||||
hfv = try_float(t.get("heading"))
|
||||
if hfv is not None:
|
||||
heading_deg = hfv * (180.0 / 3.141592653589793)
|
||||
heading_val = f"{heading_deg:.{dec_simp}f} °"
|
||||
except Exception:
|
||||
else:
|
||||
heading_val = str(t.get("heading"))
|
||||
try:
|
||||
x = float(t.get("x"))
|
||||
y = float(t.get("y"))
|
||||
z_m = float(t.get("z"))
|
||||
x_val = f"{x:.{dec_simp}f} m"
|
||||
y_val = f"{y:.{dec_simp}f} m"
|
||||
z_val = f"{(z_m * 3.280839895):.{dec_simp}f} ft"
|
||||
except Exception:
|
||||
x_val = str(t.get("x"))
|
||||
y_val = str(t.get("y"))
|
||||
|
||||
xfv = try_float(t.get("x"))
|
||||
yfv = try_float(t.get("y"))
|
||||
zfv = try_float(t.get("z"))
|
||||
x_val = f"{xfv:.{dec_simp}f} m" if xfv is not None else str(t.get("x"))
|
||||
y_val = f"{yfv:.{dec_simp}f} m" if yfv is not None else str(t.get("y"))
|
||||
if zfv is not None:
|
||||
z_val = f"{(zfv * 3.280839895):.{dec_simp}f} ft"
|
||||
else:
|
||||
z_val = str(t.get("z"))
|
||||
|
||||
vals = (
|
||||
t.get("index"),
|
||||
t.get("flags"),
|
||||
idx,
|
||||
flags_display,
|
||||
heading_val,
|
||||
x_val,
|
||||
y_val,
|
||||
z_val,
|
||||
)
|
||||
|
||||
# ensure we always insert a 6-tuple (Treeview expects 6 columns)
|
||||
if not isinstance(vals, (list, tuple)) or len(vals) != 6:
|
||||
# fallback: make a safe 6-element tuple
|
||||
vals = (idx, flags_display, "", "", "", "")
|
||||
|
||||
self.ris_tree.insert("", tk.END, values=vals)
|
||||
except Exception as _e:
|
||||
# on malformed target entries, insert a visible placeholder
|
||||
try:
|
||||
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
|
||||
except Exception:
|
||||
# ignore malformed JSON for now
|
||||
pass
|
||||
|
||||
17
todo.md
Normal file
17
todo.md
Normal file
@ -0,0 +1,17 @@
|
||||
code da fare
|
||||
|
||||
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
|
||||
sull'edito, se seleziono una manovra, vederla colorata di un altro colore sulla preview per capire cosa sto toccando.
|
||||
aggiungere visualizzazione nell'editor su ris_status in questo modo:
|
||||
1) dati raw, dati come vengono spediti, senza conversioni
|
||||
2) dati convertiti secondo intefaccia gui del mission computer
|
||||
3) dati dei target in range/elevation
|
||||
|
||||
la visualizzazione ppi in simulazione se tiene conto della rotazione del ptazimuth dovrebbe ruotare in modo che il cono di scansione dell'antenna si muove
|
||||
di conseguenza. Immagino che la mappa ppi sia sempre diretta a nord, quindi quando io con l'aereo vado a nord tutto torna
|
||||
se invece cambio direzione dell'aereo la mappa ruota e quindi ruotano anche le label attorno in modo che siano sempre riferite al muso dell'aereo.
|
||||
Quindi dovremmo inserire una nuova legenda oltre a quella attuale che indichi che il nord è sempra. per ricordare all'utente che la ppi è verso l'alto.
|
||||
Loading…
Reference in New Issue
Block a user