Jak sterować robotem, czyli budowa i obsługa prostego enkodera.

Jak sami zauważyliście, dwukołowa platforma robota, którą oferuje sklep Nettigo.pl ma tendencję do skręcania. Spróbujcie – napiszcie program, który nakazuje jedynie jazdę na wprost. Celem tego i kilku następnych artykułów będzie analiza i minimalizacja tego zjawiska oraz prezentacja różnych sposobów regulacji. Mam nadzieję, że będzie to przyjemny start w świat regulatorów.

Liczenie obrotów układ

Analiza problemu

Czemu robot skręca?

Powodów ku temu jest wiele. Najważniejszym jest fakt, że roboty zwykle nie jeżdżą na ślepo. Zazwyczaj stosuje się różne czujniki (transoptory odbiciowe, fototranzystory, fotorezystory, czujniki ultradźwiękowe, etc.) aby kontrolować kierunek w jakim porusza się pojazd względem podłoża, czy to ma trzymać się założonej linii czy omijać przeszkody. W związku z tym, dopuszcza się przeciętną precyzję wykonania takich elementów jak koła czy silniki. Po prostu różnice w ich sposobie pracy i tak zostaną zniwelowane przez program sterujący. Kolejnym aspektem jest wpływ podłoża na kierunek jazdy – każdy wybój i  nierówność powoduje skręcanie robota. Różnice pomiędzy tarciem jednego i drugiego koła z podłożem są tak małe, że można je pominąć.

Poszukiwanie rozwiązań

Czyli za co można się zabrać, a co jest wolą nieba, z którą się zawsze zgadzać trzeba?

Zauważyłem, że silniki w moim robocie czasami obracają się z różnymi prędkościami, zarówno pod obciążeniem jak i bez, mimo zadania im tego samego wypełnienia. Gdyby sprawdzić jak często obraca się każde koło można by wyeliminować skręcanie pochodzące od różnicy właściwości mechanicznych silników i od występowania poślizgów między kołem a podłożem. Niestety, zniwelowanie wpływu nierówności, luzów w mocowaniu koła do silnika i niewielkiej różnicy wielkości kół jest ciut bardziej złożone. Postaram się opisać to w kolejnych postach.

Z początku pominąłem kwestię przeciętnej jakości wykonania kół i zająłem się samymi silnikami. Postanowiłem zatem zliczyć obroty kół w danym czasie i sprawdzić, które koło obróciło się więcej razy. To pozwoli pozbyć się skręcania powodowanego przez inne właściwości mechaniczne silników oraz wynikających z różnicy poślizgów. Musiałem zatem znaleźć początek koła i zmontować układ, który będzie wykrywał czy przekroczy on pozycję wejściową. Inaczej mówiąc – musiałem zbudować enkoder.

Montaż układu

Czyli nawet ślepy robot potrzebuje czujników.

Do zliczania obrotów zmontowałem taki układ:

Schemat_enkodera

Umiejscowienie fototranzystora i diody IRFototranzystory działają jak przycisk czy przekaźnik. W momencie kiedy są oświetlane przez diodę podczerwoną zwierają układ do masy i na wejściu cyfrowym pojawia się stan niski. W teorii pozostaje tylko policzyć ile stanów niskich pojawiło się w danym czasie. Niestety, jak pokażę niżej, nie jest to takie proste. Wykorzystałem tutaj rezystory 10k i 220 Ohm. Te pierwsze mają za zadanie uchronić wejście cyfrowe i układ zasilający przed uszkodzeniem w wyniku niekontrolowanego przepływu prądu. Czemu akurat 10k? Akurat to miałem pod ręką ;) Wejście cyfrowe wytrzymuje do 40 mA prądu, co przy napięciu zasilania 5 V daje minimalną oporność rezystorów R2 i R3 na poziomie 125 Ohm. Jednak w tym układzie badane są zmiany napięcia, a nie prądu, więc prąd można ograniczyć do minimum. Mniejszy prąd oznacza też mniejsze straty na rezystorze, R2 i R3 nie będą się grzać. Lekko zmodyfikowana plastikowa płytka, dołączona do zestawu, posłuży jako ruchoma przesłona obracająca się z tą samą prędkością co koło. Dla wygody zakleiłem je taśmą izolacyjną tak, by odsłonięty był tylko jeden – łatwiej mi było sprawdzić czy program dobrze zlicza obroty. Odsłonięcie większej ilości otworów zwiększa rozdzielczość enkodera, ja jednak odsłoniłem zaledwie dwa, zamiast sześciu, otwory na obwodzie ostatecznej wersji płytki. Więcej zdjęć można znaleźć w galerii na dole strony.

Modyfikowanie przesłony, enkoderModyfikowanie płytki, cd

Zmodyfikowana płytka

 

Program

Na co zwracać uwagę przy pomiarach tego typu? Jakie można napotkać trudności i jakie są rozwiązania?

Zacząłem od zastanowienia się jak ma wyglądać algorytm sterujący. Rada ze szczerego serca – przed napisaniem czegokolwiek, usiądźcie z kartką, długopisem spróbujcie narysować graf obrazujący działanie programu. Wcześniejsze przyrównanie fototranzystora do przycisku jest o tyle celne, że tutaj też trzeba zmierzyć się ze zjawiskiem bounceingu. Jeśli się go nie uwzględni można otrzymać bezsensowne wyniki jak np, wzrost wartości licznika od 0 do 30 dla jednego obrotu. Dlatego musiałem wyposażyć program w narzędzie do debounceingu. Nie mogłem po prostu wpisać linijki delay(50), ponieważ zliczanie obrotów jest krytyczne czasowo. Funkcja delay() sprawia, że zatrzymuje się wykonywanie całego programu, co jest bardzo kłopotliwe ze względu na występowanie dwóch kół. Opiszę to na przykładzie:
Kiedy koło A przejdzie przez zero, zostanie uruchomiona funkcja delay(). Przez czas opisany w argumencie, mikrokontroler nie będzie robił nic – nie będzie sprawdzał czy koło B również przeszło przez pozycję zerową. Taki sposób pomiarów odpada. Alternatywą jest wykorzystanie funkcji millis().

...
int dt = 50; // gęstość próbkowania
...
unsigned long czas; //wartość czasu od uruchomienia programu
unsigned long czasa = millis() + dt; //czas rozpoczęcia zliczania dla koła A
...
vala = digitalRead(BUTTON_PIN_A);
  valb = digitalRead(BUTTON_PIN_B);
  if (vala == LOW) 
  {
    if(czas >= czasa)
    {
    count.A++;
    czasa = czas + dt;
    }
...

Funkcja millis() mierzy czas od uruchomienia Arduino. Zmienna dt to czas jaki ma upłynąć przed wykonaniem danej funkcji, w tym wypadku inkrementacji licznika. Program na początku sprawdzi ile czasu zajęło mu „uruchomienie się”, następnie do tego czasu doda wartość zmiennej dt. W ten sposób otrzyma czas jaki ma minąć przed pierwszą inkrementacją licznika. Jeśli na wejściu cyfrowym pojawi się stan niski, a ten czas upłynie – licznik zwiększy swoją wartość, a zmienna czasa (oznaczająca następny moment inkrementacji) zostanie zmieniona. I tak w kółko.

Podsumowanie

Ocena skuteczności danego rozwiązania i napisanego programu. Czy istnieją inne rozwiązania?

Występuje pewna poprawa, dobrze widoczna szczególnie przy mniejszych prędkościach ruchu – oznacza to, że udało się osiągnąć sukces! Niestety, pojazd nadal delikatnie zbacza z toru ruchu. Dlaczego? Opisaną tutaj metodę można z powodzeniem przyrównać do maszerowania na wprost z zamkniętymi oczami – człowiek stara się zachować równą długość kroku, jednak każda nierówność sprawia, że maszerujący zaczyna skręcać. Robot, dzięki enkoderom, sam dostosowuje wypełnienie sygnału zasilającego silniki w zależności od stanu silników, jest to odpowiednik długości kroku. Prawdę mówiąc, jedynym pewnym sposobem na „wyprostowanie” kierunku ruchu robota jest regulacja w oparciu o położenie względem otoczenia/podłoża, co jest ciut bardziej skomplikowane. Mam nadzieję, opisać tę metodę w następnych postach. Powodzenia we własnych eksperymentach!

Lista elementów:

  • 2x LTR-301 & LTE-302
  • kilka kabelków od podłączenia całości
  • klej typu  „kropelka”

Cały szkic do Arduino do ściągnięcia: szczurek_2.ino

Poniżej sposób podłączenia:

Liczenie obrotów układ