added docs

This commit is contained in:
Ayzen
2026-10-16 18:35:02 +03:00
parent b88d704126
commit ad2b3e555a
19 changed files with 3719 additions and 663 deletions
+238
View File
@@ -0,0 +1,238 @@
# Установка и запуск
Программа работает в Linux: на рабочей станции с экраном и на Raspberry Pi 5 без
оператора. Python-часть ставится в виртуальное окружение `.venv` внутри каталога
проекта, C++-часть собирается командой `make` в `build/bin/`.
## Что нужно
| Что | Зачем |
| --- | --- |
| Linux, bash, coreutils, `flock` | запуск через `start.sh` |
| Python 3.10 или новее с модулем `venv` | программа и окружение |
| компилятор C++20 (g++), `make` | процессы конвейера |
| библиотеки `libusb-1.0` и `libatomic.so.1` | USB-доступ к LibreVNA и кольца разделяемой памяти |
| `libxcb-cursor0`, `libxkbcommon-x11-0` (Debian/Ubuntu) | окно Qt на рабочем столе |
| видеокарта NVIDIA с драйвером, NVRTC и заголовки CUDA | только для режима 3D SAR |
| библиотеки L-Card `libx502api.so`, `libe502api.so` | только для радиофотонного радара с АЦП E-502 |
Python-пакеты перечислены в `requirements.txt`:
| Пакет | Для чего |
| --- | --- |
| `numpy` | массивы данных |
| `scipy` | оптимизация в калибровке по объекту |
| `libusb1` | USB-драйвер LibreVNA |
| `pyserial` | последовательный порт платы лазеров |
| `PyQt6` | окно программы (без экрана — тоже, в режиме `offscreen`) |
| `pyqtgraph` | графики |
| `fastapi`, `uvicorn[standard]` | веб-интерфейс |
| `nvidia-cuda-nvrtc`, `nvidia-cuda-runtime` | NVRTC и заголовки CUDA для 3D SAR; ставятся только на x86_64 |
PyQt6 ставится только из готовых сборок (wheel), поэтому pip выбирает самую новую
версию, которая работает с системной glibc.
## Установка
Из каталога проекта:
```sh
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -r requirements.txt
make # build/bin/data_preprocessor и build/bin/data_processor
make rph_radar_collector # только для радиофотонного радара с АЦП E-502
```
`./start.sh` при обычном запуске делает это сам: создаёт `.venv`, если его нет, ставит
недостающие пакеты, ставит системные библиотеки через менеджер пакетов (apt, dnf, yum,
pacman, zypper или brew, через `sudo`), правило udev для LibreVNA и собирает C++. Без
экрана (`--headless`) он ничего не ставит: всё должно быть установлено заранее.
## Запуск
```sh
./start.sh --profile run_config_examples/run_config_librevna_multi_per_point.example.json
```
Без `--profile` программа берёт последний использованный профиль, а если его нет —
корневой `run_config.json` (симулятор). Порядок выбора профиля — в главе
[Файл конфигурации](configuration.md). Но сам `start.sh` без `--profile` определяет
модель радара, решает, собирать ли коллектор E-502, и проверяет программы по
корневому `run_config.json`, а `--producer-only` берёт именно его. Поэтому с профилем
радиофотонного радара и для `--producer-only` всегда указывайте `--profile`.
| Ключ `start.sh` | Что делает |
| --- | --- |
| `--profile ПУТЬ` | профиль для запуска; файл должен существовать. Относительный путь — от каталога проекта |
| `--headless` | без окна: окно не показывается, через 0,5 с выполняется **Apply Radar**, ещё через 1 с — **Start**; если **Start** не удался, программа завершается с кодом 1 (`Headless auto-start did not bring the pipeline up`). Ничего не устанавливает |
| `--auto-start` | с окном, но **Start** выполняется сам через 0,5 с после запуска |
| `--producer-only` | запустить только процесс сбора для профиля, без окна; вывод — в терминал |
| `--skip-build` | не собирать C++ (наличие программ всё равно проверяется) |
| `--build-only` | подготовить окружение, собрать и выйти |
| `--clean-shm` | удалить известные кольца в `/dev/shm` перед запуском (глава [Данные на диске](data.md)) |
| `-h`, `--help` | справка |
Порядок работы `start.sh`: проверка окружения → определение модели радара по профилю
→ системные библиотеки и правило udev (не для `--headless`) → Python-пакеты → сборка
C++ (для радиофотонного радара — и коллектора) → проверка программ в `build/bin/` →
остановка службы `radar.service`, если она работает → блокировка
`/tmp/radar_system.lock` → запуск программы. Если блокировку держит другой
экземпляр, `start.sh` завершается с
`Another radar instance already holds /tmp/radar_system.lock; aborting.`
Для разработки окно можно запустить и напрямую:
`.venv/bin/python -m python_app.gui.main`. Тогда нет ни сборки, ни блокировки.
### Первый запуск без железа
1. Запустите `./start.sh` (корневой профиль — симулятор).
2. Нажмите **Preprocessing…**, затем **Create Neutral S21 Sets**: предобработке
нужны наборы калибровки и референса, нейтральные данные не меняют.
3. Нажмите **Start**. Симулятор показывает точечный отражатель, который движется
по сцене; режим обработки меняется списком **Mode**.
Режим 3D SAR без видеокарты NVIDIA показывает только предупреждение.
### Первый запуск с железом
1. Скопируйте нужный профиль из `run_config_examples/` и проверьте в нём серийные
номера, порты, линии GPIO и геометрию антенн (глава
[Файл конфигурации](configuration.md)).
2. Запустите `./start.sh --profile <профиль>`. При первом запуске он может спросить
пароль `sudo`, чтобы поставить системные библиотеки и правило udev для LibreVNA.
3. Нажмите **Apply Radar**, снимите калибровку и референс (глава
[Калибровка и предобработка](preprocessing.md)) и нажмите **Start**.
4. Нажмите **Save Config…**: выбор наборов и правки в окне сохраняются только так.
Порядок работы по шагам — в главе [Типовые сценарии](workflow.md).
## Видеокарта для 3D SAR
Ядра 3D SAR компилируются при запуске библиотекой NVRTC под установленную карту.
`make` ищет `nvrtc.h`, `cuda.h` и `libnvrtc` в пакетах `nvidia-cuda-*` из `.venv` и в
`/usr/local/cuda`, а `libcuda.so.1` (драйвер) — в системных каталогах. Если чего-то
нет, `make` пишет `note: CUDA not found, selecting sar3d will show a warning` и
собирает процессор без 3D SAR. После установки CUDA снова запустите `make`: он
заметит изменение и пересоберёт нужную часть.
- На x86_64 CUDA 13 ставится из `requirements.txt`. Целевая карта — RTX 5070.
- NVRTC 13 не компилирует под карты старее поколения sm_75 (например, GTX 1060,
sm_61). Для них поставьте NVRTC 12 отдельно от `.venv` и соберите в отдельный
каталог:
```sh
pip install --target ~/.cache/radar_nvrtc12 nvidia-cuda-nvrtc-cu12 nvidia-cuda-runtime-cu12
make BUILD_DIR=/tmp/build-nvrtc12 CUDA_ROOTS="$HOME/.cache/radar_nvrtc12/nvidia/cuda_nvrtc $HOME/.cache/radar_nvrtc12/nvidia/cuda_runtime"
```
Программа запускает процессор только из `build/bin/`, поэтому такая сборка нужна
для проверки на старой карте (глава [Разработка](development.md)).
- На Jetson CUDA берётся из JetPack (`/usr/local/cuda`); pip-пакеты CUDA там не
ставятся. PyQt6 на Jetson с glibc 2.35 — версии 6.7.
## Служба без экрана
На машине без оператора программу запускает служба systemd. Установка — один раз,
от обычного пользователя через `sudo`:
```sh
sudo bash deploy/install-daemon.sh
```
Скрипт создаёт `/etc/systemd/system/radar.service`, разрешает пользователю без пароля
`sudo systemctl stop|start|restart radar.service` (`/etc/sudoers.d/radar`) и включает
службу при загрузке, но не запускает её. Служба работает от имени этого пользователя
в каталоге проекта, запускает `start.sh --headless --skip-build`, перезапускается через
3 с после сбоя, а при остановке ждёт программу до 25 с.
```sh
sudo systemctl start radar.service # запустить
systemctl status radar.service # состояние
journalctl -u radar.service -f # журнал
sudo systemctl disable --now radar.service && sudo rm /etc/systemd/system/radar.service /etc/sudoers.d/radar && sudo systemctl daemon-reload # удалить
```
Служба берёт последний использованный профиль. Перед её запуском откройте окно
программы на этой машине, загрузите профиль с железом, выберите наборы и нажмите
**Save Config…**. Работа со службой — в разделе «Работа без экрана» главы
[Веб-интерфейс, кнопка и локатор](web.md).
## Машина развёртывания
Raspberry Pi 5 Model B (Cortex-A76 ×4, 4 ГиБ), Debian 13, Python 3.13. Проект лежит в
`~/Documents/radar_system`. На машине собираются `.venv` и C++; копировать их с
рабочей станции нельзя: там другая архитектура (x86_64).
```sh
python3 -m venv .venv && .venv/bin/python -m pip install -r requirements.txt
make -j4
QT_QPA_PLATFORM=offscreen .venv/bin/python -m unittest discover -s python_app/tests
```
На Pi нужна только часть проекта: `data_acq_and_processing`, `deploy`, `python_app`,
`run_config_examples`, `Makefile`, `requirements.txt`, `run_config.json`, `start.sh`.
Каталог `device_firmware/` и документация не нужны.
> **Внимание.** Номер GPIO-чипа 40-контактного разъёма на Pi 5 зависит от версии
> ядра. После установки и обновления ядра проверьте его: `gpiodetect` и
> `gpioinfo -c gpiochip0`. Неверный чип в профиле — ключи, которые молча не
> переключаются.
## Обновление с флешки
На рабочей станции:
```sh
deploy/pack-usb.sh /media/<пользователь>/<флешка>
```
Без аргумента скрипт берёт единственную подключённую съёмную флешку. В каталог
`radar_update/` на ней он кладёт архив `radar_system-<дата коммита>-<хеш>.tar.gz`
с частью проекта для Pi из **последнего коммита** (незакоммиченные изменения в него не
попадают) и скрипт `update.sh`.
На машине, от обычного пользователя (не через `sudo`), из каталога, где лежит
`radar_update`:
```sh
bash radar_update/update.sh # перенести текущий .venv
bash radar_update/update.sh --python 3.13 # собрать .venv заново этим Python
```
Скрипту можно передать путь к архиву: `bash radar_update/update.sh <архив>`; без него
берётся последний по имени `radar_system-*.tar.gz` рядом со скриптом.
Перед обновлением закройте окно программы, иначе скрипт откажется и покажет, какие
процессы работают в каталоге. Службу он остановит сам и запустит снова, если она
работала.
Что делает `update.sh`:
1. проверяет архив и переименовывает текущую версию в `radar_system<N>` — следующий
свободный номер; это копия для отката;
2. разворачивает новую версию в `~/Documents/radar_system` (другой каталог задаёт
переменная `RADAR_DIR`);
3. переносит из прежней версии: `run_config.json`; профили из
`run_config_examples/`, изменённые на машине (версия из архива ложится рядом с
окончанием `.new`); `python_app/runtime/` без журналов; данные
`python_app/data*` и чужие каталоги верхнего уровня — жёсткими ссылками, без
копирования и места на диске; `.venv` — копией;
4. ставит пакеты из `requirements.txt` и собирает C++ (`make all rph_radar_collector`);
5. записывает имя архива в файл `RELEASE` и запускает службу, если она работала.
Если что-то пошло не так, скрипт печатает команду отката. Вручную:
```sh
sudo systemctl stop radar.service
mv ~/Documents/radar_system ~/Documents/radar_system_failed
mv ~/Documents/radar_system<N> ~/Documents/radar_system
sudo systemctl start radar.service
```
Новую версию при откате лучше переименовать, а не удалять: в ней могут быть
измерения, снятые после обновления.
На свежую машину (без прежней версии) `update.sh` спрашивает
`Install a fresh one there? [y/N]` и ставит корневой `run_config.json` из архива, то есть
симулятор: профиль с железом нужно выбрать после установки.