Ta strona używa ciasteczek (plików cookies), dzięki którym może działać lepiej. Dowiedz się więcejRozumiem i akceptuję

Regulator PD dla LineFollowera - problem

Autor Wiadomość
NightWatcher 



Posty: 7
Wysłany: 11-10-2017, 18:57   Regulator PD dla LineFollowera - problem

Witam.

Stworzyłem ostatnio swojego pierwszego robota typu LineFollower. Konstrukcję mechaniczną wraz z całą elektroniką mam ukończoną, pozostało jedynie napisać odpowiedni program. Przy budowie robota posiłkowałem się wieloma poradnikami dostępnymi w internecie stąd od początku moim celem było zastosowanie regulatora PD do podążania za trasą. I tu pojawia się problem gdyż już któryś dzień z rzędu staram się dobrać odpowiednie nastawy i wszelkie próby kończą się fiaskiem. Dlatego proszę o pomoc na forum, gdzie na pewno znajdują się ludzie, którzy mają doświadczenie w tej kwestii.

Procesor użyty to Atmega 328p, program pisany jest w języku C z użyciem Arduino IDE. Robot posiada 8 czujników umieszczonych w lekkim półkolu w odległości ~14mm od siebie.
Regulator staram się stroić wyłączając część D i próbując dobrać odpowiednie Kp tak aby robot był w stanie pokonywać zakręty (gdzieś czytałem, że podobno sam człon P wystarczy aby przejechać trasę ale nie mam pojęcia ile w tym prawdy). Problem jest jednak taki, że przy małych wartościach Kp robot wypada z trasy na bardzo łagodnych zakrętach (około 30 stopni) a przy większych z trudem dojeżdża do zakrętu, gdyż na prostej dość mocno się chwieje. Włączenie części różniczkującej w moim odczuciu niewiele daje (nie widać jakiejś zauważalnej poprawy).
Być może jest to wina tego, że przy wykryciu skrętu część różniczkująca jest różna od zera tylko i wyłącznie pomiędzy samplami w których wykryto różnicę w odczycie - poźniej, pomimo wykrywania zakrętu odczyt pozostaje taki sam wobec czego różniczka znów jest zerem co sprawia, że część D była obecna w sygnale sterującym silnikami tylko przez ~5ms (= brak reakcji silników). Z drugiej strony jednak, wszystkie przykładowe kody bądź pseudokody regulatora PD dla LineFollowera wyglądały tak samo, więc nie wiem czy moja hipoteza jest prawdziwa (pewnie nie).

Poniżej zamieszczam kod. Nie jest to całkowity kod programu, wkleiłem tylko to co jest istotne z punktu widzenia regulatora PD.


Kod programu: Zaznacz cały


const int SensorWeight[8] = { -8, -4, -2, -1, 1, 2, 4, 8};
const int SetPoint = 0;
const int NoActiveSensor = 221;

int Kp = 1;
int Td = 0;

int gain = 0;
int derivative = 0;
int feedback = 0;

int control = 0;
int baseMotorSpeed = 50;

unsigned long int startTime;


int GetSensorValues()
{
  int value = 0;
  int activeSensors = 0;

  for (int i = 0; i < 8; i++)
  {
    if (digitalRead(i))
    {
      value += SensorWeight[i];
      activeSensors++;
    }
  }

  if(!activeSensors)
    return NoActiveSensor;
 
  value = value / activeSensors;
  return value;
}

void SetMotors(int speed)
{
  SetLeftMotor(baseMotorSpeed + speed);
  SetRightMotor(baseMotorSpeed - speed);
}


void SetLeftMotor(int speedValue)
{
  if (speedValue<0)
    speedValue = 0;
  else if(speedValue>255)
    speedValue = 255;
   
  analogWrite(IA1, speedValue);
}

void SetRightMotor(int speedValue)
{
  if (speedValue<0)
    speedValue = 0;
  else if(speedValue>255)
    speedValue = 255;
   
  analogWrite(IB1, speedValue);
}

void PD() {
      startTime = millis();
      feedback = GetSensorValues();

      if(feedback == NoActiveSensor)
        error = previousError;
      else
        error = SetPoint - feedback;
     
      gain = Kp * error;
      derivative = (error - previousError) * Td;     
      control = gain + derivative;
     

      SetMotors(control);
   
      previousError = error;

      while (millis() - startTime < 5);
}



Będę wdzięczny za pomoc i z góry dziękuję.

Warto przeczytać » Tworzenie aplikacji Android - #1 - Wstęp


Ostatnio zmieniony przez NightWatcher 11-10-2017, 18:58, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
slawko_k 




Posty: 297
Pomógł: 10 razy
Otrzymał 50 piw(a)
Skąd: podkarpackie
Programuję w:
Bascom, Arduino
Wysłany: 11-10-2017, 19:58   

Czy koła mogą kręcić się w tył?
Czy driver silnika umożliwia jego hamowanie?
Czy w twoim programie error nie rośnie do kwadratu w funkcji odległości?
Nie wiem czy zrozumiałem dobrze twój kod ale jeśli 2 zewnętrzne czujniki są na linii to error=8+4 czyli 12 a jak linia jest na samym końcu to tylko 8?

Postaw piwo autorowi tego posta
 
 
 
NightWatcher 



Posty: 7
Wysłany: 11-10-2017, 21:21   

1. Tak, mogą tylko, że z różnymi trybami wygaszania prądu (o ile dobrze zrozumiałem dokumentację)
2. Z tego co wyczytałem to driver ma dostępne funkcje Coast/fast decay i Brake/slow decay, więc chyba tak (driver to HR8833)
3. Niby tak, ale nie do końca (patrz pkt. 4) - wagi czujników to po prostu kolejne potęgi dwójki - przyjmowałem już najróżniejsze, z marnym skutkiem.
4. Nie, odczyt z czujników jest dzielony przez ilość aktywnych czujników, więc dla 2 skrajnych error = 6, dla ostatniego skrajnego error = 8.

Ostatnio zmieniony przez NightWatcher 11-10-2017, 21:35, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
lukix 



Posty: 97
Pomógł: 1 raz
Otrzymał 9 piw(a)
Programuję w:
C
Moje roboty:
Bluescreener, Deimos

Wysłany: 11-10-2017, 23:45   

Człon P powinien być liczony jak najczęściej. Ograniczenie do 5ms powinno być stosowane tylko do członu D (i ja bym je zwiększył do około 20ms, ale z tym trzeba po prostu poeksperymentować).
A wagi czujników dobrałbym bardziej liniowo w zależności od odległości.

Ostatnio popularny » Wytrzymałość materiałów - #2 - Symulacja w CAD


Postaw piwo autorowi tego posta
 
 
NightWatcher 



Posty: 7
Wysłany: 13-10-2017, 17:41   

Zrobiłem tak jak napisał lukix - jest nieco lepiej bo LF daje rade pokonywać łagodne i średnie zakręty, dość szybko się stabilizuje, nadal jednak ma problem z ostrymi zakrętami (po prostu wypada z trasy). Wszystko dotyczy oczywiście (póki co) małych prędkości (około 12% wypełnienia PWM), więc podejrzewam, że zwiększenie prędkości jeszcze pogorszy sprawę.

EDIT: dodam jeszcze, że robot dostaje dużego przyspieszenia przy wyjściu z zakrętu co sprawia, że gorzej mu idzie pokonanie następnego.

Ostatnio zmieniony przez NightWatcher 13-10-2017, 17:42, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
lukix 



Posty: 97
Pomógł: 1 raz
Otrzymał 9 piw(a)
Programuję w:
C
Moje roboty:
Bluescreener, Deimos

Wysłany: 13-10-2017, 18:21   

1) Zauważyłem, że masz w kodzie zły znak w liczeniu zmiennej derivative. (powinno być previousError - error).
2) Ostre zakręty w dosłownym znaczeniu (mniej niż 90 stopni)?
3) Problem z wyjściem z zakrętu możesz rozwiązać w ten sposób, że będziesz tylko zmniejszać pwm dla jednego silnika, bez zwiększania dla drugiego.
4) Jak dalej nie będzie efektów to może pokaż jakiś filmik jak to wygląda.

Postaw piwo autorowi tego posta
 
 
NightWatcher 



Posty: 7
Wysłany: 14-10-2017, 21:14   

Jesteś pewien co do tej zmiennej derivative? Mi się wydaje, że jest liczona w dobry sposób (gdy nagle pojawi się niezerowy error, to derivative będzie mieć ten sam znak co gain wobec czego wymusi mocniejszy zakręt aby skorygować tor).

Spróbowałem zastosować sposób o którym mówiłeś - zmniejszanie PWM jednego silnika przy stałej wartości drugiego - trochę pomogło. Następnie dodałem do tego możliwość zmiany kierunku obrotów na zakręcie. Podziałało zaskakująco dobrze - na tyle dobrze, że wróciłem do poprzedniej wersji ze zmianą PWM obu silników naraz. Przy takiej konfiguracji z małymi prędkościami robot bez problemu pokonuje trasę, którą wykleiłem sobie na podłodze. Niestety przy zwiększaniu prędkości (~22% PWM, więc wciąż mało) przy mocniejszym zakręcie (około 70 stopni) robot zaczyna zachowywać się dziwnie.

Mianowicie:
1. Czasami przejedzie poprawnie (mocno hamując i bujając się przy wyjściu)
2. Czasami robiąc kilka kółek z rzędu po prostu pojedzie prosto jakby nie widział zakrętu (mimo tego, że przed chwilą kilkakrotnie go pokonał)
3. Czasami zrobi jeden obrót w miejscu i dopiero wtedy pojedzie dalej poprawną trasą
4. A czasami zawróci

Nie wiem za bardzo, w którą stronę powinienem iść z nastawami aby wyeliminować ten problem. Zmienić P/D czy może częstotliwość liczenia członu D? A może dodać inny parametr, który np. zmniejszy prędkość bazową silników przy wykryciu mocnego zakrętu?
Z góry dziękuję za wszelkie porady.

Postaw piwo autorowi tego posta
 
 
lukix 



Posty: 97
Pomógł: 1 raz
Otrzymał 9 piw(a)
Programuję w:
C
Moje roboty:
Bluescreener, Deimos

Wysłany: 14-10-2017, 21:38   

Kilka razy się upewniałem z tym znakiem, a i tak się pomyliłem ;) Masz rację - jest dobrze.
Ja już chyba za wiele nie wniosę. Musisz eksperymentować i obserwować wyniki.
Nie wiem jakie masz silniki i koła, ale np. 22% PWM dla silników Pololu 10:1 z kołami 32mm to nie jest taki zły wynik (choć da się lepiej) ;)

EDIT: Ważne są też mechaniczne kwestie - moment bezwładności, odległość czujników od osi kół itd. Może to tu jest większy problem?

Ostatnio zmieniony przez lukix 14-10-2017, 21:43, w całości zmieniany 2 razy  
Postaw piwo autorowi tego posta
 
 
Więcej szczegółów
Wystawiono 1 piw(a):
NightWatcher
NightWatcher 



Posty: 7
Wysłany: 14-10-2017, 21:51   

Dzięki za pomoc. Owszem silniki to Pololu 10:1 (oryginalność przede wszystkim), koła też od Pololu dokładnie te: https://botland.com.pl/kola-pololu/147-kola-solarbotics-rw2.html Opony z bardzo klejącej gumy, świetnie zbiera kurz z podłogi ;)
Szczerze mówiąc zaskoczyłeś mnie mówiąc, ze 22% PWM to dobrze. Spodziewałem się, że na spokojnie można dojść do 60%, może 70. Ale skoro tak to jestem zadowolony z efektów. Będę eksperymentować z nastawami i innymi parametrami, jako pojawi się coś ciekawego to dam znać.
Jeszcze raz dzięki za pomoc i inspiracje. ;)

EDIT: No jeśli faktycznie problem leży w rozkładzie masy, rozstawie kół lub czymś podobny to niestety z tym już nie mogę nic zrobić :(

Ostatnio zmieniony przez NightWatcher 14-10-2017, 21:56, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
lukix 



Posty: 97
Pomógł: 1 raz
Otrzymał 9 piw(a)
Programuję w:
C
Moje roboty:
Bluescreener, Deimos

Wysłany: 14-10-2017, 22:06   

Nie miałem styczności z tymi oponami, więc nie wiem jak dobre one są.
Ja na zwykłych pololu osiągałem (jeśli dobrze pamiętam) coś około 32% pwm.
Później zmieniłem koła na takie:
https://www.fingertechrobotics.com/proddetail.php?prod=ft-minisumo-wheels-1125
I teraz jestem w stanie osiągnąć 45 - 55% pwm na trasie z kątami prostymi. Opony muszą być często czyszczone, bo przyczepność bardzo szybko spada.
Przy tych 50% wydaje mi się, że można już zaczynać myśleć o jakiś miejscach na zawodach, ale na to też wpływa bardzo dużo czynników. Trzeba też pamiętać, że pwm nie przekłada się idealnie na prędkość robota.

Postaw piwo autorowi tego posta
 
 
NightWatcher 



Posty: 7
Wysłany: 14-10-2017, 22:53   

Widziałem podobne (albo nawet takie same) na Botlandzie, jednak cena była strasznie wysoka (około 230 zł o ile dobrze pamiętam). Na tej stronie widzę, że są dużo tańsze chociaż koszty przesyłki zza granicy pewnie zrobiłyby swoje.

Postaw piwo autorowi tego posta
 
 
ciuupa 



Posty: 38
Programuję w:
C
Wysłany: 16-10-2017, 20:06   

Hey o wiele lepsze są te - jakośćnaprawde fajna. Moj kumpel kupil kilka zestawow (teraz sprzedaje za 90zl za dwie szt)
http://www.jsumo.com/slt20-aluminum-silicone-wheel-set-33mmx20mm-pair

Postaw piwo autorowi tego posta
 
 
NightWatcher 



Posty: 7
Wysłany: Wczoraj 13:56   

Mam jeszcze jedno pytanie - podczas wielu testów na kilku torach (nadal wyklejonych na podłodze), zmagałem się z problemem, którego nie potrafiłem rozwiązać zmianą nastaw tudzież modyfikacją programu. Otóż przy zakrętach pod kątem prostym robot czasami (w około połowie przypadków) skręcał w przeciwną stronę (czyli np. jeśli zakręt był w prawo to robot skręcił w lewo w skutek czego albo wypadł z trasy albo zawrócił). Czy ktoś ma jakiś pomysł dlaczego tak się dzieje, czy jest to po prostu coś co trzeba wyeliminować drogą eksperymentów?

Postaw piwo autorowi tego posta
 
 
lukix 



Posty: 97
Pomógł: 1 raz
Otrzymał 9 piw(a)
Programuję w:
C
Moje roboty:
Bluescreener, Deimos

Wysłany: Wczoraj 17:18   

Ja u siebie rozwiązałem to tak, że w momencie gdy żaden czujnik nie widzi linii, robot wie w którą stronę skręcić na podstawie tego pod którym skrajnym czujnikiem (najbardziej wysunięty w lewo albo w prawo) ostatnio widział linię. Czyli podobne rozwiązanie, które już stosujesz (na podstawie kodu w pierwszym poście), ale bierz pod uwagę tylko skrajne czujniki.
Gdybyś miał skrajne czujniki przesunięte lekko do tyłu względem pozostałych to prawdopodobnie nie było by tego problemu nawet przy obecnym programie.

Ostatnio zmieniony przez lukix Wczoraj 17:19, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Wersja do druku

Skocz do:  

Nie rozwiązałeś swojego problemu? Zobacz podobne tematy: Kombinowanie z przer... Mikrokontrolery z ob... [ Bascom] Jak zrobić... Generowanie przebieg...
lub przeszukaj forum po wybranych tagach: linefollower, pd, pid, problem, regulator


Powered by phpBB modified by Przemo © 2003 phpBB Group
Popularne kursy: Arduinopodstawy elektroniki