SDK: Управление манипулятором Medu с помощью Python

Документация по использованию Python SDK для манипуляторов ПРОМОБОТ

1. Введение и Обзор

Python SDK — это библиотека от компании «ПРОМОБОТ», предназначенная для программного управления манипуляторами через приложение M Control. SDK позволяет отправлять команды и получать обратную связь от робота. Библиотека распространяется бесплатно и может быть установлена на персональные компьютеры.

Требование к сети: манипулятор и компьютер должны быть доступны друг другу по сети (локально или через Интернет).
Требование к Python: установите Python 3.12, создайте виртуальное окружение и используйте его для запуска SDK — это обеспечит воспроизводимость и отсутствие конфликтов с системными пакетами.

SDK требует наличия Python 3.12. Ниже — краткие инструкции по проверке и установке на популярных платформах, а также рекомендация по использованию виртуального окружения.

Проверка версии

python3.12 --version
# или, если система использует "python"
python --version

Ожидаемый вывод: Python 3.12.x. Если команда не найдена или версия ниже — нужно установить/обновить.

Установка

  • Ubuntu / Debian (пример):
    sudo apt update
    sudo apt install -y python3.12 python3.12-venv python3.12-distutils
  • Fedora / CentOS / RHEL: используйте пакетный менеджер дистрибутива или сборку из исходников; можно также установить через pyenv.
  • macOS (Homebrew):
    brew update
    brew install python@3.12
  • Windows: скачайте официальный инсталлятор Python 3.12 с python.org и выполните установку, включив опцию "Add Python to PATH". После установки проверьте в PowerShell:
    python --version
  • Переиспользование нескольких версий — pyenv (рекомендуется разработчикам):
    # установка pyenv (пример)
    curl https://pyenv.run | bash
    
    # затем
    
    pyenv install 3.12.0
    pyenv global 3.12.0

Виртуальное окружение (обязательно для проекта)

Рекомендуется запускать SDK внутри виртуального окружения, созданного той же версией Python 3.12.

# создать venv
python3.12 -m venv .venv

# Linux / macOS

source .venv/bin/activate

# Windows (PowerShell)

.venv\Scripts\Activate.ps1

# обновить pip/setuptools

python -m pip install --upgrade pip setuptools wheel

Установка SDK

После активации виртуального окружения установите SDK из предоставленного организаторами архива:

# Установка из wheel файла
pip install dist/*.whl

# Или установка из tar.gz архива
pip install dist/pm_python_sdk-0.6.11.tar.gz

Проверьте версию установленного SDK:

pip show pm-python-sdk

Важно: Установите необходимые зависимости:

pip install pydantic==2.11.7 paho-mqtt==2.1.0

Важно: Архив с SDK (папка dist) будет предоставлен организаторами. Скопируйте его в директорию проекта перед установкой. Убедитесь, что установлены все зависимости с указанными версиями

2. Описание архитектуры программного обеспечения

Доступны два способа программирования: визуальный (Blockly) и программирование через SDK. Оба способа в итоге выполняют код на манипуляторе.

Взаимодействие построено по модели клиент — сервер с использованием протокола MQTT.

Ключевые компоненты
  • Клиент: компьютер пользователя / приложение с SDK.
  • Сервер (pm_develop_api): работает на манипуляторе и обрабатывает команды.
  • M Control: приложение с собственным SDK, которое переводит действия GUI в ROS2/rosbridge команды.

Сервер не только принимает команды, но и возвращает ответы, а также ведет стриминг текущих декартовых координат и состояния суставов.

3. Типы команд

SDK поддерживает несколько типов команд для гибкого управления:

  • Синхронные — выполняются по очереди и блокируют выполнение до завершения: manipulator.get_control().
  • Асинхронные — не блокируют выполнение; имеют суффикс _async и варианты с возможностью ожидания (async/await).
  • Стриминговые — для реального управления малыми шагами (скорости, позы, суставы).
  • no_wait — аналог асинхронного метода, но без возможности ожидания результата.
Примеры вызовов
# синхронный
manipulator.get_control()

# асинхронный (awaitable)
await manipulator.get_control_async_await()

#стриминговый
for i in range(5):
    manipulator.stream_cartesian_velocities(lin, ang)
    time.sleep(0.1)

# no_wait
manipulator.get_control_no_wait()
Далее в примерах будут использоваться синхронные методы.

4. Программные блоки (Структура программы)

Структуру программы удобно разбить на логические блоки:

  1. Подключение библиотек и зависимостей.
  2. Подключение к манипулятору и захват управления.
  3. Основной блок выполнения (движения, чтение данных).
  4. Завершающий блок — опционально (отключение, освобождение ресурсов).

Ниже — минимальный пример подключения и захвата управления.

from sdk.manipulators.medu import MEdu

host = "192.168.88.182" #IP манипулятора
client_id = "122"       #ID клиента
login = "13"            #Логин
password = "14"         #Пароль

manipulator = MEdu(host, client_id, login, password)
manipulator.connect()
manipulator.get_control()

5. Примеры движений

5.1 Движение по углам

У MEdu три управляемых угла: основание, плечо, стрела.

# Пример: move_to_angles
manipulator.move_to_angles(
    povorot_osnovaniya=0.05,    # угол поворота основания [рад]
    privod_plecha=-0.35,        # угол плеча [рад]
    privod_strely=-0.75,        # угол стрелы [рад]
    v_osnovaniya=0.0,           # скорость основания [рад/с]
    v_plecha=0.0,               # скорость плеча [рад/с]
    v_strely=0.0,               # скорость стрелы [рад/с]
    velocity_factor=0.1,        # коэффициент скорости
    acceleration_factor=0.1,    # коэффициент ускорения
)

Параметры:

  • povorot_osnovaniya (float, обязательный): угол поворота основания в радианах
  • privod_plecha (float, обязательный): угол плеча в радианах
  • privod_strely (float, обязательный): угол стрелы в радианах
  • v_osnovaniya (float, опциональный, по умолчанию 0.0): скорость основания в рад/с
  • v_plecha (float, опциональный, по умолчанию 0.0): скорость плеча в рад/с
  • v_strely (float, опциональный, по умолчанию 0.0): скорость стрелы в рад/с
  • velocity_factor (float, опциональный, по умолчанию 0.1): коэффициент скорости (0.0-1.0)
  • acceleration_factor (float, опциональный, по умолчанию 0.1): коэффициент ускорения (0.0-1.0)
  • timeout_seconds (float, опциональный, по умолчанию 60.0): таймаут операции в секундах
  • throw_error (bool, опциональный, по умолчанию True): выбрасывать исключение при ошибке

5.2 Движение по координатам

from sdk.commands.move_coordinates_command import MoveCoordinatesParamsPosition, MoveCoordinatesParamsOrientation

position = MoveCoordinatesParamsPosition(0.32, -0.004, 0.25)
orientation = MoveCoordinatesParamsOrientation(0, 0, 0, 1.0)

manipulator.move_to_coordinates(position, orientation, velocity_scaling_factor=0.1, acceleration_scaling_factor=0.1, planner_type=PlannerType.LIN, timeout_seconds=30.0, throw_error=True)

Параметры:

  • position: позиция — объект с полями x, y, z.
  • orientation: ориентация — объект с полями x, y, z, w.
  • velocity_scaling_factor: коэффициент скорости (доля от максимальной скорости, по умолчанию 0.1).
  • acceleration_scaling_factor: коэффициент ускорения (доля от максимального ускорения, по умолчанию 0.1).
  • planner_type: тип планировщика (по умолчанию PlannerType.LIN).
  • timeout_seconds: таймаут ожидания завершения (секунды).
  • throw_error: выбрасывать исключение при ошибке (по умолчанию True).

Примечания

  • В случае, если движение манипулятора не происхоит и возникает ошибка расчетов траектории, указывайте более точные координаты.
START_POSITION = MoveCoordinatesParamsPosition(
        0.2279991579119544, -0.25677241023135805, 0.24713621034095856)

5.3 Движение по дуге

from sdk.commands.arc_motion import ArcMotion, Pose, Position


target = Pose(position=Position(target_x, target_y, target_z), orientation=Orientation())
center_arc = Pose(position=Position(center_x, center_y, center_z), orientation=Orientation())

manipulator.arc_motion(target, center_arc, step=0.05, count_point_arc=50,
max_velocity_scaling_factor=0.5, max_acceleration_scaling_factor=0.5)

Параметры:

  • target: целевая точка (объект с position и orientation).
  • center_arc: точка центра дуги (объект с position и orientation).
  • step: шаг между точками дуги (по умолчанию 0.05).
  • count_point_arc: количество точек для аппроксимации дуги (по умолчанию 50).
  • max_velocity_scaling_factor: максимальный масштаб скорости (по умолчанию 0.5).
  • max_acceleration_scaling_factor: максимальный масштаб ускорения (по умолчанию 0.5).
  • timeout_seconds: таймаут ожидания завершения (секунды).
  • throw_error: выбрасывать исключение при ошибке (по умолчанию True).

6. Работа с насадками

Насадка: Гриппер (Gripper) — механический захват для MEdu.

Требования:

  • Перед активацией насадки необходимо включить питание с помощью manipulator.nozzle_power(True).

Варианты работы:

  1. Прямой контроль через класс-насадку — используйте GripperAttachment и его методы activate/deactivate. Подходит, когда нужно явно управлять захватом из кода и отслеживать статус команды.
  2. Вызов через манипулятор — например
    manipulator.manage_gripper(rotation=..., gripper=...)

Примеры использования


# 1) Прямой
manipulator.nozzle_power(True)  # обязательно включить питание
gripper = GripperAttachment(manipulator)
gripper.activate(rotation=20, gripper=10)   # закрыть/захватить
gripper.deactivate()                         # открыть

# 2) Через манипулятор
manipulator.nozzle_power(True)
manipulator.manage_gripper(rotation=20, gripper=10)
  

Параметры (activate):

  • rotation — угол поворота насадки в градусах.
  • gripper — позиция/угол захвата в градусах.

7. Стриминг

Поддерживается управление в трех режимах: TWIST (скорости), POSE (целевая поза), JOINT_JOG (положение суставов).

Перед началом каждого стриминга необходимо включить соответствующий режим:

from sdk.utils.enums import ServoControlType

# Режимы
manipulator.set_servo_control_type(ServoControlType.TWIST)
manipulator.set_servo_control_type(ServoControlType.POSE)
manipulator.set_servo_control_type(ServoControlType.JOINT_JOG)

# Либо короткий вариант
manipulator.set_servo_twist_mode()  # Для скорости
manipulator.set_servo_pose_mode()   # Для позы
manipulator.set_servo_joint_jog_mode()  # Для суставов

Стриминг скоростей

# Включаем режим TWIST
manipulator.set_servo_twist_mode()

linear_vel = {"x": 0.02, "y": 0, "z": 0}
angular_vel = {"rx": 0, "ry": 0, "rz": 0.01}
manipulator.stream_cartesian_velocities(linear_vel, angular_vel)

Параметры (stream_cartesian_velocities):

  • position: позиция (объект с x, y, z).
  • velocities: скорость (объект с rx, ry, rz).
  • header: информация о штампе времени и системе координат (по умолчанию now и base_link).

Стриминг позы

# Включаем режим POSE
manipulator.set_servo_pose_mode()

position = MoveCoordinatesParamsPosition(0.27, 0.0, 0.15)
orientation = MoveCoordinatesParamsOrientation(0, 0, 0, 1)
manipulator.stream_coordinates(position, orientation)

Параметры (stream_coordinates):

  • position: позиция (объект с x, y, z).
  • orientation: ориентация (объект с x, y, z, w).
  • header: информация о штампе времени и системе координат (по умолчанию now и base_link).

Стриминг суставов

# Включаем режим JOINT_JOG
manipulator.set_servo_joint_jog_mode()

manipulator.stream_joint_angles(
    povorot_osnovaniya=0.5, privod_plecha=1.0, privod_strely=0.8,
    v_osnovaniya=0.2, v_plecha=0.1, v_strely=0.15
)

Параметры (stream_joint_angles):

  • povorot_osnovaniya, privod_plecha, privod_strely: позиции (углы) для каждого сустава.
  • v_osnovaniya, v_plecha, v_strely: скорости для каждого сустава.
  • header: информация о штампе времени и системе координат (опционально).

8. Программы

SDK позволяет запускать готовые программы, JSON-сценарии и выполнять Python-код прямо на манипуляторе.

# Запуск готовой программы
manipulator.run_program('edum/default')

# Запуск JSON-программы
program_json = {
  'Root':[{'Move':{'content':[{'Point':{'positions':[0.3,-0.3,-0.4],'time':0.5}}],'type':'Simple'}}]
}
manipulator.run_program_json('program_1', program_json)

# Запуск Python-кода на роботе
manipulator.run_python_program("print('Hello!')")

Параметры (run_program):

  • name: название программы (строка).

Параметры (run_program_json):

  • name: название программы (строка).
  • json: JSON-программа — объект с корневым ключом Root и массивом команд.

Параметры (run_python_program):

  • code: строка с Python-кодом для выполнения на манипуляторе.

9. Остановка движениями

Остановка всего движения с таймаутом.

manipulator.stop_movement(timeout_seconds=5.0)

10. Состояния и данные

Методы для получения состояния манипулятора и подписок:

  • manipulator.get_joint_state() — текущие углы суставов.
  • manipulator.get_home_position() — домашняя позиция.
  • manipulator.get_cartesian_coordinates() — текущие координаты X, Y, Z.

11. Конвейерная лента (MGbot)

Управление конвейерной лентой и связанными устройствами.

# Установить скорость мотора (0..100)
manipulator.mgbot_conveyer.set_speed_motors(10)

# Повернуть сервопривод
manipulator.mgbot_conveyer.set_servo_angle(45)

# Установить цвет светодиода (0..255)
manipulator.mgbot_conveyer.set_led_color(255, 0, 0)

# Показать текст на дисплее
manipulator.mgbot_conveyer.display_text('Hello')

# Звуковой сигнал (1..15)
manipulator.mgbot_conveyer.set_buzz_tone(10)

# Чтение датчиков
sensor_data = manipulator.mgbot_conveyer.get_sensors_data(True)
# Возвращаемые поля: "DistanceSensor", "ColorSensor", "Prox"

Параметры:

  • set_speed_motors(speed): задает скорость мотора в диапазоне 0..100.
  • set_servo_angle(angle): поворачивает сервопривод (градусы).
  • set_led_color(r, g, b): задает цвет светодиодов (каждый канал 0..255).
  • display_text(text): показывает текст на дисплее конвейера (utf-8).
  • set_buzz_tone(level): подает звуковой сигнал в диапазоне 1..15.
  • get_sensors_data(enabled): получить данные с датчиков. True — данные возвращаются в виде JSON.

Возвращаемые данные (sensor_data):

  • DistanceSensor — значение расстояния / показания дистанционного датчика.
  • ColorSensor — объект с полями R, G, B, Prox (например {"R":97,"G":114,"B":108,"Prox":50}).
  • Prox — значение приближения к ColorSensor.
Инструкция по подключению
  1. Подключите кабель USB к разъему на конвейере и к разъему USB на задней панели манипулятора.
  2. Подключите кабель питания в разъем рядом с USB-портом на конвейере. При подаче питания моторы кратковременно инициализируются и могут сделать короткое движение.
  3. Проверьте индикацию светодиодов на плате конвейера:
    • LED1 (синий): горит, когда есть питание 5 В через USB-порт.
    • LED2 (красный): горит, когда есть питание от внешнего источника 8–30 В.
    • LED3 (розовый): режим выхода или ШИМ.
Важные предупреждения и рекомендации
  • Разъем Type-C: контроллер чувствителен к ориентации кабеля USB-C. Если устройство не определяется — попробуйте аккуратно перевернуть разъем кабеля и повторно подключить.
  • Проблемы со стартом/остановкой ленты: если лента не начинает движение или не останавливается, аккуратно приподнимите стеклянную крышку и нажмите кнопку RESET слева от платы конвейера.
  • Подключение по Wi-Fi: при отправке команд через Wi-Fi убедитесь в стабильном соединении и достаточной пропускной способности сети — нестабильный Wi-Fi может приводить к потерям команд и задержкам.
  • Подсветка дисплея: при подключении USB-кабеля к манипулятору возможна потеря яркости дисплея ленты — это нормальное поведение.
  • Не работают сенсорные датчики: в случае отсутствия показаний сенсоров попробуйте перезапустить манипулятор. Если проблема сохраняется — проверьте подключение кабелей или обратитесь в техподдержку ПРОМОБОТ.

12. Управление GPIO

GPIO (General Purpose Input/Output) позволяет управлять цифровыми входами и выходами манипулятора. Это полезно для взаимодействия с внешними устройствами, датчиками, светодиодами и другими периферийными компонентами.

Основные методы

# Синхронная запись в GPIO
manipulator.write_gpio_bit(name, value, timeout_seconds=60.0, throw_error=True)

# Чтение значения GPIO
manipulator.get_gpio_bit(name, timeout_seconds=60.0, throw_error=True)

Параметры

  • name: имя GPIO-пина (строка)
  • value: значение для записи (0 или 1)
  • timeout_seconds: таймаут выполнения команды (по умолчанию 60.0)
  • throw_error: выбрасывать исключение при ошибке (по умолчанию True)
Важные предупреждения
  • get_gpio_bit и write_gpio_bit: доступны только синхронные методы.

Пример использования

# Определение имени GPIO-пина
gpio_name = "/dev/gpiochip4/e1_pin"

# Функция для управления светодиодом
def set_led(on: bool):
    try:
        manipulator.write_gpio_bit(gpio_name, 1 if on else 0, timeout_seconds=0.5, throw_error=False)
    except Exception as e:
        print(f"Ошибка управления GPIO: {e}")

# Использование
set_led(True)   # Включить светодиод
set_led(False)  # Выключить светодиод

Типичные сценарии использования

  • Управление внешними светодиодами или индикаторами
  • Включение/выключение периферийных устройств
  • Взаимодействие с простыми датчиками
  • Создание световых сигналов о состоянии системы

13. Получение данных из I2C

Интерфейс I2C (Inter-Integrated Circuit) позволяет читать данные с различных датчиков и устройств, подключенных к манипулятору. Это полезно для получения показаний сенсоров, коммутаторов и других периферийных компонентов.

Основной метод

# Получение значения I2C устройства
value = manipulator.get_i2c_value(name, timeout_seconds=60.0, throw_error=True)

Параметры

  • name: имя I2C устройства (строка)
  • timeout_seconds: таймаут выполнения команды (по умолчанию 60.0)
  • throw_error: выбрасывать исключение при ошибке (по умолчанию True)

Доступные I2C устройства

Коммутатор:

  • commutator/sel_serv — выбор сервопривода
  • commutator/en_serv — включение сервопривода
  • commutator/en_fan — включение вентилятора
  • commutator/pwm1 — значение ШИМ 1
  • commutator/pwm2 — значение ШИМ 2
  • commutator/fd_key — статус кнопки freedrive
  • commutator/adc_temp — температура с АЦП

Примеры использования

Чтение значения с I2C устройства


# Получение значения с коммутатора
fd_key_value = manipulator.get_i2c_value("commutator/fd_key")
if fd_key_value is not None:
    print(f"Статус freedrive: {'ВКЛ' if fd_key_value < 1000 else 'ВЫКЛ'} (значение: {fd_key_value})")
else:
    print("Не удалось получить значение")

# Завершение работы
manipulator.disconnect()

Типичные сценарии использования

  • Определение статуса кнопки freedrive
  • Мониторинг температуры для контроля перегрева
  • Диагностика состояния периферийных устройств
Примечание: Значение fd_key = 4095 означает, что freedrive выключен.

14. Воспроизведение аудио

Манипулятор поддерживает воспроизведение аудиофайлов. Это может быть полезно для звуковых уведомлений, предупреждений или интерактивных сценариев.

Основные методы

# Синхронное воспроизведение аудио
manipulator.play_audio(file_name, timeout_seconds=60.0, throw_error=True)

Параметры

  • file_name: имя аудиофайла (строка). Файл должен находиться в доступной директории манипулятора.
  • timeout_seconds: таймаут выполнения команды (по умолчанию 60.0)
  • throw_error: выбрасывать исключение при ошибке (по умолчанию True)

Примеры использования

Синхронное воспроизведение

# Простое воспроизведение аудиофайла
try:
    manipulator.play_audio('start.wav')
    print("Аудиофайл воспроизведен успешно")
except Exception as e:
    print(f"Ошибка воспроизведения аудио: {e}")

Типичные сценарии использования

  • Звуковые уведомления о начале/завершении операции
  • Предупреждающие сигналы при ошибках
  • Интерактивные сценарии с обратной связью
  • Озвучивание состояния системы

Примечания

  • Поддерживаются распространенные аудиоформаты (WAV, MP3)
  • Файлы должны быть предварительно загружены на манипулятор
  • Воспроизведение выполняется через встроенную аудиосистему манипулятора

Примеры использования команд

В составе SDK предоставлены примеры, демонстрирующие использование основных команд управления манипулятором и дополнительными модулями. Они позволяют ознакомиться с базовыми возможностями, а также служат отправной точкой для разработки собственных сценариев.

Примеры включают вызовы для перемещения по координатам, управления гриппером и другой функциональности. Их рекомендуется использовать для первичного ознакомления и проверки работоспособности системы.

Заключение

Если возникли проблемы — используйте диагностические инструменты SDK и обращайтесь в техническую поддержку ПРОМОБОТ с подробными логами.

Рекомендация: Для повышения надежности исполнения все вызовы команд следует оборачивать в конструкцию try/except, чтобы корректно обрабатывать возможные ошибки при взаимодействии с манипулятором.