161 lines
12 KiB
Markdown
161 lines
12 KiB
Markdown
# Разработка
|
||
|
||
## Сборка
|
||
|
||
C++ собирается командой `make` из корня проекта; Eigen и nlohmann/json лежат в
|
||
`data_acq_and_processing/third_party/`, других внешних библиотек нет.
|
||
|
||
| Цель | Что собирает или делает |
|
||
| --- | --- |
|
||
| `all` (по умолчанию) | `build/bin/data_preprocessor`, `build/bin/data_processor` |
|
||
| `rph_radar_collector` | `build/bin/rph_radar_collector`; в `all` не входит |
|
||
| `check-native` | тесты C++: кадры, кольца, конфигурация, наборы, режекторный фильтр, локатор, псевдотерминал коллектора (на поддельной библиотеке L-Card) |
|
||
| `check-sar3d` | 3D SAR на настоящем CUDA-бэкенде против эталона |
|
||
| `check-gpr` | GPR на CPU, без видеокарты, против эталона |
|
||
| `clean` | удаляет каталог сборки |
|
||
|
||
| Переменная | По умолчанию | Что задаёт |
|
||
| --- | --- | --- |
|
||
| `BUILD_DIR` | `build` | каталог сборки. Программа запускает процессы только из `build/bin/`, другой каталог нужен для проверок |
|
||
| `CUDA_ROOTS` | пакеты `nvidia/*` в `.venv` и `/usr/local/cuda` | где искать `nvrtc.h`, `cuda.h`, `libnvrtc` |
|
||
| `PYTHON` | `.venv/bin/python` | интерпретатор для `check-sar3d` и `check-gpr` |
|
||
| `NATIVE_SANITIZERS` | не задана | санитайзеры для тестов C++, например `address,undefined` |
|
||
| `CXX`, `CXXFLAGS`, `LDFLAGS` | `g++`, `-std=c++20 -O2 …`, `-pthread -lrt` | компилятор и флаги |
|
||
|
||
`BUILD_DIR`, `CUDA_ROOTS`, `CXX`, `CXXFLAGS` и `LDFLAGS` задаются в командной строке
|
||
`make`, а не через окружение; `PYTHON` и `NATIVE_SANITIZERS` можно задать и переменной
|
||
окружения. `CXXFLAGS` в командной строке заменяет весь набор флагов, вместе с
|
||
`-std=c++20` и отслеживанием зависимостей `-MMD -MP`. `make` сам пересобирает нужное, если
|
||
изменились найденная CUDA или
|
||
санитайзеры. Сборка с CUDA и без неё описана в главе [Установка и запуск](installation.md).
|
||
|
||
## Тесты
|
||
|
||
```sh
|
||
QT_QPA_PLATFORM=offscreen .venv/bin/python -m unittest discover -s python_app/tests
|
||
make check-native
|
||
ASAN_OPTIONS=detect_leaks=0 make check-native NATIVE_SANITIZERS=address,undefined
|
||
make check-sar3d
|
||
make check-gpr
|
||
```
|
||
|
||
| Набор | Что нужно |
|
||
| --- | --- |
|
||
| Python, `python_app/tests` | `.venv` с пакетами, `QT_QPA_PLATFORM=offscreen` (дисплея у тестов нет), запись в `/dev/shm`, псевдотерминалы, UDP на loopback. Железо не нужно |
|
||
| C++, `make check-native` | g++ с C++20 |
|
||
| 3D SAR, `make check-sar3d` | сборка с CUDA и пригодная видеокарта; без неё проверяются только предупреждение и правила рамок, остальное пропускается |
|
||
| GPR, `make check-gpr` | numpy |
|
||
|
||
Особые случаи:
|
||
|
||
- `test_processor_history` запускает настоящий `build/bin/data_processor` и
|
||
пропускается, если он не собран.
|
||
- Тесты окна строят настоящее окно на временном профиле из
|
||
`run_config_examples/run_config_simulator.example.json` и не зависят от корневого
|
||
`run_config.json` (`python_app/tests/gui_test_support.py`).
|
||
- `test_deploy_scripts` гоняет `deploy/update.sh` во временном каталоге с заглушками
|
||
`systemctl` и `make`.
|
||
- `test_cart_firmware` компилирует прошивку тележки на компьютере и пропускается без
|
||
g++.
|
||
- `data_acq_and_processing/tests/test_backprojection.py` в общий прогон не входит:
|
||
его запускают `make check-sar3d` и `make check-gpr`.
|
||
- `test_documentation` проверяет документацию: `docs/configuration.md` называет каждый
|
||
ключ профиля и `processing_live.json`, главы называют каждую подпись окна и диалогов
|
||
(жирным, кодом или заголовком), а относительные ссылки ведут на существующие файлы.
|
||
Новый ключ или кнопка без описания роняет этот тест.
|
||
|
||
> **Внимание.** Не запускайте тесты от root: созданные ими кольца в `/dev/shm`
|
||
> станут принадлежать root, и программа от обычного пользователя получит отказ в
|
||
> доступе.
|
||
|
||
Проверка на старой видеокарте (NVRTC 13 не компилирует под карты старее sm_75):
|
||
|
||
```sh
|
||
make check-sar3d BUILD_DIR=/tmp/radar_build_nvrtc12 CUDA_ROOTS="$HOME/.cache/radar_nvrtc12/nvidia/cuda_nvrtc $HOME/.cache/radar_nvrtc12/nvidia/cuda_runtime"
|
||
```
|
||
|
||
## Эталоны 3D SAR и GPR
|
||
|
||
`data_acq_and_processing/tests/sar3d_reference.npz` и `gpr_reference.npz` строит
|
||
генератор, который выполняет неизменённые функции ноутбука
|
||
`Multi_depthnorm_clean.ipynb` (ячейки 1 и 5) и скрипта `Horns_motion_4x4_ground.py` с
|
||
заменёнными параметрами. В эталоне 3D SAR десять случаев: шесть объёмов (ширина
|
||
отклика, вычитание среднего предыдущих коллекций для каждого кадра апертуры,
|
||
отношение к фону) и четыре сцены точечных отражателей в шуме для CLEAN с объектами и
|
||
рамками. Правила рамок проверяются по одному на синтетических объектах. Архивы
|
||
записывают хеши SHA-256 исходников и версии NumPy и SciPy.
|
||
|
||
Перегенерировать эталоны нужно только при правке алгоритма; ноутбук и скрипт
|
||
хранятся вне репозитория:
|
||
|
||
```sh
|
||
.venv/bin/python data_acq_and_processing/tests/generate_backprojection_reference.py \
|
||
--notebook /путь/к/Multi_depthnorm_clean.ipynb \
|
||
--gpr-script /путь/к/Horns_motion_4x4_ground.py
|
||
```
|
||
|
||
Другую сборку можно проверить так: `make check-sar3d BUILD_DIR=/путь/к/сборке` или
|
||
`BACKPROJECTION_FIXTURE=/путь/к/сборке/native_tests/backprojection_fixture` при запуске
|
||
`test_backprojection.py Sar3dTest`.
|
||
|
||
## Утилиты
|
||
|
||
| Команда | Что делает |
|
||
| --- | --- |
|
||
| `.venv/bin/python -m python_app.scripts.rph_radar_calibrate --config <профиль> --sweeps 200 [--warmup 10] [--apply]` | фазовая калибровка радиофотонного радара (глава [Оборудование](hardware.md)) |
|
||
| `.venv/bin/python -m python_app.scripts.per_point_switching_check --config <профиль> [--collections 3] [--switch-connected]` | проверка переключения стимула на железе; выход 0 — норма, 1 — сбой |
|
||
| `./start.sh --producer-only --profile <профиль>` | только процесс сбора с выводом в терминал — для отладки железа |
|
||
|
||
## Правила кода
|
||
|
||
- Обязателен только функциональный контракт: программа в правильном порядке
|
||
собирает коллекции, предобрабатывает, обрабатывает и показывает результат в окне и в
|
||
вебе, даёт выбрать настройки предобработки и выполнить действия пользователя.
|
||
Внутреннее устройство можно менять под этот контракт.
|
||
- Код — читаемый и без лишнего: понятные имена, без мёртвых опций и «умных» трюков.
|
||
- Наименьшая версия Python — 3.10 (код использует `dataclass(slots=True)` и `match`).
|
||
- `.venv/bin/pyright python_app` — 0 ошибок, без подавлений и расширения исключений
|
||
(режим `basic`).
|
||
- Нумерацию антенн и портов задаёт профиль: она уточняется по железу, менять её
|
||
самостоятельно нельзя.
|
||
- Корневой `run_config.json` остаётся профилем симулятора.
|
||
- Изменив поведение, исправьте документацию в том же изменении (таблица «Где что
|
||
править» в главе [Устройство программы](architecture.md)); полноту ключей и подписей
|
||
проверяет `test_documentation`. Документ описывает, как устроено сейчас; числа
|
||
перепроверяются по коду.
|
||
|
||
## Прошивки
|
||
|
||
> **Внимание.** `top_master.bin` и `combined.vnafw` — единственные копии рабочего
|
||
> битстрима мастера и рабочего образа; битстрим заново не воспроизводится. Не
|
||
> перезаписывайте их, новые сборки кладите под новыми именами.
|
||
|
||
- VHDL — только ASCII: любой другой символ, даже длинное тире в комментарии, ломает
|
||
GHDL (`invalid character, even in a comment`).
|
||
- В `VNA.xise` закреплено `Starting Placer Cost Table (1-100) Map spartan6 = 2`; не
|
||
сбрасывайте его в 1: ограничение `MCU_MOSI OFFSET hold` и в стоковой прошивке
|
||
проходит с запасом всего +0,458 нс.
|
||
- После правки FPGA прогоните тестбенч и мутационный тест — внесите ошибку и
|
||
убедитесь, что тестбенч падает:
|
||
|
||
```sh
|
||
ghdl -a --std=93 Sweep.vhd Test_Sweep.vhd && ghdl -r --std=93 Test_Sweep --assert-level=error
|
||
```
|
||
|
||
- Изменение объёма логики FPGA сравнивайте по Timing Score с контрольной сборкой
|
||
стоковой прошивки.
|
||
|
||
Порядок сборки прошивок —
|
||
[reproduce/README.md](../device_firmware/multi_libreVNA_firmware/reproduce/README.md).
|
||
|
||
## Git
|
||
|
||
- Основная ветка — `main`.
|
||
- Правила `build*` и `build/` в корневом `.gitignore` скрывают и файлы комплекта сборки
|
||
прошивок (в том числе `build.sh` и эталонные бинарники STM32); для них добавлены
|
||
исключения, а часть файлов скрывает ещё и вложенный `.gitignore` LibreVNA. Добавляя
|
||
файлы в `device_firmware/`, проверяйте `git status --ignored` и при необходимости
|
||
`git add -f`.
|
||
- В репозиторий не входят: `.venv`, `build/`, `python_app/data*`, `python_app/runtime`,
|
||
ноутбуки `*.ipynb`, локальные инструменты разработчиков.
|