Я намагаюся керувати моторизованим фейдером (лінійним потенціометром ковзання) за допомогою Arduino.
PID-контроль дає хороші результати для «стрибків» на певну цільову позицію, але відстеження пандусів - це проблема, вона зовсім не гладка. Рух дуже ривковий, що б я не намагався.
Ось графік опорного положення, вимірюваного положення та виходу двигуна при відстеженні пандуса:
А ось відео того самого тесту.
У комерційних системах, здається набагато більш гладкою, см це .
Детальніше :
Мотор-фейдер - це Альпи RSA0N11M9A0K . Для його управління я використовую Н-міст ST L293D , що живиться від регульованого 10 В постійного струму ( XL6009 ).
У Arduino UNO (ATmega328P) я використовую шпильки 9 і 10 з частотою ШІМ 31,372 кГц, щоб зробити його нечутливим (Timer1 з дозволом 1, TCCR1B = (TCCR1B & 0b11111000) | 0b001
).
Потенціометр проводиться між землею і 5 В, а склоочисник переходить до ADC0, як зазвичай.
Контролер :
я використовую простий PID-контролер з антивідступним режимом, який оновлюється зі швидкістю 1 кГц (Ts = 1e-3 s):
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 до входу, до сигналу управління, до похідної складової PID-контролера, але безрезультатно. Я також спробував знизити роздільну здатність аналогового входу, використовуючи гістерезис, щоб запобігти його переключенню між двома значеннями, коли нерухомий. Це, здається, ні на що не впливає. Збільшення кроку часу до 10 мс також не допомагає.
Я також спробував зробити ідентифікацію системи в MATLAB і спробував налаштувати її в Simulink (після цієї серії відео ). У мене з'явилася модель з придатністю 91%, але я не знав, як боротися з вхідними та вихідними нелінійностями моделі MATLAB, як вони впливають на настройку PID та як їх реалізувати на Arduino.
Остаточне, що я спробував, - це зробити два різних контролера: один для великих стрибків у опорному положенні та один для невеликих помилок під час відстеження пандуса. Це, здається, трохи допомагає, тому що тоді я можу збільшити інтегральний коефіцієнт під час відстеження, не збільшуючи простріл при стрибках.
Однак, збільшуючи інтегральний (і пропорційний) коефіцієнт посилення, мотор зараз завжди щось робить, навіть коли він повинен бути нерухомим, а еталон не змінюється. (Він насправді не рухається, але ви можете відчувати, що він вібрує.)
У мене практично немає похідних коефіцієнтів, тому що збільшення його вище, ніж 1e-4, здається, ще більше поштовху, і я не помічаю різниці між 0 і 1е-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.