Привет, меня зовут Станислав Архипенко. Сейчас я работаю в IT, но с раннего детства я был увлечён техникой. Ещё совсем маленьким я подключал батарейки к моторчикам и мечтал о том, что когда-нибудь смогу создавать настоящих роботов. Моя мечта осуществилась. Я не работаю сборщиком роботов, но новенький 3D-принтер позволил мне окунуться в разработку и строительство робот с голов от дизайна и печати 3д деталей, до сборки и пайки, программирования и отладки. В этой статье покажу своего гексапода и расскажу об управлении с помощью игровой консоли Steam Deck. 

Какого робота я собрал и как

На сайте thingiverse.com — огромной коллекции 3д проектов — я случайно обнаружил замечательный проект авторства AlexKorvin. Сочетание интересного внешнего дизайна и  хорошей спецификации со списком деталей и ссылками на магазины, а также открытое программное обеспечение не оставили мне выбора — я решил реализовать проект. Однако при детальном изучении материалов я обнаружил, что Алексей принял несколько конструктивных решений, с которыми я не согласен:

  • Повышающие преобразователи и однобаночные аккумуляторы в системе питания.

  • Arduino для управления servo-приводами.

  • В качестве контроллера — джойстики от playstation 2 и дополнительный китайский модуль для получения сигнала.

  • Аналоговые приёмник и передатчик для видео.

Мне показалось, что электронику можно сделать проще, поэтому я внёс изменения:

  • Использовать классический подход для питания в таких случаях: 4-баночный аккумулятор и понижающий преобразователь.

  • Основной модуль управления — Raspberry Pi Zero W.

  • Для управления servo использовать две классические платы управления на основе PCA9685

  • Контроллер управления от Xbox One через bluetooth.

С аппаратной частью всё понятно, но вот с программной есть небольшая проблема: программа, которую использует Alex (от совершенно другого проекта) написана под Arduino и не подходит для Raspberry Pi. Самое сложное в этой программе — расчёты положения ног. Мне не хотелось разрабатывать программу с нуля. Во-первых, расчёты положения ног — кропотливая работа, а во-вторых, Alex реализовал ряд классных функций, которые я не хотел терять.

Я не стал переписывать программу с нуля, а вместо этого перевёл код из C в Python3. Во время перевода я не использовал автоматические утилиты-переводчики и ограничился поиском и заменой по тексту. Так я смог привести C-синтаксис в состояние, понятное Python-интерпретатору.

Затем я удалил всё, что связано с аппаратной частью: управления серво, связь с джойстиком — а оставшийся код трансформировал в родительский класс hexapod, который реализовывал вычисления положения ног и логику управления.

Следующим шагом я разработал дочерний класс AcpRobot, в который и включил всё, что связано с аппаратурой. Мне такой подход показался удачным: благодаря разделению на родительский и дочерний классы теперь можно использовать логику управления с разными аппаратными реализациями.

В вопросе операционный системы я пошёл по пути наименьшего сопротивления и применил Raspbian

Для Xbox-контроллера я использовал драйвер xpadneo и следующую конфигурацию bluetooth в /etc/bluetooth/main.conf:

[General] 

ControllerMode = dual 

Privacy = device

Чтобы программа управления роботом запускалась автоматически, я написал небольшой сервис для systemd, а позже скрипт, который устанавливает весь Python-код и генерирует systemd-сервис по шаблону. Передачу видео на телефон я решил оставить на потом, мне совсем не хотелось разбираться с мобильной разработкой. Получилось так:

Как я связал робота и Steam Deck

Согласно Википедии, Steam Deck — это портативный игровой компьютер, разработанный Valve Corporation. Мне кажется, что ключевое слово здесь «компьютер», так как эта консоль действительно полноценный, настоящий x86-64 комп с Linux (SteamOS) на борту. На нём даже по умолчанию Python предустановлен! С учётом того, что я так и не решил проблему передачи видео, Steam Deck — идеальный кандидат в качестве нового джойстика управления. Так как мой робот — полноценный компьютер, и Steam Deck — тоже полноценный компьютер, я решил использовать Wi-fi для дистанционного управления. 

Сетевой обмен данными

Для получения сетевого стека я использовал Apache Thrift. Это фреймворк для разработки межъязыковых сервисов, он позволяет генерировать сетевой RPC-код по заданной схеме для десятка разных языков. Моя схема содержала пару структур данных и пять запросов: 

  • Ping — просто пинг, чтобы проверить, работает ли связь.

  • Axis — информация о стиках.

  • Button — информация о нажатых кнопка.

  • Get_status — статус робота, включает: текущий режим, под режим, статус огней и батареи

  • Get_logs — передача логов из робота.

Используя схему, я сгенерировал RCP код для сервера — робота и клиента — Steam Deck. Далее использовал его для обмена данными.

Пользовательский интерфейс

Для меня пользовательский интерфейс — случай, когда задача казалась очень сложной, а вышла очень простой. Я использовал PySimpleGUI, с помощью которого элементарно строить пользовательский интерфейс. Немного магии, 200 строк кода, и UI модуль готов!

  • RC — адрес сервера удалённого управления (RC — remote control).

  • VD — адрес видео стрима (VD — video).

  • M: CALI — означает текущий режим (mode) — калибровка (calibration).

  • SM: NA — текущий под-режим (sub-mode) отсутствует (NA означает Not Available).

  • Speed: FAST — текущий скоростной режим переключён в положение «быстро».

  • L1 и L2 — свет (Light) 1 и 2 активированы.

  • View: LOGS — переключение между режимом отображения журнала (Log) или видео.

Видеострим

Со стороны робота я использовал камеру raspberry pi camera v2. Для захвата изображения я использовал ustreamer — лёгкий и быстрый сервер для потоковой передачи видео MJPEG с устройств V4L2 в сеть. К сожалению, в репозиториях rasbian нет пакета с ustreamer, однако сборка из исходных кодов оказалось элементарной:

export WITH_SYSTEMD=1

sudo apt install libevent-dev libjpeg9-dev libbsd-dev libsystemd-dev

git clone https://github.com/pikvm/ustreamer.git

cd ustreamer

make

Для запуска сервера я использую следующие флаги:

--host $(hostname) \

--port  9999 \

--format=uyvy \

--encoder=m2m-image \

--workers=3 \

--persistent \

--dv-timings \

--drop-same-frames 30 \

--desired-fps 24

Со стороны Steam Deck я использовал urllib для чтения потока данных и opencv-python для конвертации изображения в подходящий формат.

Что есть сейчас и что ещё нужно сделать

Проект ещё не доведён до конца: надо избавиться от багов, завернуть Python-код в пакеты, оптимизировать видеострим. Но ключевые функции уже работают и радуют. 

Если вы решите повторить мой путь, эти ссылки вам помогут:

Комментарии (6)


  1. solderman
    05.12.2022 18:35
    -3

    Смею предположить, что скорость ролика, как минимум в 3 раза больше реальной скорости, а если реальная, то интересен ресурс серв в минутах.

    Прикольный лог в начале первого ролика : много строчек controller not found, после которых паук бодро просыпается.

    Правда штоле, что ролики ваши? Тогда почему поаглицки?


    1. Geek_and_Cat
      05.12.2022 21:28

      Не знаю как у @blognetology, а у автора исходного проекта робот двигался примерно с такой же скоростью и проработал как минимум несколько часов на морозе и не сломался после этого, вот ссылка на видео: https://www.youtube.com/watch?v=M3o6ToZ4Auc
      А про английский язык какая-то очень странная придирка


  1. beeptec
    06.12.2022 10:01

    После прочтения статьи об очередном гексаходе, в который раз убеждаюсь в стереотипном мышлении разработчиков, изначально кодеров - программистов, в зашоренности полета их мысли в сторону построения абстрактных и далеких от жизненно востребованных обществом систем рутинных процессов, от бытовых, к индустриальным.
    От чего так происходит, парадокс в том что в основной массе кодеры не занимаются мехатроникой, в полном понимании смысла ее значения. Они вовлечены в процесс воспроизведения алгоритма управления перемещением, который имеет априори иной, природный механизм, от того и совершенен в своей родной оболочке.
    Жду не дождусь публикацию на такие темы, когда процесс роботизации не выглядит яйцом, источником цыпленка. Люди берутся строить автоматизированные теплицы, школьных учителей, гостиничных батлеров, официантов, а там за кулисами полный технологический раздрай и полная телега конфликтов.
    Вдоволь наигравшись роботизированными официантами, владельцы ресторанов констатируют убытки, полиция применяющая роботов - собак перестает заниматься своими обязанностями и впадает в уличные шоу, строительная 3D печать зданий и сооружений сносит крышу строительным компаниям, как следствие отказ от рисков в смене технологии.... Робототехника как была таки и остается очень полярной с гигантской пропастью между хобби и там, где многомиллионные вложения и прибыльность (медицина, авто, самолето индустрия и оборонка правят баллом, ну, не без того - распил денег налогоплательщиков в не столь удаленных местах ;).


  1. chukov
    06.12.2022 10:21

    Тоже хочется задействовать SteamDeck как станцию управления своим роботом. Только у меня вместо wifi nrf24l01, а за видео отвечает fpv камера на 5gz и usb ucv приемник.


    1. general_ro
      06.12.2022 14:08

      Кстати у меня есть план сделать usb (или bluetooth) свисток для управления по nrf24l01, что бы можно было использовать дэк для управления на большом расстоянии. К слову мой предыдущий проект построен на базе nrf https://zzbot.org/projects/remote-controller/


  1. sshemol
    06.12.2022 16:47

    Я не стал переписывать программу с нуля, а вместо этого перевёл код из C в Python3

    Какой ужас.

    Как и замена ардуины (real time работа с железом) на RPI (ОС не реального времени с соответствующей кучей абстракций и багов)

    Снижение эффективности и отказоустойчивости.