В одной из прошлых статей я мельком затронул возможность реализации бильярда, управляемого через интернет.
Ну вот, вроде бы и статья осталась в прошлом, а мысль-то не отпускает! И я подумал: почему бы и нет? И работа закипела…
Честно говоря, я и сам не знал, что меня ждёт, но неизвестность звала к себе:-) Сразу скажу, что это своего рода эксперимент, который ещё требует дальнейшей работы, но, тем не менее, было занятно.
Так как в прошлом я достаточно много работал с IOT-протоколом MQTT, я решил остановиться именно на нём. Этот протокол позволяет очень просто получать доступ к устройствам, находящимся в локальной сети, без необходимости заботиться о том, какой IP-адрес у конкретного устройства и изменился ли он.
Кто не в курсе, что это за протокол, может прочитать о нём в статье, ссылку на которую я дал выше. Ближе к её концу я вкратце описал концепцию его работы, чтобы те, кто не знает, быстро смогли получить представление.
А уже более подробную информацию вы можете почерпнуть самостоятельно из открытых источников.
Итак, MQTT… Начать я решил с системы управления, так как подозревал, что меня там будут ждать некоторые подводные камни, несмотря на то, что у меня есть опыт. И я нисколько не ошибся в этом предположении.
Несколько лет назад, для другого проекта, я искал и нашёл единственный, доступный на тот момент, так называемый «MQTT-джойстик», представляющий собой приложение под Android и реализующий функционал джойстика.
Любые действия с джойстиком отправляли данные в один и тот же MQTT-топик (да, не слишком удобно), которые можно было забирать и на основе их осуществлять какие-то действия:
Однако, когда я, спустя уже достаточно большое время, попытался оживить этот джойстик, это мне не удалось по той простой причине (как я сам подозреваю), что те бесплатные открытые западные MQTT-брокеры (т.е. не требующие регистрации, так как джойстик умеет взаимодействовать только с такими), которые я использовал, перестали работать с Россией.
Либо джойстик содержал скрытые механизмы, которые сделали его неработоспособным, так как в данный момент это приложение отсутствует в списке приложений Google Play (или, по крайней мере, не находится, если искать из России).
Промучившись с ним некоторое время, я поднял одну руку и резко её опустил, после чего решил использовать другой способ…
Несколько забегая вперёд, скажу, что он оказался даже существенно лучше предыдущего, с этим джойстиком ;-)
В любом случае, даже если бы этот джойстик у меня заработал, думаю, было бы неправильно, чтобы проект базировался на нём, если люди не смогут его найти и скачать в Google Play.
В качестве дополнительной ремарки скажу, что я использовал Android-приложение и далее будет описываться работа именно с ним.
Пользователи iOS могут ознакомиться со всей концепцией, после чего найти и настроить какое-либо приложение с аналогичным функционалом под свою систему самостоятельно.
Однако, чтобы лучше понять дальнейшее, необходимо сделать небольшое отступление и рассказать обо всей концепции в целом…
Я решил собрать роботизированный манипулятор, который мог бы управлять кием для бильярда, получая команды через интернет с помощью протокола MQTT от пользователя, взаимодействующего с Android-приложением.
В процессе размышления над всей этой темой я выбирал между двух концепций:
- Установленным прямо над бильярдным столом манипулятором, вращающимся на 360°.
- Манипулятором, перемещающимся по периметру игрового стола.
Несмотря на заманчивость первого варианта, я всё же решил остановиться на втором, так как, на мой взгляд, он более естественен, ведь по сути имитирует перемещения человека во время игры.
Далее, необходимо было продумать систему степеней свободы манипулятора, где одной из самых сложных задач стала бы реализация системы движения вокруг стола.
Однако я решил справиться с этим самым простым и естественным образом: просто-напросто вращать стол вокруг оси!
А чтобы в процессе такого вращения шары не смещались со своих мест:
- вращать на малой скорости;
- покрыть стол достаточно толстым «сукном», в котором шары будут несколько утопать, и это будет предохранять их от случайных смещений;
- выставить игровой стол в горизонталь по уровню, используя для этого смартфон, положенный прямо на игровой стол, с запущенным приложением-уровнем.
Кроме того, было реализовано перемещение кия вдоль стола — назовём это перемещение условно X, а также подтаскивание/оттаскивание кия к шару/от шара — назовём это Y.
Также мне подумалось, что будет полезно, если кий сможет менять угол наклона.
Таким образом, мы имеем 4 степени свободы, из которых первая (вращение стола) была реализована с помощью шагового двигателя, установленного прямо под столом, а 3 другие — X, Y, наклон кия — с помощью сервоприводов.
Однако этого мало для полноценной игры — необходимо ещё и как-то нанести удар по шару!
Те, кто работали с мини-сервоприводами SG90, в курсе, что это довольно вялые ребята :-)
В том смысле, что они вполне хорошо и быстро работают в рамках возложенных на них целей, однако не особо годятся в качестве средства нанесения удара.
Да, я понимаю, что вы скажете, что можно к серве приделать рычаг, чтобы за счёт его длины кончик описывал достаточно большую окружность и наносил достаточно живой удар в конце движения.
Однако я решил пойти другим путём: использовать пружину. А именно: кий соединён с пружиной, которую взводит одна серва, оттягивая кий назад, после чего другая серва оттаскивает вбок «собачку» — то есть упор, в который упирается первая серва, что приводит к тому, что кий перестаёт удерживаться, срывается с места и наносит удар по шару:
Сначала взводила мелкая серва SG90, но не справилась с усилием, поэтому поставил мощную с металлическими шестернями. Марку не помню, но что-то на около 10 кг тяги (слева внизу — как стало, справа наверху — как было):
Сила удара, то есть степень того, насколько мы растянули пружину, может выставляться пользователем.
И, кстати, в этом есть очень интересная возможность (в отличие от джойстика и реальной жизни): мы можем постоянно и стабильно наносить удар с одной и той же силой каждый раз!
В качестве средства создания компонентов робота я решил использовать FDM 3D печать.
Концепцию стола замыслил такой: сделать его номинальным, только обозначив лузы. Почему: чтобы не мучаться доставанием шаров из них.
Вместо этого, лузы — это отверстия в бильярдном столе, а сам стол устанавливается на шаговый двигатель (и приклеивается силиконовым термоклеем; некогда было крепёж делать) и уже они оба ставятся в поддон (посудка для еды, с которой когда-то ходил на работу :-) ). Таким образом, шарик, попадая в лузу, просто падает в поддон, откуда его удобно забрать. Всё просто!
Вот как это выглядит (размер стола — 80х50 мм):
После распечатки, на стол решил наклеить кусок старой толстовки, чтобы получился бильярдный стол — по ощущениям, получилось очень похоже на настоящий стол — чуток пружинит и прогибается под шарами, так как подкладка мягкая:
В итоге вышло так (снизу приклеил на термоклей шкив, который потом насажу на шаговый двигатель):
Ниже можно видеть остальные части системы, распечатанные и собранные:
Заодно видно нюансы:
- качающаяся верхняя часть подвешена на оси с помощью 2 подшипников 15х5х6 мм (6 мм проходное сечение);
- в качестве трубчатых направляющих взяты алюминиевые трубки из Леруа (что-то около 70 руб. за метр — 1000х6х1 мм);
- в качестве кия тоже взят кусок той же трубки (видно, что он на фотографиях в сборе — пока не отпилен);
- в задней части видно вертикальную оранжевую пластинку — собачку спускового механизма (покажу позже подробнее, как работает).
Так как сразу подозревал, что наводится будет очень сложно — взял в «Комус»-е лазерную указку, разобрал, припаялся и прикрепил её на конец кия, с помощью кусочка резинового шланга -то есть, лазер будет светить прямо внутри кия — такой, как бы, лазерный прицел:
Итак, всё собрано и готово к подключению:
Однако вернёмся к приложению для управления со смартфона — в качестве него я решил использовать IoT MQTT Panel:
Почему, спросите вы? Очень просто: без каких-либо личных предпочтений, просто самое первое, которое попалось под руку.
Наверняка, если поискать, есть и более удобные варианты… Тем более, что в этом приложении мне лично не понравилось то, что все мои необходимые элементы управления не помещались в один экран (несмотря на то, что половина экрана остаётся пустой), и мне приходилось пролистывать список, чтобы добраться до двух последних. На картинке ниже я показал всё сразу, как если бы оно отображалось правильно:
Из приятных плюшек, как можно заметить на картинке выше, ползунки могут изменять цвет динамически: чем сильнее сдвигаем ползунок вправо, тем ярче он окрашивается в красный, проходя через жёлтый. «Красивое устройство — и работает хорошо»©
Если мы зайдём внутрь любого из управляющих элементов, то сможем увидеть там настройки.
Как можно видеть на картинке ниже, при нажатии/отжатии кнопки (вращать стол влево) происходит отправка 1 или 0 в соответствующий топик:
В качестве MQTT-брокера я выбрал clusterfly.ru, где зарегистрировался и получил доступ, который позволяет отправлять максимум одно сообщение в секунду (неудобно, надо будет ещё посмотреть брокеров, где можно чаще), и периферийное устройство тоже должно залогиниться на брокере, чтобы иметь возможность работы с ним.
Кстати говоря, в качестве периферийного устройства я использовал ESP32, а в качестве драйвера шагового двигателя, который будет вращать бильярдный стол, взял TB6600, схему соединений и код для управления которым позаимствовал вот отсюда (эта схема показана ниже):.
Картинка: makerguides.com
О сервах, которые будут использоваться, следует сказать ещё несколько подробнее…
Дело в том, что при работе с сервами самый неудобный момент заключается в том, чтобы понять, в каком положении закрепить качалку сервы — вот этот белый рычаг на ней.
В своё время я для этого приобрёл достаточно удобную штуку — тестер серв:
Он генерит ШИМ сигнал разной длины импульсов, что позволяет поворачивать вал сервопривода на разные углы. Подробнее об этом можно глянуть вот здесь.
Как можно увидеть выше, я взял питание от powerbank-а, подал его на ESP32 и вывел питание с её пинов на тестер, к которому подключал сервоприводы, один за другим, тестировал и прикручивал качалку в нужном положении.
Ниже видео, как примерно это происходит:
И тестирование некоторых серв, уже установленных на аппарат:
Тяги для серв были сделаны из нержавеющей сварочной проволоки для полуавтомата, сечением в 1 мм (купил как-то по случаю упаковку как раз для таких целей):
Ещё один момент касательно серв заключается в том, что стандартная библиотека для работы с сервами (Servo.h) конфликтует с ESP32 (по крайней мере, на моей версии Arduino IDE и текущей версии API от производителя ESP32 — компании Espressif).
Таким образом, используя её, скомпилировать код не получится.
Достаточно давно, в попытке решить этот вопрос, на одном из англоязычных форумов я наткнулся на весьма простое решение (хотя, если подумать, можно было бы догадаться и самому :-)): просто-напросто генерировать ШИМ самостоятельно с разным заполнением, изменяя которое, мы и будем поворачивать сервопривод!
Там же были приведены и крайние значения, выведенные опытным путём для маленьких сервоприводов типа SG90, поворачивающихся в диапазоне 0...180°: 1638-7864.
Собственно говоря, эта идея и реализована в коде прошивки для ESP32.
Сама прошивка для удобства выполнена в отдельных вкладках:
Где все вкладки будут сохранены отдельными файлами, среди которых следует запускать вкладку под названием billiard_version_… (версию специально не пишу, так как к моменту выхода статьи наверняка ещё прикручу чего-нибудь…
Структурно весь основной код находится в этой вкладке, откуда после поступления сообщения через mqtt и происходит вызов функции-менеджера drives_controller(), которая и раздаёт задания всем доступным приводам (сервам и шаговому двигателю).
После чего исполнение задания для шагового двигателя происходит с помощью функции table_motor(), а для сервоприводов — с помощью функции-менеджера servo(), которая и управляет сервоприводами, передавая задание для конкретного сервопривода, ниже, для функции-исполнителя servo_angle_rotator().
Весь код достаточно подробно закомментирован, так что, я думаю, если кому это будет нужно, то сможете легко разобраться.
Ещё один момент касательно кода: компания Espressif (производитель ESP32) относительно недавно изменила API, так что, если вы хотите, чтобы код, который я выложил, работал у вас, следует использовать Arduino IDE версии 2.3.2 — там ещё нет этого нового API.
Иначе вам придётся многие функции, использованные в коде, рефакторить самостоятельно, чтобы привести в соответствие с последним API от Espressif.
В качестве бильярдных шаров решил использовать шарики от подшипника, который и был разобран:
Предвосхищая вопросы: да, подшипник жалко. Однако «чего не сделаешь ради искусства?».
Диаметр подшипников, взятых в качестве шаров — 4 мм. Правда, их меньше, чем нужно для бильярда (не 15), но протестить концепцию вполне годится.
Саму прошивку вместе с необходимыми библиотеками, а также 3d модели компонентов робота для печати, можно скачать здесь.
Ну и то, что наверняка ждали многие — ниже видео работы системы. Сразу извиняюсь, — нет у меня второй видеокамеры, поэтому — управлял со смартфона и снимал на вебку:
Выводы по результатам тестов для себя определил следующие:
- Сервы работают несколько резковато, и даже таская ползунки на экране смартфона, их сложно выставить как надо. Один из вариантов улучшения — привод осуществлять не напрямую, с качалки сервы, а через посредник в виде колеса: тяга от сервы крепится к точке на большем диаметре, а на меньшем диаметре закреплена вторая тяга, приводящая в действие устройство (как бы самодельный редуктор). Альтернатива — перейти на другие двигатели, например, шаговые, с приводными ремнями.
- Лазер внутри кия оказался весьма удобным:: только по нему и ориентировался. Если бы его не было — даже не представляю, как наводиться, не стоя за кием (реально сложно).
- В целом, код работает, но его можно значительно улучшить. Если у вас есть желание, попробуйте доработать и переработать его.
- Ткань на столе отлично справляется: шары надёжно удерживаются на месте, и даже не требуется дополнительная настройка уровня.
- Забавный момент обнаружился в процессе: разрабатывал устройство для резкого удара, а оказалось, что простое толкание кия вперёд (его обычная подача) тоже отлично работает как удар. В итоге появилось два типа удара: резкий и не резкий, что значительно расширяет возможности.
- Хотелось бы отметить про саму игру: на то, как я играю в видео выше, особо внимания не обращайте. У меня физически не было времени, чтобы научиться играть как следует. Как я и предполагал, это оказалось непросто — поэтому я и установил лазер. Кроме того, общая сложность управления роботом также добавила трудностей. Тем не менее под конец я уже более-менее сносно выставлял угол кия и бил им :-))
- По поводу плавности перемещений: уже после завершения теста и написания статьи я понял, как добиться лучшей плавности! Проблема заключалась в жадности: я хотел, чтобы робот мог двигаться на максимальные расстояния, но это усложнило управление («дайте мне таблетки от жадности, да побольше!»). У качалок серв (т.е. у этих белых тяг на осях) есть целый ряд дырочек, где тяги можно просто воткнуть ближе к оси — и тогда все движения робота станут более плавными, но на меньшие расстояния. Есть и более простой способ: как можно видеть в начале, в Android-приложении для MQTT я настроил шкалы на диапазон 0…100. Можно было бы уменьшить диапазон, например, до 0…50 или даже до 0…30. Это бы ещё больше упростило плавность движений, даже без изменений в физической конструкции. Или можно применить комбинацию этих методов… или даже трёх, добавив внешнее колесо-редуктор, как описано выше, чтобы плавность была ещё большей. В общем, это всё вполне решаемо.
Напоследок хочется сказать вот что: в целом, всё это было сделано ради проверки концепции. При желании многие элементы можно доработать, сделав их более аккуратными и надёжными.
Кроме того, стоит подумать о соотношении размеров стола и качалок серв, чтобы не пришлось их удлинять (или удлинять умеренно, чтобы не перегружать сервы такими рычагами).
Но в целом, мне эта идея кажется достаточно любопытной, и при должном желании её можно развить даже в бизнес — в качестве онлайн-сервиса для игры на настоящих бильярдных столах.
Однако если вы не строите таких амбициозных планов, то такая забава, как мне видится, вполне подойдёт для того, чтобы провести интересное время с друзьями, даже находясь на другом конце света: у кого-то одного стоит этот стол, он транслирует видео в сеть, а другие играют. В любом случае, новогодние выходные вполне располагают к этому :-)
Нужно будет только додумать и дописать код для механизма автоматической смены игроков а также улучшить (сделать более плавными) механические передачи.
© 2024 ООО «МТ ФИНАНС»
Автор: DAN_SEA