Zdalnie sterowany robot

Zdalnie sterowany robot

Jeżdżący robot

Od jakiegoś czasu interesuję się modelami zdalnie sterowanymi. Spod mojej ręki wyszło kilka quadrokopterów, a po bezdrożach szaleję od czasu do czasu terenowym samochodem zdalnie sterowanym. O ile jednak pojazdy zdalnie sterowane są ciekawe, to jeszcze ciekawsze są pojazdy autonomiczne – takie, które mogą samodzielnie poruszać się i podejmować decyzje. Postanowiłem więc zbudować jeżdżącego robota.

Założenia

Na wstępie założenia. Zdecydowałem, że robot musi spełniać następujące wymagania:

  • Robot będzie jeździł na czterech kołach.

  • Zawieszenie powinno wystarczyć do pokonywania niewielkich przeszkód – to wymaga też odpowiedniego prześwitu pomiędzy podwoziem a ziemią;

  • Robot musi być programowalny w relatywnie prostym języku;

  • Konieczne jest zdalne sterowanie – w przypadku, gdyby wymknął się spod kontroli muszę mieć możliwość przejęcia kontroli i powrotu

  • Nadwozie musi pozwalać na montaż dodatkowych komponentów – serw lub czujników.

Wybieramy części

Pierwsza decyzja, którą musiałem podjąć, dotyczyła podwozia. W internetowych sklepach można znaleźć dużo komponentów, z których można złożyć własne podwozie – od fragmentów ram, czy wręcz gotowych zestawów konstrukcyjnych przez silniki, koła aż do zębatek, z których można samodzielnie składać odpowiednie przekładnie. Ponieważ jednak bardziej interesowało mnie zaprojektowanie części elektronicznej i oprogramowanie robota, zdecydowałem się na gotowe podwozie o nazwie Multi-Chassis 4WD DAGU DG012-ATV.

Mamy tu do czynienia z podwoziem czterokołowym z dosyć wysokim zawieszeniem oraz – co ciekawe – napędem na cztery koła: każde koło obracane jest niezależnym silnikiem. Trzeba uczciwie powiedzieć, że samo podwozie jest rewelacyjne – rama ma dziesiątki otworów, które śrubami M3 pozwalają przykręcić coś praktycznie w dowolnym miejscu; całość jest też dosyć lekka, ale jednocześnie wytrzymała, z 2,5mm grubości aluminium. Co więcej, w ramie znajduje się dedykowany otwór na serwo (rozmiaru, na przykład, TowerPro MG-995). Początkowo cieszyłem się, że będzie można w modelu bardzo łatwo zamontować serwomechanizm, ale szybko mina mi zrzedła: otwór wykorzystywany jest bowiem w innych wersjach podwozia – w wariancie ATV jest on bowiem bardzo skutecznie zasłonięty dwoma przednimi silnikami.

Kolejnym krokiem był wybór jednostki sterującej robotem. Wahałem się pomiędzy Raspberry Pi a Arduino, ale mój wybór padł dosyć szybko na ten drugi, ponieważ Raspberry charakteryzuje się znacznie większym poborem prądu, zajmuje więcej miejsca i na moje potrzeby jest po prostu za bardzo zaawansowane: sterowanie prostego robocika przy pomocy komputera z Linuksem wydało mi się niepotrzebną komplikacją. Dlatego też zaopatrzyłem się w oryginalne Arduino Leonardo – jest niewielkie, funkcjonalne i można je programować przy pomocy zwykłego kabla microUSB, których chyba w każdym domu walają się dziesiątki.

Teraz musiałem rozwiązać problem sterowania silnikami przy pomocy Arduino. Wśród wielu sterowników silników znalazłem DFRobot TB6612 Quad Motor Driver – idealny na moje potrzeby shield do Arduino pozwalający na sterowanie czterema silnikami szczotkowymi.

W kwestii zdalnego sterowania nie miałem większego wyboru – od lat jestem użytkownikiem aparatury FrSky Taranis, a w szufladzie po moich eksperymentach zostało kilka ośmiokanałowych odbiorników FrSky X8R, co w zupełności wystarczyło na moje potrzeby. Taranis to prawdziwy scyzoryk szwajcarski wśród aparatur modelarskich – w pełni programowalny, w odpowiednich warunkach pozwalający na wykorzystanie do 32 kanałów i w relatywnie przystępnej cenie (w porównaniu do podobnych aparatur firm typu Futaba czy Spektrum). Jeżeli ktoś wiąże plany z budową zdalnie sterowanych modeli, czy robotów, może zaopatrzyć się w młodszego brata Taranisa, czyli QX-7, który tylko w niewielkim stopniu ustępuje modelowi X9D.

Aby uczynić projekt nieco bardziej ciekawym, postanowiłem zamontować na robocie czujnik odległości US-015. Ten tani sensor pozwala wykrywać przeszkody w zakresie od 2cm do 4m. Aby zwiększyć możliwości robota, umieściłem go na serwie TowerPro MG-995. Do tak lekkiego montażu jest to nieco przesadzone rozwiązanie, ale dzięki temu robot będzie rozwojowy – na tak dużym serwie będzie można sporo zamocować.

Na koniec zasilanie – mojemu robotowi mocy dostarcza akumulator LiPo Gens Ace 1800 mAh o imponującej wydajności prądowej 40C (czyli możemy z niego przy napięciu 7.4V bezpiecznie pociągnąć 1.8*40 = 72A). Oprócz tego skorzystałem z małego modułu BEC (Battery Eliminator Circuit), który obniża napięcie do 5V – a takie właśnie potrzebne mi jest do zasilenia serwa.

Oprócz tego przyda się trochę drobnicy:

  • Przewodów połączeniowych m-m, m-ż i ż-ż

  • Kabli

  • Śrub M3 o różnych długościach oraz nakrętek

  • Dystansów aluminiowych i plastikowych

  • Zipów (trytek)

  • Płytek aluminiowych – na przykład fragmentów obudowy starego sprzętu

  • Kawałka kątowego profilu aluminiowego do montażu czujnika odległości

Nie obędziemy się też bez wtyczki 2.1mm do zasilenia Arduino.

Narzędzia

Podczas budowy robota przydały się:

  • Wiertarka z wiertłami 3mm (śruby) 4mm (otwory do trytek) i 7-8mm (otwory na przewody)

  • Do wiercenia otworów w aluminium przydaje mi się frez do wiertarki (technicznie nie używa się go do prac ręcznych, ale kto bym się tym przejmował). Oprócz tego korzystam też z małych kamieni szlifierskich, które przyspieszają obróbkę aluminium

  • Zestaw pilników

  • Lutownica

  • Mała wkrętarka (opcjonalnie – przyspiesza montaż niektórych elementów)

Montaż

Na początku montujemy podwozie – zgodnie z instrukcją. Fabrycznie silniki dostarczone są z wtyczkami JST, ale przewody są zbyt krótkie, by wygodnie je podłączyć do sterownika – a poza tym, jeżeli nie chcemy modyfikować sterownika silników – potrzebujemy na końcu każdego kabla gołego przewodu. Pierwotnie skorzystałem z przewodów żeńsko-żeńskich, które przeciąłem na pół i wykorzystałem jako przedłużacze do wtyczek. Znacznie bardziej praktyczne okazało się jednak usunięcie wtyczek i przedłużenie przewodów – w ten sposób można znacznie elastyczniej rozłożyć komponenty robota.

Kolejnym etapem jest przygotowanie dodatkowej płytki, na której zamontujemy Arduino i serwo – na fabrycznym podwoziu jest na to zbyt mało miejsca. Z większego fragmentu aluminium wyciąłem brzeszczotem płytkę o wymiarach 18cm x 13,5cm – są to dokładne wymiary obrysu robota.

W tak przygotowanym górnym podwoziu wycinamy otwór na serwo, nie zapominając o małych otworkach o średnicy 3mm, przy pomocy których przykręcimy serwo do płytki. Ja na początku nawierciłem kilka otworów wiertłami o różnych średnicach, potem skorzystałem z frezu by wyciąć aluminium, później małego kamienia szlifierskiego i na koniec – pilników. Serwo pasuje w wycięty otwór idealnie.

Górny pokład z dolnym połączymy przy pomocy dystansów aluminiowych – podniosą go one nad linię kół, zostawiając jednocześnie miejsce na dosyć spory akumulator. Długo zachodziłem w głowę, w którym miejscu przykręcić dystanse – w oryginalnej obudowie dosyć dużo miejsca zajęte jest przez silniki i pod płytką przykrywającą silniki nie ma miejsca na łby śrubek. Okazało się jednak, że zmieszczą się one pomiędzy silnikiem a przednią i tylną krawędzią podwozia – jest tam akurat tyle miejsca, żeby zmieściły się łby śrub. Dzięki temu montaż jest pewny – górny pokład nie będzie się giął ani chwiał, jest też sporo miejsca na umieszczenie akumulatora.

Przykręcamy do dolnej płytki dystanse, płytkę do podwozia (przeprowadzając wcześniej przez otwory przewody od silników) i w zasadzie całą dolną część mamy gotową.

Plan rozłożenia komponentów na górnym pokładzie jest na poniższym rysunku.

Aby schować plątaninę przewodów (bez której się nie obędziemy), Arduino umieściłem na półeczce podniesionej ponad górny pokład na plastikowych dystansach. Pod spodem można swobodnie zmieścić wszystkie przewody. Pamiętajmy, żeby ostrożnie dokręcać plastikową ramkę, na której leży Arduino, do aluminiowej półki – bardzo łatwo pęka pod naciskiem.

No to czas na plątaninę przewodów. Mamy kilka obszarów do okablowania:

  • Zasilanie 7.4V (Arduino i silniki)

  • Zasilanie 5V (Odbiornik RC, serwo)

  • Przesył danych (odbiornik RC, czujnik odległości i serwo do Arduino)

Na początek lutujemy przewód do wtyczki T-dean – będzie to główny przewód zasilający. Do niego lutujemy wtyk 2.1mm – zasilimy nim Arduino. Następnie lutujemy przewody do BECa i na koniec dwa dodatkowe, luźne przewody, które podłączymy do sterownika silników.

Wtyczkę z BECa podłączamy do nieużywanego kanału w odbiorniku RC – we wszystkich odbiornikach, z których korzystałem, piny 5V i GND są pozwierane, więc nie ma znaczenia, którymi z nich doprowadzimy zasilanie. Aby oszczędzić sobie lutowania, możemy też dzięki temu łatwo zasilić serwo – wystarczy w innym wolnym kanale wpiąć dwa przewody i podłączyć je do linii 5V i GND serwa. Bez obaw – odbiornik jest do tego przystosowany, w latających modelach zasila się w ten sposób serwa sterujące powierzchniami sterowymi.

Mocujemy teraz półkę z Arduino i chowamy plątaninę kabli pod nią. Kiedy to zrobimy, możemy zacząć łączyć piny danych.

Shield sterujący silnikami korzysta z pinów Arduino 3, 4, 5, 6, 7, 8, 11 i 12. Do pozostałych możemy więc podłączać wszystkie komponenty. Najpierw odbiornik RC – wykorzystamy tylko trzy kanały; łączymy je więc przewodami: kanał 1, 2 i 3 z pinami 0, 1 i 2 Arduino. Czujnik odległości podłączamy do pinów 9 (TRIG) i 10 (ECHO). Z uwagi na to, że pobiera on śladowe ilości prądu, możemy zasilić go bezpośrednio z Arduino – osobnymi przewodami łączymy piny 5V i GND.

Serwo mamy już zasilone, ale nikt nim nie steruje. Pojedynczym przewodem łączymy je z pinem 13 Arduino; pamiętajmy, że jest to też pin sterujący diodą LED na płytce.

Część obliczeniowa shielda sterującego silnikami zasilana jest bezpośrednio z Arduino, ale osobno musimy dostarczyć zasilanie do silników. Do tego celu wykorzystujemy dodatkowy kabel, który przylutowaliśmy wcześniej. Z drugiej strony przykręcamy przewody silników (uważając na polaryzację i kolejność silników). Na koniec pozostaje już tylko wpięcie wtyczki do Arduino, by prawidłowo je zasilić.

Schemat połączeń wygląda następująco (orientacyjny, komponenty na schemacie są podobne, ale nie takie same, jakich użyłem):

Gotowy robot prezentuje się następująco:

Programowanie

Możemy teraz zacząć programować naszego robota. Na początek napiszmy prosty programik, który sprawdzi, czy silniki są prawidłowo podłączone:

Sterowanie silnikami

Sterownik silników używa czterech pinów do sterowania kierunkiem obrotów silników i kolejnych czterech pinów do sterowania prędkością obrotu. Funkcje M_Advance i M_Back pozwalają łatwo sterować silnikami – powyższy programik powinien uruchomić kolejne silniki na pół sekundy, a potem zrobić przerwę na dwie sekundy – i tak w kółko.

Obsługa odbiornika RC

Odbiornik RC wysyła na każdym kanale sygnał PWM. Skrót ten rozwija się do Pulse Width Modulation – czyli modulacja szerokością pulsu. 55 razy na sekundę na przewodzie sygnału wzbudzane jest i wygaszane napięcie 5V. Czas trwania takiego wzbudzenia przekłada się na wartość sygnału: 1ms oznacza wartość minimalną, 1,5ms – wartość środkową, zaś 2ms – wartość maksymalną. Musimy więc napisać kawałek kodu, który rozpozna wzrost i spadek napięcia i zmierzy czas pomiędzy nimi. W tym celu skorzystamy z wygodnej biblioteki EnableInterrupt ( https://github.com/GreyGnome/EnableInterrupt ) – na potrzeby tego programiku wypinamy serwo z pinu 13 Arduino!

Powyższy kod działa w następujący sposób:

  • Na początku ustawia przerwanie, które wystąpi w momencie wzrostu napięcia na pinie 0 – powinna się wtedy wywołać funkcja pin0Rising.

  • Kiedy to się dzieje, zapamiętujemy liczbę mikrosekund od uruchomienia programu, zdejmujemy przerwanie dla wzrostu napięcia, a w zamian ustawiamy przerwanie dla spadku napięcia na pinie 0.

  • Kiedy to nastąpi (i wywoła się funkcja pin0Falling), po raz drugi sprawdzamy, ile upłynęło mikrosekund od startu programu; kiedy odejmiemy od tej wartości liczbę zapamiętaną w poprzednim przerwaniu, otrzymamy czas trwania pulsu w mikrosekundach.

  • Teraz możemy zrobić z otrzymaną wartością co chcemy – testowy programik zapala diodę na Arduino, gdy długość sygnału przekracza 1,5ms (położenie środkowe).

Mierzenie odległości

Trzeci programik „proof-of-concept” testuje działanie czujnika odległości. Również i dla tego typu czujników istnieje gotowa biblioteka, NewPing ( http://playground.arduino.cc/Code/NewPing ). Używa się jej bardzo łatwo – wystarczy poinformować ją tylko, na którym pinie podłączyliśmy pin sygnału wzbudzającego test odległości (TRIG) oraz pin odpowiedzi (ECHO).

Tym razem jest jeszcze łatwiej niż poprzednio – tworzymy obiekt NewPing o nazwie sonar, przekazując mu odpowiednie informacje. Teraz możemy korzystać z dostarczanych przez niego metod (na przykład ping_cm), aby otrzymać precyzyjną informację o odległości od przeszkody.

Przykładowy programik miga cyklicznie diodą Arduino; mignięcia są krótkie, jeżeli najbliższa przeszkoda na drodze czujnika jest dalej niż 30cm, a długie – gdy jest bliżej.

Program robota

Poniżej znajduje się kompletny kod robota pozwalający na jego zdalne sterowanie. Dodatkowo robot co pewien czas testuje obszar przed sobą i uniemożliwia ruch silników do przodu, gdy znajduje się zbyt blisko przeszkody.

Kilka szczegółów, które pomogą przeanalizować powyższy programik:

  • xValue i yValue przechowują położenie drążka w poziomie i pionie w zakresie od -250 do 250;
  • USCounter (UltraSonicCounter) to zmienna, przy pomocy której co 10 cykl wyzwalany jest test odległości.
  • DISTANCE_THRESHOLD_2 i DISTANCE_THRESHOLD_1 to odległości w centymetrach, przy których podejmowane jest odpowiednie działanie:
    • Jeżeli przeszkoda jest pomiędzy 80 a 40 cm od przodu robota, zmniejszana jest maksymalna prędkość obrotu silników do przodu o połowę (robot zwalnia).
    • Jeżeli przeszkoda jest bliżej niż 40 cm od przodu robota, maksymalna prędkość obrotu silników do przodu jest zerowana (silniki mogą kręcić się tylko do tyłu, więc robota można obrócić lub cofnąć, ale nie – pojechać do przodu)
  • Zmienna USLock decyduje o sposobie ograniczania silników: 1 – spowalniane, 2 – blokowany ruch do przodu, 0 – brak ograniczeń
  • sonar.ping_median powoduje, że test odległości wykonywany jest kilkukrotnie, a następnie zwracana jest mediana (wartość środkowa) – ogranicza to błędy pomiaru.

Uczymy się na błędach

Powiedzenie mówi, że człowiek uczy się na błędach, a mądry człowiek – na błędach innych. Oto kilka błędów, które popełniłem – możecie się ich ustrzec.

  • Podwozie jest bardzo fajne, ale za drugim razem wybrałbym raczej wersję na gąsienicach. Mało realne jest jeżdżenie takim podwoziem po terenie – piasek, kurz i pył lądują we wnętrzu robota, a autonomiczne poruszanie się po nierównym terenie na razie wykracza poza moje możliwości programistyczne. Poza tym wewnątrz byłyby tylko dwa silniki, co pozwoliłoby na montaż serwa w przeznaczonym dla niego miejscu.
  • Podwozie z dwoma silnikami zamiast czterech pozwoliłoby zastosować prostszy sterownik oraz zwolniłoby 4 dodatkowe piny – obecnie mam wykorzystane wszystkie. Alternatywnie można skusić się na Arduino Mega zamiast użytego przeze mnie Leonardo.
  • Razem z podwoziem dostarczony jest koszyk na baterie AA. Jest beznadziejny – trzeba się trochę napracować, żeby baterie prawidłowo stykały. A kiedy wszystko się uda, okaże się, że podczas obrotu silniki pobierają tak duży prąd, że powstaje przysiad napięcia i zarówno Arduino jak i odbiornik RC na chwilę tracą zasilanie. Wydajny akumulator Lipo rozwiązuje takie problemy.
  • Czujnik odległości radzi sobie dobrze z dużymi obiektami, natomiast słabo z niewielkimi, o nierównym kształcie lub z materiału (ten rozprasza ultradźwięki)

Podsumowanie

W ten sposób zbudowaliśmy platformę, którą możemy teraz oprogramowywać do jazdy samodzielnej. Oprócz kanałów 1 i 2, przy pomocy których sterujemy robotem, pozostaje nam jeszcze kanał 3. Możemy nim przekazać informację, czy robot ma reagować na zdalne sterowanie, czy jechać samodzielnie – w ten sposób odzyskamy nad nim kontrolę, gdy zajdzie taka potrzeba.

Ocena: 5/5 (głosów: 12)

Podobne posty

6 komentarzy do “Zdalnie sterowany robot

  • Dlaczego oksymoron? Robot może być autonomiczny, może być zdalnie sterowany, może być czymś pośrednim (jak mój – wspomaga sterowanie). Według Wikipedii: “Robot – mechaniczne urządzenie wykonujące automatycznie pewne zadania. Działanie robota może być sterowane przez człowieka, przez wprowadzony wcześniej program, bądź przez zbiór ogólnych reguł, które zostają przełożone na działanie robota przy pomocy technik sztucznej inteligencji.”

    Odpowiedz
  • Czy autko wysterowane do przodu jedzie faktycznie prosto? Robiłem kiedyś analogiczny temat (napęd tylko na przód) i niestety miałem z tym problem, nawet po zastosowaniu enkoderów ciężko było zsynchronizować obroty silników.

    Odpowiedz

Odpowiedz

anuluj

Masz uwagi?