Łazik z NASA Space Apps Challenge – szczegóły techniczne

ucgosu.pl 6 lat temu

Ostatnio pisałem relację z NASA Space Apps Challenge. Dzisiaj pora na trochę szczegółów technicznych dotyczących naszej konstrukcji. Wybraliśmy temat „Can you build a …” i podtemat „Make Sense Out of Mars”. Celem było stworzenie sensora, który mógłby pomóc pierwszym kolonizatorom Marsa. Naszym czujnikiem był oczywiście łazik. Jego zadaniem miało być zbieranie informacji o najbliższym otoczeniu obozowiska z uwzględnieniem zróżnicowania terenu i potencjalnych niebezpieczeństw takich jak np. doły i kratery.

Założenia

Naszym głównym założeniem było skonstruowanie robota mobilnego z kamerą. To co miał dokładnie robić było już sprawą drugorzędną. Drugim ważnym założeniem było poznanie technologii, z którymi nie mieliśmy wcześniej styczności. Najważniejszą z nich był ROS – Robot Operating System. Działa on pod Linuxem i zawiera moduły obsługujące praktycznie wszystko co może przydać się w robotyce, a więc między innymi:

  • Nawigację
  • Mapowanie terenu
  • Obsługę czujników
  • Komunikację
  • Obliczenia fizyczne i matematyczne
  • Analizę obrazu
  • Planowanie trasy

Do tego chcieliśmy wykorzystać technologie Intela:

  • RealSense – kamerę zwracającą poza zwykłym obrazem również informacje o odległości.
  • Movidius – jednostkę obliczeniową do sieci neuronowych. Dzięki temu obliczenia mogą odbywać się na pokładzie robota i nie trzeba ich przesyłać do chmury.

Początkowo był plan, żeby użyć Intel Euclid, czyli płytki z Linuxem i postawionym ROSem zintegrowanej z RealSensem i baterią. Niestety nie udało się otrzymać Euclida z próbek. A szkoda, bo – jak się miało później okazać – oszczędziłoby to nam ogromnej ilości problemów.

Poza tym chcieliśmy również wypróbować kilka bibliotek i tooli na mikrokontrolery:

  • C++ – programu na pewno nie chcieliśmy pisać w C. Przez myśl przeszły mi jeszcze Rust i Ada, ale tam by było trudniej o gotowe biblioteki, które na hackatonie są gwarancją sukcesu.
  • DistoRTOS – system operacyjny na STM32 napisany w C++. Od dłuższego czasu miałem zamiar go wykorzystać, ale jeszcze nie było okazji.
  • Kvasir.io – biblioteka do obsługi rejestrów peryferiów bazująca na templatach.
  • cmake – system buildowania bardziej przyjazny od pisania wszystkiego bezpośrednio w makefile.
  • Ninja – też system buildowania, ale bardziej lowlevelowy. Cmake generuje skrypty dla make albo ninja do późniejszego wykonania adekwatnego builda.

Koncepcja systemu

Początkowa koncepcja systemu została narysowana na kartce:

Głównym elementem jest Raspberry Pi (korzystaliśmy z wersji 3B+) z działającym ROSem. Podłączamy do niego RealSense, Movidiusa i STM Discovery F4. W planach było również podłączenie do RPi czujnika IMU z akcelerometrem, żyroskopem i magnetometrem, ale na razie tego nie zrobiliśmy. Komunikacja z STMem odbywa się po UART. Głównym zadaniem STMa jest sterowanie czterema silnikami dzięki mostków H. Jako podwozie użyliśmy gotowego kita Pirate 4WD z czterema kołami i silnikiem podłączonym niezależnie do każdego z kół. Logika zasilana jest z powerbanka, a silniki z LiPola 2S 800mAh. Z zasilaniem logiki trochę przesadziliśmy bo powerbank ma 30Ah, jest ciężki i zajmuje ogromną ilość miejsca, a energii daje tyle, iż nigdy go nie rozładujemy. Ale akurat takiego mieliśmy pod ręką. Do tego wykorzystaliśmy jeszcze płytkę stykową, żeby rozprowadzić zasilanie z lipola na mostki H i połączyć z przyciskiem ON/OFF.

Trochę używanych części

Przy okazji taka dygresja – o ile kiedykolwiek przyjdzie wam do głowy, żeby robić na hackatonie projekt hardware’owy, nie nastawiajcie się na zrobienie powalającego systemu. Projekty czysto software’owe są dużo prostsze do wykonania, nie trzeba się tyle wcześniej przygotowywać i nie trzeba mieć wszystkich elementów pod ręką. Dodatkowo w trakcie więcej rzeczy się może zepsuć, a realizowalność na hardware bardzo mocno weryfikuje wszystkie pomysły. Dlatego jak mierzycie w sukcesy, albo po prostu chcecie oszczędzić sobie pracy – skupcie się na samym sofcie. To samo tyczy się np. projektów na uczelnie.

Ok, to teraz pora na omówienie problemów, jakie mieliśmy.

ROS na Raspberry Pi

TLDR: Nie udało nam się postawić ROSa na Raspberry.

Przed hackatonem uruchomiliśmy pierwszy znaleziony w necie image na RPi z ROSem i działał. Myśleliśmy, iż to wystarczy. Okazało się, iż to starsza wersja, gdzie nie było części potrzebnych nam modułów. Głównie chodziło o RealSense. Jest to zastanawiające, ponieważ istnieje projekt TurtleBot wspierany przez duże firmy takie jak Intel, czy Microsoft. W specyfikacji można wyczytać, iż wykorzystuje on właśnie Raspberry i RealSense. Nasz RealSense jest co prawda nowszy – wersja R300, a w TurtleBocie jest R200. Ale zgodnie ze specyfikacją oba korzystają z USB 3.0. Może to jest przyczyna problemów.

W każdym razie podczas hackatonu sprawdziliśmy kilkanaście różnych image’ów karty SD. Próbowaliśmy z Raspbianem i UbuntuMate. Każdy z nich trzeba było ściągnąć z neta a WiFi nie było najwyższych lotów i potrafiło się w trakcie zawiesić. Poza tym na niektórych imagach próbowaliśmy kompilować ROS ze źródeł na RPi. Trwało to długo i czasem się wieszała, prawdopodobnie z przegrzania.

Ostatecznie nie wykorzystaliśmy w ogóle ROSa, a RPi miało tylko proste streamowanie obrazu ze zwykłej kamery USB po WiFi.

Po hackatonie prawdopodobnie zrezygnujemy z Raspberry. Pojawiła się opcja, żeby wykorzystać płytkę zawierającą Intel Atom, który obsłuży ROSa i STM32F4, który zastąpi Discovery. Wtedy nie powinno być już żadnych problemów z podłączeniem RealSense.

RealSense

Samo RealSense najpierw próbowaliśmy uruchomić z PCta. Pierwszym problemem było znalezienie odpowiedniego kabla. Mieliśmy moduł RealSense ze specjalnym złączem i drugą płytkę – konwerter na USB 3.0 micro B. Po podłączeniu okazało się, iż w naszym RealSense działa tylko czujnik odległości. Kamera RGB nie przesyła obrazu. Nie spodobało się to programowi z oficjalnego SDK, który z tego powodu wywalał exceptiony. Trzeba było odpowiednio zmodyfikować kod. Czujnik jest bardzo delikatny i nie mieliśmy go w wersji z obudową. Możliwe, iż się uszkodził. Drugą, mniej prawdopodobną, opcją są jakieś problemy z driverami.

Pierwsza wersja robota – jeszcze wykorzystywał RealSense na serwie.

STM32F4 Discovery

Początkowo oczywiście mieliśmy problemy z podłączeniem debugera do PC. Wykorzystywaliśmy nowe Discovery i oczywiście na początku nie działało z OpenOCD. Okazało się, iż skrypty dla płytki korzystają z stlink-v2, a powinny z stlink-v2-1. Między tymi wersjami zmieniły się ID device USB i system ich nie rozpoznawał.

Stanowisko testowe – koła są w powietrzu, więc można spokojnie sprawdzać działanie silników.

Plany wykorzystania bibliotek również się nie udały. Kvasir na razie jest dopiero w wersji eksperymentalnej. Na masterze nie ma naszego procka. Ostatni commit z końca 2017. Ostatni release – i za razem pierwszy – (0.1.0) z 2016. W sumie można było to wcześniej sprawdzić i nie robić sobie nadziei.

DistoRTOS – miałem nadzieję, iż łatwo się doda do naszego projektu i uruchomi wszystko od ręki. Są skrypty dla F4 Discovery i komenda do wklejenia w readme. Liczyłem jednak, iż dodam go bezproblemowo do istniejącego projektu. Po chwili stwierdziłem, iż na DistoRTOS będę potrzebował więcej czasu. Dlatego zapadła decyzja, żeby wszystko klepać w czystym c++ a do DistoRTOSa wrócić po hackatonie.

Pisanie w c++ na czystym projekcie też nie przebiegło bez problemów. Moje skrypty linkera nie radzą sobie z konstruktorami statycznych obiektów, które są inicjalizowane w startupie przed wejściem do funkcji main. To też temat na dłuższą rozkminę, więc zostaje do naprawienia później. Prawdopodobnie użyję skrypty z DistoRTOSa, gdzie ten problem jest rozwiązany. Przy okazji producenci procków np. STM udostępniają tylko proste skrypty linkera, które wspierają jedynie C.

Bez Kvasira trzeba było na bieżąco wymyślić sposób obsługi rejestrów sprzętowych. Początkowo chciałem wzorować się na rozwiązaniu opisanym na blogu Faebhas. Jednak ostatecznie okazało się, iż jest to przerost formy nad treścią. Drivery zostały zrealizowane jako klasy, inicjalizacja była ukryta za warstwą abstrakcji. Przerwania były obsługiwane przy wykorzystaniu klas z metodami statycznymi. Opiszę jeszcze dokładniej tą koncepcję. Stworzyłem ją na gwałtownie i docelowo pewnie trzeba będzie ją ulepszyć.

Kolejną rzeczą jakiej nie udało się dodać do STMa była integracja z biblioteką ros_serial_client. Implementuje ona komunikację z ROSem. Dzięki temu silniki mogą być obsługiwane na STMie, a RPi wyśle tylko odpowiednie komendy na topic obsługiwany przez tą bibliotekę. Niestety repo nie jest wystarczające do uruchomienia biblioteki. Folder rosserial_msgs nie zawiera źródeł, trzeba je sobie samemu wygenerować. Są do tego odpowiednie skrypty, które z kolei zależą od Catkina, który służy w ROSie do buildowania i korzysta z cmake i pythona. Kiedy w niedzielę rano doszedłem do tego Catkina i spytałem co to jest chłopaki, którzy męczyli się już cały poprzedni dzień z ROSem tylko mnie wyśmiali. Mieli choćby na RPi z poprzednich kompilacji wygenerowane jakieś rosserial_msgs, ale jak po uruchomieniu Catkina zamiast sourców pojawiły się kolejne skrypty do uruchomienia, daliśmy sobie spokój.

Nic nie działa, od patrzenia w ekran się nie naprawi

Jedyną nową rzeczą, która faktycznie zdała egzamin był cmake i ninja. Rebuild całego projektu od zera z użyciem ninja zajmuje mniej niż kompilacja inkrementalna z makefile. I robiła się zwykle w mniej niż sekundę. Sam cmake też mocno upraszcza tworzenie skryptów buildowania.

Składanie Hardware’u

Organizatorzy udostępnili nam drukarkę etykiet, dzięki czemu mogliśmy opisać przewody. Część z nich się odkleiła, ale i tak to bardzo fajny wynalazek. Na niewykorzystane goldpiny naklejaliśmy taśmę, żeby je zaizolować. Miałem już wcześniej doświadczenia z ruchomymi evalboardami, które na poruszającym się robocie powodowały zwarcia i spalały całą elektronikę. Podłączanie wszystkiego do kupy pozostało oczywiście na ostatnią chwilę. Na szczęście poszło bardzo sprawnie i udało się wszystko odpalić za pierwszym razem. Korzystałem tu z wcześniejszego doświadczenia i po podłączeniu każdego modułu starałem się na bieżąco sprawdzać, czy wszystko działa. W trakcie podłączania trzeba było tylko przelutowywać przewody od przełącznika ON/OFF. Cały zespół uczestniczył w akcji i przypominało to trochę operację chirurgiczną. Ostatecznie wszystko działało i nic nie spaliliśmy, więc pod tym względem pełny sukces.

Praca zespołowa przy składaniu i lutowaniu robota

Co dalej?

Będziemy na spokojnie rozwijać dalej projekt. Uruchomimy niedziałające elementy, to co się nie da uruchomić zastąpimy nowymi. Części działające na gwałtownie podmienimy na takie od zaprzyjaźnionych firm. Sam łazik będzie wykorzystywany jako atrakcja na różnych eventach.Dodatkowo jest plan, żeby zrobić z niego pomocnika biurowego i może choćby przerodzi się w komercyjny produkt. Na razie rozwijamy go jako open source. Kod można zobaczyć na GitHubie. Na razie za wiele tam nie ma – tylko prosty programik na STM, który steruje silnikami, żeby w kółko wykonywały te same operacje. Z czasem dodamy do projektu też kod na ROSa i pomyślimy o jakimś procesie prowadzenia projektu wykorzystującym toole do CI, statycznej analizy itp.

Na koniec jeszcze filmik z działającym robotem:

Idź do oryginalnego materiału