projector version

This commit is contained in:
awe
2026-09-15 19:06:05 +03:00
parent 62c0266a6b
commit b3339d101c
33 changed files with 2605 additions and 51 deletions
@@ -72,6 +72,21 @@ class ProcessingLiveConfig:
gpr_visible_x_max_m: float = 2.0
gpr_visible_z_min_m: float = 0.0
gpr_visible_z_max_m: float = 14.0
# 3D SAR (sar3d processor) parameters; defaults mirror VNA_AlGo gpr_core.
# The frequency band, depth gate, antenna selection and motion parameters
# are shared with the gpr_* fields above.
sar3d_frame_radius: int = 6
sar3d_edge_frame_weight: float = 0.75
sar3d_pitch_deg: float = 6.0
sar3d_center_depth_m: float = 5.6
sar3d_half_width_x_m: float = 1.8
sar3d_half_width_y_m: float = 1.0
sar3d_half_width_z_m: float = 1.8
sar3d_grid_nx: int = 150
sar3d_grid_ny: int = 120
sar3d_grid_nz: int = 160
sar3d_use_compensation: bool = True
sar3d_normalize_pairs: bool = True
# When true, the C++ data_processor ignores socket-supplied vlc updates
# and keeps using `gpr_speed_m_s` from this file.
ignore_socket_speed: bool = False
@@ -136,6 +151,18 @@ class ProcessingLiveConfig:
"gpr_visible_x_max_m": float(self.gpr_visible_x_max_m),
"gpr_visible_z_min_m": float(self.gpr_visible_z_min_m),
"gpr_visible_z_max_m": float(self.gpr_visible_z_max_m),
"sar3d_frame_radius": int(self.sar3d_frame_radius),
"sar3d_edge_frame_weight": float(self.sar3d_edge_frame_weight),
"sar3d_pitch_deg": float(self.sar3d_pitch_deg),
"sar3d_center_depth_m": float(self.sar3d_center_depth_m),
"sar3d_half_width_x_m": float(self.sar3d_half_width_x_m),
"sar3d_half_width_y_m": float(self.sar3d_half_width_y_m),
"sar3d_half_width_z_m": float(self.sar3d_half_width_z_m),
"sar3d_grid_nx": int(self.sar3d_grid_nx),
"sar3d_grid_ny": int(self.sar3d_grid_ny),
"sar3d_grid_nz": int(self.sar3d_grid_nz),
"sar3d_use_compensation": bool(self.sar3d_use_compensation),
"sar3d_normalize_pairs": bool(self.sar3d_normalize_pairs),
"ignore_socket_speed": bool(self.ignore_socket_speed),
"reprocess_current_result": bool(self.reprocess_current_result),
"history_command_seq": int(self.history_command_seq),
@@ -283,6 +283,19 @@ class ProcessSupervisor:
def _acquisition_command(self, config_path: Path) -> list[str]:
"""Return acquisition producer command selected by radar.model."""
# A configured replay dataset overrides the model's normal producer:
# recorded snapshots are replayed into the raw ring instead of
# acquiring from (mock) hardware.
replay_dir = self._read_replay_dataset_dir(config_path)
if replay_dir:
logger.debug("Selecting replay producer for dataset_dir=%s", replay_dir)
return [
sys.executable,
"-m",
"python_app.scripts.replay_raw_producer",
"--config",
str(config_path),
]
radar_model = self._read_radar_model(config_path)
logger.debug("Selecting acquisition producer for radar.model=%s", radar_model)
if radar_model in {"librevna_multi", "sn9000"}:
@@ -318,6 +331,20 @@ class ProcessSupervisor:
return "librevna"
return str(radar_payload.get("model", "librevna"))
@staticmethod
def _read_replay_dataset_dir(config_path: Path) -> str:
"""Read `radar.replay.dataset_dir` cheaply, '' when replay is off."""
payload = json.loads(config_path.read_text(encoding="utf-8"))
if not isinstance(payload, dict):
return ""
radar_payload = payload.get("radar")
if not isinstance(radar_payload, dict):
return ""
replay_payload = radar_payload.get("replay")
if not isinstance(replay_payload, dict):
return ""
return str(replay_payload.get("dataset_dir", "")).strip()
def _stop_processes(self, names: Iterable[str]) -> None:
"""Gracefully terminate processes, then force-kill on per-process timeout."""
ordered_names = list(names)
@@ -591,6 +618,7 @@ class ProcessSupervisor:
"build/bin/sweep_orchestrator",
"python_app.scripts.matrix_raw_producer",
"python_app.scripts.kamil_adc_raw_producer",
"python_app.scripts.replay_raw_producer",
)
try:
raw = (Path("/proc") / str(pid) / "cmdline").read_bytes()