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
+341
View File
@@ -0,0 +1,341 @@
# Окно программы
Окно называется **Radar System Control** и открывается развёрнутым на весь экран.
Слева — графики выбранного режима обработки, справа — панель управления. Работу ведут
несколько процессов — конвейер: процесс сбора управляет железом, препроцессор
калибрует данные, процессор их обрабатывает и держит TCP-локатор для внешних программ;
между собой они передают данные через кольца в разделяемой памяти (главы
[Устройство программы](architecture.md) и [Словарь](glossary.md)).
```text
┌──────────────────────────────────────┬─┬──────────────────────────────────┐
│ │ │ Actions (не прокручивается)│
│ │ │ ┌──────────────────────────────┐ │
│ графики │›│ │ Data Actions │ │
│ (вид зависит от режима) │ │ │ Switches │ │
│ │ │ │ Selected Preprocess Sets │ │
│ │ │ │ Processing │ │
│ │ │ │ Radar │ │
│ │ │ └──────────────── прокрутка ───┘ │
│ │ │ Status: … History: … │
│ │ │ Runtime Log Level ▾ │
│ │ │ [журнал] │
└──────────────────────────────────────┴─┴──────────────────────────────────┘
```
Стрелка между графиками и панелью (подсказка **Hide settings panel** или
**Show settings panel**) прячет и показывает всю панель; графики тогда занимают всю ширину.
Положение
стрелки не запоминается. Секция **Actions** со списком **Mode** всегда на месте,
остальные секции прокручиваются. Меню, панели инструментов и сочетаний клавиш нет.
Многие действия приостанавливают сбор: останавливают процесс сбора и препроцессор, но
оставляют работать процессор и локатор, а по окончании продолжают сбор, если он шёл.
Так работают **Apply Radar**, **Clear Runtime History**, **Remove Last Measurement**,
**Capture Temporary Reference** и съём наборов. Приостановка завершает и запись на
диск. **Stop** отменяет ожидающее продолжение. Если в это время идёт другое такое
действие, программа отвечает `Wait for the current pipeline operation to finish`.
## Actions
| Кнопка | Что делает |
| --- | --- |
| **Start** | запускает непрерывный сбор и обработку |
| **Single Capture** | снимает одну коллекцию, показывает результат и останавливает сбор |
| **Stop** | останавливает сбор |
| **Apply Radar** | отправляет настройки радара в железо, не запуская сбор |
| **Load Config…** | загружает профиль из файла |
| **Save Config…** | сохраняет текущие настройки в профиль |
| **Preprocessing…** | открывает окно **Preprocessing Setup**: наборы калибровки и референса, калибровка по объекту ([Калибровка и предобработка](preprocessing.md)) |
| **Clear Runtime History** | очищает историю в памяти |
| **Mode** | режим обработки: `pass_through`, `bscan`, `gpr`, `sar3d` ([Режимы обработки](processing.md)) |
### Start
Перед запуском программа проверяет всё и при любой ошибке отказывает, ничего не
остановив; ошибка показывается окном `Failed to start pipeline: <тип>: <текст>`.
Проверяются:
- значения полей (например, буквы в поле **Points**: `invalid literal for int()…`);
- профиль сбора: режим драйвера, модель, ключи, линии GPIO, размер слотов колец;
- требования режима обработки (B-scan, GPR, 3D SAR — в главе
[Режимы обработки](processing.md));
- выбранные наборы калибровки и референса (глава
[Калибровка и предобработка](preprocessing.md)).
Если проверка прошла, программа:
1. перезапускает процессор, если изменились настройки, от которых он зависит
(глава [Файл конфигурации](configuration.md));
2. записывает файлы наборов и рабочую копию профиля в `python_app/runtime/`;
3. очищает историю, если процессор запускается заново (первый **Start**, перезапуск на
шаге 1) или изменились профиль сбора, наборы или режекторный фильтр (тогда в
журнале `History reset because run settings changed`);
4. запускает процесс сбора и препроцессор и ждёт до 3 с, пока они поднимутся;
5. начинает читать кольца; строка состояния — **Status: running**.
Если во время работы процесс конвейера завершился, программа пишет отчёт с хвостом
его вывода и перезапускает конвейер: первый раз сразу, следующие подряд — не раньше
чем через 6, 12, 24, 48, затем 60 с после предыдущей попытки, пока не получится. Повторное
нажатие **Start** при работающем сборе отвечает
`Pipeline is already running`.
### Single Capture
Делает то же, что **Start**, но процесс сбора снимает одну коллекцию и завершается.
Если шёл непрерывный сбор, он сначала останавливается. Программа ждёт результат
коллекции, снятой после нажатия, рисует его и останавливает сбор
(`Single capture completed`). Строка состояния — **Status: single capture running**.
Если результата нет 300 с, сбор останавливается с
`Single capture timed out after 300s with no result; stopping.` В режиме 3D SAR, если
результат не посчитался, строка состояния показывает **Status: no signal**,
**Status: error** или **Status: warning**.
### Stop
Останавливает процесс сбора, дочитывает кольца (до 0,35 с), останавливает
препроцессор и дочитывает результаты (до 0,25 с). Процессор и локатор продолжают
работать: так остановленный B-scan можно пересчитать, а клиенты локатора остаются
подключёнными. Запись на диск завершается. **Stop** отменяет и ожидающие действия:
автозапуск, продолжение после приостановки, съём для калибровки по объекту,
пересчёт B-scan.
### Apply Radar
Приостанавливает сбор, проверяет профиль и:
- одиночный LibreVNA (`native`) — открывает прибор, отправляет настройки развёртки,
закрывает;
- многоприборная схема — приборы не трогает (их настраивает процесс сбора), только
перечитывает пределы мастера;
- радиофотонный радар — программирует плату лазеров, если она включена в профиле;
- режим `mock` у любой модели — ничего (`Radar pre-configuration skipped (mock mode)`).
Если работает только процессор, а настройки, от которых он зависит, изменились,
**Apply Radar** перезапускает процессор и очищает историю.
В журнал пишется `Radar settings applied: start=…, stop=…, points=…, ifbw=…, power=…`.
Профиль кнопка не меняет.
### Load Config… и Save Config…
**Load Config…** открывает выбор файла (**Load Config Profile**) и загружает профиль:
все поля, таблицы геометрии, выбранные наборы, режим. Сбор должен быть остановлен,
иначе — `Stop all pipeline processes before loading a config profile`. Ошибка чтения
показывается как `Failed to load config profile: …`, текущий профиль при этом не
меняется.
**Save Config…** (**Save Config Profile**) записывает профиль; имя без расширения
получает `.json`, существующий файл перезаписывается. Записываются все поля окна,
выбранные наборы и геометрия. Загруженный или сохранённый профиль становится
стартовым для следующего запуска.
### Clear Runtime History
Приостанавливает сбор, отбрасывает непрочитанные данные колец, очищает историю
окна и процессора, очищает графики и продолжает сбор. Файлы на диске не трогает;
подтверждения не спрашивает. Поздние результаты коллекций, снятых до очистки,
отбрасываются.
## Data Actions
| Элемент | Что делает |
| --- | --- |
| **Save Last 1000** | сохраняет до 1000 последних коллекций каждой стадии (сырые, предобработанные, результаты) в новый каталог набора данных |
| **Save S21 JSON** | сохраняет S21 предобработанной стадии в файлы JSON, по файлу на пару |
| **Remove Last Measurement** | удаляет новейшую коллекцию из истории всех стадий |
| **Capture Temporary Reference** | снимает временный референс и сразу его применяет ([Калибровка и предобработка](preprocessing.md)) |
| **Start + Record to Disk** | запускает сбор, если он остановлен, и записывает на диск следующие **Sweeps to record** коллекций |
| **Sweeps to record** | сколько коллекций записать, от 1 до 1 000 000 |
| **Path**, **Browse…** | каталог, в котором создаются наборы данных |
| **Name** | имя набора данных; пусто — `snapshot_<дата>_<время>` по UTC |
Каталог набора данных — `<Path>/<префикс>_<Name>`. Префикс описывает снятое:
модель, полосу, число точек (у радиофотонного радара — `adc`) и мощность. Каталог
не должен существовать (`Snapshot directory already exists`). Рядом с данными
кладутся профиль, с которым они сняты (`config_profile.json`), и все ревизии
настроек обработки (`processing_settings.json`). Состав файлов — в главе
[Данные на диске](data.md).
Перед сохранением программа дочитывает данные из колец; идущий сбор и запись при
этом не прерываются. Если в памяти нет ни одной коллекции, сохранение отказывает:
`No runtime data is available for save`. Окно хранит в памяти до 1000 коллекций каждой
стадии; что старее,
не сохранить. Без колец-копий (`raw_tap`, `preprocessed_tap`) сохраняются только
результаты.
**Save S21 JSON** пишет по файлу на пару: для каждой коллекции — сырая и
предобработанная развёртка, рядом профиль `vna_config_profile.json`. Его можно
направить в существующий каталог набора данных: существующие файлы данных JSON не
перезаписываются, а `vna_config_profile.json` заменяется.
**Remove Last Measurement** приостанавливает сбор и удаляет из истории окна и
процессора самую новую коллекцию; если её результат ещё в пути, процессор его не
выдаст. Повторное нажатие удаляет следующую.
**Start + Record to Disk** записывает коллекции, которые придут после нажатия. Запись
заканчивается, когда записано заданное число, по **Stop**, при приостановке сбора
(очистка истории, временный референс, съём) или если диск не успевает и очередь
записи переполнилась; причина пишется в журнал. Одновременно идёт только одна запись
(`A recording is already in progress…`), а каталог должен быть новым. Закрытие окна
дописывает принятые данные.
## Switches
| Элемент | Что делает |
| --- | --- |
| **Settling (ms)** | пауза после переключения ВЧ-ключей перед развёрткой, мс (`run.settling_ms`) |
| **Run combos** и **Select** | список пар сбора `вход:выход` через запятую; пусто — полная матрица. **Select** делает этот список источником пар |
| **Single combo**: **Input**, **Output** и **Select** | одна пара сбора; **Select** делает её источником пар |
| **B-scan pair** | какую пару показывать в B-scan; доступно в режиме B-scan |
| **Next Combination** | следующая пара B-scan; доступно, когда пар в истории хотя бы две |
Пары сбора применяются при **Start**. У многоприборной схемы список всегда равен
полной матрице и не редактируется. В режимах pass-through и B-scan, если оба ключа
`mock` или у обоих одно положение, снимается только пара `0:0`.
## Selected Preprocess Sets
Показывает выбранные наборы: **S21 calibration**, **S21 reference**,
**Object calibration**; `<not selected>` — набор не выбран. Выбираются наборы в окне
**Preprocessing Setup**.
## Processing
Страница настроек выбранного режима. Каждое поле описано в главе
[Режимы обработки](processing.md). В режимах GPR и 3D SAR над настройками — таблицы
геометрии антенн.
### Таблицы геометрии
**Tx geometry** — передающие антенны: **Output** (номер выхода), **X (m)**, **Y (m)**,
**Z (m)**. **Rx geometry** — приёмные: **Input**, **X (m)**, **Y (m)**, **Z (m)**.
Координаты — в осях радара (глава [Как работает радар](principles.md)).
- **Add Antenna** добавляет строку со следующим свободным номером; строка начинает
действовать после ввода X, и до этого кнопка недоступна. Недоступна она и тогда,
когда строк столько же, сколько выходов или входов.
- **Remove Selected** удаляет выделенные строки.
- Каждая правка проверяется: номер — целый, в пределах матрицы, без повторов;
координаты — числа; требования GPR и 3D SAR выполняются. Неверная правка
откатывается с сообщением **Invalid Antenna Geometry**.
- Принятая правка сразу уходит процессору и пересчитывает результат. Если она не
совпадает с геометрией выбранной калибровки по объекту, выбор этой калибровки
снимается.
## Radar
Для LibreVNA и симулятора секция показывает развёртку:
| Поле | Ключ профиля |
| --- | --- |
| **Start (Hz)** | `radar.sweep.start_hz` |
| **Stop (Hz)** | `radar.sweep.stop_hz` |
| **Points** | `radar.sweep.points` |
| **IF bandwidth (Hz)** | `radar.sweep.if_bandwidth_hz` |
| **Stimulus power (dBm)** | `radar.sweep.stimulus_power_dbm` |
Под полями — пределы прибора: `Limits: freq=…, points=1..N, ifbw=…, power=…`. В режиме
`mock` и у радиофотонного радара пределов нет: `Device limits are not available.` (с
`driver_mode: "native"` без подключённого прибора окно не открывается — глава
[Неполадки](troubleshooting.md)). С известными пределами подпись поля дополняется
диапазоном, а значения вне его подрезаются с предупреждением
`Radar fields were adjusted to satisfy device limits.` Поле применяется, когда из него
уходит фокус или нажат Enter. Если
изменение меняет ключ радара, выбор наборов сбрасывается, а границы частот обработки
подрезаются под новую развёртку.
Для радиофотонного радара вместо развёртки показаны поля коллектора и платы
лазеров:
| Поле | Ключ профиля |
| --- | --- |
| **Project dir**, **Executable path**, **TTY path** | `radar.rph_radar.project_dir`, `executable_path`, `tty_path` |
| **Arguments** (по строке на параметр) | `radar.rph_radar.args` |
| **Environment JSON** | `radar.rph_radar.env` |
| **Startup timeout (s)**, **Read timeout (s)**, **Stop timeout (s)** | `startup_timeout_s`, `sweep_timeout_s`, `stop_timeout_s` |
| **Board enabled** | `radar.laser_control.enabled` |
| **Board port**, **Board mode** | `port`, `mode` (`manual` или `variation`) |
| **PI 1 P**, **PI 1 I**, **PI 2 P**, **PI 2 I** | `pi_coeff1_p`, `pi_coeff1_i`, `pi_coeff2_p`, `pi_coeff2_i` |
| **Temperature 1**, **Temperature 2**, **Current 1**, **Current 2** (режим `manual`) | `manual.temp1`, `temp2`, `current1`, `current2` |
| **Static temp 1**, **Static temp 2**, **Static current 1**, **Static current 2**, **Min value**, **Max value**, **Step**, **Time step**, **Delay time** (режим `variation`) | `variation.static_temp1` … `delay_time` |
Поля платы доступны при включённой **Board enabled**; видны поля только выбранного
режима. Единицы и пределы — в главе [Файл конфигурации](configuration.md). Поля
коллектора применяются при **Start**, поля лазера — кнопкой **Apply Radar**.
## Строка состояния и журнал
Под секциями — строка состояния и счётчик истории
`History: raw=0, preprocessed=0, results=0` (сколько коллекций каждой стадии в памяти).
| Состояние | Что значит |
| --- | --- |
| **Status: idle** | сбор остановлен |
| **Status: running** | идёт непрерывный сбор |
| **Status: single capture running** | идёт однократный съём |
| **Status: error** | в журнал записана ошибка; состояние держится до следующего изменения |
| **Status: result display error (acquisition continues)** | не удалось нарисовать результат; сбор продолжается |
| **Status: runtime display/recording error (acquisition continues)** | ошибка отображения или записи на диск; сбор продолжается |
| **Status: no signal**, **Status: warning** | итог однократного съёма в режиме 3D SAR |
**Runtime Log** — журнал программы. Список **Level** (**Debug**, **Info**,
**Warning**, **Error**) задаёт наименьший уровень записей; он применяется сразу и
сохраняется в профиль при **Save Config…**. Стрелка справа прячет и показывает журнал.
В окне хранится до 2000 последних записей; при переполнении появляется
`Log panel overflow: N record(s) dropped (they are still in the log file).` Полный
журнал — в `python_app/runtime/logs/radar.log` (глава [Данные на диске](data.md)).
Повторяющиеся ошибки отрисовки показываются один раз.
## Графики
| Режим | Что на экране |
| --- | --- |
| pass-through | **Pass-Through S21**: модуль (**Magnitude (dB)**) и фаза (**Phase (deg)**) по частоте, кривая на пару, легенда `in<вход>/out<выход>` |
| B-scan | **B-scan S21 in<вход>/out<выход> \| sweeps=N**: номер развёртки — дальность |
| GPR | **GPR coherent BP — ground plane**: карта плоскости земли и объекты |
| 3D SAR | **Front (X-Y)**, **Side (Z-Y)**, **Top (X-Z)**, **3D Projection** и строка состояния 3D SAR над ними |
Подробно виды описаны в главе [Режимы обработки](processing.md). Приставку единиц на
осях (Гц, МГц, ГГц, м, мм) график подбирает сам.
Графики управляются мышью так, как принято в библиотеке pyqtgraph: колесо меняет
масштаб, перетаскивание сдвигает, правая кнопка открывает меню (**View All** —
вернуть весь график, экспорт картинки). Щелчок по строке легенды прячет и показывает
кривую. Графики окна видны и в веб-интерфейсе.
Последняя развёртка снятого набора (калибровка, референс, временный референс)
рисуется на графике pass-through с подписью вида `Tmp S21 Reference last trace`.
## Сообщения
Ошибка действия открывает окно с ошибкой и пишется в журнал. Без экрана, для
действий из веб-интерфейса и для GPIO-кнопки окон нет: ошибка уходит в журнал, а
веб-интерфейсу — в ответ на запрос. Причины частых ошибок — в главе
[Неполадки](troubleshooting.md).
Окно ошибки называется по действию и обычно показывает
`<заголовок>: <тип ошибки>: <текст>` (у записи на диск — `<заголовок>: <текст>`):
| Заголовок | Действие |
| --- | --- |
| `Failed to start pipeline` | **Start**, **Single Capture** |
| `Failed to stop pipeline` | **Stop** |
| `Failed to apply radar settings` | **Apply Radar** |
| `Failed to load config profile`, `Failed to save config profile` | **Load Config…**, **Save Config…** |
| `Failed to open preprocessing panel` | **Preprocessing…** |
| `Failed to clear runtime history`, `Failed to remove last runtime measurement` | **Clear Runtime History**, **Remove Last Measurement** |
| `Failed to save snapshot`, `Failed to save VNA history JSON` | **Save Last 1000**, **Save S21 JSON** |
| `Failed to start disk recording` | **Start + Record to Disk** |
| `Failed to capture tmp reference` | **Capture Temporary Reference** |
| `Cannot switch processing mode to <режим>` | **Mode** |
| `Failed to update live processing settings`, `Failed to update plot display settings`, `Failed to render processing settings` | правка настроек обработки и вида |
| `Failed to recompute the B-scan` | пересчёт остановленного B-scan |
| `Failed to start <вид> sequence`, `Failed to capture combo; previous captures kept, retry when ready`, `Failed to undo last preprocess capture`, `Failed to save preprocess set`, `Failed to abort capture sequence`, `Failed to refresh preprocessing sets`, `Failed to create neutral S21 sets` | окно **Preprocessing Setup** |
| `Failed to capture object-calibration data`, `Failed to calculate object calibration`, `Failed to save object calibration`, `Failed to update object calibration after geometry change` | калибровка по объекту |
| `Cannot perform data action`, `Cannot modify runtime history during active capture sequence` | действие с данными во время съёма или остановки |
| `Shutdown operation failed` | закрытие окна |
Пока идёт съём наборов, часть действий недоступна, и программа объясняет почему:
`Finish the active capture sequence first`, `Wait for preprocessing capture to finish`,
`Wait for object-calibration capture to finish`, `Wait for pipeline shutdown to finish`.