Arduino + Matlab = Ramię robota

Arduino + Matlab = Ramię robota

 

Witam,

chciałbym przedstawić Wam mój projekt zaliczeniowy z przedmiotu Systemy Mikroprocesorowe. Przez  większość zajęć realizowaliśmy zagadnienia związane z Arduino, więc właśnie na tej platformie zrealizowałem swój projekt. Mnóstwo razy w internecie spotykałem się z pytaniami i problemami dotyczącymi połączenia Arduino i Matlaba, więc zdecydowałem się opublikować moją pracę – może ktoś z niej skorzysta. Na wstępie – Arduino można połączyć z Matlabem na dwa sposoby: za pomocą nakładki (do ściągnięcia w jednym z linków poniżej), dzięki której naszą płytkę możemy zaprogramować pisząc komendy w Matlabie lub za pomocą portu szeregowego. Dzięki pierwszej metodzie mamy od razu dostęp do wszystkich zmiennych, które możemy przedstawiać na wykresie lub realizować na nich różne operacje matematyczne. Ciekawą możliwością jest również napisanie prostego interfejsu graficznego do obsługi naszego programu na Arduino, więcej o tej metodzie: tutaj lub tutaj. Przy pracy z Matlabem polecam szukanie pomocy na oficjalnej stronie Mathworks, wszystkie funkcje są tam dokładnie opisane. Mimo to, samo programowanie mikrokontrolera w Matlabie jest dosyć toporne i przy moim projekcie zdecydowałem się na programowanie klasyczne, a komunikację z Matlabem nawiązałem drugim sposobem.

12544798_1292561870761310_1152922667_o

 

 

Założenia projektowe

Chciałem zbudować małe ramię robota zdolne do uniesienia i przemieszczenia małych obiektów. Podczas pracy dotarło do mnie, że samo sterowanie ręczne to trochę mało, ponieważ to tylko ładnie ubrane ruszanie czterema serwami, więc zacząłem pracować nad automatycznym znajdowaniem obiektu za pomocą kamerki internetowej i przenoszeniem go przez robota.

Jak to działa?

Myślę, że nie ma sensu omawiać konstrukcji projektu. Całość to po prostu cztery serwomechanizmy połączone jeden z drugim. Wszystko zmontowane z tego, co miałem pod ręką, ramię między trzecim serwem, a chwytakiem oraz biała podstawka to wycięte spienione pcv.

Wykorzystane elementy, o których warto wspomnieć:

Szukając ciekawych spoobów na sterowanie kilkoma serwami wpadłem na wykorzystanie myszy komputerowej. Wykorzystałem tę bibliotekę oraz ten schemat podłączenia. Całość nie powinna przysporzyć większych problemów. Strasznie irytująca okazała się praca nad zdjęciem izolacji i przylutowaniem kabelków od myszki, ponieważ są niesamowicie cienkie i łatwo się urywają.DSC_0039

Schemat układu:

schemat

A co z częścią automatyczną?

Niestety – to rozpoznawanie pozycji jest trochę oszukane. System faktycznie rozpoznaje gdzie leży obiekt, ale tylko, jeżeli znajduje się on w jednym z trzech wybranych miejsc.Napisanie programu zdolnego do pracy z obiektem znajdującym się gdziekolwiek w przestrzeni roboczej manipulatora byłoby dużo bardziej złożone, wymagałoby to między innymi rozwiązania odwrotnego zadania kinematyki i prawdopodobnie większość czasu, który poświęciłem na ten projekt pracowałbym nad czymś niezwiązanym z przedmiotem.

Aby Matlab mógł się dogadać z naszą kamerką internetową musimy mu zainstalować odpowiednią nakładkę. W górnym pasku ikon klikamy Add-Ons, wybieramy Get Hardware Support Packages, wybieramy Install from Internet i szukamy USB Webcams. Znowu odsyłam do strony Mathworks, z której sporo można się dowiedzieć.

Poniżej opiszę krok po kroku algorytm obróbki obrazu. Do artykułu dołączę kod źródłowy dla Arduino i dla Matlaba, a także “raport” z obróbki obrazu. Poniżej opiszę tylko najważniejsze funkcje tego skryptu. Jeżeli w poniższym opisie coś będzie niezrozumiałe – zerknij do kodu, może tam to się wyjaśni.

Na początek muszę zapisać sobie zdjęcie, które będzie stanowiło punkt odniesienia. Kamerkę ustawiam dokładnie tak, jak będzie stała przez cały czas działania programu, a następnie robię zdjęcie sceny bez taśmy klejącej (mojego obiektu, który staram się uchwycić):

Dosprawka_01

Takie zdjęcie pobieramy tylko jedno, będziemy z niego korzystać przy każdej iteracji skryptu.

Obraz możemy zapisać następująco:

 

Powinniśmy zobaczyć teraz okno z takim zdjęciem, klikamy na odpowiednią ikonkę i zapisujemy obraz w folderze roboczym matlaba jako plik .fig.

Kolejne kroki będą wykonywane co iterację.

Pobieramy aktualny kadr kamerki:

Dosprawka_03

Przenosimy obydwa obrazy na odcienie szarości:

Dosprawka_04Dosprawka_05

 

 

Następnie odejmujemy czarno biały obraz aktualny od wzorcowego. Matlab widzi obrazy jako macierz pikseli, więc jeżeli obrazy są takich samych rozmiarów, może je odjąć:

Dosprawka_06

Na wynikowym obrazie “bardziej białe” są obszary, w których obrazy różnią się najmocniej. W naszym przypadku – to taśma + jakieś zakłócenia.

To był ostatni krok w odcieniach szarości, teraz przechodzimy na zero-jedynkową formę, czyli obraz czarno biały. Idea jest taka: Wystarczająco różne od zdjęcia odniesienia fragmenty będą białe, inne czarne.

Dosprawka_07

Ostatni krok: usuwam wszystkie obszary o polu mniejszym, niż ustawione pole graniczne:

Dosprawka_08

Pozostaje nam wyłuskać z tego obrazu położenie obiektu. Robię to za pomocą funkcji regionprops:

 

imgclean to mój ostateczny obraz, Centroid odpowiada za zwrócenie środka masy obiektu, w tym przypadku będzie to dwuelementowy wektor zawierający współrzędne x oraz y środka białego pola. MajorAxisLenghth zwraca promień obszaru, ostatecznie nie wykorzystałem tego parametru.

 

Mając już dane dotyczące położenia naszego obiektu, wystarczy napisać warunek: jeżeli x jest taki, a y taki, wyślij do Arduino “1”, jeżeli taki, a taki, wyślij “2”, a jeżeli jeszcze taki i taki, to wyślij “3”.

Jak zrealizować to wysyłanie? Na początku używam funkcji:

 

Zapewnia ona wyczyszczenie portu szeregowego.

Następnie :

 

Te funkcje tworzą i otwierają komunikację szeregową z Arduino.

Pozostaje już tylko wysłać dane:

 

zmienne ax,ay,bx,by,cx,cy tworzę przed uruchomieniem całego programu, ustawiajac taśmę na miejscach 1,2,3 oraz odczytując wyznaczone przez program współrzędne środka dla tych położeń.

W tym momencie do Arduino zostaje wysłana cyfra 1, 2 lub 3. Robot będzie ignorował przychodzące do niego sygnały dopóki nie wcisnę buttona, wtedy odbierze tę aktualną pozycję i zgarnie taśmę. W kodzie Arduino “łopatologicznie” zapisałem trajektorię ruchu, którą robot musi wykonać, aby chwycić taśmę znajdującą się w każdym z położeń, czyli po prostu wpisałem, w jakiej kolejności muszą się ustawiać kolejne serwa i na jaką pozycję.

Ważna sprawa – kiedy otwieramy komunikację szeregową, Arduino resetuje się. Wystarczy, że klikniemy na “lupę” w kompilatorze Arduino IDE i możemy zaobserwować reset urządzenia. Aby uniknąć takiego ciągłego resetowania mojego robota, przylutowałem kondensator 10uF między pin RESET i GND (+ kondensatora do RESETu), szczegóły tutaj.

Wiem, że ten opis może nie wyjaśniać wszystkiego, jeżeli chcesz się czegoś dowiedzieć lub jest to niejasne – pytaj. Dla zainteresowanych tematem na tyle, żeby przejrzeć załączony kod z Matlaba – zdaję sobie sprawę, że nie jest on optymalny. Kilka operacji jest wykonywanych niepotrzebnie za każdą iteracją, zamiast tylko raz, ale całość jest w miarę prosta w zrozumieniu.

Komunikacja w drugą stronę

Udało nam się ustanowić komunikację w jedną stronę – Arduino odbiera sygnały wysyłane przez Matlaba. Czy da się zrobić coś podobnego, ale tak, aby to Arduino coś wysyłało, a Matlab odbierał i np. tworzył z tego wykresy w czasie rzeczywistym? Oczywiscie, że tak. Pamiętajmy jednak, że komunikacja za pomocą portu szeregowego nie może następować w dwie strony jednocześnie, musimy się zdecydować, czy odbieramy, czy nadajemy sygnał.

Jak wysłać sygnał z Arduino do Matlaba? Dokładnie tak samo, jak wysyłamy go do okienka z podglądem portu szeregowego – Serial.println() w zupełności wystarczy:

Po stronie Matlaba wygląda to następująco:

Po wykonaniu takich instrukcji, do zmiennej x przypiszemy zmienną, którą Arduino aktualnie wysyła przez port szeregowy. W moim projekcie wysyłałem 4 zmienne (pozycję każdego serwa) i chciałem obserwować je na czterech różnych wykresach, rozwiązałem to wysyłając je z Arduino do seriala jedno pod drugim, a w Matlabie:

 

%f oznacza, że chcę odebrać liczbę, [1,1] definiuje rozmiar, czyli chcę odebrać tylko jeden element.

Film z działaniem programu.

 

Używanie nakładki dla Arduino

Aby ją zainstalować, możemy skorzystać z jednego z linków ze wstępu lub z opcji Add-Ons -> Get Hardware Support Packages -> Install from Internet -> Arduino.

Zainstalowanie tego dodatku da nam do dyspozycji szereg funkcji umożliwiających pracę z Arduino, ich listę znajdziecie tutaj.

Jak wspominałem – napisanie całego programu za pomocą Matlaba jest wykonalne, ale strasznie toporne, a w dodatku mamy tutaj do dyspozycji ograniczone możliwości. Już pierwszym problemem jest chociażby wykorzystywanie jakichkolwiek zewnętrznych bibliotek do Arduino.

Mimo tego, że Matlab nie nadaje się do pisania funkcjonalnych programów na Arduino, można go wykorzystać w ciekawy sposób. Wpadłem na to rozwiązanie kiedy szukałem zamiennika dla oscyloskopu przy obserwowaniu sygnałów zmiennych w czasie. Świetnie spisał się następujący kod:

 

Nasz sygnał podłączamy do analogowego wejścia Arduino i już możemy podziwiać wykresy.

 

Tic rozpoczyna odliczanie czasu, toc przujmuje wartość równą ile sekund minęło od wywołania tic. Nasz program będzie rysował wykres napięcia na pinie A0 przez 10 sekund. Przykładowe wykresy:

pidstep2

przere

 

 

oscylacj

Jak widać, na osi poziomej nie mamy czasu, a numer próbki, ale to niewielka strata.

Załączniki i podsumowanie

Połączenie naszego mikrokontrolera z Matlabem jest naprawdę proste. Daje to kilka ciekawych możliwości, które przedstawiłem w tym artykule, ale to tylko te najprostsze. Arsenał tego połączenia jest dużo bardziej imponujący. W razie pytań lub problemów pytajcie – w miarę możliwości chętnie pomogę.

Załączniki_majsterkowo

Ocena: 4.47/5 (głosów: 49)

Podobne posty

11 komentarzy do “Arduino + Matlab = Ramię robota

  • Projekt zaawansowany. Gratulacje!
    Ciekawie opisany sposób rozpoznawania obrazu – nie miałem pojęcia jak takie rzeczy są robione.
    Teraz łyżka dziegciu – nie jest to niestety projekt dla domowych majsterkowiczów mn. dlatego że: użyty soft nie jest tani (poza zasięgiem domowego dłubacza), mała szansa na praktyczne zastosowanie w domu i zagrodzie :)
    Nie chcę krytykować bo doceniam i wiedzę autora i chęć podzielenia się nią z innymi ale lepszym miejscem na tego typu projekty byłby np. Forbot lub podobne forum hightech :)

    Odpowiedz
    • Darmowym zamiennikiem Matlaba jest Scilab, wersja niesamowicie zubożona, w której prawdopodobnie będzie brakowało tej wygodnej nakładki do podłączenia kamerki, ale jestem przekonany, że komunikacja z wykorzystaniem Seriala będzie działała tak samo ;)

      Odpowiedz
  • Hej, super artykuł, zastanawia mnie tylko jedna rzecz: Po co użyłeś Matlaba?
    Darmową i nieskomplikowaną alternatywą byłoby użycie pythona + openCV :)

    Odpowiedz
  • Właśnie się zastanawiałem jak skutecznie połączyć Arduino + Matlab, tak żeby możliwe było korzystanie z bibliotek Arduino, a nie tylko najprostsze komendy jak digitalWrite. Dzięki Wielkie – super poradnik!

    Odpowiedz

Odpowiedz

anuluj

Masz uwagi?