13 KiB
Run Config Reference
run_config.json is the stable runtime configuration consumed by the GUI,
Python helpers, and C++ pipeline binaries. The active file is normally
run_config.json; root-level *.example.json files are templates.
JSON does not support comments. Keep notes in docs, not inside config files.
Top-Level Sections
{
"radar": {},
"switches": {},
"run": {},
"preprocess": {},
"gpr": {},
"rings": {}
}
radar
Selects the radar model and sweep settings.
"radar": {
"model": "compact_m_k209",
"serial": "",
"remote_host": "127.0.0.1",
"remote_port": 50209,
"driver_mode": "native",
"mock_signal_hz": 5000000.0,
"multi_device": {},
"kamil_adc": {},
"laser_control": {},
"sweep": {}
}
Fields:
| Field | Meaning |
|---|---|
model |
librevna, librevna_multi, compact_m_k209, sn9000, or kamil_adc. |
serial |
LibreVNA serial. Empty means first device for single LibreVNA. For librevna_multi, this is the master serial. Unused by compact_m_k209 and sn9000. |
remote_host |
SCPI server host. For compact_m_k209 it is the K209 relay server host; for sn9000 it is the SNVNA HiSLIP host. Ignored by LibreVNA modes. |
remote_port |
SCPI server TCP port. Default 50209 for compact_m_k209 (relay), 4880 for sn9000 (SNVNA HiSLIP). |
driver_mode |
native for hardware, mock for supported synthetic LibreVNA modes. K209, SN9000, and Kamil ADC require native. |
mock_signal_hz |
Existing LibreVNA mock signal parameter used by C++ mock acquisition. |
multi_device |
Extra settings for librevna_multi. |
kamil_adc |
External collector process and TTY settings for kamil_adc. |
laser_control |
Laser board settings applied before kamil_adc collection starts. |
sweep |
Frequency, point count, IFBW, and power settings. |
radar.sweep
"sweep": {
"start_hz": 1000000.0,
"stop_hz": 6000000000.0,
"points": 201,
"if_bandwidth_hz": 50000.0,
"stimulus_power_dbm": -10.0
}
Fields:
| Field | Meaning |
|---|---|
start_hz |
Sweep start frequency in Hz. |
stop_hz |
Sweep stop frequency in Hz. Must be >= start_hz. |
points |
Number of frequency points. |
if_bandwidth_hz |
IF bandwidth in Hz. |
stimulus_power_dbm |
Output power in dBm. |
K209 limits reported by the tested device:
frequency_hz: 9000 .. 9000000000
ifbw_hz: 1 .. 300000
power_dbm: -55 .. +5
points: 2 .. 500001
radar.multi_device
Used only when radar.model == "librevna_multi".
"multi_device": {
"slave_serials": [
"SLAVE_SERIAL_1",
"SLAVE_SERIAL_2"
],
"force_external_reference": true,
"recovery_attempts": 3
}
Fields:
| Field | Meaning |
|---|---|
slave_serials |
Exactly two slave LibreVNA serials. |
force_external_reference |
Configure the synchronized external reference path. |
recovery_attempts |
Reopen/retry attempts after native multi-device acquisition errors. |
radar.kamil_adc
Used only when radar.model == "kamil_adc".
"kamil_adc": {
"project_dir": "/home/europa/Documents/kamil_adc",
"executable_path": "/home/europa/Documents/kamil_adc/kamil_adc_capture",
"tty_path": "/tmp/ttyADC_data",
"args": [
"profile:phase",
"clock:internal",
"internal_ref_hz:2000000",
"mode:diff",
"channels:2",
"ch1:2",
"ch2:3",
"do1_toggle_per_frame",
"do1_pair_subtract_avg"
],
"env": {},
"startup_timeout_s": 5.0,
"sweep_timeout_s": 5.0,
"stop_timeout_s": 2.0
}
Fields:
| Field | Meaning |
|---|---|
project_dir |
Working directory for the external ADC collector. Required. |
executable_path |
Full path to the Raspberry Pi executable. Required; no filename is assumed. |
tty_path |
TTY stream path, for example /tmp/ttyADC_data. The producer appends tty:<tty_path>. |
args |
Explicit collector arguments, excluding any tty: argument. |
env |
Extra environment variables for the collector process. |
startup_timeout_s |
Time allowed for the collector to create a fresh TTY path. |
sweep_timeout_s |
Time allowed to receive one full sweep packet. |
stop_timeout_s |
Graceful stop timeout before killing the collector process. |
The TTY frame format is strict: packet start is 0x000A 0xFFFF 0xFFFF 0xFFFF,
then each sweep point is 0x000A step data1 data2. Steps must arrive as
1..N; N is derived from the stream when the next packet start arrives.
radar.sweep.points is not used by the Kamil ADC producer. S21 is
data1 + j*data2; S11 is stored as explicit zeros.
radar.laser_control
Used with kamil_adc when the laser board must be configured before ADC
collection starts. laser_control and kamil_adc are one hardware
configuration unit: changing either section requires restarting acquisition.
"laser_control": {
"enabled": true,
"port": "/dev/ttyUSB0",
"mode": "variation",
"pi_coeff1_p": 2560,
"pi_coeff1_i": 128,
"pi_coeff2_p": 2560,
"pi_coeff2_i": 128,
"manual": {
"temp1": 25.0,
"temp2": 25.0,
"current1": 30.0,
"current2": 30.0
},
"variation": {
"variation_type": "CHANGE_CURRENT_LD1",
"static_temp1": 28.0,
"static_temp2": 28.9,
"static_current1": 33.0,
"static_current2": 35.0,
"min_value": 33.0,
"max_value": 60.0,
"step": 0.05,
"time_step": 50,
"delay_time": 10
}
}
mode="manual" uses manual. mode="variation" uses variation.
variation_type is the enum name from laser_control, for example
CHANGE_CURRENT_LD1 or CHANGE_TEMPERATURE_LD2.
switches
Two RF switch sections are used:
"switches": {
"port1": {},
"port2": {}
}
By convention in the C++ pipeline:
port1 -> output switch
port2 -> input switch
Switch fields:
| Field | Meaning |
|---|---|
name |
Human-readable switch name. |
driver_mode |
native for GPIO, mock to avoid GPIO access. |
driver |
h7992 or hmc349a. |
radar_port |
Physical radar port mapping, must be unique and either 1 or 2. |
positions |
Number of switch positions. |
default_position |
Position selected on open. Zero-based. |
gpio_chip |
Linux GPIO chip path, usually /dev/gpiochip0. |
pin_a |
First GPIO control pin. |
pin_b |
Second GPIO control pin for h7992. |
invert_logic |
Logic inversion for supported switch drivers. |
Use mock switches on a laptop without GPIO:
"driver_mode": "mock"
control_button
Optional physical GPIO push-button that triggers a runtime action on press. The watcher runs in both GUI and headless modes (it is attached to the main window, which both launch paths build). On press it reuses the existing "Capture Tmp Reference" flow: stop the pipeline, capture a fresh tmp S21 reference with the current sweep settings, then restart the pipeline if it had been running.
"control_button": {
"enabled": true,
"gpio_chip": "/dev/gpiochip0",
"pin": 26,
"active_low": true,
"bias": "",
"debounce_ms": 50,
"action": "capture_tmp_reference"
}
| Field | Meaning |
|---|---|
enabled |
Master switch. When false (default) no GPIO line is opened, so non-Pi hosts are unaffected. |
gpio_chip |
Linux GPIO chip path, usually /dev/gpiochip0. |
pin |
BCM line offset of the button. 26 is physical pin 37, with GND on physical pin 39. |
active_low |
true for a button wired to GND with the internal pull-up: the line idles high and a press is detected on the falling edge. false mirrors this for a button wired to 3V3 with a pull-down (rising edge). |
bias |
Internal bias override: pull_up, pull_down, or disabled. Empty (default) derives the bias from active_low. |
debounce_ms |
Hardware debounce period applied by the kernel, in milliseconds. |
action |
Action to run on press. Currently only capture_tmp_reference. |
Occupied BCM lines (native switches) are 17, 22, 23, 27; pick a free
line such as 16, 20, 21, or 26 for the button. A failure to open the
line (missing chip, line already in use) is logged as a warning and never
aborts startup.
run
Runtime behavior and combo selection.
"run": {
"settling_ms": 0,
"idle_sleep_ms": 2,
"continuous": true,
"processing_live_config_path": "python_app/runtime/processing_live.json",
"locator_server": {},
"combos": [
{"input": 0, "output": 0}
]
}
Fields:
| Field | Meaning |
|---|---|
settling_ms |
Delay after switching before measuring. |
idle_sleep_ms |
Sleep between continuous collections. |
continuous |
true loops until stopped; false captures one collection and exits. |
processing_live_config_path |
Runtime path used by processing live settings. |
locator_server |
Embedded TCP server settings for publishing locator results. |
combos |
Zero-based switch combinations to acquire. |
combos entries use input/output switch positions:
{"input": 2, "output": 1}
For librevna_multi and sn9000, the model constraints force the canonical
virtual matrix:
input: 0..3
output: 0..1
run.locator_server
Settings for the embedded locator result TCP server.
| Field | Meaning |
|---|---|
device_id |
Device identifier in locator payloads. |
protocol_version |
Locator payload protocol version. |
host |
Bind host, commonly 0.0.0.0. |
port |
TCP port, commonly 8888. |
max_payload_bytes |
Maximum result payload size. |
client_queue_size |
Per-client queue size. |
logger_name |
Logger name used by the service. |
preprocess
Names or bundle paths for calibration/reference assets used by preprocessing.
"preprocess": {
"s21": {
"calibration": {"set_name": "", "bundle_path": ""},
"reference": {"set_name": "", "bundle_path": ""}
},
"s11": {
"calibration": {
"open": {"set_name": "", "bundle_path": ""},
"short": {"set_name": "", "bundle_path": ""},
"load": {"set_name": "", "bundle_path": ""}
},
"reference": {"set_name": "", "bundle_path": ""}
},
"notch": {
"enabled": true,
"bands_hz": [],
"taper_width_hz": 40000000.0,
"taper_type": "cosine"
}
}
set_name selects a stored set for the active radar key. bundle_path can
point to an exported bundle. Empty values mean no asset is selected.
notch.bands_hz is a list of [low_hz, high_hz] ranges. taper_type is
cosine or hard.
gpr
GPR geometry and processing configuration.
"gpr": {
"relative_permittivity": 1.0,
"tx_geometry": [
{"output_pos": 0, "x_m": 0.905}
],
"rx_geometry": [
{"input_pos": 0, "x_m": -0.18}
]
}
Fields:
| Field | Meaning |
|---|---|
relative_permittivity |
Medium relative permittivity used for propagation speed. |
tx_geometry |
Transmitter positions keyed by output switch position. |
rx_geometry |
Receiver positions keyed by input switch position. |
Geometry positions must match configured switch positions. For example, an
output_pos of 1 requires the output switch to have at least 2 positions.
rings
Shared-memory ring endpoints used by native processes.
"rings": {
"raw": {"name": "/radar_raw", "capacity": 50, "slot_size_bytes": 2097152},
"raw_tap": {"name": "/radar_raw_tap", "capacity": 50, "slot_size_bytes": 2097152},
"preprocessed": {"name": "/radar_preprocessed", "capacity": 50, "slot_size_bytes": 2097152},
"preprocessed_tap": {"name": "/radar_preprocessed_tap", "capacity": 50, "slot_size_bytes": 2097152},
"results": {"name": "/radar_results", "capacity": 50, "slot_size_bytes": 2097152}
}
Fields:
| Field | Meaning |
|---|---|
name |
POSIX shared-memory object name. |
capacity |
Number of slots. |
slot_size_bytes |
Maximum serialized payload size per slot. |
Use unique ring names for parallel tests to avoid collisions with a running GUI session.
Minimal Model Examples
Single LibreVNA:
"radar": {
"model": "librevna",
"serial": "",
"driver_mode": "native"
}
Multi-device LibreVNA:
"radar": {
"model": "librevna_multi",
"serial": "MASTER_SERIAL",
"driver_mode": "native",
"multi_device": {
"slave_serials": ["SLAVE_1", "SLAVE_2"],
"force_external_reference": true,
"recovery_attempts": 3
}
}
Compact-M K209 via remote server:
"radar": {
"model": "compact_m_k209",
"remote_host": "192.168.1.10",
"remote_port": 50209,
"driver_mode": "native"
}
SN9000 (PLANAR Иридиум) via SNVNA HiSLIP:
"radar": {
"model": "sn9000",
"remote_host": "192.168.1.10",
"remote_port": 4880,
"driver_mode": "native"
}
Kamil ADC:
"radar": {
"model": "kamil_adc",
"serial": "kamil_adc",
"driver_mode": "native",
"kamil_adc": {
"project_dir": "/home/europa/Documents/kamil_adc",
"executable_path": "/home/europa/Documents/kamil_adc/kamil_adc_capture",
"tty_path": "/tmp/ttyADC_data"
},
"laser_control": {
"enabled": true,
"port": "/dev/ttyUSB0",
"mode": "variation"
}
}