Я пытаюсь управлять моторизованным фейдером (линейным скользящим потенциометром) с помощью Arduino.
ПИД-управление дает хорошие результаты для «прыжка» в определенную целевую позицию, но отслеживание рамп является проблемой, это не совсем плавно. Движение очень резкое, что бы я ни пытался.
Вот график эталонной позиции, измеренной позиции и мощности двигателя при отслеживании рампы:
И вот видео того же теста.
В коммерческих системах это выглядит намного более плавно, посмотрите на это .
Детали : Фейдер
двигателя - Альпы RSA0N11M9A0K . Для привода я использую H-мост ST L293D , питаемый от регулируемого источника питания 10 В постоянного тока ( XL6009 ).
На Arduino UNO (ATmega328P) я использую выводы 9 и 10 с частотой ШИМ 31,372 кГц, чтобы сделать его не слышимым (Timer1 с прескалером 1, TCCR1B = (TCCR1B & 0b11111000) | 0b001
).
Потенциометр подключен между землей и напряжением 5 В, а стеклоочиститель, как обычно, движется к ADC0.
Контроллер :
я использую простой ПИД-регулятор с анти-виндапом, который обновляется с частотой 1 кГц (Ts = 1e-3 с):
float update(int16_t input) {
int16_t error = setpoint - input;
int16_t newIntegral = integral + error;
float output = k_p * error
+ k_i * newIntegral * Ts
+ k_d * (input - previousInput) / Ts;
if (output > maxOutput)
output = maxOutput;
else if (output < -maxOutput)
output = -maxOutput;
else
integral = newIntegral;
previousInput = input;
return output;
}
Выход контроллера имеет значение от -127 до 127. Выход ШИМ генерируется следующим образом:
const int8_t knee = 48;
uint8_t activation(int8_t val) {
if (val == 0)
return 0;
else {
return map(val, 0, 127, 2 * knee, 255);
}
}
void writeMotor(int8_t val) {
if (val >= 0) {
analogWrite(forward, activation(val));
digitalWrite(backward, 0);
} else {
analogWrite(backward, activation(-val));
digitalWrite(forward, 0);
}
}
Я добавил 48 к 7-битному сигналу ШИМ, потому что именно здесь двигатель начинает двигаться с частотой 31 кГц, а затем я увеличил его до 8-битного числа (потому что именно этого analogWrite
ожидает функция):
Что я пробовал :
я пытался добавить фильтр EMA на вход, на управляющий сигнал, на производный компонент ПИД-регулятора, но безрезультатно. Я также попытался понизить разрешение аналогового входа, используя гистерезис, чтобы он не переключался между двумя значениями в стационарном режиме. Кажется, это ни на что не влияет. Увеличение шага по времени до 10 мс тоже не помогает.
Я также попытался выполнить идентификацию системы в MATLAB и попытался настроить ее в Simulink (после этой серии видео ). Я получил модель с подгонкой 91%, но я не знал, как справиться с нелинейностями ввода и вывода модели MATLAB, как они влияют на настройку ПИД-регулятора и как реализовать ее на Arduino.
Последнее, что я попробовал, - это создание двух разных контроллеров: один для больших прыжков в референтной позиции и один для небольших ошибок при отслеживании рампы. Это, кажется, немного помогает, потому что тогда я могу увеличить интегральный коэффициент при отслеживании, не увеличивая превышение при прыжке.
Однако, увеличивая интегральное (и пропорциональное) усиление, двигатель теперь всегда что-то делает, даже когда он должен быть неподвижным, и задание не меняется. (На самом деле он не двигается, но вы можете почувствовать его вибрацию.)
У меня практически нет производного усиления, потому что увеличение его выше, чем 1e-4, кажется, делает его еще более резким, и я действительно не замечаю никакой разницы между 0 и 1e-4.
Я предполагаю, что ему нужно больше энергии, чтобы преодолеть статическое трение, тогда динамическое трение меньше, поэтому он срабатывает, поэтому он двигает двигатель назад, заставляя его снова остановиться, затем ему снова нужно преодолеть статическое трение, он снова движется вперед. , и т.д.
Как коммерческие контролеры преодолевают эту проблему?
Мой опыт :
я учусь на третьем курсе бакалавриата по электротехнике, я прошел курсы по теории управления, цифровой обработке сигналов, LQR-контролю и т. Д., Поэтому у меня есть некоторые теоретические знания, но у меня возникают проблемы с применением всех этих теорий к эта система реального мира.
Изменить :
Я проверил измерения датчика разомкнутого контура, как рекомендовано Laptop2d, и я весьма удивлен результатами: при высоких частотах ШИМ в показаниях есть неприятные пики. На 490 Гц их нет.
И это при постоянном рабочем цикле, поэтому я не могу себе представить, какой шум я получаю, когда двигатель очень быстро меняет направление.
Поэтому мне придется найти способ отфильтровать этот шум, прежде чем я снова начну работать с контроллером.
Редактировать 2 :
Использование экспоненциального фильтра скользящего среднего было недостаточно, чтобы отфильтровать шум.
Я пробовал с полюсами в 0,25, 0,50 и 0,75. Малые полюса не имели большого эффекта, а более крупные полюсы добавляли слишком много задержки, поэтому мне пришлось снизить усиление, чтобы сохранить его стабильность, что привело к ухудшению общей производительности.
Я добавил конденсатор 0,1 мкФ через потенциометр (между стеклоочистителем и землей), и это, кажется, очистило его.
Пока это работает достаточно хорошо. А пока я читаю газету, опубликованную Тимом Уэскоттом .
Спасибо за вашу помощь.
This device is suitable for use in switching applications at frequencies up to 5 kHz.
Но электрические характеристики на странице 3 предполагают абсолютный максимум 690 кГц, если вы сложите все задержки. (нижние 4 строки) Лично я бы пошел намного медленнее, но я бы подумал, что 31 кГц должно быть достаточно ... если бы не примечание на странице 1.Ответы:
Система управления работает так же хорошо, как ее датчик, запустите разомкнутый контур датчика и удалите управляющий вход. Создайте свой собственный вход для датчика и медленно сдвиньте его (или найдите способ надежного скольжения), принимая данные о положении, чтобы убедиться, что это не датчик. Если датчик шумит, улучшите его характеристики, получив новый датчик или подключив его параллельно, или отфильтровав выходной сигнал датчика . Вам может понадобиться датчик с более высоким разрешением.
Если датчик не шумит, вам понадобится другой контур управления. PID являются системами первого порядка и не очень хороши в управлении скоростью.
источник
Вы правы в том, что проблема связана с трением или, возможно, сочетанием трения и люфта. Ваш график зависимости средней скорости от рабочего цикла для импульсов различной ширины характерен для системы с трением. В этом документе объясняется, что вы видите, и приведен сборник решений, которые с тех пор использовались для решения проблем. Вы не увидите их в своей инженерной программе, потому что их трудно анализировать; Вы должны в основном возиться с ними на индивидуальной основе, чтобы заставить их работать.
Я не знаю, что делают коммерческие контроллеры, хотя подозреваю, что существует множество решений. То, что я делал в прошлом с такими вещами, это когда сигнал привода двигателя от моего ПИД-регулятора падает ниже некоторого порогового значения (вероятно, от 60 до 70 отсчетов в вашем случае), я начинаю пульсировать привод двигателя с порога, с долгами цикл, который делает средний привод равным выходному сигналу ПИД. Я обычно использую для этого модулятор сигма-дельта-иша, потому что он может быть реализован в очень короткие строки, но вы можете использовать то, что вам подходит.
источник
Кажется, что большая часть шума исходит от сигнала привода ШИМ.
Вы пытались синхронизировать захват АЦП с циклом ШИМ? Большинство микроконтроллеров имеют способ запуска захвата АЦП по таймеру, поэтому вы всегда можете запустить в одной и той же точке цикла.
Для наименьшего шума оптимальное положение выборки должно быть прямо перед включением питания двигателя, потому что тогда любые пики имели самое длительное время для установления. Но независимо от того, какая позиция, синхронизация захвата уменьшит пики, потому что величина смещения останется примерно одинаковой в той же точке цикла ШИМ.
источник
Вы можете отфильтровать шум датчика (или любое другое шумовое измерение / переменную) в коде примерно так (фильтрация нижних частот):
источник