(RaspberryPi + Node.js) == zdalnie sterowany pojazd
19.02.2015 13:11
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: [youtube=https://www.youtube.com/watch?v=l1UwL0LlIjQ]