5.5 KiB
Испытательный UDP-протокол
1. Назначение
Этот backend нужен для испытаний, когда проект должен отправлять состояние цели в блок наведения по UDP в локальной сети.
В проекте этот режим включается через:
AUTOPILOT_BACKEND = "proto_udp"
PROTO_UDP_ENABLE = True
или через env:
FPV_AUTOPILOT_BACKEND=proto_udp
FPV_PROTO_UDP_ENABLE=1
2. Куда это встроено
Реализация находится в:
autopilot_bridge.py
Новый backend называется:
proto_udp
3. Транспорт
- протокол: UDP
- адрес:
PROTO_UDP_HOST - порт:
PROTO_UDP_PORT
По умолчанию:
PROTO_UDP_HOST = "127.0.0.1"
PROTO_UDP_PORT = 5005
4. Формат пакета
Формат упаковки:
<BBBhhbbB
Это little-endian бинарный пакет фиксированной длины.
Поля идут в таком порядке:
descriptorobject_idtarget_stateoffset_y_pxoffset_x_pxoffset_y_pctoffset_x_pctbbox_area_pct
5. Таблица полей
descriptor
- тип:
uint8 - стандартное значение:
1 - задается через
PROTO_UDP_DESCRIPTOR
object_id
- тип:
uint8 - диапазон:
0..255 0, если цели нет
target_state
- тип:
uint8 - значения:
0— цели нет1— цель есть, идет обычная детекция/сопровождение3— детекция потеряна, но проект удерживает цель трекингом
Значение 2 в пользовательском протоколе зарезервировано под сценарий "несколько целей". Текущая реализация проекта его не отправляет, потому что runtime всегда выбирает одну основную цель.
offset_y_px
- тип:
int16 - знак:
- вверх
+ - вниз
-
- вверх
offset_x_px
- тип:
int16 - знак:
- вправо
+ - влево
-
- вправо
offset_y_pct
- тип:
int8 - диапазон:
-100..100 - считается относительно половины высоты кадра
offset_x_pct
- тип:
int8 - диапазон:
-100..100 - считается относительно половины ширины кадра
bbox_area_pct
- тип:
uint8 - диапазон:
0..100 - отношение площади bbox к площади кадра в процентах
6. Что отправляется при отсутствии цели
Если цели нет, пакет отправляется с нулями:
object_id = 0target_state = 0- все offsets =
0 bbox_area_pct = 0
Это соответствует вашему описанию:
если цели нет, все значения остаются нулевыми
7. Как вычисляются значения
Смещение в пикселях
Берется из guidance-точки:
aim_xaim_y
Относительно центра кадра:
offset_x_px = aim_x - center_xoffset_y_px = center_y - aim_y
То есть знак сделан так, чтобы:
- вправо было положительным;
- вверх было положительным.
Смещение в процентах
Нормируется к половине размера кадра:
- по X к
frame_w / 2 - по Y к
frame_h / 2
И затем ограничивается до -100..100.
Площадь bbox
Используются:
box_wbox_hframe_wframe_h
Формула:
bbox_area_pct = 100 * (box_w * box_h) / (frame_w * frame_h)
8. Включение в локальном запуске
PowerShell
$env:FPV_AUTOPILOT_BACKEND = "proto_udp"
$env:FPV_PROTO_UDP_ENABLE = "1"
$env:FPV_PROTO_UDP_HOST = "192.168.1.50"
$env:FPV_PROTO_UDP_PORT = "5005"
python main.py
Bash
export FPV_AUTOPILOT_BACKEND=proto_udp
export FPV_PROTO_UDP_ENABLE=1
export FPV_PROTO_UDP_HOST=192.168.1.50
export FPV_PROTO_UDP_PORT=5005
python3 main.py
9. Включение в Docker
В docker-compose.yml:
FPV_AUTOPILOT_BACKEND: "proto_udp"
FPV_PROTO_UDP_ENABLE: "1"
FPV_PROTO_UDP_HOST: "192.168.1.50"
FPV_PROTO_UDP_PORT: "5005"
10. Пример приема пакета на Python
import socket
import struct
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("0.0.0.0", 5005))
while True:
data, addr = sock.recvfrom(1024)
descriptor, object_id, target_state, off_y_px, off_x_px, off_y_pct, off_x_pct, bbox_area_pct = struct.unpack(
"<BBBhhbbB", data
)
print(addr, descriptor, object_id, target_state, off_y_px, off_x_px, off_y_pct, off_x_pct, bbox_area_pct)
11. Что важно проверить на стенде
- Совпадает ли порядок байтов с ожидаемым приемником.
- Совпадает ли знак вертикали и горизонтали.
- Устраивает ли блок значение
target_state = 3при удержании без детекции. - Не нужен ли вам в будущем отдельный режим
target_state = 2.