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

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

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

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

Однако, оригинальные аппараты Segway отличались достаточно высокой ценой (в своё время, я отслеживал, и там было что-то около 350000 руб на период начала 2010-х годов; что, соответственно, в наше время будет стоить около миллиона или более).  

Примерно в середине 2010-х годов, ситуация кардинально изменилась с массовым появлением и распространением недорогих двухколёсных транспортёров подобного же типа, только гораздо более малых габаритов — «гироскутеров»:

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

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

Например, сделать «гиро-мотоцикл»:

Или, скажем, тоже интересное решение — гироскопическая инвалидная коляска:

Таким образом, мы видим, что сам балансирующий принцип представляется разработчикам достаточно привлекательным, в виду чего, они его стараются применить в разных направлениях, так что здесь явно ещё существует простор для фантазии ;-)

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

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

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

Почему мы этому уделяем внимание: так как априори планируется автономный робот, не привязанный ни к чему проводом, то принятие во внимание этого момента является важным, в рамках конкретной вашей решаемой задачи — а будет ли подобный робот, в течение вашего конкретного требуемого времени работы и вашего источника питания, достаточно автономным? И, возможно, стоит выбрать альтернативные решения?

Впрочем, если шаговые двигатели уже есть под рукой, а всё это «для развлечения», то, почему бы и нет... :-) 

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

Обратимся к одному из типовых решений в этой области, где для начала, посмотрим на результат его работы:

Как видно, автор этого робота явно решил, что «шаговые двигатели — не только для настольных моделей» :-D и сделал полноразмерное устройство с довольно существенной тягой. 

Посмотрим на его принципиальную схему компонентов и соединений:

                                                                                                                                                                                github.com/electrical-pro/ESP32_Robot

Как видим (а также это написано на странице проекта) что система запитывается от трёх литий-полимерных аккумуляторов, для заряда которых использована специальная плата контроля заряда/разряда и балансировки (чтобы происходил равномерный заряд/разряд всех трёх «банок»). 

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

*В этом проекте использованы драйверы двигателей DRV8825, которые, как и многие другие, обладают защитой от превышения по току — просто-напросто отключают питание нагрузки, и включается соответствующий сигнал nFAULT (пин FLT) — то есть, микроконтроллер может постоянно отслеживать состояние этого пина, и понять, что произошло какое-то превышение по току (и температуре) и всё отключилось. 

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

Ну, почему бы и нет, информация никогда не бывает лишней… 

То есть, делая вывод по системе мониторинга можно сказать, что такая сборка позволяет ловить малейшие симптомы и делать выводы, а не просто констатировать факт: «что-то не так». :-)

В остальном, всё довольно стандартно: в качестве источника координатной информации для выравнивания используется известная плата акселерометра-гироскопа MPU6050, подключенная к esp32 по i2c шине. 

Перед запуском требуется откалибровать как MPU6050, так и драйверы двигателей по току. Как это сделать можно найти вот здесь.

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

Сразу начнём со сложного: алгоритм выравнивания включает в себя алгоритмы PID регулятора, которые позволяют добиться нужного положения, с минимальной раскачкой «туда/сюда», за минимальное время.

Если кто до этого не сталкивался, то вкратце скажу, чтобы если бы алгоритма PID не было придумано наукой, то в автоматических системах очень сложно было бы достичь заданного значения (температуры, положения вала, нужной скорости и т.д. и т.п.) и исполнительное устройство постоянно проскакивало бы мимо нужного значения — то выше, то ниже. 

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

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

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

Таким образом, если даже попытаться собрать практически один в один устройство как у автора, выравнивание может не сработать. 

Собственно говоря, это отмечает и сам автор, говоря, что работа с PID алгоритмом — задача та ещё, и не для новичков…

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

Скажу честно: опираясь на этот ресурс, я в своё время настраивал прямолинейное автономное движение роботов :-) 

Более-менее* получилось ;-) и даже простым ручным подбором коэффициентов. Так что ничего прямо ужасного там нет… Ну да, несколько помурыжиться придётся, зато результат то какой интересный может быть! ;-) 

*Почему более-менее: вперёд робот двигался практически идеально, а вот назад — постоянно сносило в какую-либо из сторон; насколько я в итоге понял, это было связано с аппаратными проблемами, а именно — банально кривой тележкой робота! А так как выравнивание у меня происходило просто подсчётом импульсов с энкодера каждого колеса и никакого акселерометра-гироскопа не использовалось, то ошибку самой конструкции я исправить никак не мог, а переводить всё на акселерометр-гироскоп MPU6050 (что исправило бы ситуацию кардинально) мне уже было лениво :-))) 

Для данного робота используется алгоритм двухуровневого (каскадного) PID регулятора, схему которую можно посмотреть здесь

Первый справа на схеме контур управления (Angle PID) постоянно стремится выровнять робота в вертикальное положение, и на вход принимает данные от MPU6050, а также данные от «внешнего» (т.к. взаимодействует с пользователем) PID алгоритма Speed PID и служебного Position PID. 

Таким образом, получается следующая картина: если пользователь не посылает никаких данных с пульта управления (на схеме это показано как «User input» (пользовательский ввод)), то алгоритм Angle PID постоянно читает только данные с MPU6050 и стремится установить робота в вертикаль, принимая в расчёт при этом текущее положение колёс (Position PID); если же от пользователя приходят управляющие данные — то ко входу алгоритма Angle PID подмешивается значение от алгоритма Speed PID, в результате чего, робот несколько наклоняется вперёд/или назад, и начинает движение, соответственно, вперёд или назад. 

При пропадании сигнала от пользователя, алгоритмы Angle PID и Position PID продолжают работать в одиночестве, стремясь снова установить робота в вертикаль… 

Из интересного ещё можно заметить, что для хранения интерфейса используется SPIFFS («Serial Peripheral Interface Flash File System») — грубо говоря файловая система на флешке esp32. 

Развёрнутый пример, что это такое, и как с этим работать, можно найти здесь

Причём, что любопытно, автором в полной мере используются все возможности хранения данных у esp32 — кроме названного SPIFFS, он ещё использует и библиотеку preferences (судя, хотя бы по строке #include <preferences.h>, ну и далее по коду), которая предоставляет возможности по быстрому сохранению и извлечению данных в формате ключ-значение (там обычно удобно хранить всевозможные настройки). 

Как работать с этой библиотекой можно найти тут. 

С помощью этой библиотеки он сохраняет настройки гироскопа, акселерометра, а также wi-fi (логин-пароль).

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

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

Таким образом, этот момент явным образом придётся доделать, и сохранять настройки, если не хотите мучаться каждый раз, при каждом включении робота! 

То есть, настроили один раз, убедились, что всё работает хорошо, выравнивание и параметры шаговых двигателей вас устраивают — нажали кнопочку и сохранили. Это придётся доделать... Так что, изучаем, как работать с preferences (ссылка на обучалку есть выше).

Ну и, напоследок, можно отметить, что он там в коде использует очень интересную технологию — OTA («On-The-Air»), то есть «Загрузка-Прошивки-По-Воздуху» — технология позволяет прошивать микроконтроллер, не подключая его проводом к компьютеру!

По опыту могу сказать, что это крайне нужная функция, так как постоянно носить робота к компьютеру (чтобы вносить какие то правки в код), особенно, если робот габаритный, это страшно неудобно и очень просится организовать удалённую прошивку по wi-fi!

Обычно это делается следующим образом: 

  • Или компьютер подключен через роутер к интернету, где роутер выступает wi-fi точкой доступа (компьютер может быть подключен к этому роутеру проводом или по wi-fi это неважно) и к этому же роутеру, подключается и esp32, установленная на робота — то есть, esp32 становится клиентом локальной wi-fi сети;

  • Или компьютер (например, ноутбук) сам является точкой доступа и esp32 подключается к нему.

Далее, определёнными манипуляциями, можно добиться того, чтобы ip-адрес этой esp32, установленной на робота, начал отображаться внутри Arduino IDE, благодаря чему, прошивку с компьютера можно загрузить прямо на esp32 по wi-fi, из среды Arduino IDE! 

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

Подытоживая, можно сказать, что мы видим, что ничего особо нереального и невозможного в создании балансирующего робота нет, все исходники выложены в открытый доступ и множество людей уже собрали подобное. Возможно, следующим, кто соберёт подобное, будете вы? :-)

P.S.Как отмечает сам автор этого робота, его проект является производным от проекта https://gitlab.com/kloppertje/balancingrobot, так что, если не будет хватать какой то информации, то вы вполне можете попробовать обратиться к первоисточнику и поискать её там.


Размещайте облачную инфраструктуру и масштабируйте сервисы с надежным облачным провайдером Beget.

Эксклюзивно для читателей Хабра мы даем бонус 10% при первом пополнении.

Воспользоваться

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


  1. LAutour
    15.05.2026 10:26

    Сразу начнём со сложного: алгоритм выравнивания включает в себя алгоритмы PID регулятора, которые позволяют добиться нужного положения, с минимальной раскачкой «туда/сюда», за минимальное время.

    А вариант на нечеткой логике?


  1. hoan51
    15.05.2026 10:26

    картинка выпала из статьи


    1. LAutour
      15.05.2026 10:26

      Это уже моноколесо, а не гироскутер.