added multidevice support

This commit is contained in:
Ayzen
2026-04-28 17:29:21 +03:00
parent 93c705a33b
commit 1ea2aabf87
37 changed files with 1860 additions and 138 deletions
+53 -1
View File
@@ -28,15 +28,25 @@ class RadarSweepModel:
power_dbm: float = -30.0
@dataclass(slots=True)
class RadarMultiDeviceModel:
"""Multi-device LibreVNA topology settings."""
slave_serials: list[str] = field(default_factory=list)
force_external_reference: bool = True
recovery_attempts: int = 3
@dataclass(slots=True)
class RadarModel:
"""Radar section of run configuration."""
model: str = ""
model: str = "librevna"
serial: str = ""
driver_mode: str = "mock"
mock_signal_hz: float = 1_000_000.0
sweep: RadarSweepModel = field(default_factory=RadarSweepModel)
multi_device: RadarMultiDeviceModel = field(default_factory=RadarMultiDeviceModel)
@dataclass(slots=True)
@@ -190,6 +200,11 @@ class RunConfigModel:
gpr: GprModel = field(default_factory=GprModel)
combos: list[ComboModel] = field(default_factory=list)
LIBREVNA_MODEL = "librevna"
LIBREVNA_MULTI_MODEL = "librevna_multi"
MULTI_DEVICE_INPUT_POSITIONS = 4
MULTI_DEVICE_OUTPUT_POSITIONS = 2
@staticmethod
def build_full_combos(input_positions: int, output_positions: int) -> list[ComboModel]:
"""Build full Cartesian product of input/output switch positions."""
@@ -199,8 +214,45 @@ class RunConfigModel:
for input_pos in range(input_positions)
]
@classmethod
def build_multi_device_virtual_combos(cls) -> list[ComboModel]:
"""Build fixed virtual combo matrix for one master and two slave devices."""
return cls.build_full_combos(
cls.MULTI_DEVICE_INPUT_POSITIONS,
cls.MULTI_DEVICE_OUTPUT_POSITIONS,
)
@property
def is_multi_device(self) -> bool:
"""Return whether this config targets synchronized multi-device acquisition."""
return self.radar.model == self.LIBREVNA_MULTI_MODEL
def apply_device_model_constraints(self) -> None:
"""Apply only required wire-format constraints for the selected device model."""
if not self.is_multi_device:
return
self.radar.model = self.LIBREVNA_MULTI_MODEL
self.output_switch.name = self.output_switch.name or "virtual_output"
self.output_switch.driver_mode = "mock"
self.output_switch.driver = self.output_switch.driver or "h7992"
self.output_switch.radar_port = 1
self.output_switch.positions = self.MULTI_DEVICE_OUTPUT_POSITIONS
self.output_switch.default_position = 0
self.input_switch.name = self.input_switch.name or "virtual_input"
self.input_switch.driver_mode = "mock"
self.input_switch.driver = self.input_switch.driver or "h7992"
self.input_switch.radar_port = 2
self.input_switch.positions = self.MULTI_DEVICE_INPUT_POSITIONS
self.input_switch.default_position = 0
self.combos = self.build_multi_device_virtual_combos()
def ensure_combos(self) -> None:
"""Populate combos with full matrix when no explicit run combos are set."""
if self.is_multi_device:
self.apply_device_model_constraints()
return
if self.combos:
return
self.combos = self.build_full_combos(self.input_switch.positions, self.output_switch.positions)