Files
radar_system/docs/web.md
T
2026-10-16 18:35:02 +03:00

19 KiB
Raw Blame History

Веб-интерфейс, кнопка и локатор

Кроме окна, с программой работают из браузера, GPIO-кнопкой и через TCP-локатор: он отдаёт внешним программам найденные объекты и принимает скорость радара. Без экрана (раздел «Работа без экрана») других способов нет.

Веб-интерфейс

Веб-сервер работает внутри программы, и с окном, и без экрана. Откройте в браузере http://<адрес машины>:8080/. Порт меняется переменной окружения RADAR_SYSTEM_WEBUI_PORT; неверное значение заменяется на 8080. Если порт занят, программа работает без веб-интерфейса, а ошибка (address already in use) видна только в выводе процесса. Если сервер не смог запуститься по другой причине, в журнале появляется Failed to start web UI.

Внимание. У веб-интерфейса нет пароля и шифрования: любой, кто достаёт до порта по сети, управляет радаром. По адресам /docs, /redoc и /openapi.json открыто описание API. Подключайте машину только к доверенной сети.

Страница

Верхняя строка — кнопки управления: Start, Single Capture, Stop, Capture Temporary Reference, Remove Last Measurement. Они делают то же, что одноимённые кнопки окна (глава Окно программы).

Processor Output — картинка с графиков окна программы. Масштабировать её в браузере нельзя: она повторяет то, что показано в окне. В режиме B-scan над ней список пар (Input i / Output o) и кнопка Next Combination, в режиме 3D SAR — строка состояния 3D SAR.

Боковая панель:

Блок Элемент Что делает
Config Profile список и Load загружает профиль из каталога run_configs/, как Load Config…; доступна при остановленном сборе. Список читается при открытии страницы; новые файлы видны после её перезагрузки
current: <файл> текущий профиль
Save / Record Dataset Save path, Name (optional) каталог и имя набора данных; при открытии страницы берутся из окна, а сохранение и запись из браузера переписывают ими Path и Name окна (запись — и Sweeps to record)
Save Last 1000 сохраняет до 1000 последних коллекций каждой стадии, как одноимённая кнопка окна
Sweeps to record и Start + Record to Disk запускает сбор и записывает на диск заданное число следующих коллекций; ниже — ход записи recording N / M sweep(s)…
Processor Settings форма настройки текущего режима обработки (ниже); заголовок сворачивает форму
таблицы Tx geometry, Rx geometry геометрия антенн в режимах GPR и 3D SAR: − удаляет антенну, Add Antenna добавляет следующую свободную
Apply отправляет изменённые поля
Clear Runtime History очищает историю, как одноимённая кнопка окна

Нижняя строка: running — идёт ли сбор, processor — работает ли процессор, ring — имя кольца результатов, scans — сколько коллекций в истории каждой стадии, и признак картинки: live — кадры приходят, stale — новых кадров нет дольше 2 с (так бывает и тогда, когда картинка просто не меняется), no data — кадров ещё не было. Сообщения об успехе и ошибках всплывают на 2,6 с; ошибки — красным.

Если окно браузера уже 760 пикселей, панель уходит под картинку.

Как выполняются действия

Каждая кнопка вызывает тот же код, что и кнопка окна, с теми же проверками. Действия из нескольких браузеров выполняются по очереди. Если окно программы не начало действие за 30 с, запрос отменяется (The desktop did not start the action in time; the request was cancelled). Если начало, но не закончило, браузер получает The desktop action is still running; check its status before retrying, а действие доводится до конца. Ошибки, которые возникают позже (например, на середине однократного съёма), видны только в журнале.

Форма настроек

Форма строится из полей окна: те же подписи, пределы и группы. В ней поле Mode и поля текущего режима; смена режима сразу перестраивает форму. Apply отправляет только изменённые поля, поэтому два человека, правящие разные поля, не мешают друг другу. Порядок полей может отличаться от окна. Значения проверяются так же, как в окне: вне пределов — Numeric setting is outside its allowed range, неизвестный вариант — Unknown setting option: …; при ошибке не применяется ни одно поле из отправленных. Дробное число округляется до точности поля окна. Изменения из окна приходят в форму раз в секунду.

Только в окне программы:

  • Apply Radar, Load Config… из произвольного места, Save Config…;
  • окно Preprocessing…: съём и выбор наборов, калибровка по объекту;
  • Save S21 JSON;
  • секции Radar и Switches: развёртка, лазер, ключи, пары сбора;
  • Show magnitude, Show phase, Unwrap phase, Scans to show (stopped);
  • журнал и его уровень, строка состояния;
  • масштаб и сдвиг графиков мышью.

Картинка и обновление

Программа снимает картинку графиков, только когда подключён хотя бы один браузер и изображение изменилось, и не чаще 5 раз в секунду. Каждый браузер получает самую свежую картинку, состояние и настройки; медленное соединение пропускает промежуточные кадры. Пока окно занято синхронным съёмом (калибровка, референс), картинка не обновляется. Браузер переподключается сам через 1,5 с после обрыва.

API

Страница работает через HTTP API, которым можно пользоваться и из своих программ. Тело запросов и ответов — JSON; ошибка действия — код 400 и {"detail": "<сообщение>"}. Тело неверного вида (поле не того типа, нет обязательного поля) даёт код 422 со списком ошибок в detail.

Запрос Тело Что делает
GET /api/status — состояние (то же, что в нижней строке страницы)
POST /api/start — Start
POST /api/single_capture — Single Capture
POST /api/stop — Stop
POST /api/tmp_reference — Capture Temporary Reference
POST /api/remove_last — Remove Last Measurement
POST /api/clear_history — Clear Runtime History
GET /api/configs — список профилей в run_configs/
POST /api/load_config {"name": "<файл>.json"} загрузить профиль
POST /api/save_dataset {"path": "…", "name": "…"} Save Last 1000
POST /api/start_recording {"path": "…", "name": "…", "count": N} Start + Record to Disk, N от 1 до 1 000 000
GET /api/live_settings — описание полей формы
POST /api/live_settings {"<поле>": значение, …} применить настройки. Имена полей — из описания формы; у настроек обработки они совпадают с ключами processing_live.json
POST /api/display_combo {"input_pos": i, "output_pos": o} выбрать пару B-scan
POST /api/next_combo — Next Combination
WS /ws — поток сообщений frame (картинка PNG в base64), status, settings

GPIO-кнопка

Кнопка, подключённая к GPIO компьютера, снимает временный референс — то же, что Capture Temporary Reference. Она настраивается в разделе control_button профиля (глава Файл конфигурации) и читается один раз при запуске программы.

Схема по умолчанию: кнопка между линией GPIO и землёй, внутренняя подтяжка к питанию, нажатие — спад уровня, по одному действию на нажатие. Индикации на самой кнопке нет; результат виден в журнале (GPIO control button pressed: capturing tmp reference, затем Tmp S21 Reference captured: …) и на графике pass-through.

Нажатие, пришедшее, пока программа останавливает сбор перед съёмом, отбрасывается (Tmp reference capture already in progress; ignoring duplicate request). Нажатие во время самого съёма ждёт его конца и запускает ещё один съём. Ошибки съёма только записываются в журнал, окон с ошибкой кнопка не открывает. Если настройки неполные, кнопка не включается (GPIO control button configuration is incomplete or unsupported; watcher not started). Если линию не удалось открыть — Failed to start GPIO control button watcher; если наблюдение за линией прервалось — GPIO control button watcher stopped: …. В обоих случаях программа работает дальше без кнопки до перезапуска.

TCP-локатор

Локатор — TCP-сервер внутри процессора. Он отдаёт подключившимся программам объекты, найденные режимом GPR, и принимает от них скорость радара для поправки на движение. Настройки — раздел run.locator_server профиля; по умолчанию порт 8888 на всех интерфейсах. Сервер работает, пока работает процессор: от первого Start до закрытия программы или перезапуска процессора. Stop, временный референс и пересчёт B-scan процессор и локатор не останавливают.

Обмен в обе стороны идёт пакетами: заголовок из 8 байт — номер устройства и длина данных (оба uint32, младший байт первым), затем текст JSON в UTF-8.

Пакет от радара:

03 00 00 00 71 00 00 00
{"obs":[{"crs":0.3,"dst":4.3},{"crs":-1.0,"dst":6.0},{"crs":1.0,"dst":2.0}],"sts":1,"tim":"13:42:25.058","ver":1}
Поле Что это
obs объекты: crs — координата X (вдоль ряда антенн, поперёк направления обзора), dst — дальность (Z), метры, округлены до 0,1 м
sts всегда 1
tim местное время сборки пакета ЧЧ:ММ:СС.ммм (не время съёма)
ver run.locator_server.protocol_version

В заголовке — run.locator_server.device_id. Пакет уходит после обработки каждой новой коллекции в любом режиме; вне режима GPR и без объектов список obs пуст. Объекты — те же, что видны на графике GPR: внутри окна видимости, после отбора по числу и фильтра приближения. При пересчёте после смены настроек уходит пакет только для новейшей коллекции. Новый клиент сразу получает последний отправленный пакет.

Пакет к радару — скорость в м/с:

00 00 00 00 0c 00 00 00
{"vlc":1.25}

Остальные поля и номер устройства в заголовке не читаются. Скорость считается свежей 5 с после прихода. Пока она свежая и на странице GPR или 3D SAR выключена Ignore socket speed, она заменяет скорость из поля, а её изменение пересчитывает новейшую коллекцию в GPR и 3D SAR. Использованная скорость сохраняется в каждом результате.

Клиентов может быть несколько; у каждого очередь на client_queue_size пакетов (по умолчанию 32), при переполнении выбрасываются старые. Клиент, который 5 с не принимает данные или прислал пакет больше max_payload_bytes (по умолчанию 65 536 байт), отключается. Сообщения локатора пишутся в python_app/runtime/logs/data_processor.err.log; если порт занят, процессор работает без локатора и пишет туда же locator server disabled.

Работа без экрана

На машине без оператора (Raspberry Pi) программу запускает служба systemd radar.service (установка — в главе Установка и запуск). Она запускает ./start.sh --headless --skip-build: окно не показывается, через 0,5 с выполняется Apply Radar, ещё через 1 с — Start, даже если Apply Radar не удался. Если Start не удался, программа завершается, и systemd запускает её снова через 3 с.

Профиль служба берёт последний использованный (из python_app/runtime/gui_session_state.json), а если его нет — корневой run_config.json, то есть симулятор. Поэтому перед установкой службы загрузите или сохраните на машине нужный профиль. Если запомненный профиль не читается, программа пишет Failed to load the last selected config profile; falling back to root run_config.json., берёт корневой профиль и запоминает уже его: исправленный профиль нужно загрузить снова.

Канал Для чего
браузер, http://<машина>:8080/ запуск и остановка, временный референс, сохранение данных, профили из run_configs/, настройки обработки
GPIO-кнопка временный референс
TCP-локатор, порт 8888 объекты и скорость
sudo systemctl start / stop / restart radar.service управление службой
journalctl -u radar.service -f журнал службы

Без экрана нет окон с ошибками: всё пишется в журнал. Окно калибровки и Save Config… без экрана недоступны: калибровку снимайте, запустив окно программы на той же машине. При запуске окна ./start.sh сначала останавливает службу; после закрытия окна она сама не запускается.

Если процесс конвейера упал, программа перезапускает конвейер: первый раз сразу, следующие подряд — не раньше чем через 6, 12, 24, 48, затем 60 с после предыдущей попытки; когда данные снова пошли, счёт начинается заново. После 400 подряд ошибок чтения колец конвейер останавливается и сам уже не запускается: нажмите Start в браузере.