Разбор: события автопилота

← Все разборы примеров

Источник: репозиторий pioneer-team/pioneer-sdk2-example (GitFlic). Справочник по классам API — на странице «Pioneer SDK 2».

subscribe_event.py — подписка

Компактный скрипт демонстрирует реактивный стиль программирования дрона: вместо цикла опроса вы подписываете функцию на события автопилота, и SDK вызывает её сам:

from pioneer_sdk2 import Pioneer, Event  # импортируем классы Pioneer и Event из библиотеки pioneer_sdk2
import time                              # библиотека time содержит функции для работы со временем

def event_activate(event):               # функция вызывается при получении события от дрона
    if event == Event.TAKEOFF_COMPLETE:  # если пришло событие завершения взлета
        drone.led_control(r=0, g=1, b=0) # включаем зеленый свет

    elif event == Event.COPTER_LANDED:   # если пришло событие завершения посадки
        drone.led_control(r=1, g=0, b=0) # включаем красный свет

drone = Pioneer()                        # создаем экземпляр класса Pioneer, устанавливаем соединение

drone.subscribe(event_activate, Event.TAKEOFF_COMPLETE) # вызываем функцию event_activate при завершении взлета
drone.subscribe(event_activate, Event.COPTER_LANDED)    # вызываем функцию event_activate при завершении посадки

try:                                     # основной код находится внутри блока try
    drone.arm()                          # включаем двигатели
    drone.takeoff()                      # взлетаем
    time.sleep(3)                        # ставим паузу на 3 секунды
    drone.land()                         # садимся, двигатели выключатся автоматически

finally:                                 # блок finally выполнится при завершении программы
    drone.close_connection()             # закрываем соединение

Механика:

  • drone.subscribe(fn, Event.X) регистрирует колбэк fn на конкретное событие. Колбэк получает само событие — поэтому один event_activate() способен обслуживать два источника.
  • В примере подписаны два события: TAKEOFF_COMPLETE → зелёные светодиоды, COPTER_LANDED → красные. Управление светодиодом — led_control(r, g, b) значениями 0/1.
  • Полезные события из этой группы: TAKEOFF_COMPLETE, COPTER_LANDED, POINT_REACHED (см. mission_examples — там POINT_REACHED используется для ожидания прилёта в точку).

unsubscribe_event.py — отписка

Показывает зеркальную команду drone.unsubscribe(). Подписка может быть временной — снять её можно прямо в середине программы:

from pioneer_sdk2 import Pioneer, Event  # импортируем классы Pioneer и Event из библиотеки pioneer_sdk2
import time                              # библиотека time содержит функции для работы со временем

def event_activate(event):               # функция вызывается при получении события от дрона
    if event == Event.TAKEOFF_COMPLETE:  # если пришло событие завершения взлета
        drone.led_control(r=0, g=1, b=0) # включаем зеленый свет

drone = Pioneer()                        # создаем экземпляр класса Pioneer, устанавливаем соединение

try:                                     # основной код находится внутри блока try
    drone.subscribe(event_activate, Event.TAKEOFF_COMPLETE) # подписываем функцию на событие завершения взлета

    drone.arm()                          # включаем двигатели
    drone.takeoff()                      # взлетаем

    time.sleep(3)                        # ставим паузу на 3 секунды

    drone.unsubscribe(event_activate, Event.TAKEOFF_COMPLETE) # отписываем функцию от события завершения взлета

    drone.land()                         # садимся, двигатели выключатся автоматически

finally:                                 # блок finally выполнится при завершении программы
    drone.close_connection()             # закрываем соединение

Колбэк живёт только между subscribe() и unsubscribe(): на взлёте LED загорается зелёным, но к моменту посадки подписки уже нет — красный свет не включится.

Когда это полезно

  • Вместо «слепых» пауз: после takeoff() ждите TAKEOFF_COMPLETE, а не time.sleep(10).
  • Цепочки действий: по POINT_REACHED — отправляется следующая точка маршрута; по TAKEOFF_COMPLETE — начинается миссия.
  • Отписка пригодится в сложных программах: например, при переходе в ручной режим снять реакцию на служебные события.