Сказ про робота Unitree A1 — Часть 1: Базовые возможности

В 2022 году наш Университет — Московский ордена Ленина, ордена Октябрьской Революции Авиационный Институт имени Серго Орджоникидзе, ну или просто МАИ принял участие и победил в конкурсе Приоритет 2030. Мы, как самое передовое в Мире МАИ подразделение конечно выдвинули много разных проектов под которые требовалось оборудование. И вот после 3 месяцев защит проектов и ещё 6 месяцев закупок мы получили наконец много нового и интересного оборудования для опасных экспериментов развития науки и прокачивания навыков наших студентов IT-магистратур.

Процесс закупки и защиты заслуживает отдельной книги в стиле Хоррор Квест статьи, но сейчас не об этом. Мы на самом деле очень благодарны за полученную возможность купить новое и интересное оборудование! Одним из долгожданных приобретений стал робот-собака Unitree A1 и несколько дополнительных плат Jetson Xavier NX для последующей модернизации и отработки алгоритмов машинного обучения без травмирования самого робота, как мы тогда думали.

И вот долгожданный момент получения оборудования настал! Первое впечатление было очень хорошим — робот оказался упакован в чемодан для транспортировки с удобной ручкой на колёсиках, что учитывая его вес очень удобно. При этом производители на забыли накидать в комплекте сменных ног в количестве 8 штук и какую-то странную палку с гвоздями специальное устройство для калибровки ног робота.

Устройство для калибровки, аккумулятор и пульт управления Unitree A1

Устройство для калибровки, аккумулятор и пульт управления Unitree A1

Чемодан и Unitree A1 отдыхающая в укромном углу IT-Центра МАИ

Чемодан и Unitree A1 отдыхающая в укромном углу IT-Центра МАИ

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

И вот он первый запуск робота! Достав из кейса всё необходимое и взяв в руки весьма информативную инструкцию совершенно непонятный листочек бумаги на китайском языке (видимо от блока питания), по итогу нагуглив в интернете инструкцию как же можно включить это чудо Китайских технологий. Почитали про его распаковку в статье на Хабр. Но не нашли ответов на некоторые наши вопросы. Собственно очень скудное количество информации по данному роботу и наши длительные поиски решений побудили написать данную серию публикаций.

TODO: Далее идет Инструкция по режимам с видосиками сделанными в анимированные  gif, ну то есть описание комбинации клавиш от самого простого режима до завершения с тройным прыжком

Включение

Для включения пульта и собаки применяется общий алгоритм. Нужно выполнить короткое нажатие, отпустить на доли секунды и выполнить длинное (3 сек) нажатие для включения, если все идет по плану, то пульт издаст звуковые сигналы что он жив, а собака должна встать сама. Выглядит это следующим образом:

Если не встала: несколько раз нажать L2+B, несколько раз L2+A. В ряде случаев это помогает, если нет, то придется воспользоваться переходником с UART на USB для считывания информации со ноунейм бортового контроллера (далее есть иллюстрация подключения). Таким образом можно понять основные неисправности. Причем только один из портов выдает информацию.

Переходник с UART на COM порт

Переходник с UART на COM порт

UART порт для идентификации неисправностей

UART порт для идентификации неисправностей

Требуется проверить показания датчиков с ног робота, подключаем USB-Serial переходник Проверяем на каком порту висит наш переходник через менеджер устройств в windows (COM3 или другой). В условном Putty выбираем Serial, порт общается с нами на скорости 115200, указываем нужный COM порт и наблюдаем окно с информацией с датчиков, нас интересуют датчики положения ног.

Значения в каждой оси должно быть порядка 1, если вылезают тысячи и прочее, следует проверить подключение кабелей к ногам изнутри, также стоит обратить внимание на датчик FootForce, если у ноги отрицательное значение или равное 0, то стоит также перепроверить подключение, а возможно заменить лапу. Лапы представляют собой резиновые шарики, которые имеют обыкновение трескаться в самый неподходящий момент и терять герметичность.

Пример лога ошибок далее. Буквы обозначают соответствующие ноги робота: F — переднее R — заднее R / L вторая буква — правое / левое. Вывод идет без разделителей строк, мы их добавили для удобство анализа данных.

Motor lose connect ([ ]/100ms):
FR 0 0 0 ; 1 1 1 ; Joint-> 0.4430 3.8730 -2.6976
FL 0 0 0 ; 1 1 1 ; Joint-> 0.0019 4.1803 -3.0198
RR 100 100 100 ; 64003 64004 64004 ; Joint-> 0.0000 0.0000 0.0000
RL 0 0 0 ; 1 1 1 ; Joint-> -0.4170 4.5541 -2.7082
IMU :: Roll = 0.0308, Pitch = 0.4153, Yaw = -1.0511
Foot Force :: [FR_] = -21.63, [FL_] = -27.05, [RR_] = 0.00, [RL_] = -28.44
GamePad CMD:: 0.00, 0.00, 0.00, 0.00
RobotVersion = 400
Firmware_version = 1000200525
HardwareVersion = 1000200420

В данном случае что-то случилось с линией правой задней ноги и придется разбирать робота и вставлять на место выпавшие разъемы где-то в недрах робособаки.

Вернемся к первому запуску. Слава богу нас все описанные выше проблемы миновали при первом запуске. Итак после того как собака встала мы можем изменять только позу собаки, для разблокировки движения нажимаем Start, после этого собака должна начать стучать лапами по земле.

Мы перешли в режим ходьбы, большинство функций в нем недоступны, собака нестабильно делает поворот вокруг своей оси и может упасть. Поэтому рекомендуем сразу переходить в спорт режим. В этом режиме в дело включается компаньон в виде Raspberry pi и страшный ROS о котором мы поговорим позже, которые помогают собаке не упасть.

Для перехода в спорт режим:

Start  переход в стоячий режим. Собака перестает стучать лапами.

Дать постоять 20 секунд (за это время гарантированно загрузится ROS), уложить на землю нажатием L2+B (иногда несколько раз, пока не достигнем результата).

L1+Start  перейти в спорт режим (должна встать после этого, если не встает L2+X)

Start  дважды (иногда трижды) — переход в режим бега

В данном режиме собака будет более интенсивно стучать лапами. Если результата не достигли, значит на Raspberry упал ROS, сеть, процессы ROS или с ней вообще что-то не так, придется подключиться к Raspberry и выяснять причины.

L2+Start  для перехода в режим быстрого бега 11 км/ч. Внимание! Собака очень нестабильно себя ведет в этом режиме, только для бега по прямой! Реально не пытайтесь поворачивать на бегу — это очень опасно и для собаки и для окружающих.

Start  несколько раз — выход из режима быстрого бега. Все основные возможности проявляются в спорт режиме, поэтому кратко приведем некоторые прикольные функции робота.

Команды в спорт режиме

R1+X  долгое выступление, включающее в себя танцы, прыжки в стороны и перекат вправо по земле (требует много свободного места)

L1+A  встать на задние лапы

L1+X  танец

R2+→(←)  илипрыжок с поворотом направо (налево)

R2+A  танец

R2+B  виляние тазом

R2+X  прыжки на месте

L1+Y  один кувырок назад

R1+Y  три кувырка назад, выполнять с осторожностью на ровной и не скользкой поверхности, иначе робот может ударится головой об пол ;)

А как же фильмы про роботов которые бегают по лестницам и терроризируют мирных граждан в постапокалиптическом мире преодолевают препятствия, подумали мы и решили попробовать робособаку в более экзотических режимах.

Для перехода в режим препятствий:

L2+B  Из спорт режима уложить собаку

L1+L2+Start  выйти из спорт режима

L1+Start  перейти в режим препятствий

Start  перейти в режим ходьбы по наклонной плоскости

L2+Start  перейти в режим медленной ходьбы чтобы переходить препятствия

Но важно учесть, что собака может преодолевать лестницы небольшой высоты до 15 см. У нас в МАИ она смогла подняться только по новой лестнице. По старым советским лестницам не поднимется, так что нам в МАИ нашествие разумных роботов не грозит имейте ввиду и ловите её пока не перевернулась.

А сколько же можно так играться?

Все очень здорово и мы решили показывать нашу Дору школьникам и выдавать студентам для опытов научных проектов по автоматизации. Сразу возник вопрос, сколько же это чудо техники может работать от аккумулятора? Оказалось, что работает она порядка 30 минут, но прыжки уже перестает делать правильно когда на индикаторе 2 светодиода (один мигает, один горит). Видимо это связано с падением напряжения на моторах. Как выяснили в последствии, после 40 минут непрерывной работы в неактивном режиме моторы просто перегреваются даже от статической нагрузки и лучше давать робособаке отдохнуть.

Итак, управлять собакой с пульта мы научились довольно быстро! Прикинули на сколько нам хватает заряда аккумулятора и купили для робособаки будку коврик для прыжков. На первом же дне открытых дверей робот-собака произвела фурор среди школьников. Решили присвоить ей имя собственное, как одному из интересных объектов нашего IT-Центра. В группе IT-центра Организовали голосование и с минимальным отрывом в 3 голоса победило имя Дора! Это имя и было решено присвоить нашей замечательной робособаке.

Голосование за имя Робособаки в Telegram

Голосование за имя Робособаки в Telegram

Правда и тут не обошлось без приключений — забыли закрыть голосование в группе и тут же набежали злые тролли и борцы за свободное демократическое общество поклонники мужских имён, которые долго возмущались новым именем робособаки. В любом случае имя уже прижилось, так же как и для нашего супервычислителя на стероидах GPU, который теперь именуется не иначе как Шелдон. Может быть про него напишем отдельную статью, так как проектирование инфраструктуры и разворачивание k8s тоже принесло много головной боли счастья.

Запуск скриптов

Для начала работы с библиотекой стоит с ней познакомиться. Библиотекой для написания скриптов выступает unitree_legged_sdk. Есть как низкоуровневое программирование движения каждого мотора на C++, так и высокоуровневый вызов функций и написание своих на Python. Мы рассмотрим именно второй вариант с примерами и немного познакомимся с низкоуровневой частью. Сама библиотека идет из коробки установленной на UPBoard, но может быть установлена и запущена с любого устройства, подключенного к внутренней сети.

Библиотека от разработчиков лежит тут. Наш форк репозитория со своими доработками и более понятным README можно посмотреть тут.

Начнем с того, как это работает, библиотека подключается стандартным образом:

#include «unitree_legged_sdk/unitree_legged_sdk.h»

Сам файл unitree_legged_sdk.h  лишь собирает все остальные header файлы в один, наиболее интересен нам comm.h, а в a1_const.h можем посмотреть максимальные значения для углов ног во избежание ошибок, в udp.h описаны настройки взаимодействия внутренних плат по сети, в kinematics.h описана физика поведения ног. Все остальные менее значимые файлы любопытные читатели могут изучить сами, они находятся в директории include.

Вернемся к самому важному для нас comm.h, он состоит из описания структур, параметров которые мы можем в них передать и получить, например состояние мотора:

typedef struct
	{
		uint8_t mode;                      // motor working mode 
		float q;                           // current angle (unit: radian)
		float dq;                          // current velocity (unit: radian/second)
		float ddq;                         // current acc (unit: radian/second*second)
		float tauEst;                      // current estimated output torque (unit: N.m)
		float q_raw;                       // current angle (unit: radian)
		float dq_raw;                      // current velocity (unit: radian/second)
		float ddq_raw;
		int8_t temperature;                // current temperature 
		std::array reserve;
	} MotorState;                          // motor feedback

Все структуры имеют вполне понятные комментарии, большинство из них относятся к низкоуровневому управлению, за исключением HighCmd и HishState, как раз таки они и переносят нас в высокоуровневую часть программирования. Описание классов и функций, которые передаются в Python при помощи pybind11 содержатся в src/python_interface_high_cmd.cpp

Для начала работы с библиотекой нужно сначала собрать ее, инструкция приведена в нашем репозитории, стоит обратить внимание на архитектуру вашей системы, изначально CMakeLists настроен на сборку под arm64, для сборки под amd64 замените arm64 на amd64 в 12 строке CMakeLists.txt

set (EXTRA_LIBS -pthread libunitree_legged_sdk_arm64.so lcm)

Приступим к первым шагам в написании скриптов робособаки на Python, для этого перейдем в директорию scripts, файл Unitree_Python_sdk.py выступает в роли header файла для скриптов, в нем нам нужно заменить в 3 строке путь до полученной в результате сборки директории build:

sys.path.append ('home/dora/mai_dora/build') # Edit the path to «build» folder on your computer

Здесь мы также можем рассмотреть класс Unitree_Robot, какие у него есть функции и какие у них есть переменные. В основном функции передают высокоуровневое состояние
моторам, но со своими параметрами, например robot_walking:

def robot_walking(self, gaitType = 1, forwardSpeed = 0.0, sidewaySpeed = 0.0, 
                      rotateSpeed = 0.0, speedLevel = 0, bodyHeight = 0.0, footRaiseHeight = 0.0):
        self.cmd_init()
        self.gaitType = gaitType
        self.speedLevel = speedLevel
        self.footRaiseHeight = footRaiseHeight
        self.forwardSpeed = forwardSpeed
        self.sidewaySpeed = sidewaySpeed
        self.rotateSpeed = rotateSpeed
        self.bodyHeight = bodyHeight
        self.mode = 2
        robot_state = self.unitree_robot.getState()
        self.recv_UDP()
        self.robot_control()
        self.send_UDP()
        return robot_state

Выше представленная функция передает моторам состояние ходьбы с параметрами вида перемещения (ходьба, бег, подъем по лестнице), скорости вперед (назад при отрицательных значениях), скорости движения в сторону (советую не использовать, велика вероятность перевернуться), скорости поворота (по часовой стрелке при отрицательных значениях, против часовой при положительных), режима скорости, высоты туловища относительно исходного состояния и высоты подъема лап от земли.

В файле Robot_Python.py мы подготовили множество примеров использования функций с комментариями, например:

if (motion_time >= 2110 and motion_time < 3170): # половина от полного оборота
      state = unitree_robot.robot_walking(gaitType = 1, forwardSpeed = 0, rotateSpeed = -2, speedLevel = 1)

Для написания полноценных сценариев действий собаки мы используем переменную motion time и с помощью нее выделяем время на элементы сценария

При помощи robot_pose, которая принимает на вход степени наклона в трех проекциях и высоту туловища, мы можем задавать конкретные позиции собаки и даже формировать из этого танцы, например:

# POINT 1 - Танцевальный элемент (опускаем переднюю часть туловища и поднимаем переднюю)
    if (motion_time >= 6010 and motion_time < 6110):
      state = unitree_robot.robot_pose(0.8, 0.8, 0.25, -0.1)
    if (motion_time >= 6210 and motion_time < 6410):
      state = unitree_robot.robot_pose(-0.8, 0.8, -0.25, -0.1)
    if (motion_time > 6510 and motion_time < 6710):
      state = unitree_robot.robot_pose(0.8, 0.8, 0.25, -0.1)
    if (motion_time >= 6810 and motion_time < 6910):
      state = unitree_robot.robot_pose(-0.8, 0.8, -0.25, -0.1)
    if (motion_time > 7010 and motion_time < 7110):
      state = unitree_robot.robot_pose(0.8, 0.8, 0.25, -0.1)
    if (motion_time >= 7210 and motion_time < 7410):
      state = unitree_robot.robot_pose(-0.8, 0.8, -0.25, -0.1)
    if (motion_time == 7410): #this
      state = unitree_robot.mode = 0  

Выглядит, конечно, как большой файл с набором условий, но в принципе на основании этого можно писать и более сложные коды для управления.

Изучение возможностей шло полным ходом, но внезапно понадобилось совершить апдейт через wifi свисток адаптер, который занял бы много времени. Собака была полностью заряжена, поэтому мы решились на этот шаг, в надежде, что 40 минут на которые хватает аккумулятора в неподвижном состоянии будет достаточно. Идея с внешним питанием на данном этапе была признана нереализуемой из-за отсутствия блока питания и разъемов ХТ-30 под рукой и мы по старой Русской традиции положились на Авось!

Это была плохая идея

Это была плохая идея

Минуты обновления пролетели незаметно и на 90% апдейта собачка грустно легла, отключив питание от Raspberry PI, у которой в результате слетел boot и система больше не запускалась.

Фотография Unitree A1 в процессе начала разборки

Фотография Unitree A1 в процессе начала разборки

«Надо фиксить» — подумал наш эксперт-собаковод Николай Николаевич, и приступил к разбору собаки, чтобы добраться на SD диска… первым делом начав с «головы» собаки.

Продолжение в следующей части…

Над статьей и робособакой работали:

Любитель роботов и один из руководителей IT-Центра — Петр Ухов

Экc-собаковод IT-Центра и студент 8-го института МАИ — Николай Филимонов

Эксперт-собаковод IT-Центра и студент 8-го института — Евгений Иванов

Специалист по поиску неординарных решений, студент 8-го института — Дмитрий Сираков 

Полезные ссылки:

© Habrahabr.ru