kamil_adc support added

This commit is contained in:
Ayzen
2026-05-08 21:23:52 +03:00
parent bde86813e5
commit 907dbf29ce
36 changed files with 2161 additions and 221 deletions
+7
View File
@@ -71,6 +71,7 @@ def locator_observations_from_collection(
min_score: float,
*,
visible_bounds: tuple[float, float, float, float] | None = None,
object_draw_limits: tuple[int, int] | None = None,
) -> list[dict[str, float]]:
"""Build locator observations from GPR rows using score threshold and optional X/Z bounds."""
rows = gpr_object_rows(collection)
@@ -88,6 +89,12 @@ def locator_observations_from_collection(
& (rows[:, 1] <= z_max)
)
filtered = rows[visible_mask]
if object_draw_limits is not None and filtered.size > 0:
max_detected_objects, draw_top_objects = object_draw_limits
if filtered.shape[0] > int(max_detected_objects):
filtered = np.zeros((0, filtered.shape[1]), dtype=filtered.dtype)
else:
filtered = filtered[: max(0, int(draw_top_objects))]
observations: list[dict[str, float]] = []
for x_m, z_m, _score in filtered:
@@ -31,6 +31,9 @@ class ProcessingLiveConfig:
gpr_range_comp_power: float = 0.28
gpr_angle_comp_power: float = 0.10
gpr_comp_power: float = 0.2
gpr_score_mode: str = "combined"
gpr_max_detected_objects_to_draw: int = 5
gpr_draw_top_m_objects: int = 2
gpr_speed_m_s: float = 0.0
gpr_look_angle_deg: float = 0.0
gpr_snr_thresh: float = 4.5
@@ -40,6 +43,7 @@ class ProcessingLiveConfig:
gpr_background_subtract_enabled: bool = True
gpr_background_mean_count: int = 10
gpr_remove_sidelobe_objects_enabled: bool = True
reprocess_current_result: bool = True
history_command_seq: int = 0
history_command: str = "none"
@@ -77,6 +81,9 @@ class ProcessingLiveConfig:
"gpr_range_comp_power": float(self.gpr_range_comp_power),
"gpr_angle_comp_power": float(self.gpr_angle_comp_power),
"gpr_comp_power": float(self.gpr_comp_power),
"gpr_score_mode": str(self.gpr_score_mode),
"gpr_max_detected_objects_to_draw": int(self.gpr_max_detected_objects_to_draw),
"gpr_draw_top_m_objects": int(self.gpr_draw_top_m_objects),
"gpr_speed_m_s": float(self.gpr_speed_m_s),
"gpr_look_angle_deg": float(self.gpr_look_angle_deg),
"gpr_snr_thresh": float(self.gpr_snr_thresh),
@@ -86,6 +93,7 @@ class ProcessingLiveConfig:
"gpr_background_subtract_enabled": bool(self.gpr_background_subtract_enabled),
"gpr_background_mean_count": int(self.gpr_background_mean_count),
"gpr_remove_sidelobe_objects_enabled": bool(self.gpr_remove_sidelobe_objects_enabled),
"reprocess_current_result": bool(self.reprocess_current_result),
"history_command_seq": int(self.history_command_seq),
"history_command": str(self.history_command),
}
+56 -11
View File
@@ -63,6 +63,21 @@ def parse_vlc(payload: dict[str, Any]) -> float:
return vlc
def format_payload_for_log(payload: Any) -> str:
"""Return compact JSON-ish payload text for logs."""
return json.dumps(payload, ensure_ascii=True, separators=(",", ":"))
def decode_packet_for_log(packet: bytes) -> tuple[int, str]:
"""Decode an outbound packet into `(device_id, payload_text)` for logging."""
if len(packet) < _PACKET_HEADER_STRUCT.size:
raise ValueError("Packet is shorter than the locator header")
header_bytes = packet[: _PACKET_HEADER_STRUCT.size]
payload_bytes = packet[_PACKET_HEADER_STRUCT.size :]
device_id, payload = decode_packet(header_bytes, payload_bytes)
return device_id, format_payload_for_log(payload)
def format_peer_name(writer: asyncio.StreamWriter) -> str:
"""Return a readable peer address for logs."""
peer_name = writer.get_extra_info("peername")
@@ -118,6 +133,7 @@ class LocatorTcpService:
self._logger = logger or logging.getLogger(str(logger_name))
self._client_queue_size = int(client_queue_size)
self._speed_updates: queue.Queue[float] = queue.Queue()
self._log_updates: queue.Queue[str] = queue.Queue()
self._loop: asyncio.AbstractEventLoop | None = None
self._server: asyncio.AbstractServer | None = None
self._thread: threading.Thread | None = None
@@ -186,12 +202,14 @@ class LocatorTcpService:
min_score: float,
*,
visible_bounds: tuple[float, float, float, float] | None = None,
object_draw_limits: tuple[int, int] | None = None,
) -> None:
"""Publish one locator payload derived from a GPR result collection."""
observations = locator_observations_from_collection(
collection,
min_score,
visible_bounds=visible_bounds,
object_draw_limits=object_draw_limits,
)
payload = build_locator_payload(
observations,
@@ -218,6 +236,24 @@ class LocatorTcpService:
except queue.Empty:
return latest
def drain_log_updates(self) -> list[str]:
"""Drain queued socket traffic log lines."""
lines: list[str] = []
while True:
try:
lines.append(str(self._log_updates.get_nowait()))
except queue.Empty:
return lines
def _queue_log_update(self, message: str) -> None:
"""Queue one socket traffic line for the GUI runtime log."""
self._log_updates.put(str(message))
def _log_socket_traffic(self, message: str) -> None:
"""Log socket traffic to both Python logging and the GUI-visible queue."""
self._logger.info(message)
self._queue_log_update(message)
def _publish_packet(self, packet: bytes) -> None:
"""Store latest packet and broadcast it to all connected clients."""
with self._snapshot_lock:
@@ -368,6 +404,17 @@ class LocatorTcpService:
packet = await client.queue.get()
client.writer.write(packet)
await client.writer.drain()
try:
device_id, payload_text = decode_packet_for_log(packet)
self._log_socket_traffic(
"Locator socket sent to %s: device_id=%d payload=%s"
% (client.peer_name, device_id, payload_text)
)
except ValueError as error:
self._log_socket_traffic(
"Locator socket sent undecodable packet to %s: bytes=%d error=%s"
% (client.peer_name, len(packet), error)
)
async def _receive_packets(
self,
@@ -377,21 +424,19 @@ class LocatorTcpService:
"""Receive inbound client packets and queue valid speed updates."""
while True:
device_id, payload = await read_packet_with_limit(reader, self._max_payload_bytes)
payload_text = format_payload_for_log(payload)
if isinstance(payload, dict) and "vlc" in payload:
self._speed_updates.put(parse_vlc(payload))
self._logger.debug(
"Received locator speed from %s: device_id=%d payload=%s",
client.peer_name,
device_id,
payload,
speed_m_s = parse_vlc(payload)
self._speed_updates.put(speed_m_s)
self._log_socket_traffic(
"Locator socket received from %s: device_id=%d payload=%s speed_m_s=%g"
% (client.peer_name, device_id, payload_text, speed_m_s)
)
continue
self._logger.info(
"Received locator payload from %s: device_id=%d payload=%s",
client.peer_name,
device_id,
json.dumps(payload, ensure_ascii=True, separators=(",", ":")),
self._log_socket_traffic(
"Locator socket received from %s: device_id=%d payload=%s"
% (client.peer_name, device_id, payload_text)
)
def _broadcast_packet(self, packet: bytes) -> None: