Update GPR and SAR3D processing

This commit is contained in:
Ayzen
2026-10-08 16:24:01 +03:00
parent 390015ec39
commit 3575ca68f5
67 changed files with 1187 additions and 2581 deletions
+46 -13
View File
@@ -66,9 +66,10 @@ controls, processing settings and a copy of the live plot through an embedded we
- **pass_through** — magnitude and phase of S21 for each combo.
- **bscan** — depth-versus-sweep B-scan heatmap.
- **gpr** — coherent back-projection GPR imaging with object detection.
- **legacy_gpr** — ellipse-intersection MIMO localization (point and extended/region modes).
- **sar3d** — 3D SAR of the reference notebook `Multi_antenna_3D_clean_v1.ipynb`
- **gpr** — coherent back-projection on the ground plane, as in `Horns_motion_4x4_ground.py`,
with object detection. Radar height and look angle define the slice in radar X/Z axes;
the wave speed is 3×10⁸ m/s (air).
- **sar3d** — 3D SAR of the reference notebook `Multi_antenna_demonstrate_depthnorm.ipynb`
on an NVIDIA GPU through CUDA: front (X-Y), side (Z-Y), top (X-Z)
and oblique maximum projections of the imaged
volume. Its settings carry the notebook's parameter names; the scene window is
@@ -77,6 +78,28 @@ controls, processing settings and a copy of the live plot through an embedded we
(default 2 cm). The radar motion is corrected from each trace's capture
timestamps, so the sweep timing needs no parameters.
Both coherent GPR and SAR apply `PAIR_DEPTH_EQUALIZE` (on by default) before the
per-pair median normalization. The notebook's 1.5 m sliding median estimates each
pair's depth-dependent level; positive gains bring the pairs to their geometric
mean while preserving phase and the common depth envelope. **Subtract mean of previous
collections** subtracts up to **Mean count** preceding spectra for each pair before
motion correction and the IFFT; zero count disables it. SAR uses a causal aperture:
`SAR_FRAME_RADIUS` previous frames plus the current frame, with the current scene origin.
The processor retains enough history for the aperture and each frame's preceding
mean; transport ring capacity does not shorten this background window.
Scene width `SAR_X_SIZE_M` and length `SAR_Z_SIZE_M` use 0 for the automatic notebook
bounds; positive values resize the axes about their automatic centres. `SAR_Y_RANGE_M`
sets the height limits. The depth gate remains independent of these scene bounds.
SAR **Zoom (%)** shows the full scene at 100%; increasing it shrinks all four
views uniformly towards the brightest response. **SAR_CLOUD_THRESHOLD** hides
values below the selected fraction of the normalization maximum. Both controls
redraw the existing result without recalculating it. Tx/Rx markers appear on the
front, side and top projections in ground coordinates. A hollow square marks the
peak; its size follows the contiguous half-maximum width along the volume axes
(FWHM, at least one voxel). This measures the imaged response rather than the
reflector's physical dimensions.
The desktop uses a light theme with dark plot canvases. **Mode** stays below the
**Actions** buttons while the settings sections scroll; the settings panel and
runtime log can be collapsed with their arrow buttons. SAR3D status, peak
@@ -88,8 +111,8 @@ first, then input, and wraps to the first recorded pair; it is enabled with at l
two pairs. Desktop and browser selectors redraw the cached B-scan immediately.
Tx/Rx antenna positions are edited in tables with switch position and X/Y/Z in
metres, on both the desktop and web interface. Coordinate and legacy-GPR medium
changes apply to the running processor and recompute its retained result. Profiles
metres, on both the desktop and web interface. Coordinate changes apply to the
running processor and recompute its retained result. Profiles
preserve all three coordinates. A new table row becomes active after X is entered;
desktop, web and profile geometry use one Python validator; C++ validates its own
input. GPR/SAR views wait for a result marked with the current settings revision,
@@ -431,6 +454,7 @@ backup to `radar_system`. Restart the service if it is normally used.
QT_QPA_PLATFORM=offscreen .venv/bin/python -m unittest discover -s python_app/tests
make check-native
make check-sar3d PYTHON=.venv/bin/python
make check-gpr
ASAN_OPTIONS=detect_leaks=0 make check-native NATIVE_SANITIZERS=address,undefined
```
@@ -441,24 +465,33 @@ also exercise mutated frames, ring concurrency, locator input and ADC whole-swee
Firmware host tests check cart timer rollover and SBUS packing; they do not validate
physical timing. Real devices, GPIO and the CUDA backend need their own hardware run.
`check-sar3d` runs the real CUDA processor (`data_acq_and_processing/tests/test_sar3d.py`).
`check-sar3d` runs the real CUDA processor (`data_acq_and_processing/tests/test_backprojection.py`).
It compares it with `sar3d_reference.npz`: compact float32/complex64 inputs, the three
maximum projections of the notebook's volume, and its joint peak/level for four
compensation/normalization and timing cases. The expected values come from unchanged
functions in cells 0 and 4 of the original notebook. The same test checks the published
maximum projections of the notebook's volume, its joint peak/level and response
widths for six compensation/normalization, equalization, background, scene and
timing cases. The expected values come from unchanged functions in cells 1 and 14
of the original notebook, with each frame's previous-collection mean subtracted
from its input spectra by NumPy. The same test checks the published
status for invalid input, a result too large for the ring slot, an empty and a very weak
signal. Without a usable GPU it checks only the CUDA warning and skips the rest; the
notebook itself is not needed to run it. To regenerate the reference, pass the
original notebook (it is kept outside the repository):
```bash
.venv/bin/python data_acq_and_processing/tests/generate_sar3d_reference.py \
--notebook /path/to/Multi_antenna_3D_clean_v1.ipynb
.venv/bin/python data_acq_and_processing/tests/generate_backprojection_reference.py \
--notebook /path/to/Multi_antenna_demonstrate_depthnorm.ipynb \
--gpr-script /path/to/Horns_motion_4x4_ground.py
```
The archive records cell-source SHA256 hashes and NumPy/SciPy versions. Another build
The generator also writes `gpr_reference.npz` from the unchanged Horns coherent BP
functions, with the notebook equalizer inserted before scalar normalization.
`make check-gpr` compares the CPU processor with those images, including motion and
previous-collection subtraction. Neither source file is needed to run the tests.
The archives record source SHA256 hashes and NumPy/SciPy versions. Another build
can be checked with `make check-sar3d BUILD_DIR=/path/to/build` or by running
`test_sar3d.py` with `SAR3D_FIXTURE=/path/to/build/native_tests/sar3d_fixture`.
`test_backprojection.py Sar3dTest` with
`BACKPROJECTION_FIXTURE=/path/to/build/native_tests/backprojection_fixture`.
For older GPUs, pass the same `BUILD_DIR` and NVRTC 12 `CUDA_ROOTS` used to build.
For development, install `pyright` into the venv, then run