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

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

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

📖 Полный постраничный справочник по каждому методу — с параметрами, возвращаемыми значениями, исключениями и примерами — в разделе «Справочник pioneer_sdk2».

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

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

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

КвадрокоптерыPioneer-SDK2Взаимодействие через:
Мини 2✅PioneerOS (предустановлен)
Мини❌❌
Базовый✅Модули: 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:8554/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:8554/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:8554/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 градусов.