Kursy • Poradniki • Inspirujące DIY • Forum
Wykorzystany sprzęt oraz oprogramowanie
W artykule wykorzystałem następujące elementy:
- STM32F4 Discovery
- Moduł sterownika silników TB6612
- Moduł enkodera magnetycznego Pololu
- Silnik Pololu z przedłużanym wałem
- Moduł Bluetooth HC-06
Kod na STM32 został napisany w środowisku Eclipse. Struktura programu jest podobna jak w moich wcześniejszych artykułach. Na mikrokontrolerze działa system FreeRTOS, a poszczególne zadania wykonywane są w wątkach. Do identyfikacji modelu transmitancyjnego silnika i zaprojektowania regulatora PID wykorzystałem środowisko MATLAB R2014a oraz pakiet Simulink wchodzący w jego skład.
Niezbędna teoria
Naszym obiektem sterowania jest silnik. Możemy nim sterować w pętli otwartej:
Gdzie u(t) to nasz sygnał wejściowy będący wartością sterowania podaną na silnik. Najczęściej jest to wypełnienie PWM. Natomiast y(t) to sygnał wyjściowy, którym jest prędkość obrotów silnika. Możemy ją odczytać za pomocą enkodera.
W tym wypadku w programie ustawiamy bezpośrednio wartość sterowania silnika. Dla tego samego sterowania prędkość może być różna w zależności od obciążenia. Program nie ma więc bezpośrednio kontroli nad prędkością silnika.
Przy sterowaniu w pętli otwartej podajemy pewną wartość na silnik wierząc, że spowoduje ona pojawienie się odpowiedniej wartości na wyjściu. Nie mamy jednak pewności, czy sterowanie odniosło pożądany skutek. Alternatywą jest sterowanie w pętli zamkniętej:
Gdzie r(t) to sygnał zadany, czyli wartość prędkości, jaką chcieli byśmy uzyskać na wyjściu. Natomiast e(t) to uchyb sterowania czyli różnica między sygnałem zadanym, a sygnałem wyjściowym.
Tym razem w programie ustawiamy wartość prędkości, jaką chcieli byśmy zaobserwować na wyjściu. Regulator na podstawie sygnału uchybu dobierze odpowiednie sterowanie. W tym wypadku, jeśli zmieni się obciążenie silnika, zmieni się także sygnał sterujący.
Regulator PID jest implementowany za pomocą następującego wyrażenia:
1 |
u = kp*e + ki*e_sum + kd*(e - e_last); |
Współczynniki kp, ki i kd, to parametry regulatora (człon proporcjonalny, całkujący i różniczkujący), e_sum to suma wszystkich wartości uchybu od początku sterowania, e_last to wartość uchybu z poprzedniej chwili czasu.
Do członu całkującego warto dodać ograniczenie na wartość e_sum niepozwalające sumie na urośnięcie powyżej zadanego progu.
Pomiar charakterystyki silnika
Do pomiaru charakterystyki silnika potrzebujemy programu składającego się z:
- obsługi sterowania silnikiem
- obsługi enkodera
- akwizycji danych
Sterowanie silnikiem zostało zrealizowane na timerze TIM2 odpowiedzialnym za generowanie sygnału PWM i dwóch wyjściach sterujących. Timer TIM3 został ustawiony w Encoder Mode z inkrementacją na zboczu rosnącym i opadającym na obu kanałach.
Dane dotyczące aktualnego sterowania podanego na silnik i wartości odczytanej z enkoderów są wysyłane do komputera przez USART połączony z modułem Bluetooth. Dane binarne zostały zapisane do pliku za pomocą programu RS-232 Data Logger, a następnie przekonwertowane do formatu tekstowego jako dwie kolumny pomiarów. Wyniki przedstawia wykres.
Z pobranych danych możemy wyznaczyć odpowiedź skokową. W tym celu posłużymy się skryptem matlabowym:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
%import danych z pliku file_data = importdata('out001.txt'); %dane z enkodera enc = file_data.data(:,1); %wartosc zadana set_val = file_data.data(:,2); %estymacja transmitancji obiektu %funkcja iddata przyjmuje: dane wyjsciowe, dane wejsciowe, czas probkowania in_data = iddata(enc(19:end), set_val(19:end), 0.005); %funkcja tfest przyjmuje: dane wejsciowo-wyjściowe jako struktura iddata, %ilosc biegunow, ilosc zer, nazwe i wartosc parametru do ustawienia (Ts to %czas probkowania). motor_tf = tfest(in_data, 1, 0, 'Ts', 0.005); %wykres sygnalu z enkodera z usunieciem poczatkowych wartosci zerowych t1 = 0:size(enc(19:end), 1)-1; t1 = t1*0.005; plot(t1, enc(19:end)) hold on %wykres odpowiedzi skokowej transmitancji silnika [y, t] = step(motor_tf); y = y*50; plot(t, y, 'r') |
Skrypt wczytuje dane z pliku i tworzy z nich strukturę iddata z czasem próbkowania 0.005. Ważne tutaj jest określenie ile pierwszych próbek znajduje się przed skokiem sygnału sterującego i odpowiednie skrócenie podawanych wektorów. U mnie nie branych pod uwagę jest 19 pierwszych próbek. Następnie funkcja tfest dopasowuje optymalny model do danych pomiarowych.
Ustawiony model zawiera jeden biegun i zero zer oraz czas próbkowania 0.005. Dalsza część skryptu rysuje na wykresie odpowiedź skokową wyznaczonego modelu i realnego układu.
Aby porównać otrzymany model z danymi rzeczywistymi, utworzyłem model pętli otwartej w Simulinku, a wynik naniosłem na jeden wykres z danymi pomiarowymi. Parametry transmitancji wziąłem ze zmiennej motor_tf ze skryptu. Wysokość sygnału skokowego ustawiłem na 50 zgodnie z sygnałem pobudzającym wykorzystanym w pomiarach.
Analizując wykres widzimy, że identyfikacja modelu zakończyła się sukcesem. Oba wykresy są do siebie bardzo podobne.
Projekt regulatora PID
Do doboru nastaw regulatora PID posłużymy się automatycznym tunerem wchodzącym w skład Matlaba. W tym celu należy stworzyć w Simulinku model pętli zamkniętej układu:
Tym razem wysokość sygnału skokowego ustawiłem na 11. W poprzednim przypadku sygnał skokowy był wyrażony w procentach wypełnienia PWM. Teraz jest to prędkość wyrażona jako ilość ticków enkodera na jednostkę czasu równą okresowi próbkowania - 5ms. We wszystkich elementach modelu i opcjach symulacji próbkowanie ustawiłem na 0.005.
Po otwarciu właściwości bloku PID otworzy nam się następujące okno:
Na czerwono zaznaczyłem wybór rodzaju regulatora (np. PI, PD, PID), pole czasu próbkowania, pola z parametrami P, I, D, wykorzystywany wzór regulatora PID oraz przycisk Tune.
W tym oknie możemy ręcznie modyfikować wartości parametrów i sprawdzać jaki mają wpływ na jakość sterowania. W zakładce PID Advanced należy ustawić Output saturation na wartości 100 i -100. Jest to ograniczenie sygnału sterującego związane z maksymalnymi wartościami PWM. Następnie klikamy przycisk Tune. Ukaże nam się następujące okno:
Za pomocą suwaków możemy tutaj modyfikować szybkość odpowiedzi skokowej układu zamkniętego. Krótszy czas ustalania wiąże się z większym przeregulowaniem.
Po osiągnięciu zadowalającej charakterystyki klikamy Update block i parametry PID zostają zaktualizowane. Moje wartości to P = 5.94, I = 347.19 i D = -0.03. Warto zauważyć, że wartości I oraz D są znormalizowane względem czasu próbkowania. Widać to na wzorze w oknie bloku PID. Tak więc wartość I jest mnożona przez czas próbkowania, a wartość D dzielona.
Obliczone wartości wprowadziłem do programu na STM, który został rozszerzony o obliczanie sterowania za pomocą algorytmu PID. Porównanie wyników w pętli otwartej i w pętli zamkniętej z nastrojonym PID prezentuje wykres:
Jak widać na wykresie, dzięki zastosowaniu PID udało się skrócić czas ustalania.
Podsumowanie
W artykule przedstawiłem sposób projektowania regulatora PID dla silnika z enkoderem. Wykorzystałem w nim gotowe funkcjonalności Matlaba takie jak funkcja tfest znajdująca model transmitancyjny dla danych pomiarowych, czy PID Tuner znajdujący automatycznie nastawy regulatora. Dzięki temu udało się uniknąć skomplikowanej teorii i wzorów.
W wyniku otrzymałem regulator PID, który znacząco przyspiesza czas ustalania prędkości w porównaniu ze sterowaniem w pętli otwartej. Dodatkową zaletą jest bezpośrednie sterowanie prędkością z poziomu funkcji sterującej, zamiast bardziej abstrakcyjnej wartości wypełnienia PWM.
Dzięki temu otrzymujemy gwarancję, że silnik będzie się kręcić z taką samą prędkością mimo np. rozładowującej się baterii, czy innej nawierzchni. Do artykułu załączam kod programu na STM z zaimplementowanym regulatorem PID.
To nie koniec, sprawdź również
Przeczytaj powiązane artykuły oraz aktualnie popularne wpisy lub losuj inny artykuł »
enkoder, matlab, PID, regulator, robot, silnik
Trwa ładowanie komentarzy...