Я пытаюсь управлять моторизованным фейдером (линейным скользящим потенциометром) с помощью 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.