aggiunta la scelta tra raw e simplied, ed il numero di decimali
This commit is contained in:
parent
36e6e8d335
commit
42f019e0a1
@ -161,6 +161,26 @@ class SfpDebugWindow(tk.Toplevel):
|
||||
# Save CSV button under the paned window
|
||||
btn_frame = ttk.Frame(ris_frame)
|
||||
btn_frame.pack(fill=tk.X, padx=5, pady=(0, 5))
|
||||
# View mode for scenario/targets: raw vs simplified
|
||||
self.scenario_view_mode = tk.StringVar(value="simplified")
|
||||
mode_frame = ttk.Frame(btn_frame)
|
||||
mode_frame.pack(side=tk.LEFT, padx=(4, 0))
|
||||
ttk.Label(mode_frame, text="View:").pack(side=tk.LEFT, padx=(0, 6))
|
||||
ttk.Radiobutton(mode_frame, text="Raw", value="raw", variable=self.scenario_view_mode).pack(side=tk.LEFT)
|
||||
ttk.Radiobutton(mode_frame, text="Simplified", value="simplified", variable=self.scenario_view_mode).pack(side=tk.LEFT)
|
||||
|
||||
# Decimals control for simplified view (user-settable)
|
||||
self.simplified_decimals = tk.IntVar(value=4)
|
||||
ttk.Label(mode_frame, text=" Decimals:").pack(side=tk.LEFT, padx=(8, 2))
|
||||
try:
|
||||
# Use tk.Spinbox; ttk.Spinbox may not be available in all tkinter versions
|
||||
sp = tk.Spinbox(mode_frame, from_=0, to=8, width=3, textvariable=self.simplified_decimals)
|
||||
sp.pack(side=tk.LEFT)
|
||||
except Exception:
|
||||
# fallback to an Entry if Spinbox is not supported
|
||||
e = ttk.Entry(mode_frame, textvariable=self.simplified_decimals, width=3)
|
||||
e.pack(side=tk.LEFT)
|
||||
|
||||
self.ris_save_csv_btn = ttk.Button(btn_frame, text="Save CSV", command=lambda: self._on_save_ris_csv())
|
||||
self.ris_save_csv_btn.pack(side=tk.RIGHT)
|
||||
|
||||
@ -596,11 +616,6 @@ class SfpDebugWindow(tk.Toplevel):
|
||||
self.scenario_tree.delete(iid)
|
||||
scenario = struct.get("scenario", {}) if isinstance(struct, dict) else {}
|
||||
if scenario:
|
||||
# Insert in deterministic order and convert to human-friendly units
|
||||
# Conversions inferred from C++ implementation:
|
||||
# - angles are sent in radians -> display degrees
|
||||
# - velocities are m/s -> display ft/s
|
||||
# - altitudes are meters -> display feet
|
||||
import math
|
||||
|
||||
def to_deg(v):
|
||||
@ -636,101 +651,162 @@ class SfpDebugWindow(tk.Toplevel):
|
||||
("longitude", "longitude", "°"),
|
||||
("true_heading", "true_heading", "°"),
|
||||
]
|
||||
|
||||
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)
|
||||
|
||||
def fmt_raw_number(v, key_name=None):
|
||||
try:
|
||||
fv = float(v)
|
||||
if key_name in ("latitude", "longitude"):
|
||||
return f"{fv:.8f}"
|
||||
return f"{fv:.6f}"
|
||||
except Exception:
|
||||
return str(v)
|
||||
|
||||
def fmt_simplified_number(v, unit_str, decimals=4):
|
||||
try:
|
||||
fv = float(v)
|
||||
return f"{fv:.{decimals}f} {unit_str}" if unit_str else f"{fv:.{decimals}f}"
|
||||
except Exception:
|
||||
return str(v)
|
||||
|
||||
for label, key, unit in order:
|
||||
if key in scenario:
|
||||
val = scenario.get(key)
|
||||
# apply conversions and show raw in parentheses
|
||||
if key == "platform_azimuth" or key == "true_heading":
|
||||
if isinstance(val, (int, float)):
|
||||
conv = to_deg(val)
|
||||
display_val = f"{conv:.6f} ° ({val:.6f} rad)"
|
||||
else:
|
||||
display_val = val
|
||||
elif key in ("ant_nav_az", "ant_nav_el"):
|
||||
# antenna angles, display degrees with raw radians
|
||||
if isinstance(val, (int, float)):
|
||||
conv = to_deg(val)
|
||||
display_val = f"{conv:.6f} ° ({val:.6f} rad)"
|
||||
else:
|
||||
display_val = val
|
||||
if view_mode == "raw":
|
||||
if key in ("platform_azimuth", "true_heading", "ant_nav_az", "ant_nav_el"):
|
||||
display_val = fmt_raw_number(val, key)
|
||||
elif key in ("vx", "vy", "vz", "baro_altitude"):
|
||||
display_val = fmt_raw_number(val, key)
|
||||
elif key in ("latitude", "longitude"):
|
||||
display_val = fmt_raw_number(val, key)
|
||||
elif key == "flags":
|
||||
try:
|
||||
display_val = f"{int(val)} (0x{int(val):X})"
|
||||
except Exception:
|
||||
display_val = str(val)
|
||||
else:
|
||||
display_val = str(val)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
display_val = fmt_simplified_number(conv, "ft", dec_simp)
|
||||
else:
|
||||
display_val = str(val)
|
||||
elif key in ("latitude", "longitude"):
|
||||
if isinstance(val, (int, float)):
|
||||
# show decimal degrees with higher precision per request
|
||||
display_val = f"{float(val):.{8}f} °"
|
||||
else:
|
||||
display_val = str(val)
|
||||
elif key == "flags":
|
||||
# show flags as int and hex
|
||||
try:
|
||||
display_val = f"{int(val)} (0x{int(val):X})"
|
||||
except Exception:
|
||||
display_val = str(val)
|
||||
elif key == "mode":
|
||||
# mode is an integer code
|
||||
try:
|
||||
display_val = str(int(val))
|
||||
except Exception:
|
||||
display_val = str(int(val)) if isinstance(val, (int, float)) else str(val)
|
||||
else:
|
||||
display_val = str(val)
|
||||
elif key in ("vx", "vy", "vz"):
|
||||
if isinstance(val, (int, float)):
|
||||
conv = m_s_to_ft_s(val)
|
||||
display_val = f"{conv:.3f} ft/s ({val:.3f} m/s)"
|
||||
else:
|
||||
display_val = val
|
||||
elif key == "baro_altitude":
|
||||
if isinstance(val, (int, float)):
|
||||
conv = m_to_ft(val)
|
||||
display_val = f"{conv:.3f} ft ({val:.3f} m)"
|
||||
else:
|
||||
display_val = val
|
||||
elif key in ("latitude", "longitude"):
|
||||
if isinstance(val, (int, float)):
|
||||
# Show decimal degrees and DMS (alt display)
|
||||
dd = float(val)
|
||||
deg = int(dd)
|
||||
md = abs((dd - deg) * 60)
|
||||
minutes = int(md)
|
||||
seconds = (md - minutes) * 60
|
||||
dms = f"{deg}°{minutes:02d}'{seconds:.3f}\""
|
||||
display_val = f"{dd:.9f} ° ({dms})"
|
||||
else:
|
||||
display_val = val
|
||||
else:
|
||||
display_val = val
|
||||
self.scenario_tree.insert("", tk.END, values=(f"{label} {('('+unit+')' if unit else '')}", display_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))
|
||||
|
||||
# targets
|
||||
for iid in self.ris_tree.get_children():
|
||||
self.ris_tree.delete(iid)
|
||||
targets = struct.get("targets", []) if isinstance(struct, dict) else []
|
||||
# Update target column headers to show units
|
||||
# Update target column headers to show units depending on view
|
||||
try:
|
||||
self.ris_tree.heading("heading", text="heading (°)")
|
||||
self.ris_tree.heading("x", text="x (m)")
|
||||
self.ris_tree.heading("y", text="y (m)")
|
||||
self.ris_tree.heading("z", text="z (ft)")
|
||||
view_mode = self.scenario_view_mode.get() if hasattr(self, "scenario_view_mode") else "simplified"
|
||||
# Column headers should be plain; units shown next to values
|
||||
self.ris_tree.heading("heading", text="heading")
|
||||
self.ris_tree.heading("x", text="x")
|
||||
self.ris_tree.heading("y", text="y")
|
||||
self.ris_tree.heading("z", text="z")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
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:
|
||||
# Convert heading (rad->deg) and z (m->ft)
|
||||
if view_mode == "raw":
|
||||
# format raw with reasonable precision
|
||||
try:
|
||||
heading = float(t.get("heading"))
|
||||
heading_deg = heading * (180.0 / 3.141592653589793)
|
||||
heading_raw = float(t.get("heading"))
|
||||
heading_val = f"{heading_raw:.6f}"
|
||||
except Exception:
|
||||
heading_deg = t.get("heading")
|
||||
heading_val = str(t.get("heading"))
|
||||
try:
|
||||
x = float(t.get("x"))
|
||||
y = float(t.get("y"))
|
||||
z_m = float(t.get("z"))
|
||||
z_ft = z_m * 3.280839895
|
||||
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 = t.get("x")
|
||||
y = t.get("y")
|
||||
z_ft = t.get("z")
|
||||
x_val = t.get("x")
|
||||
y_val = t.get("y")
|
||||
z_val = t.get("z")
|
||||
|
||||
vals = (
|
||||
t.get("index"),
|
||||
t.get("flags"),
|
||||
f"{heading_deg:.3f} ° ({t.get('heading')})",
|
||||
f"{x:.3f} m ({t.get('x')})",
|
||||
f"{y:.3f} m ({t.get('y')})",
|
||||
f"{z_ft:.3f} ft ({t.get('z')})",
|
||||
heading_val,
|
||||
x_val,
|
||||
y_val,
|
||||
z_val,
|
||||
)
|
||||
else:
|
||||
# simplified: converted values with units next to number
|
||||
try:
|
||||
heading = float(t.get("heading"))
|
||||
heading_deg = heading * (180.0 / 3.141592653589793)
|
||||
heading_val = f"{heading_deg:.{dec_simp}f} °"
|
||||
except Exception:
|
||||
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"))
|
||||
z_val = str(t.get("z"))
|
||||
|
||||
vals = (
|
||||
t.get("index"),
|
||||
t.get("flags"),
|
||||
heading_val,
|
||||
x_val,
|
||||
y_val,
|
||||
z_val,
|
||||
)
|
||||
|
||||
self.ris_tree.insert("", tk.END, values=vals)
|
||||
except Exception:
|
||||
# ignore malformed JSON for now
|
||||
|
||||
Loading…
Reference in New Issue
Block a user