sistemata rotazione antenna in base al ptaz

This commit is contained in:
VALLONGOL 2025-11-19 11:32:13 +01:00
parent a6d679e7a5
commit 48bfc9f730
3 changed files with 76 additions and 47 deletions

View File

@ -289,21 +289,16 @@ class SimulationStateHub:
"""
try:
ts = float(timestamp) if timestamp is not None else time.monotonic()
# Apply platform azimuth inversion: many external sources use an
# opposite angular convention. Store the raw value and keep the
# inverted/normalized value for internal use.
raw = None
try:
# The antenna azimuth provided by external sources should be
# treated as raw and stored as-is (normalized to [0,360)). Do not
# invert it here — only platform/heading values use the inverted
# internal convention.
raw = float(azimuth_deg)
except Exception:
raw = None
az_inverted = _invert_azimuth_deg(raw)
if az_inverted is None:
return
az = raw % 360
except Exception:
return
with self._lock:
self._antenna_azimuth_deg = az_inverted
self._antenna_azimuth_deg = az
self._antenna_azimuth_ts = ts
self._antenna_azimuth_raw = raw

View File

@ -802,31 +802,77 @@ class MainView(tk.Tk):
if self.simulation_hub:
# Update antenna sweep line
if self.ppi_widget.animate_antenna_var.get():
az_deg, _ = self.simulation_hub.get_antenna_azimuth()
antenna_srv, _ = self.simulation_hub.get_antenna_azimuth()
# Compute displayed antenna azimuth depending on display mode
# North-Up: use server-provided antenna azimuth directly
# Heading-Up: express antenna azimuth in body (muso) reference
antenna_display = None
if antenna_srv is not None:
try:
# Debug: record the value read from the hub and hub identity
# Log solo se l'azimuth è valido (non None)
if az_deg is not None:
self.logger.debug(
"MainView: read antenna az from hub -> az=%s hub_id=%s",
az_deg,
id(self._hub),
mode = self.ppi_widget.display_mode_var.get()
# Prefer raw heading when present for correct arithmetic
ownship_state = self.simulation_hub.get_ownship_state() or {}
platform_h_raw = ownship_state.get(
"heading_deg_raw", ownship_state.get("heading_deg", 0.0)
)
platform_h_raw = float(platform_h_raw) if platform_h_raw is not None else 0.0
if mode == "North-Up":
antenna_display = float(antenna_srv)
else: # Heading-Up
# Convert antenna (absolute wrt North) into body-referenced
# angle by adding twice the platform heading. The
# antenna offsets are expressed relative to the nose
# and earlier logic used 2×heading to compute the
# plotted antenna position so preserve that.
antenna_display = float(antenna_srv) #- (0.25 * platform_h_raw)
# Normalize into (-180, 180]
while antenna_display > 180:
antenna_display -= 360
while antenna_display <= -180:
antenna_display += 360
except Exception:
pass
if az_deg is not None:
self.ppi_widget.render_antenna_line(az_deg)
antenna_display = float(antenna_srv)
# Render (or hide) the antenna using the final display angle
if antenna_display is not None:
self.ppi_widget.render_antenna_line(antenna_display)
else:
self.ppi_widget.render_antenna_line(None) # Hide if no data
self.ppi_widget.render_antenna_line(None)
else:
self.ppi_widget.render_antenna_line(None) # Hide if animation is off
# Update ownship state for both PPI orientation and status display
# Use the raw heading (if available) for visualization, since the
# hub stores an inverted heading for internal reasons. Preserve
# the full state for controls but display heading_raw when present.
ownship_state = self.simulation_hub.get_ownship_state()
if ownship_state:
ownship_heading = ownship_state.get("heading_deg", 0.0)
self.ppi_widget.update_ownship_state(ownship_heading)
self.simulation_controls.update_ownship_display(ownship_state)
# Prefer raw heading if present
ownship_heading_raw = ownship_state.get(
"heading_deg_raw", ownship_state.get("heading_deg", 0.0)
)
# Convert raw heading to PPI convention: external/raw positive
# is to the right (clockwise), while Matplotlib/PPI uses
# positive CCW (to the left). Negate the raw heading for
# visualisation only so the ownship points in the expected
# direction on the PPI. Keep the raw value for controls.
try:
ownship_heading_for_ppi = (-float(ownship_heading_raw)) % 360
except Exception:
ownship_heading_for_ppi = ownship_heading_raw
self.ppi_widget.update_ownship_state(ownship_heading_for_ppi)
# Prepare a display-friendly copy where heading_deg shows the raw value
display_state = dict(ownship_state)
if "heading_deg_raw" in display_state:
try:
display_state["heading_deg"] = display_state["heading_deg_raw"]
except Exception:
pass
self.simulation_controls.update_ownship_display(display_state)
else:
# Ensure display is cleared if no ownship data is present
ownship_state = {}

View File

@ -733,32 +733,20 @@ class PPIDisplay(ttk.Frame):
else:
az_float = float(az_deg)
# WORKING SOLUTION confirmed by user:
# North-Up with heading=+10°:
# - Server sends ant_nav_az from +50° to -70°
# - Add 2×heading: result is +70° to -50° ✓ CORRECT
#
# Heading-Up with heading=+10°:
# - Grid is rotated by -10° (via set_theta_offset)
# - Scan lines are drawn at heading ± limit
# - Antenna needs same transformation as scan lines
#
# Solution: use SAME formula for both modes
# - North-Up: add 2×heading
# - Heading-Up: add 2×heading (counter-rotates for the rotated grid)
# Treat the provided az_deg as the final absolute antenna
# azimuth (degrees relative to North, positive=CCW). The
# caller (MainView) computes North-Up vs Heading-Up logic.
final_az_for_plot = az_float
final_az_for_plot = az_float + (2.0 * self.ownship_heading_deg)
# Normalize to [-180, 180] range
# Normalize to (-180, 180]
while final_az_for_plot > 180:
final_az_for_plot -= 360
while final_az_for_plot < -180:
while final_az_for_plot <= -180:
final_az_for_plot += 360
# Convert final angle to theta for Matplotlib (0=N, positive=CCW)
theta = np.deg2rad(final_az_for_plot)
max_r = self.ax.get_ylim()[1]
self._antenna_line_artist.set_data([theta, theta], [0, max_r])
self._antenna_line_artist.set_visible(True)