Pioneer SDK 2 — программирование на Python

pioneer_sdk2 — вторая версия официальной Python-библиотеки для квадрокоптеров серии «Пионер». На Пионере Мини 2 работает через предустановленную Pioneer OS. Ниже — справочник по всем классам: Pioneer (полёты, телеметрия, события, RC-каналы), Camera, ImageViewer, RecorderControl, ServoCamera — с официальными примерами кода.

Примеры готовых скриптов: страница «Примеры» и репозиторий pioneer-sdk2-example.

Библиотека Pioneer-SDK2

Вторая версия библиотеки для программирования квадрокоптеров серии Пионер на языке Python

Поддержка Pioneer-SDK2 квадрокоптерами серии Пионер

КвадрокоптерыPioneer-SDK2Взаимодействие через:
Мини 2PioneerOS (предустановлен)
Мини
БазовыйМодули: radxa zero или pi zero
FPV
Макс (ROS программирование)

Запуск Python скрипта

В целях безопасности, при выполнении полётного задания, автопилот проверяет "наличие пилота" и при его отсутствии откажется выполнять полет. Подключите пульт управления и переведите тумблер SWB в нижнее положение, при необходимости, проверку можно отключить отредактировав параметр Copter_flyWithoutRc = 1, установив значение 1 в конфигураторе Pioneer Station, а непосредственно запуск производится в используемой вами IDE, например, Visual Studio Code.

Примеры скриптов

Управление через клавиатуру с видео и управление грузом (адаптация примера Pioneer-SDK)

  • Для управления RC-каналами требуется убедиться, что параметры автопилота соответствуют требуемым: Copter_man_rcMode0=6.0, Copter_man_rcMode1=3.0, Copter_man_rcMode2=3.0, Copter_flyWithoutRc=1.0, SensorMux_rc=2.0
  • Управление модулем груза осуществляется с помощью Lua скрипта, но с помощью Python можно имитировать 5 канал (тумблер SWC). Для корректной работы, загрузите соответствующий Lua скрипт на плату автопилота.
  • Стоит учитывать, что в зависимости от качества связи, могут вырастать задержки в исполнении команд, а одиночное нажатие клавиши может быть не отработано.
from pioneer_sdk2 import Pioneer, ImageViewer # импортируем класс Pioneer, ImageViewer из библиотеки pioneer_sdk2
import time                                   # библиотека time содержит функции для работы со временем
import keyboard                               # библиотека keyboard предназначена для работы с клавиатурой

min = 1200 # условно минимальное значение канала, минимум 1000, влияет на скорость max = 1800 # условно максимальное значение канала, максимум 2000, влияет на скорость

drone_1 = Pioneer() # создаем экземпляр класса Pioneer time.sleep(3) # пауза, ожидаем подключения к квадрокоптеру video_drone_1 = ImageViewer() # создаем экземпляр класса ImageViewer

print(""" Управление: _______________________________________________________ 1 - arm | ↶q w↑ e↷ | space ↑ | r - вкл. магнит | 2 - disarm | ←a d→ | ctrl ↓ | f - выкл. магнит | 3 - takeoff | s↓ | | esc - выход из программы | 4 - land |||_______________________| """)

while True: # запускаем бесконечный цикл ch1=1500 # автопилот требует постоянное наличие "радиосигнала", имитируем центральное положение стиков: ch2=1500 ch3=1500 ch4=1500 ch5=2000 # имитация тумблера через который происходит управление магнитом, 2000 = 2 для Lua

video_drone_1.imshow("video", frame, fps=30) # запускаем трансляцию, содержит аргументы: # video - название трансляции # frame - по умолчанию передает изображение в формате BGR # fps=30 - количество кадров в секунду при передаче видео # трансляция выполняется по адресу: 10.42.0.1:8889/video

if keyboard.is_pressed("esc"): # если нажата Esc - завершаем программу drone_1.led_control() # выключаем светодиоды drone_1.land() # производим посадку video_drone_1.stop() # останавливаем видеопоток drone_1.close_connection() # закрываем соединение break # выходим из цикла

elif keyboard.is_pressed("1"): # если нажата 1 - запускаем двигатели drone_1.arm() elif keyboard.is_pressed("2"): # если нажата 2 - выключаем двигатели drone_1.disarm() elif keyboard.is_pressed("3"): # если нажата 3 - взлет drone_1.takeoff() elif keyboard.is_pressed("4"): # если нажата 4 - посадка drone_1.land()

elif keyboard.is_pressed("w"): # если зажата W - летим вперед ch3=min elif keyboard.is_pressed("s"): # если зажата S - летим назад ch3=max elif keyboard.is_pressed("a"): # если зажата A - летим влево ch4=min elif keyboard.is_pressed("d"): # если зажата D - летим вправо ch4=max

elif keyboard.is_pressed("q"): # если зажата Q - поворачиваем налево ch2=max elif keyboard.is_pressed("e"): # если зажата E - поворачиваем направо ch2=min elif keyboard.is_pressed("space"): # если зажат Пробел - набираем высоту ch1=max elif keyboard.is_pressed("ctrl"): # если зажат Ctrl - сбрасываем высоту ch1=min

elif keyboard.is_pressed("r"): # если нажата R - активируем магнит ch5=1000 # 1000 = 0 для Lua drone_1.led_control(g=1) # меняем цвет светодиодов магнита на зеленый elif keyboard.is_pressed("f"): # если нажата F - деактивируем магнит ch5=1500 # 1500 = 1 для Lua drone_1.led_control(r=1) # меняем цвет светодиодов магнита на красный

drone_1.rc_sdk1_to_sdk2( # имитируем значения каналов пульта channel_1=ch1, channel_2=ch2, channel_3=ch3, channel_4=ch4, channel_5=ch5) time.sleep(0.05) # небольшая задержка, улучшает отзывчивость

Смена цвета светодиодов в зависимости от высоты (определение высоты по дальномеру)

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

limit_1 = 0.5 # первая граница высоты limit_2 limit_3 = 1.5 # третья граница высоты

drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение time.sleep(3) # пауза, ожидаем подключения к квадрокоптеру

while True: # запускаем бесконечный цикл height = drone_1.get_dist_sensor_data() # получаем данные высоты и записываем в переменную height

if height is not None: # если данные валидны, выполняем тело условия if keyboard.is_pressed("esc"): # если нажата Esc - завершаем программу drone_1.led_control() # выключаем светодиоды drone_1.close_connection() # закрываем соединение break # выходим из цикла

elif height < limit_1: # если высота меньше limit_1, включаем зеленый свет drone_1.led_control(g=1) elif height < limit_2 and height > limit_1: # если высота меньше limit_2 и больше limit_1, включаем желтый свет drone_1.led_control(r=1, g=0.4) elif height < limit_3 and height > limit_2: # если высота меньше limit_3 и больше limit_2, включаем красный свет drone_1.led_control(r=1) else: # если условия выше ложные, включаем синий свет drone_1.led_control(b=1)

print(height) # выводим полученную высоту в терминал time.sleep(1) # ставим паузу, чтобы не мусорить данными в терминал

Полет по окружности с видео

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

circle = 360 # окружность для полета (в градусах) circle_radius = 0.7 # радиус окружности circle_points = 8 # количество совершаемых остановок на окружности circle_angle = 0 # стартовый угол на окружности перед полетом (в градусах) z = 1.0 # высота полета в метрах

def get_point_on_circle(angle, radius): # функция расчета координат на окружности radians = math.radians(angle) # вычисляем радианы x = radius * math.cos(radians) # вычисляем координату X y = radius * math.sin(radians) # вычисляем координату Y yaw = radians # угол поворота по YAW return x, y, yaw # возвращаем X, Y, YAW

drone_1 = Pioneer() # создаем экземпляр класса Pioneer time.sleep(3) # пауза, ожидаем подключения к квадрокоптеру video_drone_1 = ImageViewer() # создаем экземпляр класса ImageViewer

drone_1.arm() # заводим двигатели drone_1.takeoff() # производим взлет drone_1.go_to_local_point(x=0, y=0, z=z, yaw=0) # набираем заданную высоту полета

while True: # запускаем бесконечный цикл video_drone_1.imshow("video", frame, fps=30) # запускаем трансляцию, содержит аргументы: # video - название трансляции # frame - по умолчанию передает изображение в формате BGR # fps=30 - количество кадров в секунду при передаче видео # трансляция выполняется по адресу: 10.42.0.1:8889/video

if circle_angle >= circle or keyboard.is_pressed("esc"): # проверяем условие drone_1.land() # производим посадку video_drone_1.stop() # останавливаем видеопоток drone_1.close_connection() # закрываем соединение break # выходим из цикла

elif drone_1.point_reached(): # если координата достигнута, выполняем тело x, y, yaw = get_point_on_circle(circle_angle, circle_radius) # получаем координаты обращаясь к функции drone_1.go_to_local_point(x=x, y=y, z=z, yaw=yaw) # летим в полученные координаты circle_angle += circle / circle_points # фиксируем текущий угол на окружности

Калибровка камеры для ArUco-маркеров

  • В результате калибровки будет получен файл data.yml, он должен находиться в одном проекте с основным ArUco скриптом.
  • Узнать больше о калибровке камеры
from pioneer_sdk2 import Camera
import cv2
import numpy as np
import glob
import time

def get_images_from_folder(folder_name, file_type="*.jpg"): # функция для получения изображений из папки images_list = glob.glob(folder_name + "/" + file_type) # берет все jpg файлы из указанной папки images = [] # переменная images с пустым списком for fname in images_list: # перебираем все файлы из папки img = cv2.imread(fname) # читает изображение images.append(img) # сохраняет текущее изображение в список images return images # возвращает список снимков

def get_images_from_drone_camera(camera, save=False): # функция для получения изображений с камеры квадрокоптера images = [] # переменная images с пустым списком print("Сделайте 15 снимков шахматной доски с разным ракурсом") print("Нажмите '1' чтобы сделать снимок") print("Нажмите 'ESC' для завершения") while True: frame = camera.get_cv_frame() # получаем кадр if frame is not None: # проверяем, что кадр получен cv2.imshow("frames", frame) # запускаем видеопоток key = cv2.waitKey(1) # считывает нажатие клавиши и присваивает ее код, переменной

if key == 27: # если нажата клавиша Esc, выполняем тело условия cv2.destroyAllWindows() # останавливаем видеопоток return images # возвращает список снимков

elif key == ord("1"): # если нажата цифра 1, выполняет тело условия images.append(frame) # сохраняет текущее изображение в список images print("Снимок №" + str(len(images))) # выводит в терминал сообщение о номере снимка time.sleep(1) # пауза 1 секунда

if save: # если в функции save=True, сохраняет снимок на компьютер cv2.imwrite("frame_" + str(len(images)) + ".jpg", frame)

def calibrate(images): CHECKERBOARD = (6, 9) # размеры шахматной доски criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

objpoints = [] # Creating vector to store vectors of 3D points for each checkerboard image imgpoints = [] # Creating vector to store vectors of 2D points for each checkerboard image

objp = np.zeros((1, CHECKERBOARD[0] * CHECKERBOARD[1], 3), np.float32) objp[0, :, :2] = np.mgrid[0 : CHECKERBOARD[0], 0 : CHECKERBOARD[1]].T.reshape(-1, 2)

# Extracting path of individual image stored in a given directory for img in images: gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Find the chess board corners # If desired number of corners are found in the image then ret = true ret, corners = cv2.findChessboardCorners( gray, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE)

if ret == True: objpoints.append(objp) # refining pixel coordinates for given 2d points. corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)

imgpoints.append(corners2)

# Draw and display the corners img = cv2.drawChessboardCorners(img, CHECKERBOARD, corners2, ret)

cv2.imshow("img", img) cv2.waitKey(0)

cv2.destroyAllWindows() ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera( objpoints, imgpoints, gray.shape[::-1], None, None ) return mtx, dist

def save_coefficients(mtx, dist, path): """Save the camera matrix and the distortion coefficients to given path/file.""" cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_WRITE) cv_file.write("mtx", mtx) cv_file.write("dist", dist) # note you release you don't close() a FileStorage object cv_file.release()

def load_coefficients(path): """Loads camera matrix and distortion coefficients.""" # FILE_STORAGE_READ cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_READ)

# note we also have to specify the type to retrieve other wise we only get a # FileNode object back instead of a matrix camera_matrix = cv_file.getNode("mtx").mat() dist_coeffs = cv_file.getNode("dist").mat()

cv_file.release() return camera_matrix, dist_coeffs

camera = Camera() images = get_images_from_drone_camera(camera) # получаем изображение с камеры квадрокоптера mtx, dist = calibrate(images) save_coefficients(mtx, dist, "data.yml")

Обнаружение ArUco-маркера

  • Обратите внимание, что в примере используются маркеры размером 4x4_50
from pioneer_sdk2 import Pioneer, Camera
import cv2
import time

aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50) # объект содержит набор маркеров 4х4_50 aruco_params = cv2.aruco.DetectorParameters() # объект содержащий параметры обнаружения aruco_detector = cv2.aruco.ArucoDetector(aruco_dict, aruco_params) # объект для поиска маркеров

camera = Camera()

while True: # запускаем бесконечный цикл frame = camera.get_cv_frame() # получаем кадр if frame is not None: # проверяем, что кадр получен if cv2.waitKey(1) == 27: # если нажата клавиша Esc, выполняем тело условия cv2.destroyAllWindows() # останавливаем видеопоток break # выходим из цикла

else: corners, ids, rejected = aruco_detector.detectMarkers(frame) # записываем данные в переменные # corners - координаты углов маркеров # ids - номер обнаруженного маркера # rejected - область не прошедшая проверку cv2.aruco.drawDetectedMarkers(frame, corners, ids) # рисуем обнаруженную область на кадре cv2.imshow("video", frame) # запускаем видеопоток time.sleep(0.02)

Обнаружение координаты ArUco-маркера

  • Обратите внимание, что в примере используются маркеры размером 4x4_50
  • Для работы примера требуется файл data.yml, его можно получить в результате калибровки камеры
from pioneer_sdk2 import Camera
import cv2
import numpy as np
import time

def load_coefficients(path): cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_READ)

camera_matrix = cv_file.getNode("mtx").mat() dist_coeffs = cv_file.getNode("dist").mat()

cv_file.release() return camera_matrix, dist_coeffs

aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50) # объект содержит набор маркеров 4х4_50 aruco_params = cv2.aruco.DetectorParameters() # объект содержащий параметры обнаружения aruco_detector = cv2.aruco.ArucoDetector(aruco_dict, aruco_params) # объект для поиска маркеров

camera_matrix, dist_coeffs = load_coefficients("data.yml")

size_of_marker = 0.05

points_of_marker = np.array( [ (size_of_marker / 2, -size_of_marker / 2, 0), (-size_of_marker / 2, -size_of_marker / 2, 0), (-size_of_marker / 2, size_of_marker / 2, 0), (size_of_marker / 2, size_of_marker / 2, 0), ] )

camera = Camera()

while True: # запускаем бесконечный цикл frame = camera.get_cv_frame() # получаем кадр if frame is not None: # проверяем, что кадр получен if cv2.waitKey(1) == 27: # если нажата клавиша Esc, выполняем тело условия cv2.destroyAllWindows() # останавливаем видеопоток break # выходим из цикла

else: corners, ids, rejected = aruco_detector.detectMarkers(frame) # записываем данные в переменные # corners - координаты углов маркеров # ids - номер обнаруженного маркера # rejected - область не прошедшая проверку if corners: success, rvecs, tvecs = cv2.solvePnP( points_of_marker, corners[0], camera_matrix, dist_coeffs)

print(success, tvecs) cv2.drawFrameAxes(frame, camera_matrix, dist_coeffs, rvecs, tvecs, 0.1) cv2.imshow("video", frame) # запускаем видеопоток time.sleep(0.02)

Следование за ArUco-маркером

from pioneer_sdk2 import Pioneer, Camera
import cv2
import numpy as np
import threading
import time
from collections import deque

def load_coefficients(path): cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_READ) camera_matrix = cv_file.getNode("mtx").mat() dist_coeffs = cv_file.getNode("dist").mat() cv_file.release() return camera_matrix, dist_coeffs

class VideoProcessingThread(threading.Thread): def init(self, camera_matrix, dist_coeffs): super().init() self.camera_matrix = camera_matrix self.dist_coeffs = dist_coeffs self.running = True self.latest_coordinates = None self.x_center = None self.frame = None

self.frame_times = deque(maxlen=30) self.last_fps_log_time = time.time()

self.aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50) self.aruco_params = cv2.aruco.DetectorParameters() self.aruco_detector = cv2.aruco.ArucoDetector(self.aruco_dict, self.aruco_params)

self.size_of_marker = 0.1 self.points_of_marker = np.array([ (self.size_of_marker / 2, -self.size_of_marker / 2, 0), (-self.size_of_marker / 2, -self.size_of_marker / 2, 0), (-self.size_of_marker / 2, self.size_of_marker / 2, 0), (self.size_of_marker / 2, self.size_of_marker / 2, 0), ])

self.camera = Camera()

def run(self): while self.running: try: frame = self.camera.get_cv_frame() corners, ids, _ = self.aruco_detector.detectMarkers(frame)

if ids is not None and len(corners) > 0: x_center = int(sum([p[0] for p in corners[0][0]]) / 4) y_center = int(sum([p[1] for p in corners[0][0]]) / 4) dot_size = 5 frame[y_center - dot_size:y_center + dot_size, x_center - dot_size:x_center + dot_size] = [0, 0, 255] cv2.aruco.drawDetectedMarkers(frame, corners)

success, rvecs, tvecs = cv2.solvePnP( self.points_of_marker, corners[0], self.camera_matrix, self.dist_coeffs ) if success: self.latest_coordinates = [tvecs.item(0), tvecs.item(1), tvecs.item(2)] self.x_center = x_center else: self.latest_coordinates = None self.x_center = None else: self.latest_coordinates = None self.x_center = None

self.frame = frame.copy()

now = time.time() self.frame_times.append(now) if now - self.last_fps_log_time > 2.0 and len(self.frame_times) > 1: fps = len(self.frame_times) / (self.frame_times[-1] - self.frame_times[0]) print(f"[Video Thread] FPS: {fps:.2f}") self.last_fps_log_time = now

except cv2.error as e: print(f"[Video Thread] OpenCV error: {e}") continue

def stop(self): self.running = False

camera_matrix, dist_coeffs = load_coefficients("data.yml") video_thread = VideoProcessingThread(camera_matrix, dist_coeffs) video_thread.start()

drone_1 = Pioneer() send_manual_speed = False airborne = False

try: while True: coordinates = video_thread.latest_coordinates x_center = video_thread.x_center frame = video_thread.frame

v_y = 0 yaw_rate = 0

if airborne and coordinates is not None and x_center is not None: distance = np.linalg.norm(coordinates) print(f"Distance: {distance:.2f} m")

if distance > 1.5: v_y = 0.4 elif distance < 1: v_y = -0.4

if x_center < frame.shape[1] / 3: yaw_rate = -0.4 elif x_center > frame.shape[1] * 2 / 3: yaw_rate = 0.4

# Если маркер виден и есть команды движения if airborne and (v_y != 0 or yaw_rate != 0): drone_1.set_manual_speed_body_fixed(vx=0, vy=v_y, vz=0, yaw_rate=yaw_rate) send_manual_speed = True

# Если маркер потерян, и до этого коптер двигался — остановка elif airborne and send_manual_speed: print("[INFO] Marker lost. Stopping drone.") drone_1.go_to_local_point_body_fixed(x=0, y=0, z=0, yaw=0) send_manual_speed = False

if frame is not None: cv2.imshow("marker_detection", frame)

key = cv2.waitKey(1) if key == 27: # Esc break elif key == 32 and not airborne: # Space print("[INFO] Takeoff initiated.") drone_1.arm() drone_1.takeoff() drone_1.go_to_local_point(x=0, y=0, z=1.5, yaw=0) while not drone_1.point_reached(): time.sleep(0.1) airborne = True print("[INFO] Drone reached hover point.")

finally: print("Landing...") video_thread.stop() video_thread.join() cv2.destroyAllWindows() if airborne: drone_1.land() drone_1.close_connection() del drone_1

Вторая версия библиотеки для программирования квадрокоптеров серии Пионер на языке Python

  • Обратите внимание, что в примере используются маркеры размером 4x4_50
  • Обратите внимание, что в примере используются маркеры размером 4x4_50
  • Обратите внимание, что в примере используются маркеры размером 4x4_50

Класс Pioneer

Основной класс для взаимодействия с квадрокоптерами серии Пионер

Инициализация класса Pioneer

Создание экземпляра класса Pioneer (Мини 2, Radxa Zero)

drone_1 = Pioneer() - создает переменную drone_1 которой присваивается объект класса Pioneer().

from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2

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

Создание экземпляра класса Pioneer (Raspberry Pi Zero)

drone_1 = Pioneer() - создает переменную drone_1 которой присваивается объект класса Pioneer().

from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2

pi_zero_1 = Pioneer(tcp="10.42.0.1:20556") # создаем экземпляр класса Pioneer, устанавливаем соединение с модулем # если модуль соединяется с вами, используйте tcp указанный в свойствах системы

Управление полетом

Полетные методы имеют две особенности:

  • При вызове некоторых полетных методов, выполнение основной программы будет заблокировано до тех пор, пока метод не получит ответ (события автопилота) о его успешном выполнении, о необходимости ожидания конкретного события будет описано в методах. Например, вы заводите двигатели и сразу же хотите включите светодиоды, но так как программа выполняется построчно, то сперва придется дождаться подтверждения запуска двигателей и только потом светодиоды включатся, а в случае, если двигатели не запускаются, программа завершится досрочно. При желании проверку событий можно отключить, для этого при создании экземпляра класса Pioneer в аргументах следует указать wait_callback=False, следует учитывать, что это также отключает вторую особенность, о которой ниже.
  • При вызове некоторых полетных методов производится контроль состояния полета, всего есть 3 состояния: ON_LAND (на земле, двигатели выключены), ARMED (на земле, двигатели включены), IN_SKY (в воздухе). В зависимости от того, в каком состоянии находится квадрокоптер при вызове полетного метода, метод будет выполнен или в выполнении будет отказано. Например, нельзя вызвать полет по координатам, если состояние не равно IN_SKY, подробнее о взаимодействии методов с состояниями будет описано непосредственно в методах. При желании контроль состояния можно отключить, для этого при создании экземпляра класса Pioneer в аргументах следует указать safety_command=False.

Включить и выключить двигатели

arm(timeout, retries) - включает двигатели.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Ожидает событие ENGINES_STARTED.
  • Вызов в состоянии ARMED игнорируется.
  • Вызов в состоянии IN_SKY игнорируется.

disarm() выключает двигатели.

  • Возвращает True, если команда успешно отправлена, иначе False.
from pioneer_sdk2 import Pioneer  # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                       # библиотека time содержит функции для работы со временем

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

drone_1.arm(timeout=5, retries=0) # включаем двигатели, содержит аргументы: # timeout(5) - задержка в секундах перед запуском двигателей # retries(0) - количество повторных попыток запуска двигателей

time.sleep(3) # ставим паузу на 3 секунды drone_1.disarm() # выключаем двигатели drone_1.close_connection() # закрываем соединение

Взлет и посадка

takeoff() - выполняет взлет до высоты указанной в параметре Copter_com_takeoffAlt.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Ожидает событие TAKEOFF_COMPLETE.
  • Вызов в состоянии ARMED доступен.
  • Вызов в состоянии ON_LAND игнорируется.
  • Вызов в состоянии IN_SKY вызывает ошибку RuntimeError.

land() - выполняет посадку, двигатели выключатся автоматически.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Ожидает событие COPTER_LANDED.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

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

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Полет в координаты (локальные)

go_to_local_point(x, y, z, yaw, time) - полет в заданную координату, на основе локальной системы координат.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Метод не является блокирующим, это значит, что после вызова метода, следует поставить паузу или использовать флаг достижения координаты point_reached, чтобы квадрокоптер не переключился на выполнение следующей команды.
  • Вызов в состоянии ARMED вызывает ошибку RuntimeError.
  • Вызов в состоянии ON_LAND игнорируется.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

drone_1

try: # конструкция try-except, основной код находится внутри блока try drone_1.arm() # включаем двигатели drone_1.takeoff() # взлетаем time.sleep(3) # ставим паузу на 3 секунды drone_1.go_to_local_point(0, 0, 1.5, 0, 0) # вызываем метод, содержит аргументы: # x(0) - координата по оси "x" (в метрах) # y(0) - координата по оси "y" (в метрах) # z(1.5) - координата по оси "z" (в метрах) # yaw(0) - поворот по курсу (в радианах) # time(0) - время за которое требуется достигнуть координату

time.sleep(5) # ставим паузу на 5 секунд drone_1.land() # садимся, двигатели выключатся автоматически drone_1.close_connection() # закрываем соединение

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Полет в координаты (внутренние)

go_to_local_point_body_fixed(x, y, z, yaw, time) - полет в заданную координату, на основе внутренних координат квадрокоптера.

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

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

try: # конструкция try-except, основной код находится внутри блока try drone_1.arm() # включаем двигатели drone_1.takeoff() # взлетаем time.sleep(3) # ставим паузу на 3 секунды drone_1.go_to_local_point_body_fixed(0, 0, 1.5, 0, 0) # вызываем метод, содержит аргументы: # x(0) - координата по оси "x" (в метрах) # y(0) - координата по оси "y" (в метрах) # z(1.5) - координата по оси "z" (в метрах) # yaw(0) - поворот по курсу (в радианах) # time(0) - время за которое требуется достигнуть координату

time.sleep(5) # ставим паузу на 5 секунд drone_1.land() # садимся, двигатели выключатся автоматически drone_1.close_connection() # закрываем соединение

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Полет в координаты (GPS)

go_to_global_point(latitude, longitude, altitude, yaw) - полет в заданную координату, на основе GPS координат.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Метод не является блокирующим, это значит, что после вызова метода, следует поставить паузу или использовать флаг достижения координаты point_reached, чтобы квадрокоптер не переключился на выполнение следующей команды.
  • Вызов в состоянии ARMED вызывает ошибку RuntimeError.
  • Вызов в состоянии ON_LAND игнорируется.
  • Если точка старта будет дальше, чем в 500 метрах от фактического местоположения, квадрокоптер откажется взлетать.
  • Параметры автопилота Flight_com_flyAreaSize, Flight_com_maxAltitude ограничивают расстояние и высоту, на которую квадрокоптер может улететь от точки старта.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

# в целях безопасности, отправим квадрокоптер в его же координаты с небольшим набором высоты

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

while True: # запускаем бесконечный цикл coord = drone_1.get_local_position_lps() # запоминаем текущие координаты if coord is not None: # проверяем, что координаты определены my_latitude, my_longitude, my_altitude = coord # распределяем координаты по разным переменным break # выходим из цикла

print(f"Широта", my_latitude) # выводим в терминал текущую широту print(f"Долгота", my_latitude) # выводим в терминал текущую доготу print(f"Высота", my_latitude) # выводим в терминал текущую высоту my_altitude += 1 # добавляем к текущей высоте 1 метр

drone_1.go_to_global_point(latitude = my_latitude, # вызываем метод, latitude - широта longitude = my_longitude, # longitude - долгота altitude = my_altitude, # altitude - высота yaw=0) # yaw(0) - азимут

time.sleep(5) # ставим паузу на 5 секунд drone_1.land() # садимся, двигатели выключатся автоматически drone_1.close_connection() # закрываем соединение

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Полет в координаты (относительно GPS)

go_to_global_point_relative(latitude_offset, longitude_offset, altitude_offset, yaw) - полет в заданную координату, с произвольным смещением на основе GPS координат.

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

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

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

drone_1.go_to_global_point_relative(latitude_offset = 0, # вызываем метод, latitude_offset - смещение по широте longitude_offset = 0, # longitude_offset - смещение по долготе altitude_offset = 1, # altitude_offset - смещение по высоте yaw=0) # yaw(0) - азимут

time.sleep(5) # ставим паузу на 5 секунд drone_1.land() # садимся, двигатели выключатся автоматически drone_1.close_connection() # закрываем соединение

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Флаг достижения координаты

point_reached() - сообщает о достижении целевой координаты, позволяет избавиться от необходимости указывать метод time.sleep().

  • Возвращает True, если заданная координата достигнута, иначе False.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

try drone_1.arm() # включаем двигатели drone_1.takeoff() # взлетаем time.sleep(3) # ставим паузу на 3 секунды drone_1.go_to_local_point(0, 0, 1.5, 0, 0) # отправляем квадрокоптер в заданные координаты while not drone_1.point_reached(): # запускаем цикл, код будет повторяться, пока условие верно time.sleep(1)

drone_1.land() # садимся, двигатели выключатся автоматически drone_1.close_connection() # закрываем соединение

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Флаг приближения к целевой координате

point_deceleration() - сообщает о приближении к целевой координаты, начинается оттормаживание.

  • Возвращает True, если заданная координата близка к достижению, иначе False.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

try drone_1.arm() # включаем двигатели drone_1.takeoff() # взлетаем time.sleep(3) # ставим паузу на 3 секунды drone_1.go_to_local_point(0, 0, 1.5, 0, 0) # отправляем квадрокоптер в заданные координаты while not drone_1.point_reached(): # запускаем цикл, код будет повторяться, пока условие верно if drone_1.point_deceleration(): # если целевая позицию близко, выполняем код print("Я близко, начинаю торможение") # выводим сообщение в терминал

else: time.sleep(1)

drone_1.land() # садимся, двигатели выключатся автоматически drone_1.close_connection() # закрываем соединение

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Задать скорость по осям (локальным)

set_manual_speed(vx, vy, vz, yaw_rate, interval) - полет с заданной скоростью, на основе локальных координат.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Вызов в состоянии ARMED вызывает ошибку RuntimeError.
  • Вызов в состоянии ON_LAND игнорируется.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

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

drone_1.set_manual_speed(0, 0, 0.2, 0, 5) # вызываем метод, содержит аргументы: # vx(0) - скорость по оси "x" (м/с) # vy(0) - скорость по оси "y" (м/с) # vz(0.2) - скорость по оси "z" (м/с) # yaw_rate(0) - скорость поворота по курсу (м/с) # interval(5) - время в течении которого метод активен

time.sleep(3) # ставим паузу на 3 секунды drone_1.land() # садимся, двигатели выключатся автоматически drone_1.close_connection() # закрываем соединение

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Задать скорость по осям (внутренним)

set_manual_speed_body_fixed(vx, vy, vz, yaw_rate, interval) - полет с заданной скоростью, на основе внутренних координат квадрокоптера.

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

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

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

drone_1.set_manual_speed_body_fixed(0, 0, 0.2, 0, 5) # вызываем метод, содержит аргументы: # vx(0) - скорость по оси "x" (м/с) # vy(0) - скорость по оси "y" (м/с) # vz(0.2) - скорость по оси "z" (м/с) # yaw_rate(0) - скорость поворота по курсу (рад/с) # interval(5) - время в течении которого метод активен

time.sleep(3) # ставим паузу на 3 секунды drone_1.land() # садимся, двигатели выключатся автоматически drone_1.close_connection() # закрываем соединение

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Задать курс

set_yaw(yaw) - задать курс (рысканье или yaw) в градусах.

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

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

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

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Вернуть в домашнюю координату

rtl() - возвращает квадрокоптер в координату после выполнения метода takeoff().

  • Возвращает True, если команда успешно отправлена, иначе False.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

try: # конструкция try-except, основной код находится внутри блока try drone_1.arm() # включаем двигатели drone_1.takeoff() # взлетаем time.sleep(3) # ставим паузу на 3 секунды drone_1.go_to_local_point(0, 0, 1.5, 0, 0) # набираем высоту до 1.5 метра time.sleep(5) # ставим паузу на 5 секунд drone_1.rtl() # возвращаем квадрокоптер на место взлета time.sleep(5) # ставим паузу на 5 секунд drone_1.land() # садимся, двигатели выключатся автоматически drone_1.close_connection() # закрываем соединение

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Узнать состояние полета

get_fly_state() - возвращает текущее состояние полета: ON_LAND, ARMED, IN_SKY

from pioneer_sdk2 import Pioneer  # импортируем класс Pioneer из библиотеки pioneer_sdk2

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

print(drone_1.get_fly_state()) # выводим в терминал результат работы метода drone_1.close_connection() # закрываем соединение

Дополнительные возможности

Управление светодиодами

led_control(led_id=255, r=0, g=0, b=0) - управляет яркостью субпикселей светодиодов.

  • Возвращает True, если команда успешно отправлена, иначе False.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

drone_1.led_control(255, r=1, g=1, b=1) # вызываем метод, включаем все светодиоды (яркий белый) # led_id - номер светодиода, нумерация начинается с 0, выбор всех светодиодов = 255 # r - управление яркостью красного субпикселя, где 0 = 0%, а 1 = 100% # g - управление яркостью зеленого субпикселя, где 0 = 0%, а 1 = 100% # b - управление яркостью синего субпикселя, где 0 = 0%, а 1 = 100%

time.sleep(2) # ставим паузу на 2 секунды drone_1.led_control(0, r=1, g=0, b=0) # включаем светодиод №0 (яркий красный) time.sleep(2) drone_1.led_control(1, r=0, g=0.5, b=0) # включаем светодиод №1 (средней яркости зеленый) time.sleep(2) drone_1.led_control(2, r=0, g=0, b=0.1) # включаем светодиод №2 (тусклый синий) time.sleep(2) drone_1.led_control(3, r=1, g=0.4, b=0) # включаем светодиод №3 (желтый) time.sleep(2) drone_1.led_control(255, r=0, g=0, b=0) # выключаем все светодиоды drone_1.close_connection() # закрываем соединение

Выполнить перезагрузку

reboot_board() - выполняет перезагрузку платы автопилота.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Всегда возвращает False на Мини 2.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

drone_1.reboot_board() drone_1.close_connection() # закрываем соединение

Узнать значение параметра автопилота

get_param(name, update) - меняет значение указанного параметра автопилота.

  • update=False - возвращает значение полученное при включении квадрокоптера (кэш).
  • update=True - принудительно считывает значение из автопилота и возвращает его.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

print(drone_1.get_param(Flight_com_navSystem)) # выводим в терминал значение указанного параметра drone_1.close_connection() # закрываем соединение

Изменить значение параметра автопилота

set_param(name, value) - меняет значение указанного параметра автопилота.

  • Возвращает True, если выполнено, иначе False.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

print(drone_1.get_param(Flight_com_navSystem)) # выводим в терминал значение указанного параметра drone_1.set_param(Flight_com_navSystem, 2) # меняем значение на 2 (OPT навигация) print(drone_1.get_param(Flight_com_navSystem, True)) # выводим в терминал значение указанного параметра (считываем из автопилота) drone_1.close_connection() # закрываем соединение

Включить или выключить логирование методов

set_logger(value=True) - включает или выключает ответы о результатах выполнения методов для объекта, по умолчанию включено.

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

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

drone_1.led_control(g=0.5) # вызываем смену цвета светодиодов, ответ будет выведен в терминал print("Выше находится ответ о подключении и выполнении метода") # выводим сообщение в терминал print("Выключил логирование, вызываю смену цвета светодиодов") # выводим сообщение в терминал

drone_1.set_logger(value=False) # вызываем метод, выключаем логирование drone_1.led_control(b=0.5) # вызываем смену цвета светодиодов, ответ не будет выведен в терминал print("\nВыше отсутствует ответ о выполнении метода") # выводим сообщение в терминал drone_1.close_connection() # закрываем соединение

Получение данных

Узнать локальные координаты

get_local_position_lps() - позволяет узнать локальный координаты. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_local_position_lps(True)) # вызываем метод time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать высоту (барометр)

get_altitude() - позволяет узнать высоту с барометра. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_altitude()) # вызываем метод time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать высоту (дальномер)

get_dist_sensor_data() - позволяет узнать высоту с дальномера. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_dist_sensor_data()) # вызываем метод time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать данные оптического потока

get_optical_data() - позволяет узнать данные модуля оптической навигации. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_optical_data(True)) # вызываем метод time.sleep(0.5) # ставим паузу на 0.5 секунды

drone_1.close_connection() # закрываем соединение

Узнать напряжение аккумулятора

get_battery_status() - позволяет узнать напряжение и температуру аккумулятора. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_battery_status()) # вызываем метод time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать углы наклона по осям

get_orientation() - возвращает ориентацию дрона по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_orientation()) # вызываем метод time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать ускорение

get_accel() - возвращает ускорение квадрокоптера по осям X, Y, Z. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_accel()) # вызываем метод time.sleep(0.5) # ставим паузу на 0.5 секунды

drone_1.close_connection() # закрываем соединение

Узнать угловую скорость

get_gyro() - возвращает скорость по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_gyro()) # вызываем метод time.sleep(0.5) # ставим паузу на 0.5 секунды

drone_1.close_connection() # закрываем соединение

Показания магнитометра (GPS)

get_mag() - возвращает показания магнитометра по осям X, Y, Z. None, если ошибка. Только при наличии GPS модуля.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_mag()) # вызываем метод time.sleep(0.5) # ставим паузу на 0.5 секунды

drone_1.close_connection() # закрываем соединение

Обороты моторов

get_motors_rpm() - возвращает обороты каждого из 4 моторов квадрокоптера. None, если ошибка.

Узнать активную систему навигации

get_nav_system(update=False) - возвращает выбранную систему навигации.

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

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

print(drone_1.get_nav_system()) # выводим активную систему навигации в терминал # NavSystem.GPS # NavSystem.LPS # NavSystem.OPT

drone_1.close_connection() # закрываем соединение

Узнать состояние LPS

get_nav_status_lps() - возвращает статус LPS навигации.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_nav_status_lps()) # выводим состояние LPS навигации в терминал # NavStatus.NO_DATA - нет данных с LPS модуля # NavStatus.CANNOT - невозможно оценить позицию # NavStatus.LOW - низкое доверие к оценке позиции # NavStatus.OK - позиция определена

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

drone_1.close_connection() # закрываем соединение

Узнать скорость по осям

get_local_velocity_lps() - возвращает скорость по осям X, Y, Z в м/с. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_local_velocity_lps()) # выводим текущую скорость в терминал time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать курсовой угол

get_local_yaw_lps() - возвращает текущий курсовой угол (рысканье). None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_local_yaw_lps()) # выводим текущий угол в терминал time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать состояние GPS

get_nav_status_gps() - возвращает статус GPS навигации.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_nav_status_gps()) # выводим состояние GPS навигации в терминал # NavStatus.NO_DATA - нет данных с GPS модуля # NavStatus.CANNOT - невозможно оценить позицию # NavStatus.LOW - низкое доверие к оценке позиции # NavStatus.OK - позиция определена

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

drone_1.close_connection() # закрываем соединение

Узнать координаты GPS

get_global_position_gps() - возвращает координаты по GPS. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_global_position_gps()) # выводим GPS координаты в терминал time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать скорость по GPS

get_global_velocity_gps() - возвращает скорость по GPS. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_global_velocity_gps()) # выводим текущую скорость по GPS в терминал time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать количество спутников

get_satellites_count() - возвращает количество обнаруженных спутников GPS и ГЛОНАСС. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_satellites_count()) # выводим количество спутников в терминал # [GPS, ГЛОНАСС] time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать время работы (GPS)

time() - возвращает время работы квадрокоптера в секундах с момента начала GPS-эпохи. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.time()) # выводим в терминал время работы time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать время работы квадрокоптера

uptime() - возвращает время работы квадрокоптера в секундах, прошедшее с момента идентификации в системе навигации. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.uptime()) # выводим в терминал время работы time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Узнать время полета квадрокоптера

flight_time() - возвращает время с начала полета квадрокоптера в секундах. None, если ошибка.

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

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

while True: # запускаем бесконечный цикл print(drone_1.flight_time()) # выводим в терминал время работы time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Управление RC-каналами

Для управления RC-каналами требуется убедиться, что параметры автопилота соответствуют требуемым: Copter_man_rcMode0=6.0, Copter_man_rcMode1=3.0, Copter_man_rcMode2=3.0, Copter_flyWithoutRc=1.0, SensorMux_rc=2.0

  • Важно понимать, что автопилот требует постоянного наличия "сигнала" на каналах, используйте циклы.

Имитация пульта

send_rc_channels(channel_1, channel_2, channel_3, channel_4, channel_5, channel_6, channel_7, channel_8) - выполняет имитацию приема каналов пульта радиоуправления.

  • Возвращает True, если команда успешно отправлена, иначе False.
from pioneer_sdk2 import Pioneer  # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                       # библиотека time содержит функции для работы со временем

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

try: # конструкция try-except, основной код находится внутри блока try while True: drone_1.send_rc_channels( # вызываем метод channel_1 = 0, # правый стик (влево -1, центр 0, вправо 1) channel_2 = 0, # правый стик (вперед -1, центр 0, назад 1) channel_3 = 0, # левый стик (вверх 1, центр 0, вниз -1) channel_4 = 0, # левый стик (налево 1, центр 0, направо -1) channel_5 = 1, # тумблер SWC (вверх 0, центр 1, вниз 2) channel_6 = 0, # тумблер SWD (вверх 0, вниз 2) channel_7 = 1, # тумблер SWB (вверх 0, центр 1, вниз 2) channel_8 = 0) # тумблер SWA (вверх 0, вниз 2)

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.close_connection()

Конвертация каналов

rc_sdk1_to_sdk2(channel_1=0, channel_2=0, channel_3=0, channel_4=0, channel_5=2000) - выполняет конвертацию значений каналов из pioneer_sdk в pioneer_sdk2. Использование данного метода целесообразно, если у вас есть программы написанные для pioneer_sdk и вы хотите перенести их в pioneer_sdk2 без изменений каналов.

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

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

try: # конструкция try-except, основной код находится внутри блока try while True: channels = drone_1.rc_sdk1_to_sdk2( # вызываем метод channel_1 = 1500, # правый стик (влево -1, центр 0, вправо 1) channel_2 = 1500, # правый стик (вперед -1, центр 0, назад 1) channel_3 = 1500, # левый стик (вверх 1, центр 0, вниз -1) channel_4 = 1500, # левый стик (налево 1, центр 0, направо -1) channel_5 = 2000) # тумблер SWC (2000) drone_1.send_rc_channels( *channels, channel_6=0, channel_7=1, channel_8=0 )

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.close_connection()

Узнать значение 8 канала

get_rc_channel() - возвращает значение 8 канала. None, если ошибка.

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

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

print(drone_1.get_rc_channel()) # выводим значение 8 канала в терминал drone_1.close_connection() # закрываем соединение

Выполнить код по тумблеру

set_rc_trigger() - позволяет выполнить часть кода в паралельном потоке при переключении тумблеров пульта радиоуправления, не прерывая выполнение основной задачи. Работает только на изменение значений тумблеров.

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

def green_blink(channel_8): # создаем функцию green_blink с проверкой 8 канала global drone_1 # обращаемся к глобальной версии объекта, не создаем новый объект

if channel_8 == 2: # если значение 8 канала равно 2, мигаем зеленым drone_1.led_control(r=0, g=1, b=0) time.sleep(0.5) drone_1.led_control(r=0, g=0, b=0)

else: # в противном случае, выключаем светодиоды drone_1.led_control(r=0, g=0, b=0)

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

drone_1.set_rc_trigger(green_blink) # вызываем метод и передаем имя функции # добавьте сюда произвольный код, он не прервет исполнение функции drone_1.close_connection() # закрываем соединение

Обработка событий автопилота

Список событий

Подписка на событие

subscribe(callback, event) - позволяет выполнить часть кода в паралельном потоке при срабатывания выбранного события, не прерывая выполнение основной задачи. Работает только на события автопилота.

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

def event_activate(event): # создаем функцию green_blink с проверкой 8 канала global drone_1 # обращаемся к глобальной версии объекта, не создаем новый

if event == Event.TAKEOFF_COMPLETE: # если пришло событие "взлет", то включаем зеленый свет drone_1.led_control(r=0, g=1, b=0)

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

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

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

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

except: # конструкция try-except, в случае ошибки будет выполнен блок except drone_1.land() drone_1.close_connection()

Отписка от события

unsubscribe(callback, event) - позволяет отписаться от события на которое раньше была активна подписка. Работает только на события автопилота.

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

def event_activate(event): # создаем функцию green_blink с проверкой 8 канала global drone_1 # обращаемся к глобальной версии объекта, не создаем новый

if event == Event.TAKEOFF_COMPLETE: # если пришло событие "взлет", то включаем зеленый свет drone_1.led_control(r=0, g=1, b=0)

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

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

Управление полезной нагрузкой (только Мини 2)

Открыть захват

grab_open(movement_time=0, velocity=100) - открывает захват квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

drone_1.grab_open(movement_time=3, velocity=50) # открываем захват, содержит аргументы: # movement_time - время открытия захвата, 0 - до упора # velocity - cкорость открытия (0% - 100%)

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

Закрыть захват

grab_close(movement_time=0, velocity=100) - закрывает захват квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

drone_1.grab_close(movement_time=3, velocity=50) # закрываем захват, содержит аргументы: # movement_time - время закрытия захвата, 0 - до упора # velocity - cкорость открытия (0% - 100%)

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

Остановить захват

grab_stop() - останавливает движение захвата квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time                      # библиотека time содержит функции для работы со временем

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

drone_1.grab_open(movement_time=3, velocity=50) # открываем захват drone_1.grab_stop() # останавливаем захват

drone_1.close_connection() # закрываем соединение

Данные модуля Ranger

get_ranger_data() - возвращает данные с модуля Ranger, установленный на "Пионер Мини 2".

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

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

while True: # запускаем бесконечный цикл print(drone_1.get_ranger_data()) # вызываем метод time.sleep(1) # ставим паузу на 1 секунду

drone_1.close_connection() # закрываем соединение

Управление магнитом (только Базовый)

Вкл/выкл магнит (способ 1)

cargo_grab() - включает магнит.

cargo_release() - выключает магнит.

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

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

drone_1.cargo_grab() # включает магнит time.sleep(3) # ставим паузу на 3 секунды drone_1.cargo_release() # включает магнит drone_1.close_connection() # закрываем соединение

Вкл/выкл магнит (способ 2)

cargo_set() - включает или выключает магнит в зависимости от аргумента.

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

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

drone_1.cargo_set(True) # включает магнит time.sleep(3) # ставим паузу на 3 секунды drone_1.cargo_set(False) # включает магнит drone_1.close_connection() # закрываем соединение

from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2

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

drone_1 = Pioneer() - создает переменную drone_1 которой присваивается объект класса Pioneer().

Полетные методы имеют две особенности:

arm(timeout, retries) - включает двигатели.

disarm() выключает двигатели.

  • Возвращает True, если команда успешно отправлена, иначе False.

takeoff() - выполняет взлет до высоты указанной в параметре Copter_com_takeoffAlt.

land() - выполняет посадку, двигатели выключатся автоматически.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Ожидает событие COPTER_LANDED.

go_to_local_point(x, y, z, yaw, time) - полет в заданную координату, на основе локальной системы координат.

go_to_local_point_body_fixed(x, y, z, yaw, time) - полет в заданную координату, на основе внутренних координат квадрокоптера.

go_to_global_point(latitude, longitude, altitude, yaw) - полет в заданную координату, на основе GPS координат.

point_reached() - сообщает о достижении целевой координаты, позволяет избавиться от необходимости указывать метод time.sleep().

  • Возвращает True, если заданная координата достигнута, иначе False.

point_deceleration() - сообщает о приближении к целевой координаты, начинается оттормаживание.

  • Возвращает True, если заданная координата близка к достижению, иначе False.

set_manual_speed(vx, vy, vz, yaw_rate, interval) - полет с заданной скоростью, на основе локальных координат.

set_yaw(yaw) - задать курс (рысканье или yaw) в градусах.

rtl() - возвращает квадрокоптер в координату после выполнения метода takeoff().

  • Возвращает True, если команда успешно отправлена, иначе False.

get_fly_state() - возвращает текущее состояние полета: ON_LAND, ARMED, IN_SKY

led_control(led_id=255, r=0, g=0, b=0) - управляет яркостью субпикселей светодиодов.

  • Возвращает True, если команда успешно отправлена, иначе False.

reboot_board() - выполняет перезагрузку платы автопилота.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Всегда возвращает False на Мини 2.

get_param(name, update) - меняет значение указанного параметра автопилота.

set_param(name, value) - меняет значение указанного параметра автопилота.

  • Возвращает True, если выполнено, иначе False.

set_logger(value=True) - включает или выключает ответы о результатах выполнения методов для объекта, по умолчанию включено.

grab_open(movement_time=0, velocity=100) - открывает захват квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.

grab_close(movement_time=0, velocity=100) - закрывает захват квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.

grab_stop() - останавливает движение захвата квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.

get_ranger_data() - возвращает данные с модуля Ranger, установленный на "Пионер Мини 2".

cargo_grab() - включает магнит.

cargo_release() - выключает магнит.

cargo_set() - включает или выключает магнит в зависимости от аргумента.

takeoff() - выполняет взлет до высоты указанной в параметре Copter_com_takeoffAlt.

land() - выполняет посадку, двигатели выключатся автоматически.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Ожидает событие COPTER_LANDED.

go_to_local_point(x, y, z, yaw, time) - полет в заданную координату, на основе локальной системы координат.

go_to_local_point_body_fixed(x, y, z, yaw, time) - полет в заданную координату, на основе внутренних координат квадрокоптера.

go_to_global_point(latitude, longitude, altitude, yaw) - полет в заданную координату, на основе GPS координат.

get_fly_state() - возвращает текущее состояние полета: ON_LAND, ARMED, IN_SKY

grab_close(movement_time=0, velocity=100) - закрывает захват квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.

grab_stop() - останавливает движение захвата квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.

get_ranger_data() - возвращает данные с модуля Ranger, установленный на "Пионер Мини 2".

time.sleep(3) # ставим паузу на 3 секундыdrone_1.cargo_release() # включает магнит drone_1.close_connection() # закрываем соединение

cargo_set() - включает или выключает магнит в зависимости от аргумента.

Основной класс для взаимодействия с квадрокоптерами серии Пионер

drone_1 = Pioneer() - создает переменную drone_1 которой присваивается объект класса Pioneer().

drone_1 = Pioneer() - создает переменную drone_1 которой присваивается объект класса Pioneer().

Полетные методы имеют две особенности:

arm(timeout, retries) - включает двигатели.

disarm() выключает двигатели.

  • Возвращает True, если команда успешно отправлена, иначе False.

takeoff() - выполняет взлет до высоты указанной в параметре Copter_com_takeoffAlt.

land() - выполняет посадку, двигатели выключатся автоматически.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Ожидает событие COPTER_LANDED.

go_to_local_point(x, y, z, yaw, time) - полет в заданную координату, на основе локальной системы координат.

go_to_local_point_body_fixed(x, y, z, yaw, time) - полет в заданную координату, на основе внутренних координат квадрокоптера.

go_to_global_point(latitude, longitude, altitude, yaw) - полет в заданную координату, на основе GPS координат.

point_reached() - сообщает о достижении целевой координаты, позволяет избавиться от необходимости указывать метод time.sleep().

  • Возвращает True, если заданная координата достигнута, иначе False.

point_deceleration() - сообщает о приближении к целевой координаты, начинается оттормаживание.

  • Возвращает True, если заданная координата близка к достижению, иначе False.

set_manual_speed(vx, vy, vz, yaw_rate, interval) - полет с заданной скоростью, на основе локальных координат.

set_yaw(yaw) - задать курс (рысканье или yaw) в градусах.

rtl() - возвращает квадрокоптер в координату после выполнения метода takeoff().

  • Возвращает True, если команда успешно отправлена, иначе False.

get_fly_state() - возвращает текущее состояние полета: ON_LAND, ARMED, IN_SKY

led_control(led_id=255, r=0, g=0, b=0) - управляет яркостью субпикселей светодиодов.

  • Возвращает True, если команда успешно отправлена, иначе False.

reboot_board() - выполняет перезагрузку платы автопилота.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Всегда возвращает False на Мини 2.

get_param(name, update) - меняет значение указанного параметра автопилота.

set_param(name, value) - меняет значение указанного параметра автопилота.

  • Возвращает True, если выполнено, иначе False.

set_logger(value=True) - включает или выключает ответы о результатах выполнения методов для объекта, по умолчанию включено.

get_local_position_lps() - позволяет узнать локальный координаты. None, если ошибка.

get_altitude() - позволяет узнать высоту с барометра. None, если ошибка.

get_dist_sensor_data() - позволяет узнать высоту с дальномера. None, если ошибка.

get_optical_data() - позволяет узнать данные модуля оптической навигации. None, если ошибка.

get_battery_status() - позволяет узнать напряжение и температуру аккумулятора. None, если ошибка.

get_orientation() - возвращает ориентацию дрона по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.

get_accel() - возвращает ускорение квадрокоптера по осям X, Y, Z. None, если ошибка.

get_gyro() - возвращает скорость по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.

get_mag() - возвращает показания магнитометра по осям X, Y, Z. None, если ошибка. Только при наличии GPS модуля.

get_motors_rpm() - возвращает обороты каждого из 4 моторов квадрокоптера. None, если ошибка.

get_nav_system(update=False) - возвращает выбранную систему навигации.

get_nav_status_lps() - возвращает статус LPS навигации.

get_local_velocity_lps() - возвращает скорость по осям X, Y, Z в м/с. None, если ошибка.

get_local_yaw_lps() - возвращает текущий курсовой угол (рысканье). None, если ошибка.

get_nav_status_gps() - возвращает статус GPS навигации.

get_global_position_gps() - возвращает координаты по GPS. None, если ошибка.

get_global_velocity_gps() - возвращает скорость по GPS. None, если ошибка.

get_satellites_count() - возвращает количество обнаруженных спутников GPS и ГЛОНАСС. None, если ошибка.

time() - возвращает время работы квадрокоптера в секундах с момента начала GPS-эпохи. None, если ошибка.

flight_time() - возвращает время с начала полета квадрокоптера в секундах. None, если ошибка.

  • Важно понимать, что автопилот требует постоянного наличия "сигнала" на каналах, используйте циклы.
  • Возвращает True, если команда успешно отправлена, иначе False.

get_rc_channel() - возвращает значение 8 канала. None, если ошибка.

grab_open(movement_time=0, velocity=100) - открывает захват квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.

grab_close(movement_time=0, velocity=100) - закрывает захват квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.

grab_stop() - останавливает движение захвата квадрокоптера "Пионер Мини 2".

  • Возвращает True, если выполнено, иначе False.

get_ranger_data() - возвращает данные с модуля Ranger, установленный на "Пионер Мини 2".

cargo_grab() - включает магнит.

cargo_release() - выключает магнит.

cargo_set() - включает или выключает магнит в зависимости от аргумента.

get_local_position_lps() - позволяет узнать локальный координаты. None, если ошибка.

get_altitude() - позволяет узнать высоту с барометра. None, если ошибка.

get_dist_sensor_data() - позволяет узнать высоту с дальномера. None, если ошибка.

get_optical_data() - позволяет узнать данные модуля оптической навигации. None, если ошибка.

get_battery_status() - позволяет узнать напряжение и температуру аккумулятора. None, если ошибка.

get_orientation() - возвращает ориентацию дрона по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.

get_accel() - возвращает ускорение квадрокоптера по осям X, Y, Z. None, если ошибка.

get_gyro() - возвращает скорость по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.

get_mag() - возвращает показания магнитометра по осям X, Y, Z. None, если ошибка. Только при наличии GPS модуля.

get_motors_rpm() - возвращает обороты каждого из 4 моторов квадрокоптера. None, если ошибка.

get_nav_system(update=False) - возвращает выбранную систему навигации.

get_nav_status_lps() - возвращает статус LPS навигации.

get_local_velocity_lps() - возвращает скорость по осям X, Y, Z в м/с. None, если ошибка.

get_local_yaw_lps() - возвращает текущий курсовой угол (рысканье). None, если ошибка.

get_nav_status_gps() - возвращает статус GPS навигации.

get_global_position_gps() - возвращает координаты по GPS. None, если ошибка.

get_global_velocity_gps() - возвращает скорость по GPS. None, если ошибка.

get_satellites_count() - возвращает количество обнаруженных спутников GPS и ГЛОНАСС. None, если ошибка.

time() - возвращает время работы квадрокоптера в секундах с момента начала GPS-эпохи. None, если ошибка.

flight_time() - возвращает время с начала полета квадрокоптера в секундах. None, если ошибка.

  • Важно понимать, что автопилот требует постоянного наличия "сигнала" на каналах, используйте циклы.
  • Возвращает True, если команда успешно отправлена, иначе False.

get_rc_channel() - возвращает значение 8 канала. None, если ошибка.

point_reached() - сообщает о достижении целевой координаты, позволяет избавиться от необходимости указывать метод time.sleep().

  • Возвращает True, если заданная координата достигнута, иначе False.

point_deceleration() - сообщает о приближении к целевой координаты, начинается оттормаживание.

  • Возвращает True, если заданная координата близка к достижению, иначе False.

set_manual_speed(vx, vy, vz, yaw_rate, interval) - полет с заданной скоростью, на основе локальных координат.

set_yaw(yaw) - задать курс (рысканье или yaw) в градусах.

rtl() - возвращает квадрокоптер в координату после выполнения метода takeoff().

  • Возвращает True, если команда успешно отправлена, иначе False.

reboot_board() - выполняет перезагрузку платы автопилота.

  • Возвращает True, если команда успешно отправлена, иначе False.
  • Всегда возвращает False на Мини 2.

get_param(name, update) - меняет значение указанного параметра автопилота.

set_param(name, value) - меняет значение указанного параметра автопилота.

  • Возвращает True, если выполнено, иначе False.

set_logger(value=True) - включает или выключает ответы о результатах выполнения методов для объекта, по умолчанию включено.

get_altitude() - позволяет узнать высоту с барометра. None, если ошибка.

get_dist_sensor_data() - позволяет узнать высоту с дальномера. None, если ошибка.

get_optical_data() - позволяет узнать данные модуля оптической навигации. None, если ошибка.

get_battery_status() - позволяет узнать напряжение и температуру аккумулятора. None, если ошибка.

get_orientation() - возвращает ориентацию дрона по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.

get_accel() - возвращает ускорение квадрокоптера по осям X, Y, Z. None, если ошибка.

get_gyro() - возвращает скорость по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.

get_mag() - возвращает показания магнитометра по осям X, Y, Z. None, если ошибка. Только при наличии GPS модуля.

get_motors_rpm() - возвращает обороты каждого из 4 моторов квадрокоптера. None, если ошибка.

get_nav_system(update=False) - возвращает выбранную систему навигации.

get_nav_status_lps() - возвращает статус LPS навигации.

get_local_velocity_lps() - возвращает скорость по осям X, Y, Z в м/с. None, если ошибка.

get_local_yaw_lps() - возвращает текущий курсовой угол (рысканье). None, если ошибка.

get_nav_status_gps() - возвращает статус GPS навигации.

get_global_position_gps() - возвращает координаты по GPS. None, если ошибка.

get_global_velocity_gps() - возвращает скорость по GPS. None, если ошибка.

get_satellites_count() - возвращает количество обнаруженных спутников GPS и ГЛОНАСС. None, если ошибка.

time() - возвращает время работы квадрокоптера в секундах с момента начала GPS-эпохи. None, если ошибка.

flight_time() - возвращает время с начала полета квадрокоптера в секундах. None, если ошибка.

get_rc_channel() - возвращает значение 8 канала. None, если ошибка.

Класс Camera

Позволяет получить изображение с камеры квадрокоптера и при необходимости обработать его

Инициализация класса

Создание экземпляра класса Camera (Мини 2, Radxa Zero)

Camera(camera_type=CameraType.MAIN) - основная камера, по умолчанию применяется этот тип камеры.

Camera(camera_type=CameraType.OPT) - камера оптической навигации, расположена на плате-адаптере. Не работает на модуле Radxa Zero.

from pioneer_sdk2 import Camera # импортируем класс Camera из библиотеки pioneer_sdk2

camera_drone_1 = Camera() # создаем экземпляр класса Camera

Создание экземпляра класса Camera (Raspberry Pi Zero)

Camera(camera_type=CameraType.MAIN) - основная камера, по умолчанию применяется этот тип камеры.

Camera(camera_type=CameraType.OPT) - камера оптической навигации, расположена на плате-адаптере.

from pioneer_sdk2 import Camera # импортируем класс Camera из библиотеки pioneer_sdk2

# создаем экземпляр класса Camera (выбираем в зависимости от способа подключения) camera_drone_1 = Camera() # при работе в терминале Pioneer OS (на борту) camera_drone_1 = Camera(camera_ip="10.42.0.1:8554") # при удаленном подключении

Управление камерой

Получить кадр и выключить видеопоток

get_cv_frame(timeout) - возвращает следующий доступный кадр из очереди в формате BGR.

stop() - останаливает передачу кадров.

from pioneer_sdk2 import Camera # импортируем класс Camera из библиотеки pioneer_sdk2
import cv2                      # библиотека cv2 содержит функции для работы с изображениями

camera_drone_1 = Camera() # создаем экземпляр класса Camera

while True: # запускаем бесконечный цикл frame = camera_drone_1.get_cv_frame(timeout=5.0) # сохраняем изображение в переменную frame # timeout=5.0 - время ожидания кадра в секундах

if frame is not None: # проверяем, что изображение получено cv2.imshow("video", frame) # выводим полученное изображение frame в окне с названием "video"

elif cv2.waitKey(1) == 27: # проверяем нажатие клавиши ESC camera_drone_1.stop() # закрываем передачу кадров break # выходим из цикла

from pioneer_sdk2 import Camera # импортируем класс Camera из библиотеки pioneer_sdk2

camera_drone_1 = Camera() # создаем экземпляр класса Camera

Camera(camera_type=CameraType.MAIN) - основная камера, по умолчанию применяется этот тип камеры.

Camera(camera_type=CameraType.OPT) - камера оптической навигации, расположена на плате-адаптере.

get_cv_frame(timeout) - возвращает следующий доступный кадр из очереди в формате BGR.

stop() - останаливает передачу кадров.

Позволяет получить изображение с камеры квадрокоптера и при необходимости обработать его

Camera(camera_type=CameraType.MAIN) - основная камера, по умолчанию применяется этот тип камеры.

Camera(camera_type=CameraType.OPT) - камера оптической навигации, расположена на плате-адаптере. Не работает на модуле Radxa Zero.

Camera(camera_type=CameraType.MAIN) - основная камера, по умолчанию применяется этот тип камеры.

Camera(camera_type=CameraType.OPT) - камера оптической навигации, расположена на плате-адаптере.

get_cv_frame(timeout) - возвращает следующий доступный кадр из очереди в формате BGR.

stop() - останаливает передачу кадров.

Класс ImageViewer (только Мини 2, Radxa Zero)

Класс для трансляции numpy-кадров по RTSP через GStreamer, доступен только при использовании драйвера камеры gstreamer

Инициализация класса

from pioneer_sdk2 import ImageViewer # импортируем класс ImageViewer из библиотеки pioneer_sdk2

video_drone_1 = ImageViewer() # создаем экземпляр класса ImageViewer, камера модуля esp32

Методы класса

Включить и выключить видеотрансляцию

imshow(name, frame, fps=30) - запускает видеотрансляцию в браузер.

close() - уничтожает все gstreamer пайплайны.

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

video_drone_1 = ImageViewer() # создаем экземпляр класса ImageViewer camera_drone_1 = Camera() # создаем экземпляр класса Camera

my_time = time.time() # объявляем переменную my_time, присваиваем текущее время (в секундах с 1970 года) cycle_time = 30 # объявляем переменную cycle_time, присваиваем желаемую длительность цикла

while time.time() - my_time < cycle_time: # запускаем цикл, код будет повторяться, пока условие верно frame = camera_drone_1.get_cv_frame() # получаем кадр и присваиваем данные переменной frame video_drone_1.imshow("video", frame, fps=30) # запускаем трансляцию, содержит аргументы: # video - название трансляции # frame - переменная с ранее полученным кадром # fps=30 - количество кадров в секунду при передаче видео

# трансляция выполняется по адресу: 10.42.0.1:8889/video # ip - по умолчанию 10.42.0.1 или скопировать из раздела хот-спот на компьютере # 8889 - порт трансляции # name - название трансляции

# при подключения квадрокоптера к вашей сети: # трансляция выполняется по адресу: ваш ip:8889/video

video_drone_1.close() # останавливаем видеопоток

imshow(name, frame, fps=30) - запускает видеотрансляцию в браузер.

close() - уничтожает все gstreamer пайплайны.

Класс для трансляции numpy-кадров по RTSP через GStreamer, доступен только при использовании драйвера камеры gstreamer

imshow(name, frame, fps=30) - запускает видеотрансляцию в браузер.

close() - уничтожает все gstreamer пайплайны.

Класс RecorderControl (только Мини 2)

Класс для управления записью фото и видео

Инициализация класса

from pioneer_sdk2 import RecorderControl # импортируем класс RecorderControl из библиотеки pioneer_sdk2

rec_drone_1 = RecorderControl() # создаем экземпляр класса RecorderControl

Методы класса

Получить список конфигураций камеры

get_camera_recording_configs() - возвращает список конфигураций выбранной камеры. Конфигурации представляют собой набор настроек камеры (ширина, высота, fps).

from pioneer_sdk2 import RecorderControl, CameraType # импортируем классы из библиотеки pioneer_sdk2

rec_drone_1 = RecorderControl() # создаем экземпляр класса RecorderControl

print(rec_drone_1.get_camera_recording_configs(CameraType.MAIN)) # выводим в терминал конфигурации основной камеры print(rec_drone_1.get_camera_recording_configs(CameraType.OPT)) # выводим в терминал конфигурации камеры оптической навигации

Видеозапись в галерею

start_recording(camera_type, recording_config, output_dir) - запускает видеозапись.

  • camera_type - камера используемая для видеозаписи.
  • recording_config - используемая конфигурация записи, если None, используется первая доступная конфигурация.
  • output_dir - место сохранения видеозаписи, по умолчанию /mnt/media/videos/.

stop_recording(camera_type) - останавливает видеозапись.

from pioneer_sdk2 import RecorderControl, CameraType # импортируем классы из библиотеки pioneer_sdk2
from time import sleep

rec_drone_1 = RecorderControl() # создаем экземпляр класса RecorderControl

print(rec_drone_1.get_camera_recording_configs(CameraType.MAIN)) # выводим в терминал конфигурации основной камеры config_drone_1 = rec_drone_1.get_camera_recording_configs(CameraType.MAIN)[0] # записываем в переменную первую конфигурацию rec_drone_1.start_recording(CameraType.MAIN, config_drone_1) # запускаем видеозапись sleep(10) # пауза на 10 секунд rec_drone_1.stop_recording(CameraType.MAIN) # останавливаем видеозапись

Фотография в галерею

take_photo(file_name, camera_type, recording_config, output_dir) - делает фотографию.

  • file_name - имя фотографии с расширением (.jpg .jpeg .png).
  • camera_type - камера используемая для видеозаписи.
  • recording_config - используемая конфигурация записи, если None, используется первая доступная конфигурация.
  • output_dir - место сохранения видеозаписи, по умолчанию /mnt/media/videos/.
  • Вызывает ошибку ValueError, если пустое имя файла или неподдерживаемое расширение.
  • Вызывает ошибку ValueError, если для выбранной камеры нет доступных конфигураций записи.
  • Вызывает ошибку RuntimeError, если произошла ошибка подготовки камеры или выполнения команды фото.
from pioneer_sdk2 import RecorderControl, CameraType # импортируем классы из библиотеки pioneer_sdk2

rec_drone_1 = RecorderControl() # создаем экземпляр класса RecorderControl

print(rec_drone_1.get_camera_recording_configs(CameraType.MAIN)) # выводим в терминал конфигурации основной камеры config_drone_1 = rec_drone_1.get_camera_recording_configs(CameraType.MAIN)[0] # записываем в переменную первую конфигурацию rec_drone_1.take_photo("photo_1.jpg", CameraType.MAIN, config_drone_1) # делаем фотографию

start_recording(camera_type, recording_config, output_dir) - запускает видеозапись.

stop_recording(camera_type) - останавливает видеозапись.

take_photo(file_name, camera_type, recording_config, output_dir) - делает фотографию.

Класс для управления записью фото и видео

start_recording(camera_type, recording_config, output_dir) - запускает видеозапись.

stop_recording(camera_type) - останавливает видеозапись.

take_photo(file_name, camera_type, recording_config, output_dir) - делает фотографию.

start_recording(camera_type, recording_config, output_dir) - запускает видеозапись.

stop_recording(camera_type) - останавливает видеозапись.

take_photo(file_name, camera_type, recording_config, output_dir) - делает фотографию.

Класс ServoCamera (только Мини 2)

Класс для управления сервоприводом камеры, позволяющий устанавливать угол поворота

Инициализация класса

from pioneer_sdk2 import ServoCamera # импортируем класс ServoCamera из библиотеки pioneer_sdk2

servo_drone_1 = ServoCamera() # создаем экземпляр класса ServoCamera, проверяет поддержку сервомотора

Методы класса

Установить угол сервопривода камеры

set_angle(angle) - устанавливает угол поворота сервопривода камеры, диапазон от -85 до 30 градусов.

  • Возвращает True, если выполнено, иначе False.
  • Вызывает Except ValueError, если угол выходит за пределы допустимого диапазона (от -85 до 30 градусов).
from pioneer_sdk2 import ServoCamera # импортируем класс ServoCamera из библиотеки pioneer_sdk2
import time                          # библиотека time содержит функции для работы со временем

servo_drone_1 = ServoCamera() # создаем экземпляр класса ServoCamera, проверяет поддержку сервомотора

servo_drone_1.set_angle(25) # устанавливаем угол камеры на 25 градусов time.sleep(3) # ставим паузу на 3 секунды servo_drone_1.set_angle(-25) # устанавливаем угол камеры на -25 градусов

set_angle(angle) - устанавливает угол поворота сервопривода камеры, диапазон от -85 до 30 градусов.

Класс для управления сервоприводом камеры, позволяющий устанавливать угол поворота

set_angle(angle) - устанавливает угол поворота сервопривода камеры, диапазон от -85 до 30 градусов.