You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
12 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# FPV Tracker Optimized
Русская документация для проекта сопровождения и удержания воздушной цели на базе `YOLO + ByteTrack + Kalman + KLT`.
Проект умеет:
- принимать видео с файла, камеры, RTSP, UDP-потока и готового UDP-дампа камеры;
- обнаруживать и сопровождать цель;
- удерживать цель при кратковременной потере детекции;
- строить команды наведения в экранных координатах;
- экспортировать команды в `json`, `mavlink`, `msp` и испытательный `proto_udp`;
- работать локально или в Docker с GPU.
## Быстрый старт
### Локальный запуск
1. Установите Python 3.12 и зависимости.
2. Проверьте, что модель `best.pt` лежит в корне проекта.
3. Настройте `SOURCE` и `MODEL_PATH` в `config.py`.
4. При необходимости настройте backend в `config_intercept.py`.
5. Запустите:
```bash
python main.py
```
### Docker-запуск
1. Установите Docker.
2. Для GPU установите NVIDIA Container Toolkit на хосте.
3. Соберите образ:
```bash
docker compose build
```
4. Запустите:
```bash
docker compose up
```
Откройте `http://localhost:8080` и запустите обработку кнопкой «Старт». Отдельный трекер без UI: `docker compose --profile standalone up fpv-tracker`.
### HDMI по USB в Docker Desktop
Linux-контейнер Docker Desktop не видит Windows DirectShow-камеры как `/dev/video*`. Перед использованием режима `HDMI по USB` один раз запустите локальный мост:
```powershell
powershell -ExecutionPolicy Bypass -File .\start-hdmi-bridge.ps1
docker compose up -d
```
В UI выберите `HDMI по USB`, индекс Windows-устройства, качество и FPS. Мост принимает HDMI на Windows и передаёт контейнеру MJPEG через `host.docker.internal:8091`. Повторный запуск скрипта не создаёт второй процесс.
## Комплект документации
- [Полный runbook](docs/RUNBOOK_RU.md)
- [Архитектура проекта](docs/ARCHITECTURE_RU.md)
- [Справочник конфигурации](docs/CONFIG_REFERENCE_RU.md)
- [Испытательный UDP-протокол](docs/PROTOCOL_UDP_RU.md)
- [Поиск и устранение проблем](docs/TROUBLESHOOTING_RU.md)
## Что является точкой входа
Основной runtime проекта запускается через:
```bash
python main.py
```
В проекте нет полноценного CLI с аргументами командной строки. Конфигурация задается:
- напрямую через `config.py`;
- напрямую через `config_intercept.py`;
- через env-переменные, если проект запускается в контейнере или через shell.
## Основные файлы
- `main.py` — основной цикл обработки видео.
- `hdmi_usb_bridge.py` — мост Windows DirectShow → MJPEG для Docker.
- `start-hdmi-bridge.ps1` — фоновый запуск HDMI-моста.
- `config.py` — настройки источника, детектора, трекинга, ROI и вывода.
- `config_intercept.py` — настройки наведения, range/PN/FSM и backend'ов.
- `guidance.py` — экранный guidance и экспорт `guidance_state.json`.
- `autopilot_bridge.py` — отправка команд наружу.
- `runtime_env.py` — env-overrides для контейнера и shell-запуска.
- `bytetrack_min_aggressive.py` — локальная реализация ByteTrack.
## Что генерируется во время работы
В зависимости от настроек проект может создавать:
- `out_infer_*.mp4` — видео с наложениями;
- `runtime-data/track-logs/track_log_*.csv` — покадровый лог;
- `runtime-data/track-summaries/track_summary_*.json` — сводка по прогону;
- `guidance_state.json` — текущее состояние guidance;
- `autopilot_cmd.json` — команды автопилота при backend `json`.
## Статус Docker-упаковки
В проекте уже подготовлены:
- `Dockerfile`
- `docker-compose.yml`
- `docker/entrypoint.sh`
- `requirements-docker.txt`
После сборки образ рассчитан на запуск без интернета.
## UDP-источники
В `Настройки → Источник → Режим` доступны пять отдельных вариантов:
- `Камера UDP — кадры с разделительным байтом` — живой поток raw-кадров. Размер и FPS задаются произвольно; профиль `512x640 @ 50 FPS` соответствует 640 строкам по 512 значений.
- `Камера UDP МИК — протокол документа` — приём и сборка payload-пакетов МИК по `first/last`, sequence и offset.
- `Камера UDP — пользовательский пакет` — конструктор заголовка и способа сборки без изменения кода.
- `Файл UDP-лога МИК` — готовый лог с четырёхбайтовой обёрткой `порт + размер payload`; порт определяется по файлу и может отличаться от `59004`.
- `Файл UDP-лога — кадры с разделителем` — готовая последовательность кадров, разделённых одним байтом.
Для live-режимов задаются bind-адрес, UDP-порт, ширина `168192`, высота `168192` и FPS `1240`. В Docker поле адреса приёма обычно должно быть `0.0.0.0`, а не IP отправителя. Docker Compose публикует `59004/udp` для МИК, `59005/udp` и `40404/udp` для кадров с разделителем. Для raw-потока размер кадра определяет его границу, поэтому значения пикселей могут совпадать с разделителем; отдельный байт между кадрами отбрасывается. Поддержаны `JPEG/PNG`, `BGR24`, `RGB24`, `Gray 8-bit`, `Gray 16-bit` и `YUYV 4:2:2`.
В поле `Способ разбора` доступны `Автоопределение`, `МИК по документу`, `Кадры с разделителем` и `Пользовательский пакет`. Автоопределение слушает выбранные адрес и порт 3 секунды, показывает фактический IP и порт отправителя, размеры датаграмм, HEX/ASCII и SHA-256 образцов, затем проверяет структуры МИК, RTP, MPEG-TS, JPEG/PNG, H.264/H.265, raw-кадров, JSON и текста. При строгом совпадении найденный режим применяется автоматически. Все UDP payload сохраняются без изменений в `runtime-data/udp-probes/*.udp`; рядом лежит JSON с временными метками, адресами отправителей и SHA-256 каждого пакета.
Конструктор показывает заголовок как ленту отдельных байтов. Кнопка `+ байт` добавляет блок, крестик удаляет его вместе с байтами, стрелки меняют порядок. Для каждого блока задаются имя, длина и назначение: `не читать`, `читать как число`, `flags`, `sequence`, `номер фрагмента` или `размер/смещение`. Размер заголовка и offsets вычисляются автоматически; именованные числовые поля читаются с выбранным endian. Отдельно задаются маски начала/конца, смысл `value`, способ сборки (`фрагменты`, `один датаграмм`, `поток`) и содержимое результата (`кадр` или массив МИК`). Для кадра выбираются размер, FPS и `JPEG/PNG`, `BGR24`, `RGB24`, `Gray8`, `Gray16` либо `YUYV422`. Повреждённая цепочка отбрасывается до следующего пакета с флагом начала.
Большие UDP-дампы загружаются напрямую в `/data/input` одним потоком, без второй временной копии в памяти или на диске. Интерфейс показывает процент загрузки и позволяет отменить операцию; незавершённый файл не попадает в список источников.
Разделительный байт не должен встречаться внутри данных кадра. Если это невозможно гарантировать, используйте формат МИК с явной длиной массива.
Готовое видео не ограничивается расширением файла: источник определяется FFmpeg по содержимому. Поддерживаются все контейнеры и кодеки, доступные в FFmpeg образа, включая `MP4`, `AVI`, `MOV`, `MKV`, `WebM`, `MPEG-TS`, `M2TS`, `MXF`, `WMV/ASF`, `FLV`, `VOB`, `OGV`, `3GP`, raw `H.264/H.265` и файлы с нестандартным расширением. В вебе любой успешно декодированный источник выводится через единый поток кадров, а обработанная запись сохраняется в совместимом MP4.
Для файла `1785156788883112336` структура разобрана согласно документу «МИК. Описание передачи данных на порт 59004»:
- `7c e6` — UDP-порт `59004` (`uint16 LE`), следующие 2 байта — длина payload;
- заголовок UDP payload: версия, флаги начала/конца, номер последовательности, номер пакета и `uint32 LE` размера/смещения;
- большой массив: `uint32 LE` количества меток, по 40 байт на метку, затем 8-байтный заголовок видеокадра;
- заголовок кадра задаёт ширину, высоту, Pixel ID и количество байт выравнивания каждой строки;
- в примере: `INT16`, `636x476`, по 8 padding-байт на строку; padding не передаётся модели как пиксели.
Декодер проверяет sequence, циклический packet number, offsets и флаги начала/конца, пропускает повреждённые последовательности, извлекает метки и формирует BGR-кадр. Поддержаны форматы `GRAY8`, `GRAY16`, `RGB888`, `YCbCr422` и `INT16`. Частота кадров берётся из настройки сценария. `PCAP/PCAPNG` сначала нужно преобразовать, извлекая UDP payload.
Переменные окружения для этих источников:
```text
FPV_SOURCE_MODE=udp_mik_live|udp_delimited_live|udp_custom_live|udp_dump|udp_delimited_file
FPV_UDP_INPUT_HOST=0.0.0.0
FPV_UDP_INPUT_PORT=59004
FPV_FRAME_SEPARATOR_BYTE=0
FPV_FRAME_ENCODING=auto|bgr24|rgb24|gray8|gray16|yuyv422
FPV_UDP_PACKET_SCHEMA={"assembly":"fragmented","header_size":8,"byte_order":"little"}
```