Зачем мне это было нужно?
Коротко: хотел расширить свой ЧПУ станок, но что-то пошло не так…
Неудачные попытки
Проект занял почти два года проб и ошибок, перепроектирования, ожидания деталей и неполно прожитых выходных, чтобы желающие повторить сэкономили себе время и нервы, считаю нужным рассказать о неудачных решениях.
- гироскоп (MPU6050) вместо энкодера — принципиально ничего против, но датчик должен располагаться на вращающемся стержне, это вносит непредсказуемое воздействие и невозможность прокрутить стержень несколько раз вокруг оси.
- абсолютный энкодер — если это потенциометр, то шум в измерения вносит даже движение проводов (в основном из-за контактов в arduino), 10-ти битный АЦП — это все же мало; если это более дорогой датчик, то считывание происходит по последовательному интерфейсу, а это вносит задержку в систему особенно в совокупности с шаговым мотором.
- нежесткость системы — в какой-то момент я брал алюминиевую трубку с грузом на конце, при колебаниях каретки, в ней самой начинались сильные колебания, и тут же было непонятно какую систему мы стабилизуем. Надо стремиться к тому, чтобы физическая система была максимально приближена тому, что смоделировано.
- трение — этим явлением часто пренебрегают, я старался уменьшить его, используя большие колеса каретки и V-slot профили, в отличие от рельсов с ползунками с маленькими шариками, т.к. трение качения обратно пропорционально радиусу.
- использование шагового двигателя — много времени потратил, пытаясь пойти этим путем, вводит в заблуждение упрощение формул (фактически мы сразу управляем ускорением основания маятника) и простота конструкции (можно забыть про трение в рельсе, энкодер мотора, если предположить, что шаги мотор не пропускает), но… Чтобы точно управлять скоростью, время между шагами должно исчисляться десятками микросекунд, значит о выводе состояния в консоль можно забыть. Без обратной связи нельзя быть уверенным, что мотор не пропустил шаги и скорость действительно такая, как система думает. Не утверждаю, что это тупиковое решение, если кому-то удастся стабилизировать маятник шаговым мотором, буду рад на это взглянуть.
Свободный маятник
Для полноты картины, смоделируем маятник на свободной каретке без трения.
Уравнения движения можно получить дифференцированием лагранжиана по обобщенным координатам. Получим следующие уравнения:
из которых можно найти, как меняется вектор состояния:
и смоделировать систему. Код здесь.
Почему система неустойчива?
Здравый смысл и визуализация нам подсказывают, что маятник сам по себе стоять не будет. Но как в этом убедиться математически?
В общем виде линеаризованная система и решение выглядят следующим образом:
Экспонента в степени матрицы выглядит понятней, если перейти в систему координат из собственных векторов, тогда матрица будет диагональной(), и экспонента будет иметь вид:
Теперь видно, при наличии собственных значений () с положительной действительной частью, соответствующая компонента вектора состояния будет стремиться в бесконечность, и система развалится. Вышесказанное касается непрерывных систем, более подробно про устойчивость рассказывается в этой видео-лекции.
Проверим так ли это, для обратного маятника. Линеаризуем нашу систему около положения равновесия при :
Ненулевые собственные значения имеют вид , таким образом мы убедились в неустойчивости.
Добавляем обратную связь
Теперь на каретку будет действовать сила , одно из уравнений перепишется в виде: , и линеаризованная система примет вид:
Теперь система () стала управляемой, в этом можно убедиться, проверив, что ранг матрицы равен размерности вектора состояния, т.е. 4. Для удержания маятника в вертикальном положении я использовал линейно-квадратичный регулятор состояния, т.е. управление (u или f) есть произведение вектора состояния на вектор параметров, которые находятся один раз минимизацией квадратичного функционала. Код симуляции здесь.
Управление двигателем
Теперь нужно управлять мотором постоянного тока, он содержит много параметров, которых я не знаю, поэтому я принял его за «черный ящик», описываемый следующими уравнениями с учетом трения:
Про вывод уравнений и оценку параметров можно прочитать здесь. Ниже приведу мои графики разгона мотора с кареткой в зависимости от напряжения (в реальности на выходе контроллера ШИМ-сигнал) и подогнанные кривые.
Коэффициенты модели я также нашел перебором, код.
Таким образом, регулятор дает нам требуемое ускорение, а из 2-го уравнения, зная все константы, найдем напряжение.
Собираем реальное устройство
Теперь у нас есть все знания, чтобы собрать и стабилизировать маятник. Я использовал следующее железо:
- Arduino Mega 2560 — не UNO, потому что для двух энкодеров нужно 4 пина для прерываний
- Энкодер для маятника — OMRON E6B2-CWZ6C 2500 пульсов на оборот — дает нам угол, вычисляем угловую скорость, разрешение достаточно высокое, поэтому хватило конечных разностей без сглаживания и усреднения
- Энкодер для мотора — LPD3806-600BM-G5-24C 600 пульсов на оборот — дает положение каретки, вычисляем скорость
- DC-мотор на 12V с редуктором 5:1
- Драйвер мотора 10Amp 5V-30V
Таким образом мы явно измеряем угол маятника, положение каретки, вычисляем угловую скорость маятника и скорость каретки — получаем полное состояние, параметры регулятора я нашел этим скриптом. К удивлению все достаточно быстро заработало как есть. Результатом я доволен, стоит и даже стакан держит!
Код для Arduino находится здесь
Что удалось усовершенствовать по сравнению с многими вариантами, которые можно найти на youtube — этот маятник тихий, потому что ШИМ настроен вне слухового диапазона, и используются пластиковые колеса.
Теперь эта задача выглядит, как лабораторная работа: измерить параметры мотора и найти коэффициенты регулятора, попутно разбираясь в происходящем.
Что дальше?
Планирую продуктизовать маятник: сделать раскачивание, избавиться от мотка проводов, сделать shield у удобными разъемами, чтобы не стыдно было подарить в какую-нибудь школу или музей. Если кто-то желает присоединиться, буду рад, есть еще много амбициозных идей.
Ссылки
- Подробное описание задачи об обратном маятнике
- Разжёвываем линейно-квадратичный регулятор для управления перевёрнутым маятником — эта статья сэкономила мне много времени при постройке моего маятника
- Отличные видео-лекции по ТАУ
Спасибо за внимание!
Комментарии (21)
lingvo
28.10.2019 23:14Ключевое слово тут — модель и моделирование. Такие задачки как раз удобно решать на модели в симуляции, а потом, когда все отлажено, генерить готовый код для прошивки. Только контроллер должен быть реал-таймовый, а с Ардуино могут быть проблемы в этом месте.
IronHead
29.10.2019 12:49А чем в вашем понятии реал-таймовый контроллер отличается от ардуино? Точнее чего нет в ардуино, что оно не может выполнять роль реал-тайм контроллера по вашей терминологии?
lingvo
29.10.2019 15:25Реал-таймовый контроллер — это тот, который способен выполнять управляющую программу в режиме жесткого реального времени. Если Ардуино так может -то пожалуйста.
Но судя по программе от автора, где производится пересчет от предыдущего времени запуска, функция loop() вызывается не-периодически и вообще непонятно с каким интервалом, а следовательно такая система не соответствует требованиям реал-тайма, так как время отклика данной системы ничем не ограничено, а джиттер огромен.
Чтобы сделать ее реалтаймовой надо бы:
- функция loop должна вызываться по прерыванию таймера или с определенной частотой и гарантированно выполняться за время до следующего прерывания.
- период вызова должен быть выбран таким, чтобы удовлетворял критерию устойчивости и регулируемости системы (чем меньше, тем лучше, ограничение в производительности процессора и I/O)
- все функции, которые могут привести к не детерменируемому времени исполнения функции, должны быть убраны из этого кода (например printы)
- все второстепенные функции должны иметь меньший приоритет, чем вызов управляющей функции и не прерывать ее исполнение.
- Если функция loop не выполняется за указанное время, ватчдог должен сбрасывать контроллер и приводить систему в устойчивое состояние — это отказ.
Применив этот подход, вам будет:
а) легче писать и отлаживать программы для управления такими вещами, и они станут соответствовать моделям (так как модели обычно моделируются с фиксированным шагом симуляции, и у автора, вроде тоже)
б) в железе все начнет работать гораздо лучше, вы сможете повысить частоту работы контроллера, а следовательно сделать его более устойчивым, уменьшить время реакции.
Если парадигма программирования Arduino так не позволяет сделать — то вот вам и проблема.
IronHead
29.10.2019 15:31+1Отлично. Замечания по правилам написания ПО вы написали верно. А ардуино как контроллер (железяка) то чем не угодил так и не объяснили?
lingvo
29.10.2019 15:47-2Контроллер для меня — это железо + софт. Если там есть возможность забебехать такой таймер, есть ватчдог, а ввод/вывод сделан на детерминированных функциях/регистрах, то железом может быть и Ардуино.
livsius
29.10.2019 01:09Было бы круто запрограммировать еще режим маятника Капицы, когда никакой обратной связи нет, подвес просто вибрирует, отчего перевернутое положение становится устойчивым.
eugenk
29.10.2019 11:42Спасибо. Очень качественное изложение. И очень качественный гитхаб проекта. Скачал себе немного поиграться :)
DirectX
29.10.2019 15:48Кстати по данной теме есть еще интересный пример — обратный маятник Капицы ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%8F%D1%82%D0%BD%D0%B8%D0%BA_%D0%9A%D0%B0%D0%BF%D0%B8%D1%86%D1%8B, когда равновесие в верхней точке становится устойчивым при приложении колебаний к точке подвеса в вертикальном направлении. Это как раз иллюстрирует пример из приведённого видео, когда за счёт некоторых доработок неустойчивую систему можно скорректировать youtu.be/h7nJ6ZL4Lf0?list=PLMrJAkhIeNNR20Mz-VpzgfQs5zrYi085m&t=464
Alexey_mosc
29.10.2019 17:13-1Это же физическая модель популярного бенчмарка для задачи обучения с подкреплением. CartPole. Там суть в том (если вы вдруг не интересовались), что, грубо говоря, по фотографии этой тележки (снимок с экрана / пиксели) НС дает команду влево/вправо/на месте. То есть все происходит внутри нейросетевой функции.
SlavaT
29.10.2019 17:48Я бы посмотрел в учебники типа "Автоматизированный электропривод типовых производственных механизмов и технологических комплексов", там и без обратной связи есть автоматизированные схемы управления и уравнения двигателей разнообразных.
prilichny
29.10.2019 17:48оно собиралось исключительно в учебных целях? чтобы теорию с практикой сопоставить? или для чего-то еще?
Arastas
Добро пожаловать в мир ТАУ, тут интересно. :)
zjor Автор
я еще хотел сделать reinforcement learning, чтобы он сам вставать научился, может в будущем :)
Undiabler
Сразу об этом подумал. Работал с таким примером маятника Self-Contained Cartpole Swingup Task
решаемым, предложенным в том же репозитории, методом эволюционирующих сетей. Учитывая что у вас физическое устройство уже собрано интересно натренировать модель и дать в управление реально устройство.
zjor Автор
класс! можно попробовать, спасибо за ссылку.
tas
Вспомнилась похожая тема: habr.com/ru/post/206980