Настройка регулятора для балансирующего робота

Автомат, адаптивный автомат ... разум

Настройка регулятора для балансирующего робота

Сообщение Radist » 18 авг 2024, 17:54

В самом начале скажу, что все нижеизложенное – это мое видение алгоритмов, чистая теория. Когда я дойду до практики – я дополню этот топик: что подтвердилось, а что нет. Казалось бы, зачем спешить? Придумал – так сперва проверь, а уж потом пиши. Но мне кажется, что именно такой порядок действий поможет мне меньше ошибаться.
Прежде чем переходить к регулятору, необходимо обсудить объект управления.
Типичный балансирующий робот является «перевернутым маятником», чем выше его центр тяжести – тем легче балансировать. Внизу робота обычно находятся пара двигателей с колесами. Чаще всего это простые двигатели с двумя контактами, которые крутятся при подаче напряжения, а при смене полярности меняют направление вращения. Двигатели эти зачастую применяются вместе с редукторами. Каждый двигатель управляется Н-мостом (таких драйверов очень много). Каждый мост имеет два управляющих сигнала – тут мы уже близко подходим к сути. Если оба сигнала одинаковые, то включаются либо нижние ключи моста, либо верхние. Это так называемый режим активного торможения. Если оба сигнала переводятся в третье состояние – получаем движение по инерции (у мотор-редукторов инерция очень маленькая). Самое интересное происходит, когда сигналы разные – это и приводит к вращению мотора и колеса. Меняем сигналы на противоположные – вращение тоже меняет направление. Есть несколько способов управления двигателями, но топик не об этом, поэтому я рассмотрю один из простых и часто использующихся способов. При этом способе один сигнал моста назовем «направление вращения», а второй сигнал будет с ШИМ. ШИМ бывает не инвертированным (пока таймер считает от нуля до границы – на выходе единица) и инвертированным (соответственно наоборот). То есть правило такое: когда сигнал «направление вращения» равен нулю – используем не инвертированный ШИМ. Для вращения колес в другую сторону используем инвертированный ШИМ. Это позволит иметь одинаковую скорость при одинаковых настройках ШИМ.
Говоря об объекте управления, обычно имеют в виду мощность, выдаваемую на объект. Мы тоже будем выдавать мощность на двигатель, но от этой мощности зависит скорость, а скорость зависит от числа, которое мы будем писать в регистр сравнения таймера. То есть по факту наш регулятор должен выдавать числа для регистра сравнения, данные об направлении вращения, и это все.
Перед тем, как описывать алгоритмы управления, я хотел бы определиться в терминах. Без этого будет не понятно, что я имею в виду. Я буду расписывать термины здесь по мере их появления в тексте топика. Рекомендую и вам сейчас их перескочить, а позже возвращаться к ним.
Термины и определения:
– уставка – заданное значение, которое должен поддерживать регулятор. В нашем случае это угол отклонения от вертикали. Наклон вперед положителен, наклон назад отрицателен;
– ошибка (рассогласование, невязка, отклонение) – это разность между уставкой и измеренным значением угла. Может быть отрицательной;
– ПИД-регулятор – регулятор, выходное воздействие которого складывается (с учетом знака) из трех составляющих. П – пропорциональная составляющая, коэффициент умножается на ошибку; И – интегральная составляющая (ошибки интегрируются (складываются) и умножаются на коэффициент И). Обычно этот коэффициент много меньше единицы, поэтому его называют временем интегрирования и делят на него; Д – дифференциальная составляющая (разность текущей ошибки и предыдущей ошибки умножается на коэффициент);
– первый дифференциал – разность текущей ошибки и ошибки на предыдущем шаге;
– второй дифференциал – разность текущего и предыдущего первых дифференциалов;
Вид регулятора.
Традиционно для задачи баланса используется ПИД-регулятор. Рассмотрим его составляющие отдельно.
Составляющая П.
Параметром ШИМ будет произведение коэффициента П и ошибки. Допустим, для начала, что П достаточно маленькое, произведение маленькое, ШИМ маленький, скорость маленькая. Робот начал падать, робот медленно поехал в сторону падения, но скорость маленькая, робот упал. Увеличиваем П. С какого-то момента робот не успевает упасть, но едет вперед или назад, пока не столкнется со стеной. Надо еще увеличить П. Скорость возросла, робот успевает компенсировать падение, но делает это долго, в результате робот катается туда/сюда с большой амплитудой. Еще увеличиваем П. Амплитуда катаний уменьшается. Достигнув минимума катаний, можно считать, что коэффициент П найден. Пока его оставим, и рассмотрим коэффициент И.
Составляющая И.
Эта составляющая позволяет накапливать ошибки, пока робот был наклонен. Но вот робот выпрямился, и двигаться никуда не надо. Но интегральная составляющая не равна нулю, а значит и скорость не будет равна нулю. Как бы это не было парадоксально, но на сегодняшний день я считаю, что интегральная составляющая в нашем регуляторе не нужна, я бы даже сказал, что она вредна. Ее типичное применение – на объектах управления с потерями (обычно это печки или холодильники).
Составляющая Д.
Для работы с дифференциальной составляющей нам нужно ввести понятие дифференциала (первый дифференциал). Чтобы можно было определять первый дифференциал, нам нужен буфер на два измеренных угла: текущее значение угла и предыдущее значение угла. Соответственно можно вычислить текущую ошибку и предыдущую ошибку. Их разность и есть первый дифференциал. Что же он делает? Допустим, мы приближаемся к уставке, а значит текущая ошибка положительная, но меньше, чем предыдущая ошибка (тоже положительная). Из меньшего вычитаем большее – первый дифференциал отрицательный. То есть скорость снижается, когда мы приближаемся к уставке. Это хорошо. А если мы удаляемся от уставки? Теперь текущая ошибка больше предыдущей, первый дифференциал положительный. Скорость увеличивается сильнее. То есть дифференциальная составляющая снижает скорость, когда мы приезжаем к уставке, и увеличивает скорость противодействия, когда робот начинает падать. Это очень хорошо.
Что можно сделать еще? Можно ввести понятие «второй дифференциал». А что нужно для его получения? Расширить буфер углов с двух до трех и ввести буфер на два значения первого дифференциала. Что дает нам второй дифференциал? Он анализирует скорость изменения скорости выхода на уставку. Если скорость постоянна, то второй дифференциал равен нулю. Если же скорость не постоянна, то второй дифференциал добавляет или убавляет скорость так, чтобы скорость приближения к уставке стала более постоянной.
Таким образом, мне кажется, что лучшим регулятором для задачи баланса будет ПДД регулятор.
Настройка регулятора.
Формула регулятора не очень сложная, но остается вопрос: как определить коэффициенты. Сразу скажу – я не знаю. Многие ученые предлагали способы настройки (эти способы названы их именами), они проводили сотни экспериментов и выводили эмпирические формулы. Наиболее близок такой способ:
– оставляем только П составляющую;
– добиваемся устойчивых колебаний;
– определяем частоту и амплитуду колебаний;
– вычисляем по эмпирическим формулам.
Проблема в том, что формулы приведены для П, ПИ и ПИД регуляторов. Для ПД формулы я не нашел (не говоря уж про ПДД). Поэтому эмпирические формулы не для нас. Кроме того, даже эти ученые говорят, что коэффициенты автонастройки – это лишь первый шаг к идеальным коэффициентам. Пропустим его и пойдем своим путем. Но чтобы было видно, в ту ли сторону мы идем, нужны какие-то критерии качества, а также какое-то средство визуализации.
Как выглядит хорошо настроенный регулятор? Регулятор должен хорошо работать и в статике (робот стоит и чуть видно, как «дрожит») и в динамике (мы толкаем робота, а он очень быстро устаканивается). Процесс устаканивания выглядит как апериодический процесс: несколько колебаний с затухающей амплитудой. Но как это увидеть? Иметь на борту графический дисплейчик? Расточительно, да и вывод на него достаточно медленный. Отправлять на ПК по радиоканалу? Тоже расточительно, способ не для всех. Записывать в свое озу мелким почерком? Это уже вариант, рассмотрим его подробнее.
Мы хотим анализировать угол наклона робота от времени. Ну допустим, на угол мы выделяем 2 байта (± 32 градуса в тысячных долях). Ну а время хранить не будем – данные идут последовательно. Скорость потока – 200 углов в секунду. 400 байт в секунду – ну на одну секунду и хватит, озу в микроконтроллерах не очень много. Явно этого мало, поэтому пойдем другим путем. Нам нужна амплитуда колебаний, а также время появления этой амплитуды. Для этого вводим системную переменную времени (данные об угле появляются по прерыванию каждые 5 мс, инкрементируем переменную времени в эти моменты – вот и наши часики). А для определения амплитуды делаем простой программный амплитудный детектор (для этого вводим переменную «максимум», изначально обнулена, и переменную «время»): пока угол не сменил знак, сравниваем его с максимумом, если меньше – ничего не делаем, если больше – пишем новый максимум и текущее относительное время. Когда угол сменит знак – эту парочку пишем в озу, затем обнуляем максимум. Если на время тоже выделим два байта, то на каждый период мы тратим 4 байта. А таких периодов легко может быть и 100 (хотя для нормально настроенного регулятора их будет не больше трех). Ну а потом эту информацию можно скинуть на ПК. Если есть способности к программированию на ПК, то можно написать программу-визуализатор, чтоб она на одном экране рисовала разным цветом разные графики изменения угла от времени (полезно также к архиву настройки добавить информацию о величине коэффициентов). Ну а кто не сможет написать такую программу – тому поможет карандаш и миллиметровка. Затем будет интересный трудоемкий процесс подбора коэффициентов. Как только вам понравится, как робот балансирует и реагирует на толчок – так и можно считать, что регулятор настроен.
Еще один момент – а какую уставку задать при работе регулятора? Ноль градусов? Это можно, если соблюдено одно условие – центр масс робота находится точно НАД осью колес И датчик положения при этом выдает угол ноль градусов. Эта ситуация возможна, но крайне маловероятна.
Допустим, чтобы центр масс робота находился над осью, робот должен отклониться на спину на угол -0.8°. Мы же ничего про его центр масс не знаем, уставку сделали 0. Регулятор вышел на уставку, но центр масс робота находится спереди, и он начинает валиться вперед. Регулятор снова его выводит в ноль и так далее. Выглядит это так, что робот едет вперед, скорее всего медленно. Что же делать? У нас робот – пусть он сам найдет нужный угол уставки, а мы ему поможем. У меня на моторах нет энкодеров, так что пока без них. Мы знаем, что при неправильном угле робот преимущественно едет в одну из сторон. Вводим следующие переменные: шаг изменения угла, переменная времени. Перед тем, как включить мотор ехать в одну из сторон, мы сбрасываем переменную времени, но перед сбросом накопленное число интегрируется в переменную времени (едем вперед – суммируем, едем назад – вычитаем). То есть шаг вперед, два назад, повторить. Со временем накопится некое число, а у нас есть граница – перешли ее, значит уезжаем в одну сторону. По стороне понятно, куда надо изменить угол. Угол меняется на наш шаг (еще нужна переменная направления). Если направление не изменилось, то шаг угла не меняется. Но вот мы подошли к правильному углу достаточно близко, а потом перепрыгнули через него. Это вилка правильного угла. Меняем переменную направления, шаг делим пополам, границу определения времени тоже уменьшаем вдвое. Такой вот дихотомией мы быстро найдем верную уставку. Чтобы вовремя остановиться, сделаем границу по величине шага – как только шаг стал достаточно маленьким – можно остановиться. И показать правильную уставку на устройстве вывода.
Как это будет выглядеть:
– начальная уставка равна нулю, шаг угла 0.5 градуса;
– через некоторое время робот поймет, что он чаще ехал вперед, значит робот наклонен вперед, и надо отклонить его назад. Угол становится -0.5 градуса;
– через какое-то время робот увидит, что все еще больше едет вперед;
– направление движения не изменилось, так что шаг не меняем. Угол стал –1 градус;
– теперь робот стал чаще ехать назад;
– направление поменялось, делим шаг пополам, границу срабатывания тоже. Угол становится -0.75 градуса;
– теперь снова едем вперед, направление снова поменялось, снова делим шаг попалам и границу тоже попалам. Угол стал -0.875;
– можно продолжать и далее, но важно вовремя остановиться, иначе попытка найти реальный угол утонет в шумах.
На этом пока все. Еще раз напомню, что я могу ошибаться. Когда появятся практические результаты – непременно ими поделюсь.
Аватара пользователя
Radist
 
Сообщения: 2253
Зарегистрирован: 01 июл 2009, 08:59
Откуда: Екатеринбург
прог. языки: асемблер AVR

Вернуться в Алгоритмы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

cron