Add real switch support for multi-device matrix radar

MultiDeviceLibreVnaService only exposes the 2x4 virtual combo matrix on
its own USB transport. When a physical GPIO switch sits on the master
stimulus and/or slave receiver path, the effective matrix is wider than
that. SwitchedMatrixRadarService wraps the inner service and drives the
extra switch(es) between acquire_collection calls, widening the combo
matrix by the physical position counts (matrix_output_switch_positions /
matrix_input_switch_positions in RunConfigModel).

Combo-matrix construction was centralized into
RunConfigModel.build_runtime_combos() so the GUI, workflows, and codec
all derive the same widened matrix instead of each computing its own
version of the virtual 2x4 layout.
This commit is contained in:
2026-07-29 17:44:28 +03:00
parent f967da7f53
commit 68bec25f17
11 changed files with 341 additions and 32 deletions
+144 -11
View File
@@ -1,6 +1,6 @@
{
"radar": {
"model": "librevna",
"model": "librevna_multi",
"serial": "",
"remote_host": "127.0.0.1",
"remote_port": 50209,
@@ -8,9 +8,14 @@
"mock_signal_hz": 5000000.0,
"visa_library": "",
"multi_device": {
"slave_serials": [],
"slave_serials": [
"20A1307D5532",
"2072306C5532"
],
"force_external_reference": false,
"recovery_attempts": 3
"recovery_attempts": 3,
"output_switch_positions": 1,
"input_switch_positions": 3
},
"kamil_adc": {
"project_dir": "",
@@ -20,7 +25,18 @@
"env": {},
"startup_timeout_s": 5.0,
"sweep_timeout_s": 5.0,
"stop_timeout_s": 2.0
"stop_timeout_s": 2.0,
"phase_calibration": {
"phase0_rad": 0.0,
"freq0_hz": 2046000000.0,
"phase1_rad": 300.0,
"freq1_hz": 5612000000.0
},
"band": {
"start_hz": 2100000000.0,
"stop_hz": 5500000000.0,
"points": 2048
}
},
"laser_control": {
"enabled": false,
@@ -75,7 +91,7 @@
"driver_mode": "mock",
"driver": "h7992",
"radar_port": 2,
"positions": 4,
"positions": 12,
"default_position": 0,
"gpio_chip": "/dev/gpiochip0",
"pin_a": 22,
@@ -92,11 +108,14 @@
"debounce_ms": 50,
"action": "capture_tmp_reference"
},
"logging": {
"level": "info"
},
"run": {
"settling_ms": 0,
"idle_sleep_ms": 2,
"continuous": true,
"processing_live_config_path": "python_app/runtime/processing_live.json",
"processing_live_config_path": "/home/guriy/Documents/radar_system/python_app/runtime/processing_live.json",
"locator_server": {
"device_id": 3,
"protocol_version": 1,
@@ -123,6 +142,38 @@
"input": 3,
"output": 0
},
{
"input": 4,
"output": 0
},
{
"input": 5,
"output": 0
},
{
"input": 6,
"output": 0
},
{
"input": 7,
"output": 0
},
{
"input": 8,
"output": 0
},
{
"input": 9,
"output": 0
},
{
"input": 10,
"output": 0
},
{
"input": 11,
"output": 0
},
{
"input": 0,
"output": 1
@@ -138,17 +189,49 @@
{
"input": 3,
"output": 1
},
{
"input": 4,
"output": 1
},
{
"input": 5,
"output": 1
},
{
"input": 6,
"output": 1
},
{
"input": 7,
"output": 1
},
{
"input": 8,
"output": 1
},
{
"input": 9,
"output": 1
},
{
"input": 10,
"output": 1
},
{
"input": 11,
"output": 1
}
]
},
"preprocess": {
"s21": {
"calibration": {
"set_name": "smoke_cal",
"set_name": "smoke_cal3",
"bundle_path": ""
},
"reference": {
"set_name": "smoke_ref",
"set_name": "smoke_cal3",
"bundle_path": ""
}
},
@@ -219,6 +302,54 @@
"x_m": 0.185,
"y_m": 0.0,
"z_m": 0.0
},
{
"input_pos": 4,
"x_m": 0.0,
"y_m": 0.0,
"z_m": 0.0
},
{
"input_pos": 5,
"x_m": 0.0,
"y_m": 0.0,
"z_m": 0.0
},
{
"input_pos": 6,
"x_m": 0.0,
"y_m": 0.0,
"z_m": 0.0
},
{
"input_pos": 7,
"x_m": 0.0,
"y_m": 0.0,
"z_m": 0.0
},
{
"input_pos": 8,
"x_m": 0.0,
"y_m": 0.0,
"z_m": 0.0
},
{
"input_pos": 9,
"x_m": 0.0,
"y_m": 0.0,
"z_m": 0.0
},
{
"input_pos": 10,
"x_m": 0.0,
"y_m": 0.0,
"z_m": 0.0
},
{
"input_pos": 11,
"x_m": 0.0,
"y_m": 0.0,
"z_m": 0.0
}
]
},
@@ -253,7 +384,7 @@
"version": 1,
"switches": {
"combo_mode": "text",
"combos_text": "0:0,1:0,2:0,3:0,0:1,1:1,2:1,3:1",
"combos_text": "0:0,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,0:1,1:1,2:1,3:1,4:1,5:1,6:1,7:1,8:1,9:1,10:1,11:1",
"single_input": "0",
"single_output": "0"
},
@@ -262,6 +393,7 @@
"pass_through": {
"show_magnitude": true,
"show_phase": false,
"unwrap_phase": false,
"combo_filter": "",
"fixed_y_enabled": false,
"y_min_db": -100.0,
@@ -333,7 +465,8 @@
"data_actions": {
"save_count": 10,
"save_path": "python_app/data/snapshots",
"save_name": "snapshot_simulator"
"save_name": "snapshot_simulator",
"record_count": 100
},
"preprocess_dialog": {
"set_name": "smoke_cal",
@@ -342,4 +475,4 @@
"median_sweep_count": 5
}
}
}
}