Как настроить смартфоны и ПК. Информационный портал
  • Главная
  • Windows 8
  • DIY: Clearwalker - самодельный робот-паук из акрила. Обзор готовых каркасов для создания роботов на Arduino

DIY: Clearwalker - самодельный робот-паук из акрила. Обзор готовых каркасов для создания роботов на Arduino

Один из вариантов создания роботов на основе Arduino и других компьютерных плат — использование готовых корпусов и разработка собственной начинки. На рынке можно найти достаточное количество таких каркасов, которые включают также механическую базу (колеса, гусеницы, шарниры и т.п.). Взяв готовый корпус, вы сможете целиком сосредоточиться на программировании робота. Предлагаем небольшой обзор таких корпусов-скелетов роботов.

Почему нужны корпусы и скелеты роботов?

Создание робота — процесс многоэтапный, включающий в себя и проектирование, и сборку, и программирование. Знания робототехники граничат с физикой, механикой, алгоритмизацией. Начинающие юные робототехники по разному тяготеют к каждому из этапов создания роботов. Кому-то легче дается создание механических частей робота, но программирование вызывает сложности. Кто-то, наоборот, с легкостью программирует логику поведения робота, но процесс создания механической модели вызывает сложности.

Тем, кому процесс проектирования механики дается с трудом, и больше заводит именно процесс подбора различных датчиков и проектирование логики робота, стоит обратить внимание на различные механические базы для построения роботов. Они продаются без электроники, по сути это корпус или скелет будущего робота. Осталось только добавить им «мозг» (например, плату Arduino ), нервы и мышцы (датчики и приводы) и оживить их (запрограммировать). Иногда такие корпуса даже содержат моторы или датчики.

Платформы на 4 колесах — основа машинки Arduino

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

Платформа для создания робота на Arduino, выполненная из алюминиевого сплава. Платформа оснащена 4 колесами, к каждому из которых подключен отдельный мотор. Моторы идут в комплекте. Платформа может использоваться как основа автомобиля или любого другого ездящего робота. Размер платформы около 20 на 20 см. Винты, гайки и провода для подключения моторов также в комплекте.

Такое основание для вашего будущего робота можно купить примерно за $75 на сайте интернет-магазина DX.com .

Еще одна четырехколесная платформа для создания робота на базе Arduino привлекает внимание своими колесами. Они имеют диаметр 80 мм, ширину 60 мм, выглядят элегантно и надежно. У этой платформы акриловое основание толщиной 1,5 мм. Корпус имеет хорошую устойчивость и подходит для создания быстро передвигающегося робота. Aliexpress продает этот робот-скелет за $60. Комплектация аналогичная предыдущей — колеса, двигатели, провода и винты уже есть в наборе.

Двух- и трехколесные шасси для создания ездящих роботов

В следующей трехколесной платформе для создания робота на базе Arduino моторы подключены только к двум колесам и это снижает стоимость. В интернет магазине DX.com такое шасси продается за $20,5. Основание выполнено из прозрачного акрила. В комплекте 2 мотора, винты, гайки, провода, батарейный блок для 4 АА батарей. Размеры примерно 20 на 10 см.

Трехколесной платформе для робота Arduino. Фото dx.com

Двухколесное основание для робота. Фото dx.com

Гусеничные шасси для танков на Arduino

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

Гусеничное шасси для создания робота-танка на базе Arduino. В комплекте 2 мотора, гусеничная передача, винты, гайки. Размеры этого шасси 18,7 см х 11,5 см х 4,3 см. В интернет-магазине DX.com такое гусеничное шасси стоит $42.

Гусеничное шасси для робота. Фото dx.com

Корпус для робота-паука на Arduino

Паук — достаточно популярная форма роботов, поэтому в продаже имеются и такие корпуса-скелеты.Конструкция паука в отличие от роботов на колесах предусматривает движение в любую сторону.

Первый паук а в нашем обзоре стоит около $100 на Aliexpress .

Корпус для робота паука. Фото: aliexpress.com

В комплекте этого корпуса нет электроники, сервоприводов, их нужно покупать отдельно. С данной моделью паука рекомендовано использовать сервопривод MG 995 Servo. Забавно, что такой привод на сайте Aliexpress можно купить как за 33 доллара, так и за за 5 долларов (правда в этом случае придется купить 10 штук). Привод нужен под каждую лапу.

Кроме того для управления большим количеством сервоприводов потребуется многоканальный контроллер управления сервоприводами . Итоговая стоимость паука может получиться достаточно высокой.

Еще один скелет шестиногого робота-паука или даже робота-таракана привлек мое внимание своей ценой в $ 42,5. Робот на шести металлических лапах должен получиться пусть и не очень маневренный, зато устойчивый. Скелет этого таракана имеет длину 24 см, ширину — 18 см, высоту — 12 см. Приобрести этого черного таракана-робота можно на сайте интернет-магазина Aliexpress.

Корпус для робота таракана. Фото: aliexpress.com

Каркасы роботов гуманоидов

Достаточно интересной кажется модель робота-гуманоида стоимостью около $ 105. Здесь также нет электроники, зато много простора для творчества. Создание робота-гуманоида и программирование человеческой походки — непростые и интересные задачи. Начать пробовать свои силы в самостоятельном создании робота-гуманоида можно с покупки такого скелета на сайте интернет-магазина Aliexpress. Если верить описанию производителя, то на основе этого карскаса можно сделать даже танцующего робота.

Оболочка для робота гуманоида. Фото: aliexpress.com

Готовый робот, готовый корпус или создание Arduino робота с нуля?

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

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

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

Если вы только начинаете изучение Arduino робототехники, рекомендуем наш курс

Все цены приведены по состоянию на 22.05.14.

Четырехногий робот-паук создан для демонстрации работы сервомашинок под управлением контроллера Arduino (для кружка робототехники).

У робота два режима:

  • автономный - робот движется вперед, при обнаружении препятствия (используется ультразвуковой датчик) поворачивается и движется дальше;
  • внешнее управление с помощью ИК-пульта.

Использовались сервомашинки Turnigy TGY-9025MG металлическим редуктором.

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

Корпус был сделан из упаковочного материала для компов. Для сервомашинок требуется отдельное питание. В качестве источника питания используется Li-po батарея Turnigy 2S 1600 mAh.

Вот вид сверху и снизу робота в процессе сборки.

Для управления сервоприводом в Arduino имеется стандартная библиотека Servo. На платах, отличных от Mega, использование библиотеки отключает возможность использования analogWrite() (PWM) на пинах 9 и 10 (вне зависимости подключены к этим пинам сервы или нет). На платах Mega, до 12 серв могут использоваться без влияния на функциональность PWM, но использование от 12 до 23 сервомашинок отключит PWM на пинах 11 и 12. Cервопривод подключается 3-мя проводами: питание, земля и сигнальный. Питание – красный провод. Черный(или коричневый) провод – земля подключается к GND выводу Arduino, сигнальный(оранжевый/желтый/белый) провод подключается к цифровому выводу контроллера Arduino. Будем использовать выводы 5,6,7,8 Arduino.

Напряжение выдаваемое батареей 7.4 – 8.4 В. Т.к. для питания сервоприводов необходимо напряжение 4.8 – 6.0 В будем использовать стабилизатор напряжения 5В, собранный на микросхеме L7805. Одна микросхема постоянно перегревалась, проблема решилась установкой параллельно двух микросхем L7805.

Для обнаружения препятствий будем использовать ультразвуковой датчик HC-SR04, который позволяет определять расстояние до объекта в диапазоне от 2 до 500 см с точностью 0.3 см. Если расстояние до препятствия меньше 10 см, робот делает поворот и движется дальше вперед.

В качестве пульта используется пульт lg, приемник ИК-сигналов - TSOP31238(1-GND, 2 - +5V, 3-OUT).

Схема электрическая

И весь робот в сборе (плата Arduino питается от батарейки Крона).

Приступим к написанию скетча

Для управления сервоприводами используется Arduino библиотека Servo. Нам необходимо реализовать совокупность движений сервоприводов для движения робота-паука вперед, назад, поворота по часовой стрелке и поворота против часовой стрелки. Кроме того необходимо реализовать функции остановки робота, а также для экономии электроэнергии предусмотрим режим засыпания (когда сервоприводы находятся в режиме detach) и пробуждения (перевод сервоприводов в режим attach). Поэтому каждое движение робота состоит из нескольких шагов.

Например движение вперед состоит из следующих шагов:

  1. левая передняя нога вперед;
  2. правая передняя нога вперед;
  3. левая задняя нога вперед;
  4. правая задняя нога вперед;
  5. четыре ноги вместе назад (что приведет к перетаскиванию тела робота-паука).

Данные для угла поворота каждой сервы на каждом шаге для каждого движения робота-паука хранятся в трехмерном массиве arr_pos.

Int arr_pos={ { // forward {90,90,90,90},{45,90,90,90},{45,135,90,90}, {45,135,45,90},{45,135,45,135},{135,45,135,45} }, { // back {90,90,90,90},{90,90,90,45},{90,90,135,45}, {90,45,135,45},{135,45,135,45},{45,135,45,135} }, { // circle_left {90,90,90,90},{0,90,90,90},{0,0,90,90}, {0,0,0,90},{0,0,0,0},{180,180,180,180} }, { // circle_right {90,90,90,90},{180,90,90,90},{180,180,90,90}, {180,180,180,90},{180,180,180,180},{0,0,0,0} } }; int pos_stop={{90,90,90,90}};

Процедура course(int variant)реализует перемещения сервоприводов для каждого шага следующих движений робота-паука: вперед, назад, поворота по часовой стрелке и поворота против часовой стрелки.

Void course(int variant) { int i=0; for(i=1;i<6;i++) { if(arr_pos[i]!=arr_pos) {myservo11.write(arr_pos[i]);} if(arr_pos[i]!=arr_pos) {myservo12.write(arr_pos[i]);} if(arr_pos[i]!=arr_pos) {myservo13.write(arr_pos[i]);} if(arr_pos[i]!=arr_pos) {myservo14.write(arr_pos[i]);} delay(200); } }

Для остановки, засыпания и пробуждения робота-паука существует процедура go_hor_all()

Void go_hor_all() { myservo11.write(pos_stop); myservo12.write(pos_stop); myservo13.write(pos_stop); myservo14.write(pos_stop); delay(500); }

Реализуем простое ИК-управление с пульта. Выбираем 7 клавиш, данные о кодах заносим в скетч в виде констант. И в цикле loop() реализуем логику выбора движений робота-паука при нажатии клавиш ИК-пульта. Программа получения кода get_ir_kod() вызывается по прерыванию CHANGE на входе 2. Используется Arduino библиотека IRremote.

К режиму управления робота с ИК-пульта добавим автономный режим. В автономном режиме робот будет двигаться вперед, при достижении препятствия робот будет делать поворот и опять двигаться вперед. Ультразвуковой датчик HC-SR04 позволяет определять расстояние до объекта в диапазоне от 2 до 500 см с точностью 0.3 см. Сенсор излучает короткий ультразвуковой импульс (в момент времени 0), который отражается от объекта и принимается сенсором. Расстояние рассчитывается исходя из времени до получения эха и скорости звука в воздухе. Если расстояние до препятствия меньше 10 см, робот делает поворот и движется дальше вперед. Переход из режима ИК-управления в автономный режим производим нажатием клавиш "желтая" и "синяя".

Для работы с датчиком HC-SR04 будем использовать Arduino библиотеку Ultrasonic. Конструктор Ultrasonic принимает два параметра - номера пинов к которым подключены выводы Trig и Echo:

#include "Ultrasonic.h" // trig -12, echo - 13 Ultrasonic ultrasonic(12, 13);

Получается такой код

// коды клавиш ИК пульта // lg 6710v00090d #define FORWARD 32 // pr + #define BACK 33 // pr - #define CIRCLE_LEFT 17 // vol- #define CIRCLE_RIGHT 16 // vol+ #define STOP 54 // зеленая #define SLEEP 55 // красная #define AWAKE 37 // ок #define EXT 50 // желтая #define AUTO 52 // синяя... .... ..... void loop() { delay(1000); if(ext==0) { float dist_cm = ultrasonic.Ranging(CM); Serial.print("dist_cm=");Serial.println(dist_cm); if(dist_cm<10.0) ir_kod=CIRCLE_LEFT; else ir_kod=FORWARD; } if(ir_kod!=0) { Serial.print("ir_kod=");Serial.println(ir_kod); switch(ir_kod) { case FORWARD: // вперед course(1); Serial.print("forward\n"); break; case BACK: // назад course(2); Serial.print("back\n"); break; case CIRCLE_LEFT: // вращение влево course(3); Serial.print("circle_left\n"); break; case CIRCLE_RIGHT: // вращение вправо Serial.print("circle_right\n"); course(4); break; case STOP: // остановка ir_kod=0; go_hor_all(); Serial.print("pause\n"); break; case SLEEP: // засыпание ir_kod=0; go_hor_all(); myservo11.detach();myservo12.detach(); myservo13.detach();myservo14.detach(); digitalWrite(13,LOW); Serial.print("sleep\n"); break; case AWAKE: // пробуждение ir_kod=0; myservo11.attach(5);myservo12.attach(6); myservo13.attach(7);myservo14.attach(8); digitalWrite(13,HIGH); go_hor_all(); Serial.print("awake\n"); break; case AUTO: // режим автономный //ir_kod=FORWARD; ext=0; myservo11.attach(5);myservo12.attach(6); myservo13.attach(7);myservo14.attach(8); Serial.print("auto\n"); break; default: break; } } } // получить код переданный с ИК пульта void get_ir_kod() { detachInterrupt(0); // отключить прерывание 0 if (irrecv.decode(&results)) { //Serial.println(results.value); if (results.value > 0 && results.value < 0xFFFFFFFF) { ir_dt = results.value; if(ir_dt==EXT && ext==0) {ir_kod = SLEEP;ext=1;} else if(ext==1) { if(ir_dt==FORWARD || ir_dt==BACK || ir_dt==CIRCLE_LEFT || ir_dt==CIRCLE_RIGHT || ir_dt==STOP || ir_dt==SLEEP || ir_dt==AWAKE || ir_dt==AUTO) ir_kod = ir_dt; } else ; } irrecv.resume(); } attachInterrupt(0, get_ir_kod, CHANGE); }

Архив со скетчем и библиотеками Ultrasonic и IRremote можно скачать ниже

Список ссылок на статьи и инструкции необходимые для сборки и настройки шестиногого робота паука Hexapod RKP-RCS-2013B-KIT

На этом изображении (см. Рис. 1) показан пример собранного шестиногого робота паука с установленным на верхней плате дополнительным оборудованием в виде модуля Bluetooth для беспроводного внешнего управления.

Набор для сборки шасси шестиногого робота паука RKP-RCS-2013B-KIT это мобильная платформа шестиногого робота повышенной проходимости и маневренности. Шасси разработано и предназначено для робототехнических проектов, обучения конструированию различных систем мехатроники и программированию, а также для разнообразных конструкторских хобби. Мобильная платформа шестиногого робота паука (RKP-RCS-2013B-KIT) имеет в составе поставки платформу предназначенную для установки различных датчиков и сенсоров, а также плат управления роботом и систем питания.
Hexapod RKP-RCS-2013B-KIT - это набор в виде конструктора для самостоятельной сборки паукообразного шестиногого робота. Все детали несущей рамы корпуса и шести конечностей робота паука изготовлены из прочного и легкого алюминия. Детали конструкции шасси шестиногого робота паука (Hexapod) уже имеют все просверленные и фрезерованные элементы конструкции.

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

Гексапод - шестиногий робот паук может управляется при помощи беспроводного джойстика от PS2 или PS3 через модуль Bluetooth (в комплект поставки не входит, а приобретается отдельно) или с помощью программируемого контроллера Ардуино с разъемом USB. Через специальное компьютерное приложение для программирования сервоконтроллера можно настраивать ползунками команды установленных в ноги робота сервоприводов и изменять скорость срабатывания каждого из них.

Плата сервоконтроллера Servo Controller Board 32 Channel USB (RKP-SCB-32C) приобретается отдельно.

Сервоконтроллер для робота паука Arduino RKP-SCB-32C имеет возможность подключения дополнительных компонентов для Arduino. ()

Для передвижения всех шести ног робот паук использует 18 микро сервомоторов, которые также приобретаются отдельно. Например, рулевая машинка класса суб-микро 9 Gram TowerPro SG90 Micro Servo (TPSG90S) или аналогичная по параметрам и размерам.

В комплект конструктора для самостоятельной сборки робота паука RKP-RCS-2013B-KIT входит:
- Комплект алюминиевых запчастей черного цвета для сборки корпуса робота паука.
- Комплект механических захватов ("жвала" робота паука). Устанавливается опционально. Для работы захватов необходимо установить 2 дополнительные рулевые машинки.
- Комплект болтов, шурупов, гаек, шайб, переходников, латунных втулок и стоек.
- Электронные компоненты для сборки: провода для подачи питания к включателю, диодный мост для питания сервоконтроллера и плат управления, выключатель для подачи питания на управляющий блок.

Для окончательной сборки и настройки робота паука необходимы следующие комплектующие (приобретаются отдельно):
- 18 сервоприводов класса суб-микро
- USB servocontroller на 32 сервопривода RKP-SCB-32C
- Беспроводной приемник управления команд получаемых от оператора (при необходимости)
- Беспроводной джойстик PS2 Wireless Gamepad V2.0 for Arduino (при необходимости)
- Аккумулятор Li-Po (2S) 7,4V
-

Много чего предстоит сделать, прежде чем мы дойдем до вот этой картинки:

Опуская росказни о том, как именно я пришел к мысли построить гексапода (это были тонны видео на ютубе), перейду сразу к процессу выбора деталек. Это был январь 2012-го. Я сразу знал, чего я хочу от своего робота, а чего - нет. Я хотел:

Каждая нога должна иметь 3 степени свободы - 3dof (3 dimensions of freedom). Потому что более простой вариант 2dof - не дает такого ощущения насекомого, а 4dof - излишне, 3dof и так позволяет свободно перемещать кончик ноги в 3д пространстве;
- 6 ног; снова-таки, это уже не 4 (тогда робот неуклюже скачет), но и еще и не 8, как у пауков и уже чрезмерно;
- небольшой;
- дешевый;
- минимум плат и соединений;

Пост большой.

Первой конечно нужно было выбирать motherboard для крохи. Много как хорошего так и плохого успел почитать к тому времени об Arduino. Но именно на него и смотрел, как на основной вариант. Паять контроллеры самому - времени не было, а брать более продвинутые платы с ARM cpu, например - дорого, да и разбираться, как их программить, как работать с ШИМ выводами и т.п. А ардуина: IDE запустил, код напедалил, upload нажал - и привет, оно тебе уже моргает. Красота! ;)

Сначала я начал смотреть на arduino mega и клонов, т.к. кол-во ШИМ выходов, которыми можно рулить сервами у них было предостаточно. Напомню, что для 3dof гексапода нужно 3*6 = 18 сервов, и раздельных каналов управления ими. Но потом я нашел настоящий Яззь среди arduino mega, это плата от Dagu, звать которую Red Back Spider Controller. Вот она на ebay.

Она предлагает все свои выходы в виде готовых 3-х штырьков (земля, питание, сигнал), и разввязку по питанию. Питание самого контроллера стабилизировано, а на разъемы двиглов идет как есть (UPD: не как есть, а тоже стабилизированные 5 вольт. И повидимому развязано с питанием контроллера, т.к. помех в работу контроллера 18 одновременно работающих сервов не вносят). Это позволяет просто подать на клемму питания 7-30 вольт достаточной мощности (питальника от eee pc 901 на 12В и 3А - оказалось достаточно для жужжания всеми 18 сервами) и не морочить голову с раздельным питанием логики и двиглов. Также это позволит в будущем легко посадить все это чудище на пачку Li-Po аккумуляторов на 7.4 вольт. И при всем этом, с программной точки зрения - это обычная ардуино мега, совместимая с софтом и либами, да и железом (кроме шилдов, устанавливающихся прямо на оригинальную mega - они не покатят). Правда цена еще выше чем даже оригинальная мега, но все остальные плюсы перевесили это.

Далее сервоприводы. На ebay по запросу micro servo их много разных. Я взял самые мощные из самых маленьких и дешевых, весом 9 грамм, пластмассовыми редукторами. Если брать лоты где их пачками шлют - выходит дешевле. Я брал 3 пачки по 6 кажется, и вышло меньше $2 штука. Забегая вперед, скажу, что жалею что не потратил больше и не взял сервы с металлическими шестернями и шариковыми подшипниками. У этих пластмассовых оказались довольно заметные люфты, и характерный хруст при чрезмерном усилии когда шестерни проскакивают. Из-за люфтов - кинематику довольно тяжело настроить точно (да это вообще самое тяжелое оказалось).

Вот собственно и все что я заказал, с доставкой это вышло примерно $100. Батарейки и передатчики\приемники для контроля и радиоуправляемости - оставил на потом. Потому что радиоуправляемая машинка у меня есть и не интересна, а что меня действительно интересовало - это ноги! Видео плавно ходящих гексаподов на ютубе - завораживало , я смотрел его, пересматривал, и каждый раз слезы котились по щекам, и я сдавлено хрипел «хочу!». Хочу не заказать такую готовую штуку, а хочу сделать самому что-нибудь такое!

Пока ждал заказа, читал, как же просвященные люди оживляют свои творения. Конечно сразу же всплыла инверсная кинематика (перевод). Если сказать просто и сразу про шарнитные «конечности», то прямая кинематика - это когда на вход подаются углы шарниров, а на выходе мы имеем модель конечности в пространстве, и координаты крайней точки конечности. Обратная же кинематика - очевидно работает наоборот - на вход поступают координаты крайней точки конечности, куда нам надо дотянуться, а на выходе мы получаем углы, на которые нужно повернуть шарниры, чтобы это осуществить. Сервоприводы как раз получают на вход угловое положение, в которое им нужно повернуться (по одному сигнальному проводу, закодированное ШИМ / PWM).

Начал писать. Начал с того, о чем читал: продумывать реализацию ИК по методу, описанному там . Но быстро пришло ощущение, что для моего случая он чрезмерно сложен. Причем как громоздок в реализации, так и вычислительно очень сложен - расчет идет итеративно. А у меня 6 ног, для каждой из которых нужно считать ИК, и всего 16Мгц не самой шустрой архитектуры AVR. Но и всего 3 степени свободы. И несложно догадаться, что до произвольной точки в «области дотягивания» можно дотянуться только одним способом. Решение уже созрело в голове.

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

Полюбовался на это дело, и помечтал, что если я на основе этого робота в будущем спаяю терминатора, который объявит войну человечеству, то потом Джон Коннор со Шварцнеггером вернутся ко мне сюда в прошлое, и отберут этот прототип и расплавят его в Ородруине. Но никто не вернулся, ничего не отобрал, и я спокойно продолжил.

Оказалось, что ИК совсем не нужно бояться, в моем случае все свелось к банальной геометрии-тригонометрии. Чтобы проще было обращаться к суставам, обратился к википедии и почитал про насекомых. У них есть специальные названия для элементов конечности:

На русском тоже есть свои и очень интересные названия для этого, но «тазик», «вертлуг», «голень» и т.п., находясь в коде, не давали бы мне заснуть. Потому я 3-х конечностям и соответствующим сервам оставил названия Coxa, Femur, Tibia. Из прототипа ноги выше видно, что у меня для coxa даже нет отдельной детали. Это просто два серва, скрепленных резинками. Femur - реализован полоской пластика, к которой с обоих сторон крепятся рычаги сервов. Таким образом, последний оставшийся серводвижок - является началом tibia, для удлинения которой к нему прикручен еще кусок пластика.

Запустил редактор, не мудствуя создал файл Leg.h, И в нем класс Leg. Ну и кучу вспомогательной мути.) Пускай в пространстве есть точка A(ax, ay, az), к которой нужно дотянуться. Тогда вид сверху выглядит так:

На рисунке я сразу показал и способ вычисления первого угла - это угол поворота серва, управляющего Coxa, вращающего всю конечность в горизонтальной плоскости. На схеме красным сразу обозначены переменные, используемые в коде (далеко не все). Не очень математично, зато удобно. Видно, что интересующий нас угол находится элементарно. Сначала primaryCoxaAngle - находится просто углом (0;A) к оси X (что эквивалентно углу точки A в полярных координатах). Но на схеме видно, что при этом сама нога - не распаложена под этим углом. Причина в том, что ось вращения coxa не находится на «линии ноги» - не знаю как это правильно сказать. Не находится в плоскости, в которой вращаются остальные 2 сустава и находится кончик ноги, вот. Это можно легко компенсировать, посчитав additionalCoxaAngle (как его считать - даже не утруждаюсь останавливаться, ну ведь все же были в школе, правда?).

Итого, у нас есть первый кусочек кода, это внутренности метода reach(Point& dest):

Float hDist = sqrt(sqr(dest.x - _cStart.x) + sqr(dest.y - _cStart.y)); float additionalCoxaAngle = hDist == 0.0 ? DONT_MOVE: asin(_cFemurOffset / hDist); float primaryCoxaAngle = polarAngle(dest.x - _cStart.x, dest.y - _cStart.y, _thirdQuarterFix); float cAngle = hDist == 0.0 ? DONT_MOVE: primaryCoxaAngle - additionalCoxaAngle - _cStartAngle;

Здесь dest - это точка, куда нажо тянуться, _cStart - координаты точки крепления (и центра вращения) coxa, в hDist считаем расстояние от _cStart до dest в горизонтальной плоскости. DONT_MOVE - это просто флаг, означающий что coxa не нужно никуда вращать, а оставить в текущем положении (т.к. dest - где-то прямо на оси вращения coxa - редко, но бывает). Вот cAngle - это уже тот угол, на который нужно будет отклониться сервоприводу от его начального угла (который находится в середине его рабочего диапазона). Видно что также юзается _cStartAngle - это угол в пространстве, на который повернут серво по деволту, при монтаже. Про _thirdQuarterFix расскажу позже, если не забуду.

При этом, задача внезапно сведется к поиску точки пересечения 2-х окружностей. Одна - в точке, откуда «растет» наша femur, вторая - точка, куда нам надо дотянуться (с уже локальным 2d координатами). Радиусы окружностей - длины femur и tibia соответственно. Если окружности пересекаются - то в одной из 2х точек можно расположить сустав. Мы всегда выбираем верхнюю, чтобы «колени» у чудища были выгнуты вверх, а не вниз. Если не пересекаются - то мы не дотянемся до целевой точки. Еще немного кода, переход в плоскость производится элементарно, только пара подводных камней еще учтена и задокументирована в коментарии, чтобы я не ломал голову потом, разбирая код. Для простоты, в этой локальной координатной «плоскости ноги» я выбрал началом координат точку, откуда растет femur:

// Moving to local Coxa-Femur-target coordinate system // Note the case when hDist <= _cFemurOffset. This is for the blind zone. // We never can"t reach the point that is nearer to the _cStart then // femur offset (_fStartFarOffset) float localDestX = hDist <= _cFemurOffset ? - _fStartFarOffset: sqrt(sqr(hDist) - sqr(_cFemurOffset)) - _fStartFarOffset; float localDestY = dest.z - _fStartZOffset; // Check reachability float localDistSqr = sqr(localDestX) + sqr(localDestY); if (localDistSqr > sqr(_fLength + _tLenght)) { log("Can"t reach!"); return false; }

Теперь localDestX и localDestY - это координаты целевой точки. Все что осталось - найти точку пересечения окружностей с центрами в (0,0) и (localDestX, localDestY), и радиусами _fLength и _tLength (соответственно длина femur и длина tibia). С этим тоже школьник справится, но тут я допускал довольно много ошибок, потому для проверки себя и вообще чтобы любой мог проверить, что это за стремные формулы, оставил ссылки на источники, где ясно и понятно разжована эта элементарная геометрическая задача:

// Find joint as circle intersect (equations from http://e-maxx.ru/algo/circles_intersection & http://e-maxx.ru/algo/circle_line_intersection) float A = -2 * localDestX; float B = -2 * localDestY; float C = sqr(localDestX) + sqr(localDestY) + sqr(_fLength) - sqr(_tLenght); float X0 = -A * C / (sqr(A) + sqr(B)); float Y0 = -B * C / (sqr(A) + sqr(B)); float D = sqrt(sqr(_fLength) - (sqr(C) / (sqr(A) + sqr(B)))); float mult = sqrt (sqr(D) / (sqr(A) + sqr(B))); float ax, ay, bx, by; ax = X0 + B * mult; bx = X0 - B * mult; ay = Y0 - A * mult; by = Y0 + A * mult; // Select solution on top as joint float jointLocalX = (ax > bx) ? ax: bx; float jointLocalY = (ax > bx) ? ay: by;

Все, осталось еще чуть-чуть - по полученным координатам вычислить собственно углы для femur и tibia сервов:

Float primaryFemurAngle = polarAngle(jointLocalX, jointLocalY, false); float fAngle = primaryFemurAngle - _fStartAngle; float primaryTibiaAngle = polarAngle(localDestX - jointLocalX, localDestY - jointLocalY, false); float tAngle = (primaryTibiaAngle - fAngle) - _tStartAngle;

Опять элементарщина - угловые координаты и всё. Я надеюсь, именование переменных уже должно быть понятным, к примеру, _fStartAngle - это femur start angle, угол на который femur направлен по дефолту. И последняя строчка метода reach() (он сказал поехали, и махнул рукой):

Move(cAngle, fAngle, tAngle);

Метод move уже непосредственно отдает команды сервам. На самом деле, в нем еще потом пришлось добавить всякие штуки для защиты от нехороших углов (на которые серво повернуться не может, но будет пытаться), а также для других ног, которые заркально расположены и/или направлены в другие стороны. Но пока же мы работаем с одной только лапой.
Эти куски - это уже финальный код, который далек от совершенства, и наверняка его можно значительно улучшить. Но он работает! Ни разу не выйдя за школьный курс геометрии-тригонометрии, мы реализовали полнофункционалную инверсную кинематику для 3dof ноги! Да еще и получаем решение сразу, за одну итерацию. Чтобы это все работало, ногу нужно было тщательно измерить, и сконфигурировать класс полученными данными. в том числе угловыми, которые сложнее всего измерять на готовом изделии. Может если проектировать в автокаде и наделать красивых рендеров - было бы легче с измерением углов, но у меня не было ни времени, ни желания заниматься этим пафосом.

Февраль только начался, а видео с ногой было уже готово. Для проверки ИК, я заставлял ногу описывать всякие фигуры в пространстве (для этого нужно было последовательно вызывать reach, обходя точки на прямоугольнике, или окружности, код скучен и уныл, потому не привожу (а закончив эксперименты с обведением примитивов, я его вообще выпилил)):

Дальше нужно было заканчивать играться с этой поделкой, на одной ноге далеко не упрыгаешь (хотя такой робот вышел бы действительно интересным). Но мне нужен гексапод. Отправился на ближайшую барахолку искать оргстекло. Нашел 2 отличных куска - один 3 мм толщиной (как раз для туловища, подумал я), другой 2 мм и синий (отличные конечности, в тон сервоприводам). Еще через пару недель я выкроил вечер, чтобы что-нибудь сделать из этого. Сделал наброски на бумаге. примерил - вроде все ок, дальше дело за ножовкой.

И вот оно, чудище заморское, шестилапое. Когда я тестил одну ногу, я питал это дело каким-то левым питальником от внешнего винта. Хватало. Но питать 6 ног от него было уже страшновато. Потому я на некоторое время повесил руки, думая что мне нужно еще раздобыть подходящий питальник. Но оказалось все гораздо проще, я выше уже упоминал - подошел питальник от eee pc 901. Ну и отлично.

Отладить работу 6-ти ног оказалось еще сложнее, чем написать движок одной ноги. Половина ног была зеркально отражена относительно другой. Кроме того направлены все в разные стороны. Вобщем конфигурировал и настраивал я все очень долго, и это меня не очень вдохновляло, т.к. средств удобной отладки не было, максимум на что я мог расчитывать - вывод лога в Serial. И тот нормально работал из основного *.ino файла, а из подключенного Leg.h - уже не виделся нужный объект. Наворотил костылей для лога (facepalm). Со временем отрефакторю. А тут еще и весна пришла, велосезон был открыт в полную силу, и я забросил своего шестилапого питомца в шкаф. Так прошло все лето и теплая часть осени.

Но пошли дожди, стало холодно, и гексапод был извлечен. Ноги его были отлажены, в том числе был введен тот самый _thirdQuarterFix для функции расчета polarAngle. Проблема была в том, что 2 ноги (левая средняя и левая задняя) двигались так, что большую часть времени находились в III четверти:

А polarAngle у меня была наивная - она возвращала углы от -пи до пи, относительно оси X. И, если иногда одной из этих 2-х ног нужно было повернуться во II-ю четверть, то значение polarAngle прыгало от -пи до пи, что собственно негативно влияло на дальнейший расчет. Пофиксил костылем - для этих 2-х ног polarAngle считается «иначе». Стыдно, стыдно мне за код, но весь проект - это proof of concept, единственная цель которого - просто понять, могу я собрать реалистично двигающегося гексапода или нет. Потому код должен работать, и прямо сейчас. А уж потом рефакторинг - перерефакторинг.

Справившись с 3-й четвертью, начал педалить паттерны шага. Для этого ввел в класс Leg точку default, т.е. в которой нога находится, когда робот стоит смирно и ровно. Эту точку можно тюнинговать, главное чтобы все ноги были на одной z координате (чтобы при этом ноги реально физически находились на одной плоскости, у Leg есть еще самая низкоуровневая tuneRestAngles()). А в пределах одной Z координаты, их можно двигать почти как угодно. Почти - потому что диапазон движения не бесконечен, и чтобы при шаге не выходить за рамки этого диапазода - default положение ног старался разместить где-то поближе к центру этого диапазона.

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

Последовательность шага выбрал простую - 3 ноги на земле, 3 - в воздухе переставляются. Таким образом, координаты ног относительно их default положения - можно разделить на 2 группы. Для этих двух групп я и проворачивал шаг в цикле (см функцию walk() в Buggy.ino). А в итоге, каждая нога вычисляла себе свою индивидуальную координату, исходя из своей default координаты.

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

До а-пода, конечно, далеко. Но я же не закончил еще.) Попедалил еще вечер - и добавил возможность двигаться в любом направлении (но не поворачивая корпус.)). Плюс для сглаживания между движениями добавил функцию (smoothTo()), которая аккуратно перемещает ноги (поднимая вверх, опять в 2-х группах, одна из которых всегда внизу, тварь на ней стоит, пока другая поднимается и перемещается) в новое положение. Это нужно чтобы тварь не дергала резко ногами, сменяя направление движения (этой фичи ох как не хватает многим игровым персонажам прошлых лет). И он резво забегал в любом направлении - вбок, по диагонали:

Оба грандиозных файла сорцов можно смотреть

Лучшие статьи по теме