Rework radar system

This commit is contained in:
Ayzen
2026-10-06 12:32:26 +03:00
parent 552cdc688a
commit 5bb86b7165
299 changed files with 13537 additions and 27763 deletions
@@ -4,13 +4,12 @@ from __future__ import annotations
from dataclasses import replace
import logging
from typing import Callable
from ..enums import PacketType
from ..enums import PacketType, SyncMode
from ..exceptions import ParseError
from ..models import Packet, StreamHandle, SweepResult, VNADatapointPacket, VNARawPoint, VNASweepSettings
from ..models import Packet, SweepResult, VNADatapointPacket, VNASweepSettings
from ..session import LibreVNASession
from ..sweep.assembler import assemble_vna_sweep, datapoint_to_raw_point
from ..sweep.assembler import assemble_vna_sweep
logger = logging.getLogger(__name__)
@@ -27,22 +26,21 @@ class VNAController:
"""Send `SweepSettings` packet to configure VNA operation."""
effective = settings
if effective.sync_mode is None:
effective = replace(effective, sync_mode=self._session.default_sync_mode)
effective = replace(effective, sync_mode=SyncMode.DISABLED)
self._settings = effective
self._session.clear_queue(PacketType.VNA_DATAPOINT)
self._session.send(Packet(PacketType.SWEEP_SETTINGS, effective), require_ack=True)
logger.info(
"VNA configured: kind=%s start=%.3fHz stop=%.3fHz points=%d ifbw=%.3fHz ports=%s",
"VNA configured: kind=%s start=%.3fHz stop=%.3fHz points=%d ifbw=%.3fHz",
effective.kind.value,
effective.f_start_hz,
effective.f_stop_hz,
effective.points,
effective.if_bandwidth_hz,
effective.excited_ports,
)
def acquire(self, *, expected_points: int | None = None, timeout_s: float = 10.0) -> SweepResult:
def acquire(self, *, expected_points: int | None = None, timeout_s: float | None = None) -> SweepResult:
"""Acquire one complete sweep and return assembled complex traces."""
if self._settings is None:
raise ParseError("VNA is not configured. Call vna.configure() before acquire().")
@@ -52,6 +50,13 @@ class VNAController:
if points_target <= 0:
raise ValueError("expected_points must be > 0")
# Firmware integrates for 1/IFBW after dwell/PLL settling at every point.
# Allow a discarded free-running tail and USB/host overhead, but detect
# a stalled instrument independently of this whole-sweep budget.
point_seconds = 1.0 / settings.if_bandwidth_hz + settings.dwell_s + 0.001
if timeout_s is None:
timeout_s = max(10.0, 2.0 * points_target * point_seconds + 2.0)
logger.info(
"VNA acquire start: expected_points=%d timeout=%.2fs standby=%s",
points_target,
@@ -66,6 +71,7 @@ class VNAController:
packet_type=PacketType.VNA_DATAPOINT,
expected_points=points_target,
timeout_s=timeout_s,
progress_timeout_s=max(1.5, 3.0 * point_seconds),
payload_type=VNADatapointPacket,
payload_error="Expected decoded VNADatapointPacket payload",
)
@@ -79,21 +85,3 @@ class VNAController:
)
logger.info("VNA acquire complete: received_points=%d", len(result.x))
return result
def stream(self, callback: Callable[[VNARawPoint], None]) -> StreamHandle:
"""Subscribe callback for every incoming VNA datapoint packet."""
if self._settings is None:
raise ParseError("VNA is not configured. Call vna.configure() before stream().")
settings = self._settings
num_ports = self._session.get_device_info().num_ports
def _on_packet(packet: Packet) -> None:
"""Decode datapoint packet and forward mapped raw point to callback."""
payload = packet.payload
if not isinstance(payload, VNADatapointPacket):
raise ParseError("Expected decoded VNADatapointPacket payload")
callback(datapoint_to_raw_point(payload, settings, num_ports=num_ports))
logger.info("VNA stream subscription started")
return self._session.subscribe(PacketType.VNA_DATAPOINT, _on_packet)