Pioneer SDK 2 — программирование на Python
pioneer_sdk2 — вторая версия официальной Python-библиотеки для квадрокоптеров серии «Пионер». На Пионере Мини 2 работает через предустановленную Pioneer OS. Ниже — справочник по всем классам: Pioneer (полёты, телеметрия, события, RC-каналы), Camera, ImageViewer, RecorderControl, ServoCamera — с официальными примерами кода.
Примеры готовых скриптов: страница «Примеры» и репозиторий pioneer-sdk2-example.
Библиотека Pioneer-SDK2
Вторая версия библиотеки для программирования квадрокоптеров серии Пионер на языке Python
Поддержка Pioneer-SDK2 квадрокоптерами серии Пионер
| Квадрокоптеры | Pioneer-SDK2 | Взаимодействие через: |
|---|---|---|
| Мини 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:8889/video
if keyboard.is_pressed("esc"): # если нажата Esc - завершаем программу
drone_1.led_control() # выключаем светодиоды
drone_1.land() # производим посадку
video_drone_1.stop() # останавливаем видеопоток
drone_1.close_connection() # закрываем соединение
break # выходим из цикла
elif keyboard.is_pressed("1"): # если нажата 1 - запускаем двигатели
drone_1.arm()
elif keyboard.is_pressed("2"): # если нажата 2 - выключаем двигатели
drone_1.disarm()
elif keyboard.is_pressed("3"): # если нажата 3 - взлет
drone_1.takeoff()
elif keyboard.is_pressed("4"): # если нажата 4 - посадка
drone_1.land()
elif keyboard.is_pressed("w"): # если зажата W - летим вперед
ch3=min
elif keyboard.is_pressed("s"): # если зажата S - летим назад
ch3=max
elif keyboard.is_pressed("a"): # если зажата A - летим влево
ch4=min
elif keyboard.is_pressed("d"): # если зажата D - летим вправо
ch4=max
elif keyboard.is_pressed("q"): # если зажата Q - поворачиваем налево
ch2=max
elif keyboard.is_pressed("e"): # если зажата E - поворачиваем направо
ch2=min
elif keyboard.is_pressed("space"): # если зажат Пробел - набираем высоту
ch1=max
elif keyboard.is_pressed("ctrl"): # если зажат Ctrl - сбрасываем высоту
ch1=min
elif keyboard.is_pressed("r"): # если нажата R - активируем магнит
ch5=1000 # 1000 = 0 для Lua
drone_1.led_control(g=1) # меняем цвет светодиодов магнита на зеленый
elif keyboard.is_pressed("f"): # если нажата F - деактивируем магнит
ch5=1500 # 1500 = 1 для Lua
drone_1.led_control(r=1) # меняем цвет светодиодов магнита на красный
drone_1.rc_sdk1_to_sdk2( # имитируем значения каналов пульта
channel_1=ch1, channel_2=ch2, channel_3=ch3, channel_4=ch4, channel_5=ch5)
time.sleep(0.05) # небольшая задержка, улучшает отзывчивость
Смена цвета светодиодов в зависимости от высоты (определение высоты по дальномеру)
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
import keyboard # библиотека keyboard предназначена для работы с клавиатурой
limit_1 = 0.5 # первая граница высоты
limit_2
limit_3 = 1.5 # третья граница высоты
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
time.sleep(3) # пауза, ожидаем подключения к квадрокоптеру
while True: # запускаем бесконечный цикл
height = drone_1.get_dist_sensor_data() # получаем данные высоты и записываем в переменную height
if height is not None: # если данные валидны, выполняем тело условия
if keyboard.is_pressed("esc"): # если нажата Esc - завершаем программу
drone_1.led_control() # выключаем светодиоды
drone_1.close_connection() # закрываем соединение
break # выходим из цикла
elif height < limit_1: # если высота меньше limit_1, включаем зеленый свет
drone_1.led_control(g=1)
elif height < limit_2 and height > limit_1: # если высота меньше limit_2 и больше limit_1, включаем желтый свет
drone_1.led_control(r=1, g=0.4)
elif height < limit_3 and height > limit_2: # если высота меньше limit_3 и больше limit_2, включаем красный свет
drone_1.led_control(r=1)
else: # если условия выше ложные, включаем синий свет
drone_1.led_control(b=1)
print(height) # выводим полученную высоту в терминал
time.sleep(1) # ставим паузу, чтобы не мусорить данными в терминал
Полет по окружности с видео
from pioneer_sdk2 import Pioneer, ImageViewer # импортируем класс Pioneer, ImageViewer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
import math # библиотека math содержит математические функции
import keyboard # библиотека keyboard предназначена для работы с клавиатурой
circle = 360 # окружность для полета (в градусах)
circle_radius = 0.7 # радиус окружности
circle_points = 8 # количество совершаемых остановок на окружности
circle_angle = 0 # стартовый угол на окружности перед полетом (в градусах)
z = 1.0 # высота полета в метрах
def get_point_on_circle(angle, radius): # функция расчета координат на окружности
radians = math.radians(angle) # вычисляем радианы
x = radius * math.cos(radians) # вычисляем координату X
y = radius * math.sin(radians) # вычисляем координату Y
yaw = radians # угол поворота по YAW
return x, y, yaw # возвращаем X, Y, YAW
drone_1 = Pioneer() # создаем экземпляр класса Pioneer
time.sleep(3) # пауза, ожидаем подключения к квадрокоптеру
video_drone_1 = ImageViewer() # создаем экземпляр класса ImageViewer
drone_1.arm() # заводим двигатели
drone_1.takeoff() # производим взлет
drone_1.go_to_local_point(x=0, y=0, z=z, yaw=0) # набираем заданную высоту полета
while True: # запускаем бесконечный цикл
video_drone_1.imshow("video", frame, fps=30) # запускаем трансляцию, содержит аргументы:
# video - название трансляции
# frame - по умолчанию передает изображение в формате BGR
# fps=30 - количество кадров в секунду при передаче видео
# трансляция выполняется по адресу: 10.42.0.1:8889/video
if circle_angle >= circle or keyboard.is_pressed("esc"): # проверяем условие
drone_1.land() # производим посадку
video_drone_1.stop() # останавливаем видеопоток
drone_1.close_connection() # закрываем соединение
break # выходим из цикла
elif drone_1.point_reached(): # если координата достигнута, выполняем тело
x, y, yaw = get_point_on_circle(circle_angle, circle_radius) # получаем координаты обращаясь к функции
drone_1.go_to_local_point(x=x, y=y, z=z, yaw=yaw) # летим в полученные координаты
circle_angle += circle / circle_points # фиксируем текущий угол на окружности
Калибровка камеры для ArUco-маркеров
- В результате калибровки будет получен файл
data.yml, он должен находиться в одном проекте с основным ArUco скриптом. - Узнать больше о калибровке камеры
from pioneer_sdk2 import Camera
import cv2
import numpy as np
import glob
import time
def get_images_from_folder(folder_name, file_type="*.jpg"): # функция для получения изображений из папки
images_list = glob.glob(folder_name + "/" + file_type) # берет все jpg файлы из указанной папки
images = [] # переменная images с пустым списком
for fname in images_list: # перебираем все файлы из папки
img = cv2.imread(fname) # читает изображение
images.append(img) # сохраняет текущее изображение в список images
return images # возвращает список снимков
def get_images_from_drone_camera(camera, save=False): # функция для получения изображений с камеры квадрокоптера
images = [] # переменная images с пустым списком
print("Сделайте 15 снимков шахматной доски с разным ракурсом")
print("Нажмите '1' чтобы сделать снимок")
print("Нажмите 'ESC' для завершения")
while True:
frame = camera.get_cv_frame() # получаем кадр
if frame is not None: # проверяем, что кадр получен
cv2.imshow("frames", frame) # запускаем видеопоток
key = cv2.waitKey(1) # считывает нажатие клавиши и присваивает ее код, переменной
if key == 27: # если нажата клавиша Esc, выполняем тело условия
cv2.destroyAllWindows() # останавливаем видеопоток
return images # возвращает список снимков
elif key == ord("1"): # если нажата цифра 1, выполняет тело условия
images.append(frame) # сохраняет текущее изображение в список images
print("Снимок №" + str(len(images))) # выводит в терминал сообщение о номере снимка
time.sleep(1) # пауза 1 секунда
if save: # если в функции save=True, сохраняет снимок на компьютер
cv2.imwrite("frame_" + str(len(images)) + ".jpg", frame)
def calibrate(images):
CHECKERBOARD = (6, 9) # размеры шахматной доски
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objpoints = [] # Creating vector to store vectors of 3D points for each checkerboard image
imgpoints = [] # Creating vector to store vectors of 2D points for each checkerboard image
objp = np.zeros((1, CHECKERBOARD[0] * CHECKERBOARD[1], 3), np.float32)
objp[0, :, :2] = np.mgrid[0 : CHECKERBOARD[0], 0 : CHECKERBOARD[1]].T.reshape(-1, 2)
# Extracting path of individual image stored in a given directory
for img in images:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Find the chess board corners
# If desired number of corners are found in the image then ret = true
ret, corners = cv2.findChessboardCorners(
gray,
CHECKERBOARD,
cv2.CALIB_CB_ADAPTIVE_THRESH
+ cv2.CALIB_CB_FAST_CHECK
+ cv2.CALIB_CB_NORMALIZE_IMAGE)
if ret == True:
objpoints.append(objp)
# refining pixel coordinates for given 2d points.
corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
imgpoints.append(corners2)
# Draw and display the corners
img = cv2.drawChessboardCorners(img, CHECKERBOARD, corners2, ret)
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
objpoints, imgpoints, gray.shape[::-1], None, None
)
return mtx, dist
def save_coefficients(mtx, dist, path):
"""Save the camera matrix and the distortion coefficients to given path/file."""
cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_WRITE)
cv_file.write("mtx", mtx)
cv_file.write("dist", dist)
# note you release you don't close() a FileStorage object
cv_file.release()
def load_coefficients(path):
"""Loads camera matrix and distortion coefficients."""
# FILE_STORAGE_READ
cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_READ)
# note we also have to specify the type to retrieve other wise we only get a
# FileNode object back instead of a matrix
camera_matrix = cv_file.getNode("mtx").mat()
dist_coeffs = cv_file.getNode("dist").mat()
cv_file.release()
return camera_matrix, dist_coeffs
camera = Camera()
images = get_images_from_drone_camera(camera) # получаем изображение с камеры квадрокоптера
mtx, dist = calibrate(images)
save_coefficients(mtx, dist, "data.yml")
Обнаружение ArUco-маркера
- Обратите внимание, что в примере используются маркеры размером 4x4_50
from pioneer_sdk2 import Pioneer, Camera
import cv2
import time
aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50) # объект содержит набор маркеров 4х4_50
aruco_params = cv2.aruco.DetectorParameters() # объект содержащий параметры обнаружения
aruco_detector = cv2.aruco.ArucoDetector(aruco_dict, aruco_params) # объект для поиска маркеров
camera = Camera()
while True: # запускаем бесконечный цикл
frame = camera.get_cv_frame() # получаем кадр
if frame is not None: # проверяем, что кадр получен
if cv2.waitKey(1) == 27: # если нажата клавиша Esc, выполняем тело условия
cv2.destroyAllWindows() # останавливаем видеопоток
break # выходим из цикла
else:
corners, ids, rejected = aruco_detector.detectMarkers(frame) # записываем данные в переменные
# corners - координаты углов маркеров
# ids - номер обнаруженного маркера
# rejected - область не прошедшая проверку
cv2.aruco.drawDetectedMarkers(frame, corners, ids) # рисуем обнаруженную область на кадре
cv2.imshow("video", frame) # запускаем видеопоток
time.sleep(0.02)
Обнаружение координаты ArUco-маркера
- Обратите внимание, что в примере используются маркеры размером 4x4_50
- Для работы примера требуется файл
data.yml, его можно получить в результате калибровки камеры
from pioneer_sdk2 import Camera
import cv2
import numpy as np
import time
def load_coefficients(path):
cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_READ)
camera_matrix = cv_file.getNode("mtx").mat()
dist_coeffs = cv_file.getNode("dist").mat()
cv_file.release()
return camera_matrix, dist_coeffs
aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50) # объект содержит набор маркеров 4х4_50
aruco_params = cv2.aruco.DetectorParameters() # объект содержащий параметры обнаружения
aruco_detector = cv2.aruco.ArucoDetector(aruco_dict, aruco_params) # объект для поиска маркеров
camera_matrix, dist_coeffs = load_coefficients("data.yml")
size_of_marker = 0.05
points_of_marker = np.array(
[
(size_of_marker / 2, -size_of_marker / 2, 0),
(-size_of_marker / 2, -size_of_marker / 2, 0),
(-size_of_marker / 2, size_of_marker / 2, 0),
(size_of_marker / 2, size_of_marker / 2, 0),
]
)
camera = Camera()
while True: # запускаем бесконечный цикл
frame = camera.get_cv_frame() # получаем кадр
if frame is not None: # проверяем, что кадр получен
if cv2.waitKey(1) == 27: # если нажата клавиша Esc, выполняем тело условия
cv2.destroyAllWindows() # останавливаем видеопоток
break # выходим из цикла
else:
corners, ids, rejected = aruco_detector.detectMarkers(frame) # записываем данные в переменные
# corners - координаты углов маркеров
# ids - номер обнаруженного маркера
# rejected - область не прошедшая проверку
if corners:
success, rvecs, tvecs = cv2.solvePnP(
points_of_marker, corners[0], camera_matrix, dist_coeffs)
print(success, tvecs)
cv2.drawFrameAxes(frame, camera_matrix, dist_coeffs, rvecs, tvecs, 0.1)
cv2.imshow("video", frame) # запускаем видеопоток
time.sleep(0.02)
Следование за ArUco-маркером
from pioneer_sdk2 import Pioneer, Camera
import cv2
import numpy as np
import threading
import time
from collections import deque
def load_coefficients(path):
cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_READ)
camera_matrix = cv_file.getNode("mtx").mat()
dist_coeffs = cv_file.getNode("dist").mat()
cv_file.release()
return camera_matrix, dist_coeffs
class VideoProcessingThread(threading.Thread):
def init(self, camera_matrix, dist_coeffs):
super().init()
self.camera_matrix = camera_matrix
self.dist_coeffs = dist_coeffs
self.running = True
self.latest_coordinates = None
self.x_center = None
self.frame = None
self.frame_times = deque(maxlen=30)
self.last_fps_log_time = time.time()
self.aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50)
self.aruco_params = cv2.aruco.DetectorParameters()
self.aruco_detector = cv2.aruco.ArucoDetector(self.aruco_dict, self.aruco_params)
self.size_of_marker = 0.1
self.points_of_marker = np.array([
(self.size_of_marker / 2, -self.size_of_marker / 2, 0),
(-self.size_of_marker / 2, -self.size_of_marker / 2, 0),
(-self.size_of_marker / 2, self.size_of_marker / 2, 0),
(self.size_of_marker / 2, self.size_of_marker / 2, 0),
])
self.camera = Camera()
def run(self):
while self.running:
try:
frame = self.camera.get_cv_frame()
corners, ids, _ = self.aruco_detector.detectMarkers(frame)
if ids is not None and len(corners) > 0:
x_center = int(sum([p[0] for p in corners[0][0]]) / 4)
y_center = int(sum([p[1] for p in corners[0][0]]) / 4)
dot_size = 5
frame[y_center - dot_size:y_center + dot_size, x_center - dot_size:x_center + dot_size] = [0, 0, 255]
cv2.aruco.drawDetectedMarkers(frame, corners)
success, rvecs, tvecs = cv2.solvePnP(
self.points_of_marker, corners[0], self.camera_matrix, self.dist_coeffs
)
if success:
self.latest_coordinates = [tvecs.item(0), tvecs.item(1), tvecs.item(2)]
self.x_center = x_center
else:
self.latest_coordinates = None
self.x_center = None
else:
self.latest_coordinates = None
self.x_center = None
self.frame = frame.copy()
now = time.time()
self.frame_times.append(now)
if now - self.last_fps_log_time > 2.0 and len(self.frame_times) > 1:
fps = len(self.frame_times) / (self.frame_times[-1] - self.frame_times[0])
print(f"[Video Thread] FPS: {fps:.2f}")
self.last_fps_log_time = now
except cv2.error as e:
print(f"[Video Thread] OpenCV error: {e}")
continue
def stop(self):
self.running = False
camera_matrix, dist_coeffs = load_coefficients("data.yml")
video_thread = VideoProcessingThread(camera_matrix, dist_coeffs)
video_thread.start()
drone_1 = Pioneer()
send_manual_speed = False
airborne = False
try:
while True:
coordinates = video_thread.latest_coordinates
x_center = video_thread.x_center
frame = video_thread.frame
v_y = 0
yaw_rate = 0
if airborne and coordinates is not None and x_center is not None:
distance = np.linalg.norm(coordinates)
print(f"Distance: {distance:.2f} m")
if distance > 1.5:
v_y = 0.4
elif distance < 1:
v_y = -0.4
if x_center < frame.shape[1] / 3:
yaw_rate = -0.4
elif x_center > frame.shape[1] * 2 / 3:
yaw_rate = 0.4
# Если маркер виден и есть команды движения
if airborne and (v_y != 0 or yaw_rate != 0):
drone_1.set_manual_speed_body_fixed(vx=0, vy=v_y, vz=0, yaw_rate=yaw_rate)
send_manual_speed = True
# Если маркер потерян, и до этого коптер двигался — остановка
elif airborne and send_manual_speed:
print("[INFO] Marker lost. Stopping drone.")
drone_1.go_to_local_point_body_fixed(x=0, y=0, z=0, yaw=0)
send_manual_speed = False
if frame is not None:
cv2.imshow("marker_detection", frame)
key = cv2.waitKey(1)
if key == 27: # Esc
break
elif key == 32 and not airborne: # Space
print("[INFO] Takeoff initiated.")
drone_1.arm()
drone_1.takeoff()
drone_1.go_to_local_point(x=0, y=0, z=1.5, yaw=0)
while not drone_1.point_reached():
time.sleep(0.1)
airborne = True
print("[INFO] Drone reached hover point.")
finally:
print("Landing...")
video_thread.stop()
video_thread.join()
cv2.destroyAllWindows()
if airborne:
drone_1.land()
drone_1.close_connection()
del drone_1
Вторая версия библиотеки для программирования квадрокоптеров серии Пионер на языке Python
- Обратите внимание, что в примере используются маркеры размером 4x4_50
- Обратите внимание, что в примере используются маркеры размером 4x4_50
- Обратите внимание, что в примере используются маркеры размером 4x4_50
Класс Pioneer
Основной класс для взаимодействия с квадрокоптерами серии Пионер
Инициализация класса Pioneer
Создание экземпляра класса Pioneer (Мини 2, Radxa Zero)
drone_1 = Pioneer() - создает переменную drone_1 которой присваивается объект класса Pioneer().
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
Создание экземпляра класса Pioneer (Raspberry Pi Zero)
drone_1 = Pioneer() - создает переменную drone_1 которой присваивается объект класса Pioneer().
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
pi_zero_1 = Pioneer(tcp="10.42.0.1:20556") # создаем экземпляр класса Pioneer, устанавливаем соединение с модулем
# если модуль соединяется с вами, используйте tcp указанный в свойствах системы
Управление полетом
Полетные методы имеют две особенности:
- При вызове некоторых полетных методов, выполнение основной программы будет заблокировано до тех пор, пока метод не получит ответ (события автопилота) о его успешном выполнении, о необходимости ожидания конкретного события будет описано в методах. Например, вы заводите двигатели и сразу же хотите включите светодиоды, но так как программа выполняется построчно, то сперва придется дождаться подтверждения запуска двигателей и только потом светодиоды включатся, а в случае, если двигатели не запускаются, программа завершится досрочно. При желании проверку событий можно отключить, для этого при создании экземпляра класса Pioneer в аргументах следует указать
wait_callback=False, следует учитывать, что это также отключает вторую особенность, о которой ниже. - При вызове некоторых полетных методов производится контроль состояния полета, всего есть 3 состояния:
ON_LAND (на земле, двигатели выключены),ARMED (на земле, двигатели включены),IN_SKY (в воздухе). В зависимости от того, в каком состоянии находится квадрокоптер при вызове полетного метода, метод будет выполнен или в выполнении будет отказано. Например, нельзя вызвать полет по координатам, если состояние не равноIN_SKY, подробнее о взаимодействии методов с состояниями будет описано непосредственно в методах. При желании контроль состояния можно отключить, для этого при создании экземпляра класса Pioneer в аргументах следует указатьsafety_command=False.
Включить и выключить двигатели
arm(timeout, retries) - включает двигатели.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Ожидает событие
ENGINES_STARTED. - Вызов в состоянии
ARMEDигнорируется. - Вызов в состоянии
IN_SKYигнорируется.
disarm() выключает двигатели.
- Возвращает
True, если команда успешно отправлена, иначеFalse.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.arm(timeout=5, retries=0) # включаем двигатели, содержит аргументы:
# timeout(5) - задержка в секундах перед запуском двигателей
# retries(0) - количество повторных попыток запуска двигателей
time.sleep(3) # ставим паузу на 3 секунды
drone_1.disarm() # выключаем двигатели
drone_1.close_connection() # закрываем соединение
Взлет и посадка
takeoff() - выполняет взлет до высоты указанной в параметре Copter_com_takeoffAlt.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Ожидает событие
TAKEOFF_COMPLETE. - Вызов в состоянии
ARMEDдоступен. - Вызов в состоянии
ON_LANDигнорируется. - Вызов в состоянии
IN_SKYвызывает ошибку RuntimeError.
land() - выполняет посадку, двигатели выключатся автоматически.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Ожидает событие
COPTER_LANDED.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try: # конструкция try-except, основной код находится внутри блока try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Полет в координаты (локальные)
go_to_local_point(x, y, z, yaw, time) - полет в заданную координату, на основе локальной системы координат.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Метод не является блокирующим, это значит, что после вызова метода, следует поставить паузу или использовать флаг достижения координаты
point_reached, чтобы квадрокоптер не переключился на выполнение следующей команды. - Вызов в состоянии
ARMEDвызывает ошибку RuntimeError. - Вызов в состоянии
ON_LANDигнорируется.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1
try: # конструкция try-except, основной код находится внутри блока try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.go_to_local_point(0, 0, 1.5, 0, 0) # вызываем метод, содержит аргументы:
# x(0) - координата по оси "x" (в метрах)
# y(0) - координата по оси "y" (в метрах)
# z(1.5) - координата по оси "z" (в метрах)
# yaw(0) - поворот по курсу (в радианах)
# time(0) - время за которое требуется достигнуть координату
time.sleep(5) # ставим паузу на 5 секунд
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Полет в координаты (внутренние)
go_to_local_point_body_fixed(x, y, z, yaw, time) - полет в заданную координату, на основе внутренних координат квадрокоптера.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try: # конструкция try-except, основной код находится внутри блока try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.go_to_local_point_body_fixed(0, 0, 1.5, 0, 0) # вызываем метод, содержит аргументы:
# x(0) - координата по оси "x" (в метрах)
# y(0) - координата по оси "y" (в метрах)
# z(1.5) - координата по оси "z" (в метрах)
# yaw(0) - поворот по курсу (в радианах)
# time(0) - время за которое требуется достигнуть координату
time.sleep(5) # ставим паузу на 5 секунд
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Полет в координаты (GPS)
go_to_global_point(latitude, longitude, altitude, yaw) - полет в заданную координату, на основе GPS координат.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Метод не является блокирующим, это значит, что после вызова метода, следует поставить паузу или использовать флаг достижения координаты
point_reached, чтобы квадрокоптер не переключился на выполнение следующей команды. - Вызов в состоянии
ARMEDвызывает ошибку RuntimeError. - Вызов в состоянии
ON_LANDигнорируется. - Если точка старта будет дальше, чем в 500 метрах от фактического местоположения, квадрокоптер откажется взлетать.
- Параметры автопилота
Flight_com_flyAreaSize,Flight_com_maxAltitudeограничивают расстояние и высоту, на которую квадрокоптер может улететь от точки старта.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
# в целях безопасности, отправим квадрокоптер в его же координаты с небольшим набором высоты
try: # конструкция try-except, основной код находится внутри блока try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
while True: # запускаем бесконечный цикл
coord = drone_1.get_local_position_lps() # запоминаем текущие координаты
if coord is not None: # проверяем, что координаты определены
my_latitude, my_longitude, my_altitude = coord # распределяем координаты по разным переменным
break # выходим из цикла
print(f"Широта", my_latitude) # выводим в терминал текущую широту
print(f"Долгота", my_latitude) # выводим в терминал текущую доготу
print(f"Высота", my_latitude) # выводим в терминал текущую высоту
my_altitude += 1 # добавляем к текущей высоте 1 метр
drone_1.go_to_global_point(latitude = my_latitude, # вызываем метод, latitude - широта
longitude = my_longitude, # longitude - долгота
altitude = my_altitude, # altitude - высота
yaw=0) # yaw(0) - азимут
time.sleep(5) # ставим паузу на 5 секунд
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Полет в координаты (относительно GPS)
go_to_global_point_relative(latitude_offset, longitude_offset, altitude_offset, yaw) - полет в заданную координату, с произвольным смещением на основе GPS координат.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try: # конструкция try-except, основной код находится внутри блока try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.go_to_global_point_relative(latitude_offset = 0, # вызываем метод, latitude_offset - смещение по широте
longitude_offset = 0, # longitude_offset - смещение по долготе
altitude_offset = 1, # altitude_offset - смещение по высоте
yaw=0) # yaw(0) - азимут
time.sleep(5) # ставим паузу на 5 секунд
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Флаг достижения координаты
point_reached() - сообщает о достижении целевой координаты, позволяет избавиться от необходимости указывать метод time.sleep().
- Возвращает
True, если заданная координата достигнута, иначеFalse.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.go_to_local_point(0, 0, 1.5, 0, 0) # отправляем квадрокоптер в заданные координаты
while not drone_1.point_reached(): # запускаем цикл, код будет повторяться, пока условие верно
time.sleep(1)
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Флаг приближения к целевой координате
point_deceleration() - сообщает о приближении к целевой координаты, начинается оттормаживание.
- Возвращает
True, если заданная координата близка к достижению, иначеFalse.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.go_to_local_point(0, 0, 1.5, 0, 0) # отправляем квадрокоптер в заданные координаты
while not drone_1.point_reached(): # запускаем цикл, код будет повторяться, пока условие верно
if drone_1.point_deceleration(): # если целевая позицию близко, выполняем код
print("Я близко, начинаю торможение") # выводим сообщение в терминал
else:
time.sleep(1)
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Задать скорость по осям (локальным)
set_manual_speed(vx, vy, vz, yaw_rate, interval) - полет с заданной скоростью, на основе локальных координат.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Вызов в состоянии
ARMEDвызывает ошибку RuntimeError. - Вызов в состоянии
ON_LANDигнорируется.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try: # конструкция try-except, основной код находится внутри блока try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.set_manual_speed(0, 0, 0.2, 0, 5) # вызываем метод, содержит аргументы:
# vx(0) - скорость по оси "x" (м/с)
# vy(0) - скорость по оси "y" (м/с)
# vz(0.2) - скорость по оси "z" (м/с)
# yaw_rate(0) - скорость поворота по курсу (м/с)
# interval(5) - время в течении которого метод активен
time.sleep(3) # ставим паузу на 3 секунды
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Задать скорость по осям (внутренним)
set_manual_speed_body_fixed(vx, vy, vz, yaw_rate, interval) - полет с заданной скоростью, на основе внутренних координат квадрокоптера.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try: # конструкция try-except, основной код находится внутри блока try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.set_manual_speed_body_fixed(0, 0, 0.2, 0, 5) # вызываем метод, содержит аргументы:
# vx(0) - скорость по оси "x" (м/с)
# vy(0) - скорость по оси "y" (м/с)
# vz(0.2) - скорость по оси "z" (м/с)
# yaw_rate(0) - скорость поворота по курсу (рад/с)
# interval(5) - время в течении которого метод активен
time.sleep(3) # ставим паузу на 3 секунды
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Задать курс
set_yaw(yaw) - задать курс (рысканье или yaw) в градусах.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try: # конструкция try-except, основной код находится внутри блока try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.set_yaw(90) # поворачиваем на 90 градусов по часовой стрелке
time.sleep(3) # ставим паузу на 3 секунды
drone_1.set_yaw(-90) # поворачиваем на 90 градусов против часовой стрелки
time.sleep(3) # ставим паузу на 3 секунды
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Вернуть в домашнюю координату
rtl() - возвращает квадрокоптер в координату после выполнения метода takeoff().
- Возвращает
True, если команда успешно отправлена, иначеFalse.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try: # конструкция try-except, основной код находится внутри блока try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.go_to_local_point(0, 0, 1.5, 0, 0) # набираем высоту до 1.5 метра
time.sleep(5) # ставим паузу на 5 секунд
drone_1.rtl() # возвращаем квадрокоптер на место взлета
time.sleep(5) # ставим паузу на 5 секунд
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Узнать состояние полета
get_fly_state() - возвращает текущее состояние полета: ON_LAND, ARMED, IN_SKY
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
print(drone_1.get_fly_state()) # выводим в терминал результат работы метода
drone_1.close_connection() # закрываем соединение
Дополнительные возможности
Управление светодиодами
led_control(led_id=255, r=0, g=0, b=0) - управляет яркостью субпикселей светодиодов.
- Возвращает
True, если команда успешно отправлена, иначеFalse.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.led_control(255, r=1, g=1, b=1) # вызываем метод, включаем все светодиоды (яркий белый)
# led_id - номер светодиода, нумерация начинается с 0, выбор всех светодиодов = 255
# r - управление яркостью красного субпикселя, где 0 = 0%, а 1 = 100%
# g - управление яркостью зеленого субпикселя, где 0 = 0%, а 1 = 100%
# b - управление яркостью синего субпикселя, где 0 = 0%, а 1 = 100%
time.sleep(2) # ставим паузу на 2 секунды
drone_1.led_control(0, r=1, g=0, b=0) # включаем светодиод №0 (яркий красный)
time.sleep(2)
drone_1.led_control(1, r=0, g=0.5, b=0) # включаем светодиод №1 (средней яркости зеленый)
time.sleep(2)
drone_1.led_control(2, r=0, g=0, b=0.1) # включаем светодиод №2 (тусклый синий)
time.sleep(2)
drone_1.led_control(3, r=1, g=0.4, b=0) # включаем светодиод №3 (желтый)
time.sleep(2)
drone_1.led_control(255, r=0, g=0, b=0) # выключаем все светодиоды
drone_1.close_connection() # закрываем соединение
Выполнить перезагрузку
reboot_board() - выполняет перезагрузку платы автопилота.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Всегда возвращает
Falseна Мини 2.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.reboot_board()
drone_1.close_connection() # закрываем соединение
Узнать значение параметра автопилота
get_param(name, update) - меняет значение указанного параметра автопилота.
update=False- возвращает значение полученное при включении квадрокоптера (кэш).update=True- принудительно считывает значение из автопилота и возвращает его.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
print(drone_1.get_param(Flight_com_navSystem)) # выводим в терминал значение указанного параметра
drone_1.close_connection() # закрываем соединение
Изменить значение параметра автопилота
set_param(name, value) - меняет значение указанного параметра автопилота.
- Возвращает
True, если выполнено, иначеFalse.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
print(drone_1.get_param(Flight_com_navSystem)) # выводим в терминал значение указанного параметра
drone_1.set_param(Flight_com_navSystem, 2) # меняем значение на 2 (OPT навигация)
print(drone_1.get_param(Flight_com_navSystem, True)) # выводим в терминал значение указанного параметра (считываем из автопилота)
drone_1.close_connection() # закрываем соединение
Включить или выключить логирование методов
set_logger(value=True) - включает или выключает ответы о результатах выполнения методов для объекта, по умолчанию включено.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.led_control(g=0.5) # вызываем смену цвета светодиодов, ответ будет выведен в терминал
print("Выше находится ответ о подключении и выполнении метода") # выводим сообщение в терминал
print("Выключил логирование, вызываю смену цвета светодиодов") # выводим сообщение в терминал
drone_1.set_logger(value=False) # вызываем метод, выключаем логирование
drone_1.led_control(b=0.5) # вызываем смену цвета светодиодов, ответ не будет выведен в терминал
print("\nВыше отсутствует ответ о выполнении метода") # выводим сообщение в терминал
drone_1.close_connection() # закрываем соединение
Получение данных
Узнать локальные координаты
get_local_position_lps() - позволяет узнать локальный координаты. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_local_position_lps(True)) # вызываем метод
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать высоту (барометр)
get_altitude() - позволяет узнать высоту с барометра. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_altitude()) # вызываем метод
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать высоту (дальномер)
get_dist_sensor_data() - позволяет узнать высоту с дальномера. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_dist_sensor_data()) # вызываем метод
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать данные оптического потока
get_optical_data() - позволяет узнать данные модуля оптической навигации. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_optical_data(True)) # вызываем метод
time.sleep(0.5) # ставим паузу на 0.5 секунды
drone_1.close_connection() # закрываем соединение
Узнать напряжение аккумулятора
get_battery_status() - позволяет узнать напряжение и температуру аккумулятора. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_battery_status()) # вызываем метод
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать углы наклона по осям
get_orientation() - возвращает ориентацию дрона по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_orientation()) # вызываем метод
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать ускорение
get_accel() - возвращает ускорение квадрокоптера по осям X, Y, Z. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_accel()) # вызываем метод
time.sleep(0.5) # ставим паузу на 0.5 секунды
drone_1.close_connection() # закрываем соединение
Узнать угловую скорость
get_gyro() - возвращает скорость по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_gyro()) # вызываем метод
time.sleep(0.5) # ставим паузу на 0.5 секунды
drone_1.close_connection() # закрываем соединение
Показания магнитометра (GPS)
get_mag() - возвращает показания магнитометра по осям X, Y, Z. None, если ошибка. Только при наличии GPS модуля.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_mag()) # вызываем метод
time.sleep(0.5) # ставим паузу на 0.5 секунды
drone_1.close_connection() # закрываем соединение
Обороты моторов
get_motors_rpm() - возвращает обороты каждого из 4 моторов квадрокоптера. None, если ошибка.
Узнать активную систему навигации
get_nav_system(update=False) - возвращает выбранную систему навигации.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
print(drone_1.get_nav_system()) # выводим активную систему навигации в терминал
# NavSystem.GPS
# NavSystem.LPS
# NavSystem.OPT
drone_1.close_connection() # закрываем соединение
Узнать состояние LPS
get_nav_status_lps() - возвращает статус LPS навигации.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_nav_status_lps()) # выводим состояние LPS навигации в терминал
# NavStatus.NO_DATA - нет данных с LPS модуля
# NavStatus.CANNOT - невозможно оценить позицию
# NavStatus.LOW - низкое доверие к оценке позиции
# NavStatus.OK - позиция определена
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать скорость по осям
get_local_velocity_lps() - возвращает скорость по осям X, Y, Z в м/с. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_local_velocity_lps()) # выводим текущую скорость в терминал
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать курсовой угол
get_local_yaw_lps() - возвращает текущий курсовой угол (рысканье). None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_local_yaw_lps()) # выводим текущий угол в терминал
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать состояние GPS
get_nav_status_gps() - возвращает статус GPS навигации.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_nav_status_gps()) # выводим состояние GPS навигации в терминал
# NavStatus.NO_DATA - нет данных с GPS модуля
# NavStatus.CANNOT - невозможно оценить позицию
# NavStatus.LOW - низкое доверие к оценке позиции
# NavStatus.OK - позиция определена
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать координаты GPS
get_global_position_gps() - возвращает координаты по GPS. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_global_position_gps()) # выводим GPS координаты в терминал
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать скорость по GPS
get_global_velocity_gps() - возвращает скорость по GPS. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_global_velocity_gps()) # выводим текущую скорость по GPS в терминал
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать количество спутников
get_satellites_count() - возвращает количество обнаруженных спутников GPS и ГЛОНАСС. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_satellites_count()) # выводим количество спутников в терминал
# [GPS, ГЛОНАСС]
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать время работы (GPS)
time() - возвращает время работы квадрокоптера в секундах с момента начала GPS-эпохи. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.time()) # выводим в терминал время работы
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать время работы квадрокоптера
uptime() - возвращает время работы квадрокоптера в секундах, прошедшее с момента идентификации в системе навигации. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.uptime()) # выводим в терминал время работы
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Узнать время полета квадрокоптера
flight_time() - возвращает время с начала полета квадрокоптера в секундах. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.flight_time()) # выводим в терминал время работы
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Управление RC-каналами
Для управления RC-каналами требуется убедиться, что параметры автопилота соответствуют требуемым:
Copter_man_rcMode0=6.0, Copter_man_rcMode1=3.0, Copter_man_rcMode2=3.0, Copter_flyWithoutRc=1.0, SensorMux_rc=2.0
- Важно понимать, что автопилот требует постоянного наличия "сигнала" на каналах, используйте циклы.
Имитация пульта
send_rc_channels(channel_1, channel_2, channel_3, channel_4, channel_5, channel_6, channel_7, channel_8) - выполняет имитацию приема каналов пульта радиоуправления.
- Возвращает
True, если команда успешно отправлена, иначеFalse.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try: # конструкция try-except, основной код находится внутри блока try
while True:
drone_1.send_rc_channels( # вызываем метод
channel_1 = 0, # правый стик (влево -1, центр 0, вправо 1)
channel_2 = 0, # правый стик (вперед -1, центр 0, назад 1)
channel_3 = 0, # левый стик (вверх 1, центр 0, вниз -1)
channel_4 = 0, # левый стик (налево 1, центр 0, направо -1)
channel_5 = 1, # тумблер SWC (вверх 0, центр 1, вниз 2)
channel_6 = 0, # тумблер SWD (вверх 0, вниз 2)
channel_7 = 1, # тумблер SWB (вверх 0, центр 1, вниз 2)
channel_8 = 0) # тумблер SWA (вверх 0, вниз 2)
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.close_connection()
Конвертация каналов
rc_sdk1_to_sdk2(channel_1=0, channel_2=0, channel_3=0, channel_4=0, channel_5=2000) - выполняет конвертацию значений каналов из pioneer_sdk в pioneer_sdk2. Использование данного метода целесообразно, если у вас есть программы написанные для pioneer_sdk и вы хотите перенести их в pioneer_sdk2 без изменений каналов.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
try: # конструкция try-except, основной код находится внутри блока try
while True:
channels = drone_1.rc_sdk1_to_sdk2( # вызываем метод
channel_1 = 1500, # правый стик (влево -1, центр 0, вправо 1)
channel_2 = 1500, # правый стик (вперед -1, центр 0, назад 1)
channel_3 = 1500, # левый стик (вверх 1, центр 0, вниз -1)
channel_4 = 1500, # левый стик (налево 1, центр 0, направо -1)
channel_5 = 2000) # тумблер SWC (2000)
drone_1.send_rc_channels(
*channels,
channel_6=0,
channel_7=1,
channel_8=0
)
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.close_connection()
Узнать значение 8 канала
get_rc_channel() - возвращает значение 8 канала. None, если ошибка.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
print(drone_1.get_rc_channel()) # выводим значение 8 канала в терминал
drone_1.close_connection() # закрываем соединение
Выполнить код по тумблеру
set_rc_trigger() - позволяет выполнить часть кода в паралельном потоке при переключении тумблеров пульта радиоуправления, не прерывая выполнение основной задачи. Работает только на изменение значений тумблеров.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
def green_blink(channel_8): # создаем функцию green_blink с проверкой 8 канала
global drone_1 # обращаемся к глобальной версии объекта, не создаем новый объект
if channel_8 == 2: # если значение 8 канала равно 2, мигаем зеленым
drone_1.led_control(r=0, g=1, b=0)
time.sleep(0.5)
drone_1.led_control(r=0, g=0, b=0)
else: # в противном случае, выключаем светодиоды
drone_1.led_control(r=0, g=0, b=0)
# Здесь начинается ваш код
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.set_rc_trigger(green_blink) # вызываем метод и передаем имя функции
# добавьте сюда произвольный код, он не прервет исполнение функции
drone_1.close_connection() # закрываем соединение
Обработка событий автопилота
Список событий
Подписка на событие
subscribe(callback, event) - позволяет выполнить часть кода в паралельном потоке при срабатывания выбранного события, не прерывая выполнение основной задачи. Работает только на события автопилота.
from pioneer_sdk2 import Pioneer, Event # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
def event_activate(event): # создаем функцию green_blink с проверкой 8 канала
global drone_1 # обращаемся к глобальной версии объекта, не создаем новый
if event == Event.TAKEOFF_COMPLETE: # если пришло событие "взлет", то включаем зеленый свет
drone_1.led_control(r=0, g=1, b=0)
elif event == Event.COPTER_LANDED: # если пришло событие "посадка", то включаем красный свет
drone_1.led_control(r=1, g=0, b=0)
# Здесь начинается ваш код
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.subscribe(event_activate, Event.TAKEOFF_COMPLETE) # указываем функцию которую нужно выполнить при событии взлета
drone_1.subscribe(event_activate, Event.COPTER_LANDED) # указываем функцию которую нужно выполнить при событии посадки
try: # конструкция try-except, основной код находится внутри блока try
drone_1.arm() # включаем двигатели
drone_1.takeoff() # взлетаем
time.sleep(3) # ставим паузу на 3 секунды
drone_1.land() # садимся, двигатели выключатся автоматически
drone_1.close_connection() # закрываем соединение
except: # конструкция try-except, в случае ошибки будет выполнен блок except
drone_1.land()
drone_1.close_connection()
Отписка от события
unsubscribe(callback, event) - позволяет отписаться от события на которое раньше была активна подписка. Работает только на события автопилота.
from pioneer_sdk2 import Pioneer, Event # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
def event_activate(event): # создаем функцию green_blink с проверкой 8 канала
global drone_1 # обращаемся к глобальной версии объекта, не создаем новый
if event == Event.TAKEOFF_COMPLETE: # если пришло событие "взлет", то включаем зеленый свет
drone_1.led_control(r=0, g=1, b=0)
# Здесь начинается ваш код
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.unsubscribe(event_activate, Event.TAKEOFF_COMPLETE) # указываем функцию, выполнение которой прекращается при событии взлета
Управление полезной нагрузкой (только Мини 2)
Открыть захват
grab_open(movement_time=0, velocity=100) - открывает захват квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.grab_open(movement_time=3, velocity=50) # открываем захват, содержит аргументы:
# movement_time - время открытия захвата, 0 - до упора
# velocity - cкорость открытия (0% - 100%)
time.sleep(3) # ставим паузу на 3 секунды
drone_1.close_connection() # закрываем соединение
Закрыть захват
grab_close(movement_time=0, velocity=100) - закрывает захват квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.grab_close(movement_time=3, velocity=50) # закрываем захват, содержит аргументы:
# movement_time - время закрытия захвата, 0 - до упора
# velocity - cкорость открытия (0% - 100%)
time.sleep(3) # ставим паузу на 3 секунды
drone_1.close_connection() # закрываем соединение
Остановить захват
grab_stop() - останавливает движение захвата квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.grab_open(movement_time=3, velocity=50) # открываем захват
drone_1.grab_stop() # останавливаем захват
drone_1.close_connection() # закрываем соединение
Данные модуля Ranger
get_ranger_data() - возвращает данные с модуля Ranger, установленный на "Пионер Мини 2".
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
while True: # запускаем бесконечный цикл
print(drone_1.get_ranger_data()) # вызываем метод
time.sleep(1) # ставим паузу на 1 секунду
drone_1.close_connection() # закрываем соединение
Управление магнитом (только Базовый)
Вкл/выкл магнит (способ 1)
cargo_grab() - включает магнит.
cargo_release() - выключает магнит.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.cargo_grab() # включает магнит
time.sleep(3) # ставим паузу на 3 секунды
drone_1.cargo_release() # включает магнит
drone_1.close_connection() # закрываем соединение
Вкл/выкл магнит (способ 2)
cargo_set() - включает или выключает магнит в зависимости от аргумента.
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1.cargo_set(True) # включает магнит
time.sleep(3) # ставим паузу на 3 секунды
drone_1.cargo_set(False) # включает магнит
drone_1.close_connection() # закрываем соединение
from pioneer_sdk2 import Pioneer # импортируем класс Pioneer из библиотеки pioneer_sdk2
drone_1 = Pioneer() # создаем экземпляр класса Pioneer, устанавливаем соединение
drone_1 = Pioneer() - создает переменную drone_1 которой присваивается объект класса Pioneer().
Полетные методы имеют две особенности:
arm(timeout, retries) - включает двигатели.
disarm() выключает двигатели.
- Возвращает
True, если команда успешно отправлена, иначеFalse.
takeoff() - выполняет взлет до высоты указанной в параметре Copter_com_takeoffAlt.
land() - выполняет посадку, двигатели выключатся автоматически.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Ожидает событие
COPTER_LANDED.
go_to_local_point(x, y, z, yaw, time) - полет в заданную координату, на основе локальной системы координат.
go_to_local_point_body_fixed(x, y, z, yaw, time) - полет в заданную координату, на основе внутренних координат квадрокоптера.
go_to_global_point(latitude, longitude, altitude, yaw) - полет в заданную координату, на основе GPS координат.
point_reached() - сообщает о достижении целевой координаты, позволяет избавиться от необходимости указывать метод time.sleep().
- Возвращает
True, если заданная координата достигнута, иначеFalse.
point_deceleration() - сообщает о приближении к целевой координаты, начинается оттормаживание.
- Возвращает
True, если заданная координата близка к достижению, иначеFalse.
set_manual_speed(vx, vy, vz, yaw_rate, interval) - полет с заданной скоростью, на основе локальных координат.
set_yaw(yaw) - задать курс (рысканье или yaw) в градусах.
rtl() - возвращает квадрокоптер в координату после выполнения метода takeoff().
- Возвращает
True, если команда успешно отправлена, иначеFalse.
get_fly_state() - возвращает текущее состояние полета: ON_LAND, ARMED, IN_SKY
led_control(led_id=255, r=0, g=0, b=0) - управляет яркостью субпикселей светодиодов.
- Возвращает
True, если команда успешно отправлена, иначеFalse.
reboot_board() - выполняет перезагрузку платы автопилота.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Всегда возвращает
Falseна Мини 2.
get_param(name, update) - меняет значение указанного параметра автопилота.
set_param(name, value) - меняет значение указанного параметра автопилота.
- Возвращает
True, если выполнено, иначеFalse.
set_logger(value=True) - включает или выключает ответы о результатах выполнения методов для объекта, по умолчанию включено.
grab_open(movement_time=0, velocity=100) - открывает захват квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
grab_close(movement_time=0, velocity=100) - закрывает захват квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
grab_stop() - останавливает движение захвата квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
get_ranger_data() - возвращает данные с модуля Ranger, установленный на "Пионер Мини 2".
cargo_grab() - включает магнит.
cargo_release() - выключает магнит.
cargo_set() - включает или выключает магнит в зависимости от аргумента.
takeoff() - выполняет взлет до высоты указанной в параметре Copter_com_takeoffAlt.
land() - выполняет посадку, двигатели выключатся автоматически.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Ожидает событие
COPTER_LANDED.
go_to_local_point(x, y, z, yaw, time) - полет в заданную координату, на основе локальной системы координат.
go_to_local_point_body_fixed(x, y, z, yaw, time) - полет в заданную координату, на основе внутренних координат квадрокоптера.
go_to_global_point(latitude, longitude, altitude, yaw) - полет в заданную координату, на основе GPS координат.
get_fly_state() - возвращает текущее состояние полета: ON_LAND, ARMED, IN_SKY
grab_close(movement_time=0, velocity=100) - закрывает захват квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
grab_stop() - останавливает движение захвата квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
get_ranger_data() - возвращает данные с модуля Ranger, установленный на "Пионер Мини 2".
time.sleep(3) # ставим паузу на 3 секундыdrone_1.cargo_release() # включает магнит drone_1.close_connection() # закрываем соединение
cargo_set() - включает или выключает магнит в зависимости от аргумента.
Основной класс для взаимодействия с квадрокоптерами серии Пионер
drone_1 = Pioneer() - создает переменную drone_1 которой присваивается объект класса Pioneer().
drone_1 = Pioneer() - создает переменную drone_1 которой присваивается объект класса Pioneer().
Полетные методы имеют две особенности:
arm(timeout, retries) - включает двигатели.
disarm() выключает двигатели.
- Возвращает
True, если команда успешно отправлена, иначеFalse.
takeoff() - выполняет взлет до высоты указанной в параметре Copter_com_takeoffAlt.
land() - выполняет посадку, двигатели выключатся автоматически.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Ожидает событие
COPTER_LANDED.
go_to_local_point(x, y, z, yaw, time) - полет в заданную координату, на основе локальной системы координат.
go_to_local_point_body_fixed(x, y, z, yaw, time) - полет в заданную координату, на основе внутренних координат квадрокоптера.
go_to_global_point(latitude, longitude, altitude, yaw) - полет в заданную координату, на основе GPS координат.
point_reached() - сообщает о достижении целевой координаты, позволяет избавиться от необходимости указывать метод time.sleep().
- Возвращает
True, если заданная координата достигнута, иначеFalse.
point_deceleration() - сообщает о приближении к целевой координаты, начинается оттормаживание.
- Возвращает
True, если заданная координата близка к достижению, иначеFalse.
set_manual_speed(vx, vy, vz, yaw_rate, interval) - полет с заданной скоростью, на основе локальных координат.
set_yaw(yaw) - задать курс (рысканье или yaw) в градусах.
rtl() - возвращает квадрокоптер в координату после выполнения метода takeoff().
- Возвращает
True, если команда успешно отправлена, иначеFalse.
get_fly_state() - возвращает текущее состояние полета: ON_LAND, ARMED, IN_SKY
led_control(led_id=255, r=0, g=0, b=0) - управляет яркостью субпикселей светодиодов.
- Возвращает
True, если команда успешно отправлена, иначеFalse.
reboot_board() - выполняет перезагрузку платы автопилота.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Всегда возвращает
Falseна Мини 2.
get_param(name, update) - меняет значение указанного параметра автопилота.
set_param(name, value) - меняет значение указанного параметра автопилота.
- Возвращает
True, если выполнено, иначеFalse.
set_logger(value=True) - включает или выключает ответы о результатах выполнения методов для объекта, по умолчанию включено.
get_local_position_lps() - позволяет узнать локальный координаты. None, если ошибка.
get_altitude() - позволяет узнать высоту с барометра. None, если ошибка.
get_dist_sensor_data() - позволяет узнать высоту с дальномера. None, если ошибка.
get_optical_data() - позволяет узнать данные модуля оптической навигации. None, если ошибка.
get_battery_status() - позволяет узнать напряжение и температуру аккумулятора. None, если ошибка.
get_orientation() - возвращает ориентацию дрона по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.
get_accel() - возвращает ускорение квадрокоптера по осям X, Y, Z. None, если ошибка.
get_gyro() - возвращает скорость по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.
get_mag() - возвращает показания магнитометра по осям X, Y, Z. None, если ошибка. Только при наличии GPS модуля.
get_motors_rpm() - возвращает обороты каждого из 4 моторов квадрокоптера. None, если ошибка.
get_nav_system(update=False) - возвращает выбранную систему навигации.
get_nav_status_lps() - возвращает статус LPS навигации.
get_local_velocity_lps() - возвращает скорость по осям X, Y, Z в м/с. None, если ошибка.
get_local_yaw_lps() - возвращает текущий курсовой угол (рысканье). None, если ошибка.
get_nav_status_gps() - возвращает статус GPS навигации.
get_global_position_gps() - возвращает координаты по GPS. None, если ошибка.
get_global_velocity_gps() - возвращает скорость по GPS. None, если ошибка.
get_satellites_count() - возвращает количество обнаруженных спутников GPS и ГЛОНАСС. None, если ошибка.
time() - возвращает время работы квадрокоптера в секундах с момента начала GPS-эпохи. None, если ошибка.
flight_time() - возвращает время с начала полета квадрокоптера в секундах. None, если ошибка.
- Важно понимать, что автопилот требует постоянного наличия "сигнала" на каналах, используйте циклы.
- Возвращает
True, если команда успешно отправлена, иначеFalse.
get_rc_channel() - возвращает значение 8 канала. None, если ошибка.
grab_open(movement_time=0, velocity=100) - открывает захват квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
grab_close(movement_time=0, velocity=100) - закрывает захват квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
grab_stop() - останавливает движение захвата квадрокоптера "Пионер Мини 2".
- Возвращает
True, если выполнено, иначеFalse.
get_ranger_data() - возвращает данные с модуля Ranger, установленный на "Пионер Мини 2".
cargo_grab() - включает магнит.
cargo_release() - выключает магнит.
cargo_set() - включает или выключает магнит в зависимости от аргумента.
get_local_position_lps() - позволяет узнать локальный координаты. None, если ошибка.
get_altitude() - позволяет узнать высоту с барометра. None, если ошибка.
get_dist_sensor_data() - позволяет узнать высоту с дальномера. None, если ошибка.
get_optical_data() - позволяет узнать данные модуля оптической навигации. None, если ошибка.
get_battery_status() - позволяет узнать напряжение и температуру аккумулятора. None, если ошибка.
get_orientation() - возвращает ориентацию дрона по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.
get_accel() - возвращает ускорение квадрокоптера по осям X, Y, Z. None, если ошибка.
get_gyro() - возвращает скорость по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.
get_mag() - возвращает показания магнитометра по осям X, Y, Z. None, если ошибка. Только при наличии GPS модуля.
get_motors_rpm() - возвращает обороты каждого из 4 моторов квадрокоптера. None, если ошибка.
get_nav_system(update=False) - возвращает выбранную систему навигации.
get_nav_status_lps() - возвращает статус LPS навигации.
get_local_velocity_lps() - возвращает скорость по осям X, Y, Z в м/с. None, если ошибка.
get_local_yaw_lps() - возвращает текущий курсовой угол (рысканье). None, если ошибка.
get_nav_status_gps() - возвращает статус GPS навигации.
get_global_position_gps() - возвращает координаты по GPS. None, если ошибка.
get_global_velocity_gps() - возвращает скорость по GPS. None, если ошибка.
get_satellites_count() - возвращает количество обнаруженных спутников GPS и ГЛОНАСС. None, если ошибка.
time() - возвращает время работы квадрокоптера в секундах с момента начала GPS-эпохи. None, если ошибка.
flight_time() - возвращает время с начала полета квадрокоптера в секундах. None, если ошибка.
- Важно понимать, что автопилот требует постоянного наличия "сигнала" на каналах, используйте циклы.
- Возвращает
True, если команда успешно отправлена, иначеFalse.
get_rc_channel() - возвращает значение 8 канала. None, если ошибка.
point_reached() - сообщает о достижении целевой координаты, позволяет избавиться от необходимости указывать метод time.sleep().
- Возвращает
True, если заданная координата достигнута, иначеFalse.
point_deceleration() - сообщает о приближении к целевой координаты, начинается оттормаживание.
- Возвращает
True, если заданная координата близка к достижению, иначеFalse.
set_manual_speed(vx, vy, vz, yaw_rate, interval) - полет с заданной скоростью, на основе локальных координат.
set_yaw(yaw) - задать курс (рысканье или yaw) в градусах.
rtl() - возвращает квадрокоптер в координату после выполнения метода takeoff().
- Возвращает
True, если команда успешно отправлена, иначеFalse.
reboot_board() - выполняет перезагрузку платы автопилота.
- Возвращает
True, если команда успешно отправлена, иначеFalse. - Всегда возвращает
Falseна Мини 2.
get_param(name, update) - меняет значение указанного параметра автопилота.
set_param(name, value) - меняет значение указанного параметра автопилота.
- Возвращает
True, если выполнено, иначеFalse.
set_logger(value=True) - включает или выключает ответы о результатах выполнения методов для объекта, по умолчанию включено.
get_altitude() - позволяет узнать высоту с барометра. None, если ошибка.
get_dist_sensor_data() - позволяет узнать высоту с дальномера. None, если ошибка.
get_optical_data() - позволяет узнать данные модуля оптической навигации. None, если ошибка.
get_battery_status() - позволяет узнать напряжение и температуру аккумулятора. None, если ошибка.
get_orientation() - возвращает ориентацию дрона по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.
get_accel() - возвращает ускорение квадрокоптера по осям X, Y, Z. None, если ошибка.
get_gyro() - возвращает скорость по углам крена(roll), тангажа(pitch), рыскания(yaw). None, если ошибка.
get_mag() - возвращает показания магнитометра по осям X, Y, Z. None, если ошибка. Только при наличии GPS модуля.
get_motors_rpm() - возвращает обороты каждого из 4 моторов квадрокоптера. None, если ошибка.
get_nav_system(update=False) - возвращает выбранную систему навигации.
get_nav_status_lps() - возвращает статус LPS навигации.
get_local_velocity_lps() - возвращает скорость по осям X, Y, Z в м/с. None, если ошибка.
get_local_yaw_lps() - возвращает текущий курсовой угол (рысканье). None, если ошибка.
get_nav_status_gps() - возвращает статус GPS навигации.
get_global_position_gps() - возвращает координаты по GPS. None, если ошибка.
get_global_velocity_gps() - возвращает скорость по GPS. None, если ошибка.
get_satellites_count() - возвращает количество обнаруженных спутников GPS и ГЛОНАСС. None, если ошибка.
time() - возвращает время работы квадрокоптера в секундах с момента начала GPS-эпохи. None, если ошибка.
flight_time() - возвращает время с начала полета квадрокоптера в секундах. None, если ошибка.
get_rc_channel() - возвращает значение 8 канала. None, если ошибка.
Класс Camera
Позволяет получить изображение с камеры квадрокоптера и при необходимости обработать его
Инициализация класса
Создание экземпляра класса Camera (Мини 2, Radxa Zero)
Camera(camera_type=CameraType.MAIN) - основная камера, по умолчанию применяется этот тип камеры.
Camera(camera_type=CameraType.OPT) - камера оптической навигации, расположена на плате-адаптере. Не работает на модуле Radxa Zero.
from pioneer_sdk2 import Camera # импортируем класс Camera из библиотеки pioneer_sdk2
camera_drone_1 = Camera() # создаем экземпляр класса Camera
Создание экземпляра класса Camera (Raspberry Pi Zero)
Camera(camera_type=CameraType.MAIN) - основная камера, по умолчанию применяется этот тип камеры.
Camera(camera_type=CameraType.OPT) - камера оптической навигации, расположена на плате-адаптере.
from pioneer_sdk2 import Camera # импортируем класс Camera из библиотеки pioneer_sdk2
# создаем экземпляр класса Camera (выбираем в зависимости от способа подключения)
camera_drone_1 = Camera() # при работе в терминале Pioneer OS (на борту)
camera_drone_1 = Camera(camera_ip="10.42.0.1:8554") # при удаленном подключении
Управление камерой
Получить кадр и выключить видеопоток
get_cv_frame(timeout) - возвращает следующий доступный кадр из очереди в формате BGR.
stop() - останаливает передачу кадров.
from pioneer_sdk2 import Camera # импортируем класс Camera из библиотеки pioneer_sdk2
import cv2 # библиотека cv2 содержит функции для работы с изображениями
camera_drone_1 = Camera() # создаем экземпляр класса Camera
while True: # запускаем бесконечный цикл
frame = camera_drone_1.get_cv_frame(timeout=5.0) # сохраняем изображение в переменную frame
# timeout=5.0 - время ожидания кадра в секундах
if frame is not None: # проверяем, что изображение получено
cv2.imshow("video", frame) # выводим полученное изображение frame в окне с названием "video"
elif cv2.waitKey(1) == 27: # проверяем нажатие клавиши ESC
camera_drone_1.stop() # закрываем передачу кадров
break # выходим из цикла
from pioneer_sdk2 import Camera # импортируем класс Camera из библиотеки pioneer_sdk2
camera_drone_1 = Camera() # создаем экземпляр класса Camera
Camera(camera_type=CameraType.MAIN) - основная камера, по умолчанию применяется этот тип камеры.
Camera(camera_type=CameraType.OPT) - камера оптической навигации, расположена на плате-адаптере.
get_cv_frame(timeout) - возвращает следующий доступный кадр из очереди в формате BGR.
stop() - останаливает передачу кадров.
Позволяет получить изображение с камеры квадрокоптера и при необходимости обработать его
Camera(camera_type=CameraType.MAIN) - основная камера, по умолчанию применяется этот тип камеры.
Camera(camera_type=CameraType.OPT) - камера оптической навигации, расположена на плате-адаптере. Не работает на модуле Radxa Zero.
Camera(camera_type=CameraType.MAIN) - основная камера, по умолчанию применяется этот тип камеры.
Camera(camera_type=CameraType.OPT) - камера оптической навигации, расположена на плате-адаптере.
get_cv_frame(timeout) - возвращает следующий доступный кадр из очереди в формате BGR.
stop() - останаливает передачу кадров.
Класс ImageViewer (только Мини 2, Radxa Zero)
Класс для трансляции numpy-кадров по RTSP через GStreamer, доступен только при использовании драйвера камеры gstreamer
Инициализация класса
from pioneer_sdk2 import ImageViewer # импортируем класс ImageViewer из библиотеки pioneer_sdk2
video_drone_1 = ImageViewer() # создаем экземпляр класса ImageViewer, камера модуля esp32
Методы класса
Включить и выключить видеотрансляцию
imshow(name, frame, fps=30) - запускает видеотрансляцию в браузер.
close() - уничтожает все gstreamer пайплайны.
from pioneer_sdk2 import ImageViewer, Camera # импортируем классы из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
video_drone_1 = ImageViewer() # создаем экземпляр класса ImageViewer
camera_drone_1 = Camera() # создаем экземпляр класса Camera
my_time = time.time() # объявляем переменную my_time, присваиваем текущее время (в секундах с 1970 года)
cycle_time = 30 # объявляем переменную cycle_time, присваиваем желаемую длительность цикла
while time.time() - my_time < cycle_time: # запускаем цикл, код будет повторяться, пока условие верно
frame = camera_drone_1.get_cv_frame() # получаем кадр и присваиваем данные переменной frame
video_drone_1.imshow("video", frame, fps=30) # запускаем трансляцию, содержит аргументы:
# video - название трансляции
# frame - переменная с ранее полученным кадром
# fps=30 - количество кадров в секунду при передаче видео
# трансляция выполняется по адресу: 10.42.0.1:8889/video
# ip - по умолчанию 10.42.0.1 или скопировать из раздела хот-спот на компьютере
# 8889 - порт трансляции
# name - название трансляции
# при подключения квадрокоптера к вашей сети:
# трансляция выполняется по адресу: ваш ip:8889/video
video_drone_1.close() # останавливаем видеопоток
imshow(name, frame, fps=30) - запускает видеотрансляцию в браузер.
close() - уничтожает все gstreamer пайплайны.
Класс для трансляции numpy-кадров по RTSP через GStreamer, доступен только при использовании драйвера камеры gstreamer
imshow(name, frame, fps=30) - запускает видеотрансляцию в браузер.
close() - уничтожает все gstreamer пайплайны.
Класс RecorderControl (только Мини 2)
Класс для управления записью фото и видео
Инициализация класса
from pioneer_sdk2 import RecorderControl # импортируем класс RecorderControl из библиотеки pioneer_sdk2
rec_drone_1 = RecorderControl() # создаем экземпляр класса RecorderControl
Методы класса
Получить список конфигураций камеры
get_camera_recording_configs() - возвращает список конфигураций выбранной камеры. Конфигурации представляют собой набор настроек камеры (ширина, высота, fps).
from pioneer_sdk2 import RecorderControl, CameraType # импортируем классы из библиотеки pioneer_sdk2
rec_drone_1 = RecorderControl() # создаем экземпляр класса RecorderControl
print(rec_drone_1.get_camera_recording_configs(CameraType.MAIN)) # выводим в терминал конфигурации основной камеры
print(rec_drone_1.get_camera_recording_configs(CameraType.OPT)) # выводим в терминал конфигурации камеры оптической навигации
Видеозапись в галерею
start_recording(camera_type, recording_config, output_dir) - запускает видеозапись.
- camera_type - камера используемая для видеозаписи.
- recording_config - используемая конфигурация записи, если
None, используется первая доступная конфигурация. - output_dir - место сохранения видеозаписи, по умолчанию
/mnt/media/videos/.
stop_recording(camera_type) - останавливает видеозапись.
from pioneer_sdk2 import RecorderControl, CameraType # импортируем классы из библиотеки pioneer_sdk2
from time import sleep
rec_drone_1 = RecorderControl() # создаем экземпляр класса RecorderControl
print(rec_drone_1.get_camera_recording_configs(CameraType.MAIN)) # выводим в терминал конфигурации основной камеры
config_drone_1 = rec_drone_1.get_camera_recording_configs(CameraType.MAIN)[0] # записываем в переменную первую конфигурацию
rec_drone_1.start_recording(CameraType.MAIN, config_drone_1) # запускаем видеозапись
sleep(10) # пауза на 10 секунд
rec_drone_1.stop_recording(CameraType.MAIN) # останавливаем видеозапись
Фотография в галерею
take_photo(file_name, camera_type, recording_config, output_dir) - делает фотографию.
- file_name - имя фотографии с расширением (
.jpg.jpeg.png). - camera_type - камера используемая для видеозаписи.
- recording_config - используемая конфигурация записи, если
None, используется первая доступная конфигурация. - output_dir - место сохранения видеозаписи, по умолчанию
/mnt/media/videos/. - Вызывает ошибку ValueError, если пустое имя файла или неподдерживаемое расширение.
- Вызывает ошибку ValueError, если для выбранной камеры нет доступных конфигураций записи.
- Вызывает ошибку RuntimeError, если произошла ошибка подготовки камеры или выполнения команды фото.
from pioneer_sdk2 import RecorderControl, CameraType # импортируем классы из библиотеки pioneer_sdk2
rec_drone_1 = RecorderControl() # создаем экземпляр класса RecorderControl
print(rec_drone_1.get_camera_recording_configs(CameraType.MAIN)) # выводим в терминал конфигурации основной камеры
config_drone_1 = rec_drone_1.get_camera_recording_configs(CameraType.MAIN)[0] # записываем в переменную первую конфигурацию
rec_drone_1.take_photo("photo_1.jpg", CameraType.MAIN, config_drone_1) # делаем фотографию
start_recording(camera_type, recording_config, output_dir) - запускает видеозапись.
stop_recording(camera_type) - останавливает видеозапись.
take_photo(file_name, camera_type, recording_config, output_dir) - делает фотографию.
Класс для управления записью фото и видео
start_recording(camera_type, recording_config, output_dir) - запускает видеозапись.
stop_recording(camera_type) - останавливает видеозапись.
take_photo(file_name, camera_type, recording_config, output_dir) - делает фотографию.
start_recording(camera_type, recording_config, output_dir) - запускает видеозапись.
stop_recording(camera_type) - останавливает видеозапись.
take_photo(file_name, camera_type, recording_config, output_dir) - делает фотографию.
Класс ServoCamera (только Мини 2)
Класс для управления сервоприводом камеры, позволяющий устанавливать угол поворота
Инициализация класса
from pioneer_sdk2 import ServoCamera # импортируем класс ServoCamera из библиотеки pioneer_sdk2
servo_drone_1 = ServoCamera() # создаем экземпляр класса ServoCamera, проверяет поддержку сервомотора
Методы класса
Установить угол сервопривода камеры
set_angle(angle) - устанавливает угол поворота сервопривода камеры, диапазон от -85 до 30 градусов.
- Возвращает
True, если выполнено, иначеFalse. - Вызывает
Except ValueError, если угол выходит за пределы допустимого диапазона (от -85 до 30 градусов).
from pioneer_sdk2 import ServoCamera # импортируем класс ServoCamera из библиотеки pioneer_sdk2
import time # библиотека time содержит функции для работы со временем
servo_drone_1 = ServoCamera() # создаем экземпляр класса ServoCamera, проверяет поддержку сервомотора
servo_drone_1.set_angle(25) # устанавливаем угол камеры на 25 градусов
time.sleep(3) # ставим паузу на 3 секунды
servo_drone_1.set_angle(-25) # устанавливаем угол камеры на -25 градусов
set_angle(angle) - устанавливает угол поворота сервопривода камеры, диапазон от -85 до 30 градусов.
Класс для управления сервоприводом камеры, позволяющий устанавливать угол поворота
set_angle(angle) - устанавливает угол поворота сервопривода камеры, диапазон от -85 до 30 градусов.