Содержание
Давайте поговорим о том как можно использовать Ардуино для создания робота, который балансирует как Сигвей.
Сигвей от англ. Segway – двухколесное средство передвижения стоя, оснащенное электроприводом. Еще их называют гироскутерами или электрическими самокатами.
Вы когда-нибудь задумывались, как работает Сигвей? В этом уроке мы постараемся показать вам, как сделать робота Ардуино, который уравновешивает себя точно так же, как Segway.
Как работает балансировка?
Чтобы сбалансировать робота, двигатели должны противодействовать падению робота. Это действие требует обратной связи и корректирующих элементов. Элемент обратной связи – гироскоп-акселерометр MPU6050, который обеспечивает как ускорение, так и вращение во всех трех осях (основы MP26050 I2C). Ардуино использует это, чтобы знать текущую ориентацию робота. Корректирующим элементом является комбинация двигателя и колеса.
В итоге должен получиться примерно такой друг:
Схема робота
Сначала подключите MPU6050 к Ардуино и проверьте соединение, используя коды в этом учебном руководстве по интерфейсу IMU. Если данные теперь отображаются на последовательном мониторе, вы молодец!
Продолжайте подключать остальные компоненты, как показано выше. Модуль L298N может обеспечить +5В, необходимый для Ардуино, если его входное напряжение составляет +7В или выше. Тем не менее, мы выбрали отдельные источники питания для двигателя и схемы.
Создание робота
Корпус робота изготовлен в основном из акрилового пластика с двумя редукторными двигателями постоянного тока:
Основная печатная плата, состоящая из Arduino Nano и MPU6050:
Модуль драйвера двигателя L298N:
Мотор редуктора постоянного тока с колесом:
Самобалансирующийся робот по существу является перевернутым маятником. Он может быть лучше сбалансирован, если центр массы выше относительно колесных осей. Высший центр масс означает более высокий момент инерции массы, что соответствует более низкому угловому ускорению (более медленное падение). Вот почему мы положили батарейный блок на верх. Однако высота робота была выбрана исходя из наличия материалов 🙂
Завершенный вариант самостоятельно балансирующего робота можно посмотреть на рисунке выше. В верхней части находятся шесть Ni-Cd-батарей для питания печатной платы. В промежутках между моторами используется 9-вольтовая батарея для драйвера двигателя.
Теория
В теории управления, удерживая некоторую переменную (в данном случае позицию робота), требуется специальный контроллер, называемый ПИД (пропорциональная интегральная производная). Каждый из этих параметров имеет «прирост», обычно называемый Kp, Ki и Kd. PID обеспечивает коррекцию между желаемым значением (или входом) и фактическим значением (или выходом). Разница между входом и выходом называется «ошибкой».
ПИД-регулятор уменьшает погрешность до наименьшего возможного значения, постоянно регулируя выход. В нашем самобалансирующем роботе Arduino вход (который является желаемым наклоном в градусах) устанавливается программным обеспечением. MPU6050 считывает текущий наклон робота и подает его на алгоритм PID, который выполняет вычисления для управления двигателем и удерживает робота в вертикальном положении.
PID требует, чтобы значения Kp, Ki и Kd были настроены на оптимальные значения. Инженеры используют программное обеспечение, такое как MATLAB, для автоматического вычисления этих значений. К сожалению, мы не можем использовать MATLAB в нашем случае, потому что это еще больше усложнит проект. Вместо этого мы будем настраивать значения PID. Вот как это сделать:
- Сделайте Kp, Ki и Kd равными нулю.
- Отрегулируйте Kp. Слишком маленький Kp заставит робота упасть, потому что исправления недостаточно. Слишком много Kp заставляет робота идти дико вперед и назад. Хороший Kp сделает так, что робот будет совсем немного отклоняться назад и вперед (или немного осциллирует).
- Как только Kp установлен, отрегулируйте Kd. Хорошее значение Kd уменьшит колебания, пока робот не станет почти устойчивым. Кроме того, правильное Kd будет удерживать робота, даже если его толькать.
- Наконец, установите Ki. При включении робот будет колебаться, даже если Kp и Kd установлены, но будет стабилизироваться во времени. Правильное значение Ki сократит время, необходимое для стабилизации робота.
Поведение робота можно посмотреть ниже на видео:
Код Ардуино самобалансирующего робота
Нам понадобилось четыре внешних библиотеки, для создания нашего робота. Библиотека PID упрощает вычисление значений P, I и D. Библиотека LMotorController используется для управления двумя двигателями с модулем L298N. Библиотека I2Cdev и библиотека MPU6050_6_Axis_MotionApps20 предназначены для чтения данных с MPU6050. Вы можете загрузить код, включая библиотеки в этом репозитории.
Значения Kp, Ki, Kd могут работать или не работать. Если они этого не делают, выполните шаги, описанные выше. Обратите внимание, что наклона в коде установлен на 173 градуса. Вы можете изменить это значение, если хотите, но обратите внимание, что это угол наклона, которым должен поддерживаться роботом. Кроме того, если ваши двигатели слишком быстры, вы можете отрегулировать значения motorSpeedFactorLeft и motorSpeedFactorRight.
Давайте поговорим о том как можно использовать Ардуино для создания робота, который балансирует как Сигвей.
Сигвей от англ. Segway – двухколесное средство передвижения стоя, оснащенное электроприводом. Еще их называют гироскутерами или электрическими самокатами.
Вы когда-нибудь задумывались, как работает Сигвей? В этом уроке мы постараемся показать вам, как сделать робота Ардуино, который уравновешивает себя точно так же, как Segway.
Как работает балансировка?
Чтобы сбалансировать робота, двигатели должны противодействовать падению робота. Это действие требует обратной связи и корректирующих элементов. Элемент обратной связи – гироскоп-акселерометр MPU6050, который обеспечивает как ускорение, так и вращение во всех трех осях (основы MP26050 I2C). Ардуино использует это, чтобы знать текущую ориентацию робота. Корректирующим элементом является комбинация двигателя и колеса.
В итоге должен получиться примерно такой друг:
Схема робота
Сначала подключите MPU6050 к Ардуино и проверьте соединение, используя коды в этом учебном руководстве по интерфейсу IMU. Если данные теперь отображаются на последовательном мониторе, вы молодец!
Продолжайте подключать остальные компоненты, как показано выше. Модуль L298N может обеспечить +5В, необходимый для Ардуино, если его входное напряжение составляет +7В или выше. Тем не менее, мы выбрали отдельные источники питания для двигателя и схемы.
Создание робота
Корпус робота изготовлен в основном из акрилового пластика с двумя редукторными двигателями постоянного тока:
Основная печатная плата, состоящая из Arduino Nano и MPU6050:
Модуль драйвера двигателя L298N:
Мотор редуктора постоянного тока с колесом:
Самобалансирующийся робот по существу является перевернутым маятником. Он может быть лучше сбалансирован, если центр массы выше относительно колесных осей. Высший центр масс означает более высокий момент инерции массы, что соответствует более низкому угловому ускорению (более медленное падение). Вот почему мы положили батарейный блок на верх. Однако высота робота была выбрана исходя из наличия материалов 🙂
Завершенный вариант самостоятельно балансирующего робота можно посмотреть на рисунке выше. В верхней части находятся шесть Ni-Cd-батарей для питания печатной платы. В промежутках между моторами используется 9-вольтовая батарея для драйвера двигателя.
Теория
В теории управления, удерживая некоторую переменную (в данном случае позицию робота), требуется специальный контроллер, называемый ПИД (пропорциональная интегральная производная). Каждый из этих параметров имеет «прирост», обычно называемый Kp, Ki и Kd. PID обеспечивает коррекцию между желаемым значением (или входом) и фактическим значением (или выходом). Разница между входом и выходом называется «ошибкой».
ПИД-регулятор уменьшает погрешность до наименьшего возможного значения, постоянно регулируя выход. В нашем самобалансирующем роботе Arduino вход (который является желаемым наклоном в градусах) устанавливается программным обеспечением. MPU6050 считывает текущий наклон робота и подает его на алгоритм PID, который выполняет вычисления для управления двигателем и удерживает робота в вертикальном положении.
PID требует, чтобы значения Kp, Ki и Kd были настроены на оптимальные значения. Инженеры используют программное обеспечение, такое как MATLAB, для автоматического вычисления этих значений. К сожалению, мы не можем использовать MATLAB в нашем случае, потому что это еще больше усложнит проект. Вместо этого мы будем настраивать значения PID. Вот как это сделать:
- Сделайте Kp, Ki и Kd равными нулю.
- Отрегулируйте Kp. Слишком маленький Kp заставит робота упасть, потому что исправления недостаточно. Слишком много Kp заставляет робота идти дико вперед и назад. Хороший Kp сделает так, что робот будет совсем немного отклоняться назад и вперед (или немного осциллирует).
- Как только Kp установлен, отрегулируйте Kd. Хорошее значение Kd уменьшит колебания, пока робот не станет почти устойчивым. Кроме того, правильное Kd будет удерживать робота, даже если его толькать.
- Наконец, установите Ki. При включении робот будет колебаться, даже если Kp и Kd установлены, но будет стабилизироваться во времени. Правильное значение Ki сократит время, необходимое для стабилизации робота.
Поведение робота можно посмотреть ниже на видео:
Код Ардуино самобалансирующего робота
Нам понадобилось четыре внешних библиотеки, для создания нашего робота. Библиотека PID упрощает вычисление значений P, I и D. Библиотека LMotorController используется для управления двумя двигателями с модулем L298N. Библиотека I2Cdev и библиотека MPU6050_6_Axis_MotionApps20 предназначены для чтения данных с MPU6050. Вы можете загрузить код, включая библиотеки в этом репозитории.
Значения Kp, Ki, Kd могут работать или не работать. Если они этого не делают, выполните шаги, описанные выше. Обратите внимание, что наклона в коде установлен на 173 градуса. Вы можете изменить это значение, если хотите, но обратите внимание, что это угол наклона, которым должен поддерживаться роботом. Кроме того, если ваши двигатели слишком быстры, вы можете отрегулировать значения motorSpeedFactorLeft и motorSpeedFactorRight.
Мне давно не давало покоя желание рассчитать какой-нибудь достаточно сложный механизм и воплотить его жизнь.
Выбор пал на задачу об обратном маятнике. Итог на видео:
Математическая модель
Я не буду приводить вывод уравнений движения, все таки это третий курс института. Для тех же, кому интересен вывод, в конце статьи ссылка, где он описан подробнее.
Систему представим в следующем виде:
Маятник это масса mp прикрепленная на конце невесомого стержня длины l. На другой конец стержня прикреплен двигатель, развивающий максимальный момент Mk и передающий его на колесо массой mw и радиусом r.
Задача управления — стабилизировать маятник в вертикальном положении и возвращать в начальное положение колесо.
Уравнения движения, описывающие обратный маятник, представимы в следующем виде:
Они кажутся довольно неприятными, но сам робот о них ничего не знает, а управление использует линеаризованную модель, то есть такую:
Синтезирование управления
Завидую людям, у которых работает PID-регулятор. Я потратил несколько часов на подгонку его коэффициентов, но так и не сумел добиться стоящего результата. Научный руководитель посоветовал воспользоваться линейно-квадратичным регулятором(вики). Этот регулятор, в отличие от PID-регулятора, представляет собой просто произведение своих коэффициентов на ошибки по каждой координате. Никаких дискретных аналогов производной и интеграла. Однако для его вычисления нужна модель системы и умение решать уравнение Риккати, ну или Matlab.
В матлабе расчет регулятора представляет собой такой набор команд:
Здесь матрицы A и B — соответствующие матрицы из линеаризованной модели с подставленными значениями реального робота.
Матрица Q определяет на сколько нужно штрафовать систему за отклонение от начала координат, заметьте, в нашем случае в координаты входят скорости.
Матрица R определяет на сколько нужно штрафовать систему за растрату энергии управлением.
В переменной K будут лежать коэффициенты регулятора.
Симуляция
В Matlab simulink можно легко эмулировать систему, если кому-нибудь необходимо ссылка на репозитарий с математической моделью в конце статьи. Здесь же я только приведу графики.
Угол отклонения маятника:
Угол отклонения колеса:
Момент двигателя:
Реализация в железе
Сам каркас робота это алюминиевые профиля 12мм и 14мм, они входят друг в друга. Соединены заклепками. Электроника прикреплена на кусок стеклотекстолита в форме буквы T. Моторы так же прикреплены через стеклотекстолитовый переходник.
Изначально я пытался использовать такие моторы:
Их крутящий момент 2,2кг*см или 0.2Нм. Исходя из симуляции нам нужно гораздо больше, поэтому были выбраны другие моторы:
ссылка на производителя
Максимальный крутящий момент 14кг*см или 1.4Нм. Тока они потребляют до 5A, поэтому популярный у ардуинщиков L293D тут не подойдет.
Для определения угла и угловой скорости используется IMU — гироскоп и акселерометр. У меня завалялась плата с гироскопом L3G и акселерометром с магнетометром LSM303. Подобных плат очень много и я не стану приводить код получения значений сенсоров. Однако показания датчиков нужно отфильтровать, так как гироскоп постоянно уходит, а акселерометр шумит и сильно врет, если робот начинает двигаться не меняя угла.
Используют разные фильтры, но наиболее популярны фильтр Калмана и RC-фильтр (complementary filter). Я использую такой код:
Работает не идеально, но достаточно хорошо для данной задачи.
Следующий сенсор — квадратурный энкодер на моторе. Он генерирует прямоугольные импульсы на 2х своих выводах:
Считать их можно либо прерываниями, либо считыванием значений в цикле. На arduino playground есть замечательная статья с примерами кода.
Осталось получить угловую скорость колеса. Тут на помощь приходит школьная формула пройденное расстояние/затраченное время.
ToPhiRad переводит количество тиков энкодера в угол колеса, мой энкодер выдает около 2240 тиков на оборот. Чтобы получить угол нужно умножить тики на 2 Пи и разделить на их количество при полном обороте колеса.
Показания сенсоров поступают в LQR регулятор:
Коэффициенты взяты из Matlab, правда для большей стабильности я подправил 2 первых коэффициента.
Мой драйвер, вернее его библиотека, принимает значения от -400 до 400. Я предположил, что на 400 он выдает на мотор 12В, т.е. мотор развивает максимальный момент (1.4Нм). Разделив 400 на 1.4 получаем коэффициент перевода из Нм, которые выдает LQR, в значения, понятные драйверу.
Просто стабилизировать робота в одной точке не очень интересно, поэтому к нему добавился BT-модуль HC-05. Модуль подключается к серийному порту микроконтроллера. Он работает на 3.3В, а arduino на 5В, поэтому подключать принимающий вход модуля надо через делитель напряжения. Вот схема подключения:
Во время цикла микроконтроллер опрашивает модуль на предмет символов:
В конечном итоге показания сенсоров поступают в регулятор, а его управление и воздействие пользователя поступают на моторы:
Раз в 50 миллисекунд посылается телеметрия-угол робота:
Добавляем радиоуправление
Управлять будем с телефона под android.
При запуске приложения попросим пользователя выбрать к кому подключаться, bt-модуль должен быть уже сопряжен с телефоном (стандартный код 1234).
После выбора устройства подключимся к нему:
После подключения стартует поток, который занимается коммуникацией между приложением и роботом:
Поток посылает сообщение основному потоку приложения через Handler, который определяется так:
balancerView это потомок класса SurfaceView, он занимается выводом на экран текущего положения робота.
Вот его метод перерисовки:
Команды роботу посылаются при появлении событий onTouch, чтобы можно было управлять роботом удерживая кнопку.
Заключение
Самое приятное во всей постройке это то, что математическая модель сошлась с физической реализацией. Сама постройка железки не представляет из себя какой-то сложности, однако подбор правильных моторов, высоты робота, массы груза сверху и синтезирование управления довольно интересная задача.
Как и обещал вывод уравнений движения перевернутого маятника на колесе: Вывод уравнений и немного о постройке
репозитарий на GitHub