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

Автозахват цели на дроне: полное руководство по реализации на базе AeroCompanion
Содержание
- 1. Обзор архитектуры
- 2. Необходимое оборудование
- 3. Программное обеспечение
- 4. Обнаружение цели: YOLO
- 5. Трекинг цели: удержание захвата
- 6. Управление дроном: от координат к командам
- 7. Полный пайплайн автозахвата
- 8. Оптимизация производительности
- 9. Готовые проекты для изучения
- 10. Меры безопасности
- Заключение
1. Обзор архитектуры
Система автозахвата строится на разделении обязанностей между двумя вычислительными узлами:
| Компонент | Роль | Модель |
|---|---|---|
| Полетный контроллер | Стабилизация, управление моторами, безопасность | Pixhawk 6X (или 6C) |
| Бортовой компьютер | Компьютерное зрение, ИИ, принятие решений | Raspberry Pi 5 |
| Камера | Захват видео | Raspberry Pi Camera Module |
| Связь | Передача команд и телеметрии | MAVLink / MAVSDK |
Raspberry Pi 5 обрабатывает видеопоток, обнаруживает цель с помощью YOLO, вычисляет отклонение и отправляет корректирующие команды полетному контроллеру через протокол MAVLink.
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. Полный пайплайн автозахвата
Объединяем все этапы в единую систему:
Полный код (схематично):
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 6X | github.com/koradeh/AeroCompanion |
| PixEagle | OpenCV + YOLO + MAVSDK для слежения | github.com/alireza787b/PixEagle |
| RAVAN 1.0 | Обнаружение воздушных целей на Pi 5 | ieeexplore.ieee.org (описание) |
| CSUN ARCS | Автономный UAV с YOLOv8 | arcs.center/autonomous-uav |
10. Меры безопасности
Внимание: Перед реальными полётами обязательно соблюдайте следующие правила:
- Всегда тестируйте в симуляторе (Gazebo SITL) перед реальными полетами.
- Установите геозону (виртуальный забор) в полетном контроллере.
- Добавьте аварийную кнопку для немедленной остановки.
- Контролируйте высоту — не позволяйте дрону снижаться ниже безопасного уровня.
- Всегда держите пульт управления наготове для ручного перехвата.
Заключение
Система автозахвата цели на базе Raspberry Pi 5 + Pixhawk — это мощное и доступное решение, которое может быть реализовано с использованием открытого ПО. Ключевые компоненты:
- YOLOv8 для быстрого и точного обнаружения
- KCF/CSRT для устойчивого трекинга
- PID-регулятор для плавного управления
- MAVLink для связи с полетным контроллером
Эта архитектура лежит в основе таких проектов, как AeroCompanion и PixEagle, и может быть адаптирована под самые разные задачи — от поисково-спасательных операций до мониторинга и доставки грузов.
Материал подготовлен на основе открытых источников и проекта AeroCompanion.





