[Из песочницы] Как я делал костюм захвата движений
Предисловие
В своем небольшом городе я занимаюсь решением нетривиальных технических задач. Так и в этот раз, организаторы одного шоу, в котором должна была выступить гимнастка со своей программой, решили добавить в ее представление некоторую «изюминку». А именно, выводить на экраны силуэт гимнастки, который бы повторял ее движения и как-то взаимодействовал с прочими эффектами, да так, чтобы все было интерактивно. Решить задачу «в лоб» не удалось. Kinect явно не справлялся со своей задачей и не был способен произвести захват движений человека, который удален от него на расстояние минимум 10 метров, к тому же в темноте. Так было принято решение сделать что-то «свое». Забегая вперед, скажу что выступление так и не состоялось, однако я настолько загорелся идеей, что продолжил свои эксперименты в качестве отдельного проекта, который впоследствии получил название impulse.
Начало работы
Я принялся за прототипирование будущего устройства как только получил необходимые компоненты. А именно:
- Arduino UNO — всем известный контроллер-конструктор, который позволяет за короткое время разработать прототип.
- HC-06 — bluetooth модуль, послужит как средство беспроводной коммуникации. Модуль очень простой, имеет UART-интерфейс.
- MPU-6050 — единственные доступные для меня инерционные датчики на тот момент. Приобрел сразу 2, чтобы проверить как они работают в паре, ведь в будущем необходимо использовать до 15 датчиков в одной системе. Этот сенсор сочетает в себе акселерометр и гироскоп, а так же датчик температуры для корректировки выходных данных.
Получив все из этого списка мне уже не терпелось увидеть mpu в действии. На официальном форуме Arduino присутствовали несколько примеров использования этих датчиков, один из них я и использовал. Для подключения сенсоров используется 5 пинов (контактов):
- VCC, GND — тут все понятно, питание и земля. Стоит отметить что рабочее напряжение сенсора 3.3v, но и на 5v он чувствует себя неплохо. Потребляемая мощность меньше 0.05Ah
- SCL, SDA — собственно пины, по которым происходит «общение» с сенсором. Эти пины отвечает за интерфейс i2c. Этот интерфейс реализует коммутацию между устройствами на одной шине, другими словами шина — это улица, а дома на ней — устройства.
- INT — пин для прерываний. Как только данные на сенсоре готовы, главный контролер забирает их по прерыванию.
Однако этот пример выводил в терминал только «сырые» значения с акселерометра, и для преобразования в привычные углы был написан код, а далее и реализован Фильтр Калмана, и все это вместе занимало уже порядка 70% ресурсов Arduino UNO. Тем не менее, в терминал уже приходили довольно плавные значения углов, устройство довольно шустро ориентировалось в пространстве, правда всего пару минут, после чего FIFO буфер переполнялся. Но Оно работало!

Стабилизируем!
Постепенно радость от рабочего датчика омрачалась продолжительностью работы всей системы. Сколько я не боролся с FIFO-буфером, он переполнялся. Тут стоит отметить что информации на то время о данных сенсорах и вообще подобных системах было мало, и ее приходилось собирать буквально по крупицам. Решив, что проблема кроется в реализации интерфейса i2c начал гуглить в этом направлении и нашел пользовательскую библиотеку I2Cdev, призванную заменить стандартную библиотеку wire для arduino. Приятным сюрпризом оказались вложенные примеры использования этой библиотеки в связке с mpu-6050. Перестроив проект на этой библиотеке, я так же получал сырые данные и преобразовывал их в углы своим кодом, но никаких переполнений уже не было. Эта была маленькая победа. В дальнейшем, изучая внутренности библиотеки я обнаружил много полезного. Так например, теперь используются данные с обоих сенсоров — и акселерометра и гироскопа. Дело в том, что акселерометр позволяет определять точные углы наклона прибора только в состоянии покоя, пока на него не действуют внешние силы, а компенсировать эти самые силы призван гироскоп. Очевидным стало использование данных с обоих сенсоров, и тут нашел применение комплементарный фильтр. Однако появилась проблема нулевого дрейфа, но об этом позже.
Больше сенсоров!
И вновь подводный камень. На этот раз проблема, которая предстала передо мной, заключалась в использовании второго датчика mpu-6050. Я уже приводил аналогию i2c интерфейса в этой статье, где шина — это улица, а устройства — дома. Представим что пакет данных, которые должны добраться до определенного устройства — это почтальон. Почтальону необходимо 2 вещи — посылка и адрес, и у каждого дома есть свой уникальный адрес, так и у устройств должны быть свои адреса. Проблема заключается именно в адресе датчика mpu-6050, он один на все такие датчики — 0x68. Этот адрес прошивается в контроллер датчика еще на заводе, а найти прошивку и изменить адрес для каждого датчика не представляется возможным. Забугорные форумы выдали один вариант решения — подключение сенсоров друг за другом, одна нога первого сенсора подключается к пину AD0 второго, и становится доступным по адресу 0x69, но такой способ предполагает использование не более 2 mpu и я сразу его отбросил.
Решением стали транзисторы. Идея заключалась в том, чтобы перед каждым датчиком поставить по паре транзисторов на пины i2c и открывать их поочередно. Алгоритм простой — необходимо считать данные с 5-го датчика, закрываем все гейты кроме 5-го (или открываем его при необходимости) и производим считывание, дальше подобным образом получаем данные с остальных. Результат видно на первом фото в этой статье, и он вполне себе работоспособный. Подобным образом мне удалось подключить 4 датчика, это не лучшим образом повлияло на стабильность, а когда у меня закончились транзисторы я решил использовать более компактные и стабильные микросхемы.
Единственное сохранившееся фото с той стадии (извиняюсь за качество):

Гейт-контроллер
Устройство, которое будет сочетать в себе эти микросхемы и позволять общаться с множеством датчиков mpu, я назвал гейт-контроллер. Его мне помог изготовить хороший знакомый, который уже имел опыт с травлением плат, а мне нужно было качество, которым мои предыдущие попытки в травлении не обладали. Из-за множества перекрещивающихся дорожек требовалась двухслойная плата, но в качестве прототипа сгодилась и многоуровневая. Результатом этой работы стала вот такая необычная плата:

Теперь остается проверить устройство в действии. Подключив сразу 10 датчиков, в мониторе появилось ровно столько же приятных сообщений об успешной инициализации — устройство работает!

Гимбл лок, кватернионы, визуализация
Гимбл лок, по-русски шарнирный замок или же складывание рамок — неприятное явление в области гироскопов и в некоторых случаях ориентирования в пространстве. Без долгого объяснения этого явления (есть хорошо объясняющие и наглядные видео на эту тему) я лишь скажу, что этот самый шарнирный замок не позволяет вертеть сенсором на все 360. Оси X Z (отклонения от горизонтальной плоскости) ограниченны примерно от -45 до 45 градусов, и не определяются корректно за этими пределами. Подробнее изучив эту тему, оказалось что решение находится у меня под носом. MPU-6050 это шестиосевые датчики, и на борту у них присутствует dmp. Dmp (DIgital Motion Processor) занимается всем тем, что я так долго писал в основном коде для прошивки главного контроллера, и даже фильтрует значения. К тому же, dmp может выводить данные в виде кватернионов, что позволяет обойти шарнирный замок, а так же это позволяет уменьшить размер пересылаемых пакетов. На этом моменте продолжилось мое знакомство с кватернионами, ранее я работал с ними в Unity3D и имел какое-то представление. Говоря простым языком, кватернион — это система чисел (4 числа) которая описывает поворот чего-либо в пространстве. Как раз вспомнив про Unity, я попробовал изобразить нечто такое:

Контроллер
Arduino и гейт-контроллер себя вполне оправдали, но их использование в финальном варианте не предполагалось. Пришло время сделать контроллер, специфичный и заточенный под конкретную задачу. К тому моменту я изрядно модифицировал прошивку для будущего контроллера, сконфигурировал dmp оптимальным образом, что позволило отказаться от использования прерываний. Таким образом каждый сенсор подключался по четырем пинам, а не пяти, как прежде. Так же отпала необходимость в двух из шести микросхем в гейт-контроллере. Все эти улучшения привели к тому, что плата для будущего устройства была спроектирована в 2 стороны, и никаких «надуровней» больше не требовалось.

Корпус
Устройство постепенно обретало свой финальный вид, и следующим шагом было логично сделать корпус. Очевидное решение — это заказать или обратиться к услугам 3D-печати. Но это все просто и неинтересно, поэтому на пару c другом приобрели свой собственный 3D-принтер. Ввиду отсутствия любой инструкции собирали его на интуитивном уровне, но все получилось. Вообще сборка, настройка, и сама подготовка к печати заслуживают отдельной статьи, но сейчас не об этом. Использовав весь пробный материал, оставалось только ждать пока придет ABS-пластик.
Для моделирования была выбрана программа 123D-Design. Программа интуитивно понятна, и любой, кто хоть немного имеет опыт работы в редакторах трехмерной графики быстро ее освоит.

Далее распечатал все корпусы, подключил датчики к контроллеру через тонкие 4-ех контактные провода, сделал крепления для датчиков, собрал все воедино и получил готовый, автономный, носимый костюм. Для первого прототипа вполне годится.



Софт
Ввиду некоторых обстоятельств, я отложил Unity3D «на потом», сроки поджимали и нужно было быстро написать программу для визуализации. Я уже давно работаю с графическим движком Xors3D (Может кто знает такой) и на этот раз он меня не подвел. Однако после того как он себя оправдал, я не вернулся к Unity, а продолжил разработку визуальной среды для костюма именно на этом движке.

Список текущих возможностей:
- Визуализация — в программе отображается модель человека, которая в реальном времени повторяет все движения за человеком в костюме
- Авто-калибровка — позволяет в любое время моментально калибровать костюм
- Позиционирование — модель так же перемещается в пространстве как и человек, может приседать, ходить и т.п.
- Запись/воспроизведение — все движения можно записывать и воспроизводить
- Режим взгляда от первого лица — предусмотрен вывод изображения для oculus rift и других шлемов виртуальной реальности.
- Интерактивность — человек носящий костюм может воздействовать на виртуальный мир. Пинать мячи, открывать двери, крутить карусель и т.д. (физический движек)
Заключение
На данный момент проект имеет 1 полностью рабочий, автономный, носимый и беспроводной прототип и все необходимое программное обеспечение. На разработку этого костюма ушло 8 месяцев (2 из которых я отдыхал, итого 6), но для меня это целая эпоха. За время проекта я прокачал свои навыки, попробовал и сделал много того, в чем раньше слабо разбирался, смог немного заработать.
Когда я начинал, был только интерес «а как это работает?» и о существовании подобных костюмов я еще не знал. Однако за время разработки как минимум 3 подобных проекта вышли на краудфандинговые площадки, и мне захотелось как-то развить impulse в качестве коммерческого проекта, но крайне тяжело заявить о себе сидя в Забайкальском крае. Сейчас не хватает мотивации сесть за второй прототип, уже беспроводной и на базе 9-ти осевых сенсоров, так что скорее всего этот проект останется для меня просто огромным и полезным опытом. В этой статье я хотел резюмировать всю проведенную работу, правда тут не отображено и 20% от нее. Не всем будут интересны тонны кода и часы пайки, 3d-печати, множество проб и ошибок, куча израсходованного материала, однако я постараюсь ответить на подобные вопросы в комментариях.

JoyToy показала распаковку фигурки Малогарста Кривого из легиона Сынов Хоруса
Iron Studios открыла предзаказ на статую Шанг Цунга из классической Mortal Kombat
Создатель оригинальной God of War раскритиковал авторов God of War Laufey за отсутствие страсти к играм
Бывший креативный директор Halo призвал Activision вернуть уволенных разработчиков для работы над серией
По данным датамайнеров, Nintendo готовит бесплатные подарки для подписчиков Switch Online
В сети появились новые кадры GTA VI из журнала Game Informer
Ветеран Bethesda заявил, что Skyrim не получила спин-офф из-за The Elder Scrolls Online
Prime 1 Studio открыла предзаказ на статую Мистера Фриза