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": { "scenario1": {
"a": 1 "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, "scan_limit": 60,
"max_range": 100, "max_range": 100,
"geometry": "1599x1089+587+179", "geometry": "1599x1089+587+179",
"last_selected_scenario": null, "last_selected_scenario": "scenario1",
"connection": { "connection": {
"target": { "target": {
"type": "sfp", "type": "sfp",

View File

@ -7,7 +7,7 @@ Constructs MMI command strings based on high-level data models.
import json import json
from typing import Dict, Any, List, Optional 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 from target_simulator.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@ -173,3 +173,79 @@ def build_acunlatch() -> str:
def build_reset() -> str: def build_reset() -> str:
"""Builds the 'reset' command.""" """Builds the 'reset' command."""
return "reset" 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,20 +722,50 @@ class MainView(tk.Tk):
use_json = False use_json = False
if use_json: if use_json:
# The server expects a single JSON payload to perform a reset. # Use the same Reset IDs JSON payload sequence as provided by the
json_reset = '{"CMD":"reset"}\n' # SFP debug window: build one-or-more compact JSON payloads that
commands_to_send = [json_reset] # explicitly disable all target IDs and send them in order.
self.logger.info("Using JSON reset payload for radar reset.") 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: else:
# Legacy textual reset sequence (no leading $; newline-terminated strings) # Legacy textual reset sequence (no leading $; newline-terminated strings)
commands_to_send = [prep_command, reset_command + "\n"] commands_to_send = [prep_command, reset_command + "\n"]
if not self.target_communicator.send_commands(commands_to_send): # When using JSON protocol, send each payload part individually.
self.logger.error("Failed to send preparatory/reset commands to the radar.") if use_json:
messagebox.showerror( all_ok = True
"Reset Error", "Failed to send reset command to the radar." for payload in commands_to_send:
) try:
return False 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(
"Reset Error", "Failed to send reset command to the radar."
)
return False
self.logger.info( self.logger.info(
"Successfully sent preparatory and atomic reset commands: %s", "Successfully sent preparatory and atomic reset commands: %s",