Автозахват цели на дроне: полное руководство по реализации на базе AeroCompanion

В этой статье мы пошагово разберем, как реализовать систему автозахвата цели на дроне с использованием связки Raspberry Pi 5 + Pixhawk — той самой, что лежит в основе проекта AeroCompanion. Система будет autonomously обнаруживать, захватывать и сопровождать движущуюся цель в реальном времени.

Администратор

ПоделитьсяВКонтактеTelegramMAX
Автозахват цели на дроне: полное руководство по реализации на базе AeroCompanion

Автозахват цели на дроне: полное руководство по реализации на базе AeroCompanion

1. Обзор архитектуры

Система автозахвата строится на разделении обязанностей между двумя вычислительными узлами:

КомпонентРольМодель
Полетный контроллерСтабилизация, управление моторами, безопасностьPixhawk 6X (или 6C)
Бортовой компьютерКомпьютерное зрение, ИИ, принятие решенийRaspberry Pi 5
КамераЗахват видеоRaspberry Pi Camera Module
СвязьПередача команд и телеметрииMAVLink / MAVSDK

Raspberry Pi 5 обрабатывает видеопоток, обнаруживает цель с помощью YOLO, вычисляет отклонение и отправляет корректирующие команды полетному контроллеру через протокол MAVLink.

Важно: В полетном контроллере должен быть активирован режим Offboard (для PX4) или Guided (для ArduPilot), чтобы он принимал команды от бортового компьютера.

2. Необходимое оборудование

КомпонентРекомендуемая модельПримечание
Бортовой компьютерRaspberry Pi 5 (4–8 ГБ ОЗУ)8 ГБ предпочтительнее
Полетный контроллерPixhawk 6X / 6CС прошивкой PX4 или ArduPilot
КамераRaspberry Pi Camera Module 3Или любая USB-камера с поддержкой OpenCV
AI-ускорительHailo-8L / Coral TPU (опционально)Ускоряет инференс YOLO в 5–10 раз
Источник питания5В / 5А USB-CСтабилизированный, для Raspberry Pi 5
Система охлажденияАктивный кулерОбязательно для длительной работы
ТелеметрияРадиомодем / 4G-модемДля отладки и мониторинга

3. Программное обеспечение

3.1 Установка ОС и базовых пакетов

На Raspberry Pi 5 установите Raspberry Pi OS (рекомендуется 64-битная версия) и выполните:

# Обновление системы
sudo apt update && sudo apt upgrade -y

# Установка Python и зависимостей
sudo apt install python3-pip python3-venv python3-opencv -y

# Создание виртуального окружения
python3 -m venv ~/drone_venv
source ~/drone_venv/bin/activate

# Установка ключевых библиотек
pip install ultralytics opencv-python pymavlink dronekit numpy

3.2 Основные библиотеки и их назначение

БиблиотекаНазначение
UltralyticsЗагрузка и запуск моделей YOLOv8/v11
OpenCVЗахват видео, предобработка, отрисовка
PyMAVLinkНизкоуровневая связь с Pixhawk
DroneKitВысокоуровневое управление дроном
NumPyМатематические вычисления

4. Обнаружение цели: YOLO

Для обнаружения целей в реальном времени используется YOLOv8 — одна из самых быстрых и точных нейросетей для детекции объектов.

4.1 Выбор модели

Для Raspberry Pi 5 рекомендуется использовать YOLOv8n (nano) — самую легкую версию модели. Она обеспечивает баланс между скоростью и точностью:

  • Скорость инференса: ~15–20 FPS на Raspberry Pi 5 (без ускорителя)
  • С ускорителем Hailo-8L: до 50+ FPS

4.2 Загрузка модели и детекция

from ultralytics import YOLO
import cv2
import numpy as np

# Загрузка предварительно обученной модели
model = YOLO('yolov8n.pt')  # или yolov8n_custom.pt для своей задачи

# Захват видео с камеры
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # Инференс YOLO
    results = model(frame, conf=0.5)  # порог уверенности 50%

    # Извлечение обнаруженных объектов
    for box in results[0].boxes:
        x1, y1, x2, y2 = map(int, box.xyxy[0])
        conf = float(box.conf[0])
        cls = int(box.cls[0])
        label = model.names[cls]

        # Отрисовка рамки
        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
        cv2.putText(frame, f'{label} {conf:.2f}', (x1, y1-10),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)

    cv2.imshow('Detection', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

4.3 Обучение собственной модели

Если нужно детектировать специфические цели (например, конкретные типы дронов или транспортных средств), модель дообучается на собственном датасете:

yolo train data=custom_dataset.yaml model=yolov8n.pt epochs=50 imgsz=640

5. Трекинг цели: удержание захвата

Обнаружение цели в каждом кадре — это только половина задачи. Чтобы дрон мог непрерывно следить за движущейся целью, используется алгоритм трекинга.

5.1 Выбор трекера

ТрекерСкоростьТочностьОсобенность
KCFВысокаяСредняяОчень быстрый, простой
CSRTСредняяВысокаяБолее точный, но медленнее
BoT-SORTСредняяВысокаяСовременный, устойчив к перекрытиям

Для Raspberry Pi 5 рекомендуется KCF как оптимальный по скорости. CSRT можно использовать при наличии AI-ускорителя.

5.2 Реализация трекинга

import cv2

# Инициализация трекера
tracker = cv2.TrackerKCF_create()  # или TrackerCSRT_create()
tracking = False
bbox = None

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # Если трекинг активен — обновляем позицию
    if tracking:
        success, bbox = tracker.update(frame)
        if success:
            x, y, w, h = map(int, bbox)
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 255), 2)
            center_x, center_y = x + w//2, y + h//2
            cv2.circle(frame, (center_x, center_y), 5, (0, 0, 255), -1)
        else:
            tracking = False  # Цель потеряна — перезапускаем детекцию

    # Если трекинг не активен — ищем цель через YOLO
    else:
        results = model(frame, conf=0.5)
        if len(results[0].boxes) > 0:
            # Берем первый обнаруженный объект
            box = results[0].boxes[0]
            x1, y1, x2, y2 = map(int, box.xyxy[0])
            bbox = (x1, y1, x2-x1, y2-y1)
            tracker.init(frame, bbox)
            tracking = True

    cv2.imshow('Tracking', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

6. Управление дроном: от координат цели к командам полета

Самый важный этап — преобразование позиции цели на экране в управляющие команды для дрона.

6.1 Вычисление ошибки

Центр кадра принимается за целевую точку. Отклонение цели от центра — это ошибка, которую нужно скорректировать:

# Параметры кадра
frame_width = 640
frame_height = 480
center_x_target = frame_width // 2
center_y_target = frame_height // 2

# Позиция цели в кадре (из трекера)
if tracking and success:
    x, y, w, h = bbox
    obj_center_x = x + w//2
    obj_center_y = y + h//2

    # Ошибка в пикселях
    error_x = obj_center_x - center_x_target  # >0 — цель справа
    error_y = obj_center_y - center_y_target  # >0 — цель ниже

    # Нормализация ошибки (в процентах от ширины/высоты кадра)
    norm_error_x = error_x / (frame_width / 2)   # от -1 до 1
    norm_error_y = error_y / (frame_height / 2)  # от -1 до 1

6.2 PID-регулятор для плавного управления

Для преобразования ошибки в команды скорости используется PID-регулятор:

class PID:
    def __init__(self, kp, ki, kd):
        self.kp = kp
        self.ki = ki
        self.kd = kd
        self.integral = 0
        self.prev_error = 0

    def update(self, error, dt):
        self.integral += error * dt
        derivative = (error - self.prev_error) / dt if dt > 0 else 0
        output = self.kp * error + self.ki * self.integral + self.kd * derivative
        self.prev_error = error
        return output

# Инициализация PID для осей X и Y
pid_x = PID(kp=0.8, ki=0.05, kd=0.1)
pid_y = PID(kp=0.8, ki=0.05, kd=0.1)

# Получение команд скорости
dt = 0.05  # ~50 мс между кадрами
vel_x = pid_x.update(norm_error_x, dt)  # скорость влево/вправо
vel_y = pid_y.update(norm_error_y, dt)  # скорость вперед/назад

6.3 Отправка команд через MAVLink

from pymavlink import mavutil

# Подключение к Pixhawk
master = mavutil.mavlink_connection('/dev/ttyACM0', baud=115200)
master.wait_heartbeat()

def send_velocity_command(vx, vy, vz, duration_ms=100):
    """
    Отправка команды скорости в режиме Offboard
    vx, vy, vz — скорости в м/с в системе координат NED
    """
    master.mav.set_position_target_local_ned_send(
        0,  # time_boot_ms
        0, 0,  # target_system, target_component
        mavutil.mavlink.MAV_FRAME_LOCAL_NED,
        0b0000111111000111,  # type_mask (только скорости)
        0, 0, 0,  # x, y, z (игнорируются)
        vx, vy, vz,  # скорости
        0, 0, 0,  # ускорения
        0, 0  # yaw, yaw_rate
    )

# Отправка команд в цикле
while tracking:
    # ... вычисление ошибок и PID ...

    # Ограничение максимальной скорости
    max_speed = 2.0  # м/с
    vx = max(-max_speed, min(max_speed, vel_x))
    vy = max(-max_speed, min(max_speed, vel_y))

    # Отправка команды (vz = 0 для удержания высоты)
    send_velocity_command(vx, vy, 0, 100)

    time.sleep(0.05)  # 50 мс цикл

7. Полный пайплайн автозахвата

Объединяем все этапы в единую систему:

[Схема архитектуры: Камера → YOLO → Трекер → PID → MAVLink → Pixhawk]

Полный код (схематично):

import cv2
import time
import numpy as np
from ultralytics import YOLO
from pymavlink import mavutil

# ===== 1. ИНИЦИАЛИЗАЦИЯ =====
# Подключение к Pixhawk
master = mavutil.mavlink_connection('/dev/ttyACM0', baud=115200)
master.wait_heartbeat()

# Загрузка YOLO
model = YOLO('yolov8n.pt')

# Инициализация камеры
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

# Инициализация трекера
tracker = cv2.TrackerKCF_create()
tracking = False
bbox = None

# PID-регуляторы
pid_x = PID(0.8, 0.05, 0.1)
pid_y = PID(0.8, 0.05, 0.1)

# ===== 2. ОСНОВНОЙ ЦИКЛ =====
while True:
    ret, frame = cap.read()
    if not ret:
        break

    # ---- Детекция или трекинг ----
    if tracking:
        success, bbox = tracker.update(frame)
        if not success:
            tracking = False
            continue
        x, y, w, h = map(int, bbox)
        obj_center = (x + w//2, y + h//2)
    else:
        results = model(frame, conf=0.5)
        if len(results[0].boxes) > 0:
            box = results[0].boxes[0]
            x1, y1, x2, y2 = map(int, box.xyxy[0])
            bbox = (x1, y1, x2-x1, y2-y1)
            tracker.init(frame, bbox)
            tracking = True
            continue

    # ---- Вычисление ошибки ----
    if tracking:
        error_x = (obj_center[0] - 320) / 320
        error_y = (obj_center[1] - 240) / 240

        # ---- PID и отправка команд ----
        vel_x = pid_x.update(error_x, 0.05)
        vel_y = pid_y.update(error_y, 0.05)

        # Ограничение скорости
        max_speed = 2.0
        vel_x = max(-max_speed, min(max_speed, vel_x))
        vel_y = max(-max_speed, min(max_speed, vel_y))

        # Отправка в Pixhawk
        master.mav.set_position_target_local_ned_send(
            0, 0, 0,
            mavutil.mavlink.MAV_FRAME_LOCAL_NED,
            0b0000111111000111,
            0, 0, 0, vel_x, vel_y, 0,
            0, 0, 0, 0, 0
        )

    # ---- Визуализация ----
    cv2.imshow('Autonomous Target Lock', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

8. Оптимизация производительности

ПроблемаРешение
Низкий FPSИспользовать YOLOv8n с квантованием INT8
Перегрев Pi 5Активное охлаждение + снижение частоты CPU при необходимости
Задержки управленияУменьшить разрешение кадра до 320×240 для детекции
Потеря целиДобавить повторную детекцию каждые N кадров
Мерцание командДобавить фильтр низких частот (сглаживание)

9. Готовые проекты для изучения

ПроектОписаниеСсылка
AeroCompanionПолноценная система на Pi 5 + Pixhawk 6Xgithub.com/koradeh/AeroCompanion
PixEagleOpenCV + YOLO + MAVSDK для слеженияgithub.com/alireza787b/PixEagle
RAVAN 1.0Обнаружение воздушных целей на Pi 5ieeexplore.ieee.org (описание)
CSUN ARCSАвтономный UAV с YOLOv8arcs.center/autonomous-uav

10. Меры безопасности

Внимание: Перед реальными полётами обязательно соблюдайте следующие правила:

  1. Всегда тестируйте в симуляторе (Gazebo SITL) перед реальными полетами.
  2. Установите геозону (виртуальный забор) в полетном контроллере.
  3. Добавьте аварийную кнопку для немедленной остановки.
  4. Контролируйте высоту — не позволяйте дрону снижаться ниже безопасного уровня.
  5. Всегда держите пульт управления наготове для ручного перехвата.

Заключение

Система автозахвата цели на базе Raspberry Pi 5 + Pixhawk — это мощное и доступное решение, которое может быть реализовано с использованием открытого ПО. Ключевые компоненты:

  • YOLOv8 для быстрого и точного обнаружения
  • KCF/CSRT для устойчивого трекинга
  • PID-регулятор для плавного управления
  • MAVLink для связи с полетным контроллером

Эта архитектура лежит в основе таких проектов, как AeroCompanion и PixEagle, и может быть адаптирована под самые разные задачи — от поисково-спасательных операций до мониторинга и доставки грузов.


Материал подготовлен на основе открытых источников и проекта AeroCompanion.

По теме: бпла, ии