Укрощение гравитации: гид от мастера по созданию самобалансирующегося робота с нуля

Укрощение гравитации: гид от мастера по созданию самобалансирующегося робота с нуля

Чем нас обычно завораживают роботы, когда мы смотрим на них на выставках? Нет, не мощью промышленных манипуляторов, а тем магическим моментом, когда груда текстолита, металла и проводов вдруг замирает в неустойчивом равновесии, а потом, чуть покачнувшись, сама выпрямляется, словно живая. Это чистая магия обратной связи созданная инженерами-электронщиками. Сегодня мы научимся, как собрать робота «балансира» с нуля.

Шаг 1. Анатомия падения: почему робот не стоит, а падает?

Начиная создавать робота. Берём два колеса, два мотора, длинный корпус и датчик угла. Собираем конструкцию, у которой центр тяжести — выше оси колёс. Затем пытаемся её удержать.

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

Разбор от мастера-электронщика:

Что делаем? Мы сознательно делаем робота высоким, устанавливаем аккумулятор или дополнительный груз в верхней части.

Что в итоге? Увеличиваем момент инерции. Робот падает медленнее — как пьяный мачтовый кран, а не как карандаш. У контроллера появляются дополнительные миллисекунды, чтобы подкрутить колёса. Проверено: низкий «коренастый» робот держит равновесие намного сложнее.

Шаг 2. Глаза и уши системы: MPU6050

Что делаем. Впаиваем модуль MPU6050. Внутри него — два датчика: акселерометр (чувствует наклон к горизонту) и гироскоп (чувствует угловую скорость).

Гироскоп и акселерометр в одном флаконе:

1. Акселерометр отлично видит горизонт, когда робот спокоен, но сходит с ума от вибраций моторов.
2. Гироскоп игнорирует тряску, но страдает «дрейфом»: со временем он начинает верить, что робот лежит, хотя тот стоит ровно.

Разбор от мастера:

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

Что в итоге получаем? Угол наклона с погрешностью меньше 1°, без дрейфа и без вибрационного шума. При правильном выборе коэффициента α (обычно 0,96–0,98) робот видит реальное положение корпуса даже во время резких рывков.

угол_новый = 0,98 × (угол_старый + скорость_гироскопа × dt) + 0,02 × угол_акселерометра

Совет мастера: Не берите готовую библиотеку DMP от MPU6050 для балансира — она выдаёт красивые кватернионы, но с задержкой. Ваш робот упадёт раньше, чем придут данные. Берите сырые значения и фильтруйте сами.

Шаг 3. Мышцы: драйвер моторов (прощай, L298N)

Соединяем контроллер (Arduino, STM32 или ESP32) с моторами через драйвер. Забываем про L298N. Что получаем. Драйвер TB6612FNG (или аналоги на полевых транзисторах) занимает в 3 раза меньше места, не требует радиатора, а напряжение на моторах — почти как на аккумуляторе.

Руководство от мастера:

Подключаем питание моторов отдельно от питания логики. Ставим конденсаторы на 100–470 мкФ рядом с драйвером. И обязательно настраиваем мёртвую зону (deadzone).

Что в итоге получаем? Моторы стартуют без задержки. Робот может давать микро-коррекции, чтобы удержать вертикаль. Без компенсации мёртвой зоны (PWM_MIN от 30 до 60, в зависимости от моторов) ШИМ-сигнал от 1 до 30 не сдвинет колёса — робот будет мелко дрожать и падать.

  • Важно: TB6612FNG держит до 1,2 А продолжительно. Если ваши моторы жрут больше — ищите драйвер на 5–10 А (например, из мёртвого электроинструмента).

Шаг 4. Мозг: ПИД-регулятор

Пишем функцию ПИД. Вход — текущий угол наклона, выход — значение ШИМ на моторы. У нас будет: три инженера в одной формуле:

• P — «Крути быстро, если сильно наклон!». Без него нет реакции вообще.
• I — «Если постоянно клонит влево — добавь подпорку». Компенсирует смещённый центр тяжести.
• D — «Тормози перед вертикалью, иначе пролетит». Гасит раскачку.

Разбор от мастера:

Сначала отключаем I и D, поднимаем Kp до первого покачивания. Потом добавляем Kd — пока робот не перестанет колбаситься. Только в самом конце, если уезжает в сторону, вводим Ki (маленькое, в 20–50 раз меньше Kp).
Что в итоге получаем? Робот не просто «старается встать», а делает это уверенно. Правильный ПИД превращает дергающуюся тележку в нечто, напоминающее оловянного солдатика.

  • Совет: Для многих балансиров I-составляющая вообще не нужна. Классический ПД-регулятор лучше, чем ПИД с плохо настроенным интегратором — последний часто вызывает медленные раскачки.

Шаг 5. Программный детерминизм: время не терпит суеты

Пишем код так, чтобы управляющий цикл запускался строго каждые 5–10 мс.
Получаем стабильную частоту вычислений (100–200 Гц). Робот получает команды через равные промежутки.

Руководство от мастера-электронщика:

Запрещаем себе delay(), Serial.print() в основном цикле и любые блокирующие вызовы. Используем прерывания по таймеру или флаги в loop() с проверкой микросекунд.

Что в итоге получаем? Обработка ПИД не плавает во времени на 20–30%. Разница в 5 мс — это разница между стоящим роботом и лежащим.

  • Мастер советует: На Arduino Uno используйте Timer1 (режим CTC), на ESP32 — таймер с приоритетом. В прерывании только считывание датчиков, фильтрация, ПИД и вывод ШИМ. Никакой математики с плавающей точкой, если можно сделать в целых числах.

Шаг 6. Настройка ПИД: как не убить батарею за час

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

Действуем строго по шагам:

1. Kp = 0. Увеличиваем, пока робот не начнёт активно дрожать и пытаться встать. Это ваш потолок.
2. Добавляем Kd, чтобы убрать дрожь и раскачку. После хорошего толчка робот должен вернуться в ноль за 1–2 колебания.
3. Ki добавляем только если робот стоит, но медленно уезжает в сторону (например, из-за разной массы колёс). Начинаем с Ki = Kp / 50.

Что в итоге получаем? Уверенный баланс робота. Но есть нюанс: батарея садится. При 12 В и 10 В поведение ПИД сильно меняется.

  • Мастер советует: Добавьте компенсацию по напряжению. Измеряйте напряжение аккумулятора через делитель (1:10) и АЦП. Выход ПИД умножайте на (U_ном / U_тек) или на аппроксимированную функцию. Тогда робот будет одинаково стоять и на полной батарее, и перед выключением.

Шаг 7. Финальная сборка и оживление робота

Укладываем провода, фиксируем платы, прячем MPU6050 от вибраций и сквозняков. У нас будет робот, который не глючит от наводок и не падает после первого резкого поворота.

Руководство от мастера:

• Крепим MPU6050 через кусочек демпфирующей резины (или на тонкой пружинной пластине).
• Питание на датчик подаём через LC-фильтр (ферритовая бусина + 10 мкФ + 0.1 мкФ).
• Укорачиваем провода от драйвера до моторов — иначе ШИМ создаст радиопомехи.
• Не используем на одном конце робота тяжёлые предметы — центр тяжести должен быть ровно посередине между колёс.

Что в итоге получаем? Работающий прототип робота, который не падает от вибрации, не рыскает и не горит.

Итог: инженерное робо-счастье

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


Новые комментарии:

Ваш адрес email не будет опубликован. Обязательные поля помечены *