Próbuję sterować zmotoryzowanym suwakiem (potencjometrem liniowym) za pomocą Arduino.
Kontrola PID daje dobre wyniki „skakania” do określonej pozycji docelowej, ale śledzenie ramp jest problemem, wcale nie jest płynne. Ruch jest bardzo gwałtowny, bez względu na to, czego próbuję.
Oto wykres pozycji odniesienia, zmierzonej pozycji i mocy silnika podczas śledzenia rampy:
A oto wideo z tego samego testu.
W systemach komercyjnych wydaje się to znacznie płynniejsze, zobacz to .
Szczegóły :
Motor fader to Alps RSA0N11M9A0K . Do jego napędzania używam mostka H ST L293D , zasilanego z regulowanego zasilacza 10 V DC ( XL6009 ).
Na Arduino UNO (ATmega328P) używam pinów 9 i 10, o częstotliwości PWM 31,372 kHz, aby uczynić go niesłyszalnym (Timer 1 z preskalatorem 1 TCCR1B = (TCCR1B & 0b11111000) | 0b001
).
Potencjometr jest podłączony między masą a 5 V, a wycieraczka przechodzi do ADC0, jak zwykle.
Kontroler :
Używam prostego regulatora PID z funkcją zapobiegającą zwijaniu, który aktualizuje się z częstotliwością 1 kHz (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;
}
Wyjście sterownika ma wartość od -127 do 127. Wyjście PWM jest generowane w następujący sposób:
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);
}
}
Dodałem 48 do 7-bitowego sygnału PWM, ponieważ w tym miejscu silnik zaczyna się poruszać przy 31 kHz, a następnie skaluję go do liczby 8-bitowej (ponieważ tego analogWrite
oczekuje funkcja):
Co próbowałem :
próbowałem dodać filtr EMA do wejścia, do sygnału sterującego, do pochodnej kontrolera PID, ale bezskutecznie. Próbowałem również obniżyć rozdzielczość wejścia analogowego, używając histerezy, aby powstrzymać ją przed przełączaniem się między dwiema wartościami podczas postoju. Wydaje się, że to nic nie wpływa. Wydłużenie kroku czasowego do 10 ms również nie pomaga.
Próbowałem również przeprowadzić identyfikację systemu w MATLAB i próbowałem dostroić ją w Simulink (po tej serii filmów ). Mam model z dopasowaniem wynoszącym 91%, ale nie wiedziałem, jak poradzić sobie z nieliniowościami wejściowymi i wyjściowymi modelu MATLAB, jak wpływają one na strojenie PID i jak zaimplementować je na Arduino.
Ostatnią rzeczą, której próbowałem, jest wykonanie dwóch różnych kontrolerów: jeden do dużych skoków w pozycji odniesienia i jeden do małych błędów podczas śledzenia rampy. Wydaje się to nieco pomóc, ponieważ wtedy mogę zwiększyć współczynnik całkowania podczas śledzenia, bez zwiększania przekroczenia podczas skoku.
Jednak zwiększając całkę (i proporcjonalność) wzmocnienia, silnik zawsze robi coś, nawet gdy powinien być nieruchomy, a wartość zadana nie zmienia się. (Nie porusza się tak naprawdę, ale można poczuć, że wibruje.)
Nie mam praktycznie żadnego wzmocnienia pochodnej, ponieważ zwiększenie go powyżej 1e-4 wydaje się jeszcze bardziej nieprzyjemne i naprawdę nie zauważam żadnej różnicy między 0 a 1e-4.
Domyślam się, że potrzebuje więcej mocy, aby pokonać tarcie statyczne, a następnie tarcie dynamiczne jest mniejsze, więc przekracza, więc napędza silnik do tyłu, powodując jego zatrzymanie, a następnie musi ponownie pokonać tarcie statyczne, ponownie strzela do przodu itp.
Jak kontrolery komercyjne pokonują ten problem?
Moje doświadczenie :
Jestem na trzecim roku licencjackim z inżynierii elektrycznej, uczestniczyłem w kursach teorii teorii, cyfrowego przetwarzania sygnałów, kontroli LQR itp., Więc mam pewne podstawy teoretyczne, ale mam problem z zastosowaniem wszystkich tych teorii do ten rzeczywisty system.
Edycja :
Przetestowałem pomiary czujnika w otwartej pętli, zgodnie z zaleceniem laptop2d, i jestem dość zaskoczony wynikami: przy wysokich częstotliwościach PWM występują nieprzyjemne piki w odczytach. Przy 490 Hz nie ma żadnych.
I to jest przy stałym cyklu pracy, więc nie wyobrażam sobie, jaki hałas mam, gdy silnik bardzo szybko zmienia kierunek.
Będę musiał znaleźć sposób na odfiltrowanie tego szumu, zanim zacznę ponownie pracować na kontrolerze.
Edycja 2 :
Zastosowanie wykładniczego filtra średniej ruchomej nie było wystarczające do odfiltrowania szumu.
Próbowałem z biegunami w 0,25, 0,50 i 0,75. Małe słupy nie miały większego efektu, a większe bieguny dodawały zbyt wiele opóźnień, więc musiałem obniżyć zyski, aby zachować stabilność, co spowodowało gorszą ogólną wydajność.
Dodałem kondensator 0,1 µF do potencjometru (między wycieraczką a ziemią) i wydaje się, że to oczyszcza.
Na razie działa wystarczająco dobrze. W międzyczasie czytam artykuł napisany przez Tima Wescotta .
Dziękuję wszystkim za pomoc.
This device is suitable for use in switching applications at frequencies up to 5 kHz.
Charakterystyka elektryczna na stronie 3 sugeruje absolutne maksimum 690 kHz, jeśli dodasz wszystkie opóźnienia. (dolne 4 wiersze) Osobiście poszedłbym o wiele wolniej, ale uważam, że 31 kHz powinno być wystarczające ... gdyby nie notatka na stronie 1.Odpowiedzi:
System sterowania jest tak dobry, jak jego czujnik, uruchom czujnik w otwartej pętli i usuń wejście sterujące. Utwórz własne dane wejściowe do czujnika i przesuwaj go powoli (lub znajdź sposób, aby powoli i niezawodnie go przesuwać), jednocześnie pobierając dane pozycji, aby upewnić się, że nie jest to czujnik. Jeśli czujnik jest głośny, popraw jego działanie, uzyskując nowy czujnik lub równolegle go lub filtrując moc wyjściową czujnika . Może być potrzebny czujnik o wyższej rozdzielczości.
Jeśli czujnik nie jest głośny, musisz uzyskać inną pętlę sterowania. PID to systemy pierwszego rzędu i niezbyt dobre w kontroli stawek.
źródło
Masz rację, że przyczyną problemu jest tarcie lub połączenie tarcia i luzu. Wykres średniej prędkości w funkcji cyklu pracy dla różnych szerokości impulsu jest charakterystyczny dla układu z tarciem. Ten artykuł wyjaśnia, co widzisz, i zawiera kompendium rozwiązań, które były stosowane od zawsze do rozwiązywania problemów. Nie zobaczysz ich w programie nauczania inżynierii, ponieważ trudno je przeanalizować; po prostu trzeba się z nimi bawić indywidualnie, aby zmusić ich do pracy.
Nie wiem, co robią kontrolery komercyjne, chociaż podejrzewam, że istnieje wiele różnych rozwiązań. W przeszłości robiłem takie rzeczy, gdy sygnał napędu silnika z mojego kontrolera PID spadł poniżej pewnego progu (prawdopodobnie w twoim przypadku 60 do 70). Zaczynam pulsować napęd silnika na progu, z obowiązkiem cykl, który powoduje, że średni napęd jest równy wyjściu PID. Generalnie używam do tego modulatora sigma-delta-ish, ponieważ można go zaimplementować w kilku liniach, ale możesz iść z tym, co Ci odpowiada.
źródło
Wygląda na to, że większość hałasu pochodzi z sygnału napędu PWM.
Czy próbowałeś zsynchronizować przechwytywanie ADC z cyklem PWM? Większość mikrokontrolerów ma sposób na wyzwolenie przechwytywania ADC na zegarze, więc zawsze możesz wyzwolić w tym samym punkcie cyklu.
W celu uzyskania najniższego poziomu hałasu optymalna pozycja próbkowania byłaby odpowiednia przed włączeniem zasilania silnika, ponieważ wtedy wszelkie kolce miały najdłuższy czas na ustabilizowanie się. Ale bez względu na położenie synchronizacja przechwytywania zmniejszy skoki, ponieważ wielkość przesunięcia pozostanie w przybliżeniu taka sama w tym samym punkcie cyklu PWM.
źródło
Możesz odfiltrować szum czujnika (lub inny zaszumiony pomiar / zmienną) w kodzie za pomocą czegoś takiego (filtrowanie dolnoprzepustowe):
źródło