aggiunto reset target iniziale prima dello start della simulazione mediante comandi json

This commit is contained in:
VALLONGOL 2025-10-31 11:22:02 +01:00
parent 34a6737fcc
commit 7e120a0f72
4 changed files with 501 additions and 15 deletions

View File

@ -1,5 +1,385 @@
{
"s1": {
"a": 1
"scenario1": {
"name": "scenario1",
"targets": [
{
"target_id": 0,
"active": true,
"traceable": true,
"trajectory": [
{
"maneuver_type": "Fly to Point",
"duration_s": 10.0,
"target_altitude_ft": 10000.0,
"target_range_nm": 20.0,
"target_azimuth_deg": 0.0
},
{
"maneuver_type": "Fly for Duration",
"duration_s": 100.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 1670.9318999999994,
"target_heading_deg": 10.0
},
{
"maneuver_type": "Fly to Point",
"duration_s": 400.0,
"target_altitude_ft": 10000.0,
"target_range_nm": 25.0,
"target_azimuth_deg": -20.0
}
],
"use_spline": false
}
]
},
"scenario2": {
"name": "scenario2",
"targets": [
{
"target_id": 0,
"active": true,
"traceable": true,
"trajectory": [
{
"maneuver_type": "Fly to Point",
"duration_s": 10.0,
"target_range_nm": 10.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,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly to Point",
"duration_s": 200.0,
"target_range_nm": 20.0,
"target_azimuth_deg": 10.0,
"target_altitude_ft": 10000.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly to Point",
"duration_s": 200.0,
"target_range_nm": 30.0,
"target_azimuth_deg": -10.0,
"target_altitude_ft": 10000.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly to Point",
"duration_s": 200.0,
"target_range_nm": 35.0,
"target_azimuth_deg": 10.0,
"target_altitude_ft": 10000.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly to Point",
"duration_s": 200.0,
"target_range_nm": 35.0,
"target_azimuth_deg": 30.0,
"target_altitude_ft": 10000.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly to Point",
"duration_s": 200.0,
"target_range_nm": 20.0,
"target_azimuth_deg": 45.0,
"target_altitude_ft": 10000.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
}
],
"use_spline": true
},
{
"target_id": 1,
"active": true,
"traceable": true,
"trajectory": [
{
"maneuver_type": "Fly to Point",
"duration_s": 10.0,
"target_range_nm": 10.0,
"target_azimuth_deg": 10.0,
"target_altitude_ft": 10000.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly to Point",
"duration_s": 10.0,
"target_range_nm": 20.0,
"target_azimuth_deg": 20.0,
"target_altitude_ft": 10000.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly to Point",
"duration_s": 30.0,
"target_range_nm": 30.0,
"target_azimuth_deg": 30.0,
"target_altitude_ft": 10000.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly to Point",
"duration_s": 30.0,
"target_range_nm": 35.0,
"target_azimuth_deg": -10.0,
"target_altitude_ft": 10000.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
}
],
"use_spline": true
},
{
"target_id": 2,
"active": true,
"traceable": true,
"trajectory": [
{
"maneuver_type": "Fly to Point",
"duration_s": 1.0,
"target_range_nm": 28.0,
"target_azimuth_deg": 0.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 506.343,
"target_heading_deg": 180.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly for Duration",
"duration_s": 300.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 506.343,
"target_heading_deg": 180.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Dynamic Maneuver",
"duration_s": 9.0,
"maneuver_speed_fps": 1519.0289999999995,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 9.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly for Duration",
"duration_s": 100.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 1012.686,
"target_heading_deg": -90.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
}
],
"use_spline": false
}
]
},
"scenario3": {
"name": "scenario3",
"targets": [
{
"target_id": 0,
"active": true,
"traceable": true,
"trajectory": [
{
"maneuver_type": "Fly to Point",
"duration_s": 10.0,
"target_range_nm": 5.0,
"target_azimuth_deg": 0.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 506.343,
"target_heading_deg": 180.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly for Duration",
"duration_s": 20.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 506.343,
"target_heading_deg": 90.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly for Duration",
"duration_s": 10.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 506.343,
"target_heading_deg": 180.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly for Duration",
"duration_s": 20.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 506.343,
"target_heading_deg": 90.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly for Duration",
"duration_s": 30.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 506.343,
"target_heading_deg": -180.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
}
],
"use_spline": true
}
]
},
"scenario_9g": {
"name": "scenario2",
"targets": [
{
"target_id": 2,
"active": true,
"traceable": true,
"trajectory": [
{
"maneuver_type": "Fly to Point",
"duration_s": 1.0,
"target_range_nm": 28.0,
"target_azimuth_deg": 0.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 506.343,
"target_heading_deg": 180.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly for Duration",
"duration_s": 300.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 506.343,
"target_heading_deg": 180.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Dynamic Maneuver",
"duration_s": 9.0,
"maneuver_speed_fps": 1519.0289999999995,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 9.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly for Duration",
"duration_s": 100.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 1012.686,
"target_heading_deg": -90.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
}
],
"use_spline": false
}
]
},
"scenario_dritto": {
"name": "scenario_dritto",
"targets": [
{
"target_id": 0,
"active": true,
"traceable": true,
"trajectory": [
{
"maneuver_type": "Fly to Point",
"duration_s": 1.0,
"target_range_nm": 20.0,
"target_azimuth_deg": -45.0,
"target_altitude_ft": 10000.0,
"target_velocity_fps": 506.343,
"target_heading_deg": 90.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
},
{
"maneuver_type": "Fly to Point",
"duration_s": 100.0,
"target_range_nm": 20.0,
"target_azimuth_deg": 45.0,
"target_altitude_ft": 10000.0,
"longitudinal_acceleration_g": 0.0,
"lateral_acceleration_g": 0.0,
"vertical_acceleration_g": 0.0,
"turn_direction": "Right"
}
],
"use_spline": false
}
]
}
}

View File

@ -3,7 +3,7 @@
"scan_limit": 60,
"max_range": 100,
"geometry": "1599x1089+587+179",
"last_selected_scenario": null,
"last_selected_scenario": "scenario1",
"connection": {
"target": {
"type": "sfp",

View File

@ -7,7 +7,7 @@ Constructs MMI command strings based on high-level data models.
import json
from typing import Dict, Any, List, Optional
from .models import Target
from .models import Target, Waypoint, ManeuverType
from target_simulator.utils.logger import get_logger
logger = get_logger(__name__)
@ -173,3 +173,79 @@ def build_acunlatch() -> str:
def build_reset() -> str:
"""Builds the 'reset' command."""
return "reset"
def build_json_reset_ids(max_id: int = 31, max_bytes: int = 1020) -> list[str]:
"""
Build one or more compact JSON payload strings that contain target entries
for IDs 0..max_id with all numeric fields zeroed and flags cleared. This
mirrors the behaviour of the SFP debug window's "Reset IDs" action and
returns a list of newline-terminated compact JSON payloads that fit within
the provided transport size limit.
Args:
max_id: Highest target id to include (inclusive). Defaults to 31.
max_bytes: Maximum bytes allowed per payload (transport limit).
Returns:
List of JSON payload strings (each ends with '\n').
"""
targets = []
for tid in range(0, max_id + 1):
wp = Waypoint(
maneuver_type=ManeuverType.FLY_TO_POINT,
target_range_nm=0.0,
target_azimuth_deg=0.0,
target_altitude_ft=0.0,
target_velocity_fps=0.0,
target_heading_deg=0.0,
)
t = Target(target_id=tid, trajectory=[wp])
t.active = False
t.traceable = False
t.restart = False
t.current_range_nm = 0.0
t.current_azimuth_deg = 0.0
t.current_velocity_fps = 0.0
t.current_heading_deg = 0.0
t.current_altitude_ft = 0.0
targets.append(t)
import json as _json
def build_compact_payload(tlist: list[Target]) -> str:
s = build_json_update(tlist)
try:
obj = _json.loads(s)
compact = _json.dumps(obj, separators=(",", ":"))
except Exception:
compact = s.replace("\n", "").replace("\r", "")
return compact
n = len(targets)
batch_size = n
while batch_size > 0:
payload = build_compact_payload(targets[:batch_size])
if len(payload.encode("utf-8")) <= max_bytes:
break
batch_size -= 1
if batch_size == 0:
# As a defensive fallback, return the full list as a single (possibly
# oversize) payload so callers can attempt to send it and handle errors.
payload = build_compact_payload(targets)
if not payload.endswith("\n"):
payload = payload + "\n"
return [payload]
payloads: list[str] = []
i = 0
while i < n:
j = min(i + batch_size, n)
p = build_compact_payload(targets[i:j])
if not p.endswith("\n"):
p = p + "\n"
payloads.append(p)
i = j
return payloads

View File

@ -722,14 +722,44 @@ class MainView(tk.Tk):
use_json = False
if use_json:
# The server expects a single JSON payload to perform a reset.
json_reset = '{"CMD":"reset"}\n'
commands_to_send = [json_reset]
self.logger.info("Using JSON reset payload for radar reset.")
# Use the same Reset IDs JSON payload sequence as provided by the
# SFP debug window: build one-or-more compact JSON payloads that
# explicitly disable all target IDs and send them in order.
try:
json_payloads = command_builder.build_json_reset_ids()
self.logger.info(
"Using JSON Reset IDs payloads for radar reset (parts=%d).",
len(json_payloads),
)
except Exception:
self.logger.exception(
"Failed to build Reset IDs JSON payloads; falling back to simple JSON reset."
)
json_payloads = ['{"CMD":"reset"}\n']
commands_to_send = json_payloads
else:
# Legacy textual reset sequence (no leading $; newline-terminated strings)
commands_to_send = [prep_command, reset_command + "\n"]
# When using JSON protocol, send each payload part individually.
if use_json:
all_ok = True
for payload in commands_to_send:
try:
ok = self.target_communicator.send_commands([payload])
except Exception:
self.logger.exception("Exception while sending JSON reset payload")
ok = False
if not ok:
all_ok = False
self.logger.error("Failed to send JSON reset payload part.")
break
if not all_ok:
messagebox.showerror(
"Reset Error", "Failed to send reset payload(s) to the radar."
)
return False
else:
if not self.target_communicator.send_commands(commands_to_send):
self.logger.error("Failed to send preparatory/reset commands to the radar.")
messagebox.showerror(