fix save heading and velocity for target editing

This commit is contained in:
VALLONGOL 2025-10-14 11:32:57 +02:00
parent b20bd40b37
commit 17a72d061e
5 changed files with 44 additions and 12 deletions

View File

@ -195,9 +195,11 @@
"trajectory": [ "trajectory": [
{ {
"maneuver_type": "Fly to Point", "maneuver_type": "Fly to Point",
"target_velocity_fps": 506.343,
"target_heading_deg": 180.0,
"duration_s": 10.0, "duration_s": 10.0,
"target_altitude_ft": 10000.0, "target_altitude_ft": 11000.0,
"target_range_nm": 20.0, "target_range_nm": 10.0,
"target_azimuth_deg": 0.0 "target_azimuth_deg": 0.0
} }
], ],

View File

@ -51,7 +51,8 @@ class Waypoint:
for f in fields(self): for f in fields(self):
if not f.name.startswith('_') and f.name != "maneuver_type": if not f.name.startswith('_') and f.name != "maneuver_type":
val = getattr(self, f.name) val = getattr(self, f.name)
if val is not None: # Forza la presenza di velocity/heading anche per Fly to Point
if val is not None or f.name in ("target_velocity_fps", "target_heading_deg"):
data[f.name] = val data[f.name] = val
return data return data

View File

@ -255,11 +255,25 @@ class PPIDisplay(ttk.Frame):
self._waypoints_plot.set_data(thetas, rs) self._waypoints_plot.set_data(thetas, rs)
self._start_plot.set_data([thetas[0]], [rs[0]]) self._start_plot.set_data([thetas[0]], [rs[0]])
heading_len = 3 heading_len = 3
heading_theta = thetas[0] # Usa heading del waypoint se disponibile
heading_r2 = rs[0] + heading_len wp_heading = None
if hasattr(self, '_heading_artist'): if waypoints and hasattr(waypoints[0], 'target_heading_deg') and waypoints[0].target_heading_deg is not None:
self._heading_artist.remove() wp_heading = waypoints[0].target_heading_deg
self._heading_artist, = self.ax.plot([heading_theta, heading_theta], [rs[0], heading_r2], color='red', linewidth=1, alpha=0.8) if wp_heading is not None:
# L'heading è rispetto al nord (0°), quindi la freccia va da (r, azimuth) verso (r+len, azimuth+heading)
start_theta = thetas[0]
start_r = rs[0]
heading_theta = start_theta + math.radians(wp_heading)
heading_r2 = start_r + heading_len
if hasattr(self, '_heading_artist'):
self._heading_artist.remove()
self._heading_artist, = self.ax.plot([start_theta, heading_theta], [start_r, heading_r2], color='red', linewidth=1, alpha=0.8)
else:
heading_theta = thetas[0]
heading_r2 = rs[0] + heading_len
if hasattr(self, '_heading_artist'):
self._heading_artist.remove()
self._heading_artist, = self.ax.plot([thetas[0], heading_theta], [rs[0], heading_r2], color='red', linewidth=1, alpha=0.8)
self.canvas.draw() self.canvas.draw()
self._on_range_selected() self._on_range_selected()
return return

View File

@ -362,9 +362,16 @@ class TrajectoryEditorWindow(tk.Toplevel):
self.sim_progress_var.set(progress) self.sim_progress_var.set(progress)
self.sim_time_label.config(text=f"{sim_time:.1f}s / {total_time:.1f}s") self.sim_time_label.config(text=f"{sim_time:.1f}s / {total_time:.1f}s")
# Se la simulazione è finita (tutti i waypoint raggiunti), ferma la preview e aggiorna i tasti # Se la simulazione è finita (tutti i waypoint raggiunti), ferma la preview e aggiorna i tasti
# Ferma la simulazione se il tempo è finito
if self.preview_engine and hasattr(self.preview_engine, 'scenario') and self.preview_engine.scenario: if self.preview_engine and hasattr(self.preview_engine, 'scenario') and self.preview_engine.scenario:
if hasattr(self.preview_engine.scenario, 'is_finished') and self.preview_engine.scenario.is_finished: targets = self.preview_engine.scenario.get_all_targets()
self._on_preview_stop() if targets:
t = targets[0]
sim_time = getattr(t, '_sim_time_s', 0.0)
total_time = self._get_total_simulation_time()
if sim_time >= total_time:
self._on_preview_stop()
self._update_preview_button_states()
finally: finally:
if self.is_preview_running.get(): if self.is_preview_running.get():
self.after(GUI_QUEUE_POLL_INTERVAL_MS, self._process_preview_queue) self.after(GUI_QUEUE_POLL_INTERVAL_MS, self._process_preview_queue)

View File

@ -58,8 +58,14 @@ class WaypointEditorWindow(tk.Toplevel):
self.t_range_var.set(wp.target_range_nm or 0.0) self.t_range_var.set(wp.target_range_nm or 0.0)
self.t_az_var.set(wp.target_azimuth_deg or 0.0) self.t_az_var.set(wp.target_azimuth_deg or 0.0)
self.t_alt_var.set(wp.target_altitude_ft or 10000.0) self.t_alt_var.set(wp.target_altitude_ft or 10000.0)
self.t_vel_var.set((wp.target_velocity_fps or 0.0) * FPS_TO_KNOTS) if wp.target_velocity_fps is not None:
self.t_hdg_var.set(wp.target_heading_deg or 0.0) self.t_vel_var.set(wp.target_velocity_fps * FPS_TO_KNOTS)
else:
self.t_vel_var.set(0.0)
if wp.target_heading_deg is not None:
self.t_hdg_var.set(wp.target_heading_deg)
else:
self.t_hdg_var.set(0.0)
# Carica i parametri dinamici se presenti # Carica i parametri dinamici se presenti
self.dyn_vel_var.set((getattr(wp, 'dynamic_velocity_fps', 0.0) or 0.0) * FPS_TO_KNOTS) self.dyn_vel_var.set((getattr(wp, 'dynamic_velocity_fps', 0.0) or 0.0) * FPS_TO_KNOTS)
self.lateral_g_var.set(getattr(wp, 'lateral_g', 0.0) or 0.0) self.lateral_g_var.set(getattr(wp, 'lateral_g', 0.0) or 0.0)
@ -175,6 +181,8 @@ class WaypointEditorWindow(tk.Toplevel):
wp.target_azimuth_deg = self.t_az_var.get() wp.target_azimuth_deg = self.t_az_var.get()
wp.target_altitude_ft = self.t_alt_var.get() wp.target_altitude_ft = self.t_alt_var.get()
wp.duration_s = self.duration_var.get() wp.duration_s = self.duration_var.get()
wp.target_velocity_fps = self.t_vel_var.get() * KNOTS_TO_FPS
wp.target_heading_deg = self.t_hdg_var.get()
elif m_type == ManeuverType.FLY_FOR_DURATION: elif m_type == ManeuverType.FLY_FOR_DURATION:
wp.duration_s = self.duration_var.get() wp.duration_s = self.duration_var.get()
wp.target_velocity_fps = self.t_vel_var.get() * KNOTS_TO_FPS wp.target_velocity_fps = self.t_vel_var.get() * KNOTS_TO_FPS