README.md
FPV Tracker Optimized
Русская документация для проекта сопровождения и удержания воздушной цели на базе YOLO + ByteTrack + Kalman + KLT.
Проект умеет:
- принимать видео с файла, камеры, RTSP, UDP-потока и готового UDP-дампа камеры;
- обнаруживать и сопровождать цель;
- удерживать цель при кратковременной потере детекции;
- строить команды наведения в экранных координатах;
- экспортировать команды в
json,mavlink,mspи испытательныйproto_udp; - работать локально или в Docker с GPU.
Быстрый старт
Локальный запуск
- Установите Python 3.12 и зависимости.
- Проверьте, что модель
best.ptлежит в корне проекта. - Настройте
SOURCEиMODEL_PATHвconfig.py. - При необходимости настройте backend в
config_intercept.py. - Запустите:
python main.py
Docker-запуск
- Установите Docker.
- Для GPU установите NVIDIA Container Toolkit на хосте.
- Соберите образ:
docker compose build
- Запустите:
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 -ExecutionPolicy Bypass -File .\start-hdmi-bridge.ps1
docker compose up -d
В UI выберите HDMI по USB, индекс Windows-устройства, качество и FPS. Мост принимает HDMI на Windows и передаёт контейнеру MJPEG через host.docker.internal:8091. Повторный запуск скрипта не создаёт второй процесс.
Комплект документации
- Полный runbook
- Архитектура проекта
- Справочник конфигурации
- Испытательный UDP-протокол
- Поиск и устранение проблем
Что является точкой входа
Основной runtime проекта запускается через:
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— команды автопилота при backendjson.
Статус Docker-упаковки
В проекте уже подготовлены:
Dockerfiledocker-compose.ymldocker/entrypoint.shrequirements-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-порт, ширина 16–8192, высота 16–8192 и FPS 1–240. В 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.
Переменные окружения для этих источников:
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"}