Skocz do zawartości

[Algorytmy] PID w robotyce amatorskiej - linefollower, cz.1 Człon P


Treker

Pomocna odpowiedź

Co do PID'u - najprościej jest odnieść go do czasu tzn.

P - odpowiada za "teraźniejszość" - wylicza poprawkę na bazie aktualnego błędu. (Im większy błąd - tym większa poprawka)

I - odpowiada za "przeszłość" - jak napisał nicki pozwala nam zniwelować błąd do zera.(Tzn. robot przestaje jeździć zygzakiem - wyjaśnienie poniżej).

D - próbuje przewidzieć "przyszłość" - pozwala lepiej reagować na szybkie zmiany. (skoro wcześniej błąd wzrósł np. o 5 - to pewnie zaraz jest zakręt(albo kąt prosty), a więc robot powinien skręcić mocniej aby się w nim wyrobić...)

Charakterystyki: Porównaj - PID szczegółowo

P - sterowany układ krąży wokół punktu równowagi - na prostej wychodzi coś a'la sinus.

PI - sterowany układ osiąga punkt równowagi - dobrze dobrany człon I tłumi drgania - wychodzi prosta krecha. Układ bardziej leniwie reaguje na zmiany.

PD - jak P tyle że bardziej "nerwowy" - podczas dużej zmiany błędu następuje mocna korekta, przy małych zmianach się "nie czepia"- na prostej dalej mamy sinus - jednak układ szybciej się ustawia na właściwej wartości przy dużych skokach.(Najczęściej wykorzystywany w LF'ach)

PID - Kompromis pomiędzy dwoma powyższymi - zarówno potrafi radzić sobie z szybkimi zmianami oraz tłumi wahania w stanie równowagi.

Jeszcze prościej:

Załóżmy że masz silnik z ciężkim kołem na osi(dość wolno się rozpędza), miernik obrotów, oraz regulator obrotów (z podziałka co 10 obr/min)do tego sinika.

Chcesz aby koło kręciło się z prędkością 95 obr/min. Zatem ustawiasz regulator na pozycje 100 obr/min i czekasz aż się rozpędzi do 96, potem ustawiasz 90, czekasz aż spadnie do 94 (człon P). Jeśli jesteś sprytny wpadniesz na pomysł aby na początku, gdy silnik się rozpędza - ustawić maksymalne obroty, a im bliżej będziesz 95 tym bardziej będziesz przykręcał gałkę - dzięki temu silnik szybciej się rozpędzi...(człon D) Potem wpadniesz na pomysł iż mimo w regulatorze jest podziałka co 10 to gałeczką da się kręcić płynnie. Regulujesz więc nią coraz delikatniej, aż nasz obrotomierz wskaże upragnione 95 obr/min (człon I).

Kilka uwag:

Jak już ktoś wcześniej wspomniał nie trzeba dzielić błędu przez ilość czujników - wprowadza to tylko dodatkowe problemy, takie jak:

  • - jeśli zapiszemy wynik jako int - utnie nam część ułamkową - tracimy precyzję.
  • - jeśli zapiszemy to jako float - AVR'y nie mają jednostki zmiennoprzecinkowej przez co liczenie kilku mnożeń trwa zdecydowanie za długo.
  • - musimy przez to pomnożyć wynik przez większe nastawy w regulatorze. (Dzielić po to by potem 3 razy mnożyć - moim zdaniem to bez sensu...)

Na koniec jeden z najprostszych sposobów wyliczania PD'a jaki znam(w C):

void pd(void){
   static uint16_t pref_err = 0;  //poprzedni błąd

   PDval = reg_p * err + reg_d * (err - pref_err);
   pref_err = err;
}
  • Lubię! 1
Link do komentarza
Share on other sites

Kilka uwag:

Jak już ktoś wcześniej wspomniał nie trzeba dzielić błędu przez ilość czujników - wprowadza to tylko dodatkowe problemy, takie jak:

- jeśli zapiszemy wynik jako int - utnie nam część ułamkową - tracimy precyzję.

- jeśli zapiszemy to jako float - AVR'y nie mają jednostki zmiennoprzecinkowej przez co liczenie kilku mnożeń trwa zdecydowanie za długo.

- musimy przez to pomnożyć wynik przez większe nastawy w regulatorze. (Dzielić po to by potem 3 razy mnożyć - moim zdaniem to bez sensu...)

Nie do końca się z tym zgodzę - załóżmy liniowe rozłożenie wag czujników i załóżmy, że dwa skrajne lewe czujniki mają wagi np 40 i 50. Jeżeli robot widzi linię na dwóch czujnikach to wynik da 90. Jeśli widzi tylko skrajnym czujnikiem, to wynik = 50. Z tego wynika, że wtedy powinien skręcać w mniejszym stopniu niż gdyby widział obydwoma czujnikami, co jest błędne.

Link do komentarza
Share on other sites

Nie do końca się z tym zgodzę - załóżmy liniowe rozłożenie wag czujników i załóżmy, że dwa skrajne lewe czujniki mają wagi np 40 i 50. Jeżeli robot widzi linię na dwóch czujnikach to wynik da 90. Jeśli widzi tylko skrajnym czujnikiem, to wynik = 50. Z tego wynika, że wtedy powinien skręcać w mniejszym stopniu niż gdyby widział obydwoma czujnikami, co jest błędne.

Po części się z Tobą zgodzę, jednak zależy to od przyjętych założeń projektowych. Z tego co się orientuję aktualną tendencją w LF'ach jest umieszczanie czujników tak, aby 2 z nich cały czas widziały linie(rozwiązania 10+ czujników). Jeśli linię widzą 3 czujniki oznacza to ponad 45 stopniowy odchył robota od linii - co wymaga już sporej poprawki.

Link do komentarza
Share on other sites

Przeanalizowałem kod Trekera

i w głowie mi się trochę pomieszało (za dużo zmiennych)

Nie wiem czy mój tok rozumowania jest dobry ale napisałem coś takiego:

$regfile = "m8def.dat"
$crystal = 8000000
Config Timer1 = Pwm , Pwm = 8 , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Config Adc = Single , Prescaler = Auto
'adc startuje ;)
Start Adc
'konfiguracja portow
Config Portd = Output
Config Portb = Output

'do mostka
Silnik_lewy_a Alias Portd.0
Silnik_lewy_b Alias Portd.1
Silnik_prawy_a Alias Portd.2
Silnik_prawy_b Alias Portd.3
Dioda Alias Portd.4


'zmienne

Dim Czujniki_licznik As Byte , Czujniki(6) As Integer , Flagalinii As Byte
Dim Waga_czujnika(7) As Integer , Suma_wag As Integer , Ile_wykrylo As Byte
Dim Aktualna_pozycja As Single , Blad As Single , Czulosc As Integer , Docelowa_predkosc As Byte , Zmiana As Integer
Czulosc = 255 - 100
Czulosc = Czulosc / 14

Docelowa_predkosc = 100

Waga_czujnika(1) = 14
Waga_czujnika(2) = 13
Waga_czujnika(3) = 12
Waga_czujnika(4) = -12
Waga_czujnika(5) = -13
Waga_czujnika(6) = -14

'stany poczatkowe na mostku i diodzie
Set Silnik_lewy_a
Reset Silnik_lewy_b
Set Silnik_prawy_a
Reset Silnik_prawy_b
Set Dioda

'granica reagowania na linie
Const Granica = 750
'docelowa pozycja
Const Docelowa_pozycja = 0

Do
Gosub Czytaj
Gosub Licz_pozycje
Gosub Licz_pid

Pwm1a = Docelowa_predkosc + Zmiana
Pwm1b = Docelowa_predkosc - Zmiana

Loop
End


Czytaj:
For Czujniki_licznik = 0 To 5
Czujniki(czujniki_licznik + 1) = Getadc(czujniki_licznik)
If Czujniki(czujniki_licznik + 1) > Granica Then Set Flagalinii.czujniki_licznik Else Reset Flagalinii.czujniki_licznik
Next
Return

Licz_pozycje:

Suma_wag = 0
Ile_wykrylo = 0

For Czujniki_licznik = 0 To 5
If Flagalinii.czujniki_licznik = 1 Then
Suma_wag = Suma_wag + Waga_czujnika(czujniki_licznik + 1)
Ile_wykrylo = Ile_wykrylo + 1
End If
Next
Aktualna_pozycja = Suma_wag / Ile_wykrylo
Return

Licz_pid:

Blad = Docelowa_pozycja + Aktualna_pozycja
Zmiana = Czulosc * Blad
Return
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

lewiś, niestety artykuł nie był kontynuowany. Wytknięto mi wtedy sporo braków w tekście (słusznie) i nie podjąłem się tworzenia kolejnych części. Było to 4 lata temu, więc możliwe, że za jakiś czas wrócę do tematu 🙂

Link do komentarza
Share on other sites

Jest szansa, że artykuł pojawi się w najbliższym czasie ? Chciałem się podjąć napisania programu do line followera wykorzystując PID, ale nie wiem jak się do tego zabrać. Nie znalazłem innego artykułu, który tłumaczyłby to w taki prosty sposób 😃

Link do komentarza
Share on other sites

Jest zrozumiałe na podstawie tego co przeczytałem tutaj. Wydaję mi się, że dobrze byłoby napisać kolejne części tego poradnika na forum. Tam jest to napisane tylko pobieżnie, natomiast na wikipedii jest to opisane trochę nieczytelne przez wszystkie obliczenia. Mam nadzieję, że kolejne części wyjdą niedługo. Bardzo dziękuję za odpowiedź. Pozdrawiam 🙂

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.