Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

(RaspberryPi + Node.js) == zdalnie sterowany pojazd

Gdy byłem małym chłopcem uwielbiałem zdalnie sterowane samochody. Zastanawiałem się wtedy – jak to działa? Koniecznie chciałem sam zbudować taki pojazd. Jako, że teraz lubię programować i „bawić się kabelkami”, stwierdziłem że marzenie z dzieciństwa najwyższy czas spełnić!

Założenia projektu

Pojazd ma być zdalnie sterowany, najlepiej z smartphona. Koszty mają być jak najniższe, obsługa jak najłatwiejsza, „gotowość” do jazdy jak najszybsza. Najlepiej żeby pojazd nie wymagał konfiguracji po ponownym włączeniu lub przeniesieniu w inne miejsce.

Potrzebny sprzęt, używane technologie

Do budowy pojazdu użyłem jednej z dostępnych podstawek z 3 kołami (2 napędzane silniczkami + 1 obrotowe). Do tego dokupiłem powerbank renomowanej chińskiej firmy „NoName” za 40 zł. Ma wyjście o natężeniu 2A, co było dla mnie wymogiem. Dorwałem też układ do sterowania dwoma silnikami. Sercem pojazdu jest tytułowe RaspberryPi B, które trochę odstaje od nowych wersji, ale nadal świetnie daje sobie radę. Jako że miałem je kupione wcześniej nie podniosło kosztów. Udało mi się znaleźć także starą kartę WiFi pod USB, więc komunikację także miałem już załatwioną. Kabelki, koszyk na baterie - no i oczywiście same baterie nie stanowiły żadnego problemu.
Na początku pojazd działał pod „opieką” programu napisanego w C++, jednak nie spełniał on moich wymagań. Musiałem wykombinować coś innego. Szybkie przeszukanie Internetu – Node.js. Zabawa sprzętem przez JavaScript? Brzmi dziwnie, ale… czemu nie? Użycie webowych technologii pozwala mi na sterowanie pojazdem z telefonu, a także komputera i to bez pisania specjalnych wersji na poszczególne systemy – po prostu miód.

Przyjemny początek

Jako że JS znam raczej dość dobrze, opanowanie podstaw i samej idei Node.js nie trwało długo. Ogólnie wychodzę z założenia, że najlepiej rzucić się na głęboką wodę, więc szybko ruszyłem z kodem. W krótkim czasie wykonałem szablon bardzo prostej strony - nie ma tam zbytnio co umieścić, a mój talent „projektowo-graficzny” reprezentuje ten sam poziom co umiejętność śpiewania – czyli tragedię. Utworzenie reakcji serwera na kliknięcia użytkownika na stronie dzięki socket.io też nie sprawiło problemów.

Przyszła pora na utworzenie plików odpowiedzialnych za sterowanie samym pojazdem. Na sam początek – możliwość połączenia się z serwerem odczytującym informacje od użytkownika. Teraz może nasunąć się pytanie – czemu nie można hostować strony na malinie? Nie chciałem jej zbyt przemęczać, to po pierwsze. Po drugie jeśli przeniosę pojazd np. do innego budynku i połączę się z inną siecią WiFi – skąd mam znać IP maliny? Hostując serwer na zewnątrz mam stały adres, a pojazd sam się z nim połączy. To rozwiązanie jest o wiele wygodniejsze. Przerzuciłem pliki na RPi, wszystko śmiga. Czas na sterowanie pinami. Okazało się, że istnieje specjalny moduł – pi-gpio (https://www.npmjs.com/package/pi-gpio). Stosuje się go praktycznie tak samo jak znane mi wcześniej WiringPi dla C++. Nawet osoba początkująca nie powinna mieć z tym większych problemów.

Mniej przyjemny dalszy ciąg

No i gdy wszystko pięknie działa lokalnie – czas przerzucić pliki serwera na zewnętrz. Wybór padł na Heroku – oferują konto za darmo, a wszystko jest ładnie opisane. Wcześniej nie miałem do czynienia z platformami chmurowymi. Poczytałem trochę, pobrałem potrzebne pliki. Heroku jest mocno związane w Gitem. Z tym się już spotkałem, jednak tylko w narzędziu VS, które jak to głosi Internet – jest złe, niegodne porównywania z Gitem w trybie poleceń i powinno zostać niezwłocznie unicestwione. Tak więc bez bagażu doświadczenia ruszyłem w świat komend i czarnego okienka. Zalogowanie się, utworzenie repozytorium i wysyłka wszystkiego do spokojnych-chaszczy-7309, bo taką nazwę wygenerowało mi Heroku, miało być łatwe i przyjemne. Nie do końca takie było.

Aplikacja z tutoriala działała, jednak mój kod już nie. Coś musiałem źle napisać. Całe szczęście – tysiące internautów miało przecież ten sam problem co ja! Kochany stackoverflow jak zawsze uratował mi życie, choć nie było łatwo. Na początek – ustalanie potrzebnych modułów i ich wersji. Potem dowiedziałem się o istnieniu Procfile, który działa chyba tylko w kodowaniu ANSI. W edytorze tekstu mam natomiast domyślnie ustawione UTF-8, więc można się domyślić jakie były efekty i ile czasu zajęło mi dojście co jest źle. Jednak mimo wszystko aplikacja nadal się wysypywała.

Po wielu przeglądniętych wątkach okazało się, że w skrócie nie mogę ustalać nasłuchiwania na porcie 80 „tak zwyczajnie”. Nie wiem tylko czy ominąłem to przypadkowo podczas czytania, czy jest to aż tak oczywiste w świecie Node.js.

Świat rzeczywisty – złóżmy to w całość!

Przyszedł wreszcie czas na złożenie całego pojazdu. Podstawka ma mnóstwo miejsc na śrubki. Niby fajnie, jednak żadne z tych miejsc nie pasowało do mojego układu… chyba, że tak:

Ale spokojnie, gdy śrubki nie dadzą rady poratować mogą dwie rzeczy, niezbędniki każdej prowizorki – taśma klejąca i trytytka znana bardziej pod pseudonimem „plastikowa opaska” lub „to coś do kabli”. Zdecydowałem się na bardziej estetyczną, drugą opcję. Sam wygląd może nie zachwyca, ale pojazd jeździ!

Ostatnie szlify, trochę Linuxa

Na Linuxie pracuję strasznie rzadko. Jednak, jako że jest on na malinie, musiałem stawić mu czoła. Zadanie? Ustawić odpowiednio kartę WiFi, a także wrzucić uruchamianie mojego pliku do hm… odpowiednika autostartu z Windowsa. Szybki przegląd pierwszej strony w Google, napisanie krótkiego skryptu i działa! Od tego momentu wystarczy podpiąć zasilanie do RPi, poczekać chwilkę i dzieje się magia - pojazd czeka na polecenia bez bawienia się w wpisywanie loginów, haseł, IP, a także bez łączenia się kontrolerem do tej samej sieci.

Krótkie podsumowanie

Projekt został ukończony, założenia spełnione. Najfajniejsza rzecz? Zdecydowanie parogodzinna frajda. Najlepsza rzecz? Nowe doświadczenia i nowa wiedza. Dodatkowe bonusy? Spełnione marzenie z dzieciństwa. Myślę, że był to świetnie wykorzystany czas, a tym wpisem zachęcę kogoś do podobnych działań. Wszelkie pytania i uwagi mile widziane!
Jeśli masz jeszcze 35 sekund wolnego czasu, zapraszam do obejrzenia pojazdu w akcji:
 

programowanie hobby inne

Komentarze

0 nowych
Magnum 44   16 #1 19.02.2015 12:25

Super sprawa! Słyszę, że tam w tle klikasz myszką. Może warto by było zrobić jakąś apkę na telefon do sterowania, ew. zbindować strzałki na klawiaturze komputera? :)

Astis   3 #2 19.02.2015 12:32

Na telefonie można bez problemu sterować z przeglądarki, taki w sumie był cel, ale czymś musiałem nagrać filmik ;) A pomysł z bindowaniem strzałek na 100% zrobię dziś albo jutro, dzięki!

En_der   9 #3 19.02.2015 12:37

Fany wpis. Osobiście jestem zwolennikiem konstruowania tego typu pojazdów, ale z zastosowaniem ATmeg. Wychodzi taniej. No ale zawsze satysfakcja bez względu na koszta jest bezcenna.

aPoCoMiLogin   7 #4 19.02.2015 13:49

Node jest zajebisty, byłem ciekaw czy wykorzystałeś websokety, podejrzałem źródło i się nie zdziwiłem ;)

cyryllo   16 #5 19.02.2015 14:04

Szkoda, że tak mało opisałeś połączenie układu całego. Kilka zdjęć elektroniki i było by Git ;)

Astis   3 #6 19.02.2015 15:28

En_der: Dzięki. Nigdy nie bawiłem się w ATmegi, może kiedyś spróbuję.

aPoCoMiLogin: I strasznie wygodnie się tego używa. Szkoda, że tak późno się przełamałem z tą technologią.

cyryllo: To jest tylko parę kabelków, w sumie nie ma zbytnio co opisywać pod tym względem.

flaszer   10 #7 19.02.2015 15:48

Repo siedzi na GitHubie? Możesz rzucić linkiem?

Astis   3 #8 19.02.2015 17:20

@flaszer: Nie siedziało, ale już siedzi.
Pliki "serwera": https://github.com/Astisus/RPiNodeServer
Pliki klienta na malinę: https://github.com/Astisus/RPiNodeClient

jarodebombel   7 #9 19.02.2015 18:30

A już miałem wpisać, po przeczytaniu komentarza @cyryllo, żebyś na Git'a kod wrzucił... Telepatia? Dzięki!

flaszer   10 #10 19.02.2015 21:43

@Astis: Dzięki ;)

  #11 21.02.2015 12:11

Fajny projekt, ale przydały by się mechanizmy właśnie nadzorujące sesję połączeniową, robiłem w ramach inżynierki taki projekt, tutaj filmik:

https://www.youtube.com/watch?v=U5ou7CYnsGg

z kamerką i innymi pierdołkami, przeglądarkowa wersja była słaba (początkowo korzystałem z Apache). Możesz pomyśleć o nad właśnie przejściem na natywną aplikację, jeśli masz nadal ochotę się bawić dalej :).

Astis   3 #12 21.02.2015 17:19

@Anonim (niezalogowany): Mój pojazd wygląda jak ubogi brat twojego ;) Miałem pomysł podłączenia kamerki - nawet próbowałem, jednak była to kamerka na USB i uzyskiwałem z niej bardzo, bardzo wolny pokaz slajdów (albo coś źle robiłem).

Natywna aplikacja - tego chciałem uniknąć, a websockety działają bardzo sprawnie (nie odczuwam opóźnień nawet przez Heroku).

Co do "mechanizmu nadzorującego sesję połączeniową" to szczerze nie wiem co dokładnie przez to rozumieć. Możesz to rozwinąć?

  #13 23.02.2015 12:31

@Astis: Chodziło mi o zalety łączności opartej na gniazdach, chociaż z tego co piszesz używasz websockety, sorki za ignorancję, nie wiem jak to działa, być może tak samo jak komunikacja na gniazdach w C++.
Generalnie jak sterowałem za pośrednictwem Apache, strony, to nie miałem kontroli nad podłączonym klientem, serwer nie wiedział kiedy ktoś się połączył. Na Soketach w razie rozłączenia zapobiega kolizji pojazdu np, dodatkowo mam czujnik odległości który też w razie draki zatrzyma pojazd.
Pojazd wygląda podobnie, największym problemem był obraz z kamery na żywo, bez opóźnień, przy 25 fps. Z tym się bawiłem dużo, jak byś się chciał pobawić, zainteresować tematem, to pod filmem podałem repo gita, serwer zawsze zapominał pushnąć, w razie czego chętnie pomogę, sam się zastanawiam co dalej kombinować, chyba na początek zamówię nowe PI.

  #14 19.06.2015 11:38

Chciałeś aby Twój pojazd działał wszędzie. Ale jeśli dobrze rozumiem i tak musisz mu podawać namiary na sieć wifi w jakiej się znajdzie? Czy nie jest to równie kłopotliwe jak ustalenie i wpisanie przyznanego IP?

Astis   3 #15 19.06.2015 18:37

@Anonim (niezalogowany): Wiesz, ciężko jest w tej sytuacji wyeliminować każdą niedogodną sytuację. Robot łączy się automatycznie jeśli znajdzie sieć bez zabezpieczenia i to w tym scenariuszu oszczędzany jest czas. Ogólnie dobre pytanie, widać że dokładnie czytałeś tekst, dzięki ;)

  #16 22.06.2015 10:57

Dzięki za szybką odpowiedź! To dorzucę jeszcze małą propozycję od siebie. Proponuję wrzucić na pokład wyświetlacz LCD, na którym nasz pojazd po zalogowaniu do sieci mógłby się przedstawić? Od razu byłoby wiadomo jakie IP wpisać w przeglądarce. Wtedy można by jednak trzymać serwer na RPi, obejść się bez chmury i domyślam się, że reakcje na sterowanie byłyby znacznie szybsze.

Astis   3 #17 29.06.2015 12:28

@Anonim (niezalogowany): To świetny pomysł, ale na nowe maliny. Na mojej chyba zabrakłoby mi pinów (kiedyś bawiłem się z jednym wyświetlaczem i zajmował większość pinów). Co do opóźnień - w domu nigdy nie mogłem narzekać, reakcje były natychmiastowe. Jednak w szkole przy obciążeniu sieci musiałem właśnie raz wyjątkowo przerzucić serwer na komputer znajdujący się w tej samej sali ;)

  #18 25.09.2015 14:49

Hej - dasz namiary na wózek/podstawkę? Gdzie można takie podstawki z kółkami zamówić?

Astis   3 #19 25.09.2015 23:24

@Anonim (niezalogowany): Kupowałem większość rzeczy w Botlandzie. Widzę, że nie mają aktualnie identycznego zestawu i jakoś drożej się zrobiło. Jeśli zależy Ci na cenie to śmiało możesz ściągać takie rzeczy z Aliexpress - na świetną jakość i wytrzymałość nie masz co liczyć w takich zestawach obojętnie gdzie kupisz i za ile ;)

  #20 26.09.2015 13:51

@Astis: dzięki za odpowiedź i inspirację! Zamówiłem kilka części i coś będę próbował, może dodatkowo z kamerą i modyfikując stronę sterowania żeby zawierała iframe ze stream'em obrazu? Pomysłów jest kilka!

Nie myślałeś może, żeby zasilanie silniczków zrobić z drugiego portu USB powerbank (5v, 1A powinno wystarczyć), tak żeby nie być uzależnionym od dwóch źródeł?

Astis   3 #21 27.09.2015 12:03

@Anonim (niezalogowany): To dobry pomysł ale mocno skraca czas jazdy. Baterie ze spokojem wystarczyły mi na parę dni zabawy podczas gdy powerbank został wyczerpany przez samą malinę kilka razy. Dodatkowo koszyczek baterii ma 6V czyli "max" dla tych silniczków co też jest jakimś plusem.

  #22 01.10.2015 12:28

@Astis: możesz proszę podpowiedzieć czym w Twoim projekcie clienta są piny enableA (7) enableb (21) oraz ich fizyczne umiejscowienie w PI?
Byłbym wdzięczny, gdybyś podpowiedział jak mam dostosować tę konfigurację do moich potrzeb, gdzie do sterownika silników mam wpięte GPIO 5, 6, 12 i 13 (nomenklatura PI, fizyczne to są zdaje się piny: 29,31,32,33 - patrząc na PI to jedne z ostatnich "po prawej stronie"). Używam wersji B+ więc są to "dodatkowe" piny.
Sterownik, którego używam to: DRV8835

Astis   3 #23 06.10.2015 20:28

@Anonim (niezalogowany): Sorry, że dopiero teraz odpisuje, ale mam aktualnie trochę urwanie głowy. Postaram się Ci pomóc w weekend ;)

  #24 11.04.2016 11:19

a jakby poprosru skonfigurowac maline do pilota zdalnie sterowanego auta ? nie byloby prosciej ?

Astis   3 #25 16.04.2016 11:15

@Anonim (niezalogowany): Gdybym miał taki pilot i wiedziałbym jakie częstotliwości odpowiadają konkretnemu przyciskowi - byłoby to jak najbardziej wykonalne.