Rename kamil_adc to rph_radar and fix its data path

This commit is contained in:
Ayzen
2026-10-06 18:15:18 +03:00
parent aef549ea76
commit a185e61495
94 changed files with 2851 additions and 9485 deletions
+38 -218
View File
@@ -2,6 +2,7 @@
from __future__ import annotations
from dataclasses import asdict
import logging
from typing import Any
@@ -105,8 +106,10 @@ def run_config_from_dict(payload: object) -> RunConfigModel:
run_payload.get("locator_server", run_payload.get("locator")),
"run.locator_server",
)
if radar_payload.get("model") == "kamil_adc":
raise ValueError("radar.model kamil_adc was renamed: use rph_radar and move radar.kamil_adc to radar.rph_radar")
multi_device_payload = _as_dict(radar_payload.get("multi_device"), "radar.multi_device")
kamil_adc_payload = _as_dict(radar_payload.get("kamil_adc"), "radar.kamil_adc")
rph_radar_payload = _as_dict(radar_payload.get("rph_radar"), "radar.rph_radar")
laser_control_payload = _as_dict(radar_payload.get("laser_control"), "radar.laser_control")
model.radar.model = _read_str(radar_payload, "model", model.radar.model)
@@ -162,36 +165,36 @@ def run_config_from_dict(payload: object) -> RunConfigModel:
"stimulus_switch_positions",
model.radar.multi_device.stimulus_switch_positions,
)
model.radar.kamil_adc.project_dir = _read_str(
kamil_adc_payload, "project_dir", model.radar.kamil_adc.project_dir
model.radar.rph_radar.project_dir = _read_str(
rph_radar_payload, "project_dir", model.radar.rph_radar.project_dir
)
model.radar.kamil_adc.executable_path = _read_str(
kamil_adc_payload, "executable_path", model.radar.kamil_adc.executable_path
model.radar.rph_radar.executable_path = _read_str(
rph_radar_payload, "executable_path", model.radar.rph_radar.executable_path
)
model.radar.kamil_adc.tty_path = _read_str(
kamil_adc_payload, "tty_path", model.radar.kamil_adc.tty_path
model.radar.rph_radar.tty_path = _read_str(
rph_radar_payload, "tty_path", model.radar.rph_radar.tty_path
)
model.radar.kamil_adc.args = _load_string_list(kamil_adc_payload, "args", "radar.kamil_adc")
model.radar.kamil_adc.env = _load_string_dict(kamil_adc_payload, "env", "radar.kamil_adc")
model.radar.kamil_adc.startup_timeout_s = _read_float(
kamil_adc_payload, "startup_timeout_s", model.radar.kamil_adc.startup_timeout_s
model.radar.rph_radar.args = _load_string_list(rph_radar_payload, "args", "radar.rph_radar")
model.radar.rph_radar.env = _load_string_dict(rph_radar_payload, "env", "radar.rph_radar")
model.radar.rph_radar.startup_timeout_s = _read_float(
rph_radar_payload, "startup_timeout_s", model.radar.rph_radar.startup_timeout_s
)
model.radar.kamil_adc.sweep_timeout_s = _read_float(
kamil_adc_payload, "sweep_timeout_s", model.radar.kamil_adc.sweep_timeout_s
model.radar.rph_radar.sweep_timeout_s = _read_float(
rph_radar_payload, "sweep_timeout_s", model.radar.rph_radar.sweep_timeout_s
)
model.radar.kamil_adc.stop_timeout_s = _read_float(
kamil_adc_payload, "stop_timeout_s", model.radar.kamil_adc.stop_timeout_s
model.radar.rph_radar.stop_timeout_s = _read_float(
rph_radar_payload, "stop_timeout_s", model.radar.rph_radar.stop_timeout_s
)
phase_calibration_payload = _as_dict(
kamil_adc_payload.get("phase_calibration"), "radar.kamil_adc.phase_calibration"
rph_radar_payload.get("phase_calibration"), "radar.rph_radar.phase_calibration"
)
calibration = model.radar.kamil_adc.phase_calibration
calibration = model.radar.rph_radar.phase_calibration
calibration.phase0_rad = _read_float(phase_calibration_payload, "phase0_rad", calibration.phase0_rad)
calibration.freq0_hz = _read_float(phase_calibration_payload, "freq0_hz", calibration.freq0_hz)
calibration.phase1_rad = _read_float(phase_calibration_payload, "phase1_rad", calibration.phase1_rad)
calibration.freq1_hz = _read_float(phase_calibration_payload, "freq1_hz", calibration.freq1_hz)
band_payload = _as_dict(kamil_adc_payload.get("band"), "radar.kamil_adc.band")
band = model.radar.kamil_adc.band
band_payload = _as_dict(rph_radar_payload.get("band"), "radar.rph_radar.band")
band = model.radar.rph_radar.band
band.start_hz = _read_float(band_payload, "start_hz", band.start_hz)
band.stop_hz = _read_float(band_payload, "stop_hz", band.stop_hz)
band.points = _read_int(band_payload, "points", band.points)
@@ -274,11 +277,6 @@ def run_config_from_dict(payload: object) -> RunConfigModel:
model.radar.laser_control.variation.delay_time = _read_int(
laser_variation_payload, "delay_time", model.radar.laser_control.variation.delay_time
)
model.radar.laser_control.variation.temp_tolerance_c = _read_float(
laser_variation_payload,
"temp_tolerance_c",
model.radar.laser_control.variation.temp_tolerance_c,
)
load_switch_payload(port1_payload, model.output_switch)
load_switch_payload(port2_payload, model.input_switch)
@@ -410,200 +408,22 @@ def run_config_from_dict(payload: object) -> RunConfigModel:
def run_config_to_dict(model: RunConfigModel) -> dict[str, Any]:
"""Encode :class:`RunConfigModel` to C++ pipeline-compatible JSON structure."""
"""Encode the model, spelling only fields whose wire names differ."""
model.ensure_combos()
sweep_payload = {
"start_hz": model.radar.sweep.start_hz,
"stop_hz": model.radar.sweep.stop_hz,
"if_bandwidth_hz": model.radar.sweep.if_bandwidth_hz,
"stimulus_power_dbm": model.radar.sweep.power_dbm,
"dwell_us": model.radar.sweep.dwell_us,
}
if not model.is_kamil_adc:
sweep_payload["points"] = model.radar.sweep.points
radar = asdict(model.radar)
sweep = radar["sweep"]
sweep["stimulus_power_dbm"] = sweep.pop("power_dbm")
if model.is_rph_radar:
sweep.pop("points")
preprocess = asdict(model.preprocess)
preprocess["notch"]["bands_hz"] = [list(band) for band in model.preprocess.notch.bands_hz]
return {
"radar": {
"model": model.radar.model,
"serial": model.radar.serial,
"driver_mode": model.radar.driver_mode,
"multi_device": {
"slave_serials": list(model.radar.multi_device.slave_serials),
"force_external_reference": model.radar.multi_device.force_external_reference,
"recovery_attempts": model.radar.multi_device.recovery_attempts,
"output_switch_positions": model.radar.multi_device.output_switch_positions,
"input_switch_positions": model.radar.multi_device.input_switch_positions,
"stimulus_switch_positions": model.radar.multi_device.stimulus_switch_positions
},
"kamil_adc": {
"project_dir": model.radar.kamil_adc.project_dir,
"executable_path": model.radar.kamil_adc.executable_path,
"tty_path": model.radar.kamil_adc.tty_path,
"args": list(model.radar.kamil_adc.args),
"env": dict(model.radar.kamil_adc.env),
"startup_timeout_s": model.radar.kamil_adc.startup_timeout_s,
"sweep_timeout_s": model.radar.kamil_adc.sweep_timeout_s,
"stop_timeout_s": model.radar.kamil_adc.stop_timeout_s,
"phase_calibration": {
"phase0_rad": model.radar.kamil_adc.phase_calibration.phase0_rad,
"freq0_hz": model.radar.kamil_adc.phase_calibration.freq0_hz,
"phase1_rad": model.radar.kamil_adc.phase_calibration.phase1_rad,
"freq1_hz": model.radar.kamil_adc.phase_calibration.freq1_hz,
},
"band": {
"start_hz": model.radar.kamil_adc.band.start_hz,
"stop_hz": model.radar.kamil_adc.band.stop_hz,
"points": model.radar.kamil_adc.band.points,
},
},
"laser_control": {
"enabled": model.radar.laser_control.enabled,
"port": model.radar.laser_control.port,
"mode": model.radar.laser_control.mode,
"pi_coeff1_p": model.radar.laser_control.pi_coeff1_p,
"pi_coeff1_i": model.radar.laser_control.pi_coeff1_i,
"pi_coeff2_p": model.radar.laser_control.pi_coeff2_p,
"pi_coeff2_i": model.radar.laser_control.pi_coeff2_i,
"manual": {
"temp1": model.radar.laser_control.manual.temp1,
"temp2": model.radar.laser_control.manual.temp2,
"current1": model.radar.laser_control.manual.current1,
"current2": model.radar.laser_control.manual.current2,
},
"variation": {
"variation_type": model.radar.laser_control.variation.variation_type,
"static_temp1": model.radar.laser_control.variation.static_temp1,
"static_temp2": model.radar.laser_control.variation.static_temp2,
"static_current1": model.radar.laser_control.variation.static_current1,
"static_current2": model.radar.laser_control.variation.static_current2,
"min_value": model.radar.laser_control.variation.min_value,
"max_value": model.radar.laser_control.variation.max_value,
"step": model.radar.laser_control.variation.step,
"time_step": model.radar.laser_control.variation.time_step,
"delay_time": model.radar.laser_control.variation.delay_time,
"temp_tolerance_c": model.radar.laser_control.variation.temp_tolerance_c,
},
},
"sweep": sweep_payload,
},
"switches": {
"port1": {
"name": model.output_switch.name,
"driver_mode": model.output_switch.driver_mode,
"radar_port": model.output_switch.radar_port,
"positions": model.output_switch.positions,
"default_position": model.output_switch.default_position,
"gpio_chip": model.output_switch.gpio_chip,
"pin_a": model.output_switch.pin_a,
"pin_b": model.output_switch.pin_b,
},
"port2": {
"name": model.input_switch.name,
"driver_mode": model.input_switch.driver_mode,
"radar_port": model.input_switch.radar_port,
"positions": model.input_switch.positions,
"default_position": model.input_switch.default_position,
"gpio_chip": model.input_switch.gpio_chip,
"pin_a": model.input_switch.pin_a,
"pin_b": model.input_switch.pin_b,
},
},
"control_button": {
"enabled": model.control_button.enabled,
"gpio_chip": model.control_button.gpio_chip,
"pin": model.control_button.pin,
"active_low": model.control_button.active_low,
"bias": model.control_button.bias,
"debounce_ms": model.control_button.debounce_ms,
"action": model.control_button.action,
},
"logging": {
"level": model.logging.level,
},
"run": {
"settling_ms": model.runtime.settling_ms,
"idle_sleep_ms": model.runtime.idle_sleep_ms,
"continuous": model.runtime.continuous,
"processing_live_config_path": model.runtime.processing_live_config_path,
"locator_server": {
"device_id": model.runtime.locator_server.device_id,
"protocol_version": model.runtime.locator_server.protocol_version,
"host": model.runtime.locator_server.host,
"port": model.runtime.locator_server.port,
"max_payload_bytes": model.runtime.locator_server.max_payload_bytes,
"client_queue_size": model.runtime.locator_server.client_queue_size,
"logger_name": model.runtime.locator_server.logger_name,
},
"combos": [{"input": combo.input, "output": combo.output} for combo in model.combos],
},
"preprocess": {
"s21": {
"calibration": {
"set_name": model.preprocess.s21.calibration.set_name,
"bundle_path": model.preprocess.s21.calibration.bundle_path,
},
"reference": {
"set_name": model.preprocess.s21.reference.set_name,
"bundle_path": model.preprocess.s21.reference.bundle_path,
},
"object_calibration": {
"set_name": model.preprocess.s21.object_calibration.set_name,
"bundle_path": model.preprocess.s21.object_calibration.bundle_path,
},
},
"notch": {
"enabled": model.preprocess.notch.enabled,
"bands_hz": [[low_hz, high_hz] for low_hz, high_hz in model.preprocess.notch.bands_hz],
"taper_width_hz": model.preprocess.notch.taper_width_hz,
"taper_type": model.preprocess.notch.taper_type,
},
},
"gpr": {
"relative_permittivity": model.gpr.relative_permittivity,
"tx_geometry": [
{
"output_pos": entry.output_pos,
"x_m": entry.x_m,
"y_m": entry.y_m,
"z_m": entry.z_m,
}
for entry in model.gpr.tx_geometry
],
"rx_geometry": [
{
"input_pos": entry.input_pos,
"x_m": entry.x_m,
"y_m": entry.y_m,
"z_m": entry.z_m,
}
for entry in model.gpr.rx_geometry
],
},
"rings": {
"raw": {
"name": model.rings.raw.name,
"capacity": model.rings.raw.capacity,
"slot_size_bytes": model.rings.raw.slot_size_bytes,
},
"raw_tap": {
"name": model.rings.raw_tap.name,
"capacity": model.rings.raw_tap.capacity,
"slot_size_bytes": model.rings.raw_tap.slot_size_bytes,
},
"preprocessed": {
"name": model.rings.preprocessed.name,
"capacity": model.rings.preprocessed.capacity,
"slot_size_bytes": model.rings.preprocessed.slot_size_bytes,
},
"preprocessed_tap": {
"name": model.rings.preprocessed_tap.name,
"capacity": model.rings.preprocessed_tap.capacity,
"slot_size_bytes": model.rings.preprocessed_tap.slot_size_bytes,
},
"results": {
"name": model.rings.results.name,
"capacity": model.rings.results.capacity,
"slot_size_bytes": model.rings.results.slot_size_bytes,
},
},
"radar": radar,
"switches": {"port1": asdict(model.output_switch), "port2": asdict(model.input_switch)},
"control_button": asdict(model.control_button),
"logging": asdict(model.logging),
"run": {**asdict(model.runtime), "combos": [asdict(combo) for combo in model.combos]},
"preprocess": preprocess,
"gpr": asdict(model.gpr),
"rings": asdict(model.rings),
}