Разбор: события автопилота
Источник: репозиторий 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— начинается миссия. - Отписка пригодится в сложных программах: например, при переходе в ручной режим снять реакцию на служебные события.