Popularny post ZbychuW 12 Napisano 16 marca Popularny post Udostępnij Napisano 16 marca Witam Ostatnio pracuję nad wersją robota mobilnego, którego głównym celem jest budowa mapy terenu. Budowa wkroczyła w fazę testów, a te mogą trwać długo, wiec postanowiłem zaprezentować efekty swoich prac. Wiem, że pajęczyna kabli nie wygląda starannie ale bez przerwy coś podpinam i odpinam, więc musi tak zostać. Sterowanie pojazem jest podzielone na dwa obszary: RaspberryPi i Arduino w wersji Mega. Komunikacja szeregowa za pomocą komunikatów przesyłanych w dwie strony. Po stronie Ardiuno, cała kontrola napędów i czujników. Po stronie RPi moduł rozpoznawania obrazów bazujący na OpenCV, generator komunikatów słownych wykorzystujący kartę dźwiękową WM8960 oraz moduł odwzorowania terenu wykorzystujący pomiary odległości, lokalizację w pomieszczeniu i rozpoznawanie przedmiotów. Do napędu użyłem 4 silników DC z enkoderami. Wykorzystałem 4 przerwania z Megi do pomiarów i algorytm PID do kontroli stabilności prędkości obrotowej poszczególnych silników. Ponieważ pojazd nie ma osi skrętnej, ważna jest precyzyjna kontrola poszczególnych napędów. Do kontroli silników DC i serw obrotu kamery i czunika odległości wykorzystuję Shield sterownika L293D. Komunikaty głosowe generowane są za pomocą pakietu Espeak z modyfikacjami poprawiającymi wymowę polskich słów. Dodatkowo komunikaty są wyświetlane na 4 wierszowym wyświetlaczu z tyłu pojazdu. Elementy drukuję na Enderze. Modele częsci powstają w OpenCADzie. Mapa terenu powstaje w formie siatki punktów, które za pomocą algorytmów pomiaru gęstości przekształcane są w odcinki. Raspberry ma własne zasilanie z baterii polimerowej a silniki napędowe z akumulatora 6V. Na czas prób przełączam się na zasilacz labolatoryjny. Niestety ze względu na rozrzut parametrów, jakość sterowania równomierności silników jest dosyć kłopotliwa. Myślę, że w następnym modelu zastosuję silniki krokowe. Warto też pomyśleć o osi skrętnej, bo sterowanie obrotami nie jest tak precyzyjne. Aktualnie pracuję nad dokładnością odwozrowania lokalizacji w pomieszczeniach. Testuję różne elementy mierzące odległość i lokalizację. Jeśli ktoś z kolegów buduje podobne urządzenia chętnie wymienie się uwagami. 6 Cytuj Link to post Share on other sites
Gieneq 1 794 17 marca Udostępnij 17 marca @ZbychuW ciekawy projekt, dziękujemy za publikację 9 godzin temu, ZbychuW napisał: Po stronie Ardiuno, cała kontrola napędów i czujników. Po stronie RPi moduł rozpoznawania obrazów bazujący na OpenCV, generator komunikatów słownych wykorzystujący kartę dźwiękową WM8960 oraz moduł odwzorowania terenu wykorzystujący pomiary odległości, lokalizację w pomieszczeniu i rozpoznawanie przedmiotów. Mógłbyś umieścić kod programu lub inne szczegóły? Cytuj Link to post Share on other sites
ZbychuW 12 18 marca Autor tematu Udostępnij 18 marca (edytowany) Ponieważ kod programów po stronie RPi i Arduino jest dosyć obszerny postanowiłem umieszczać poszczególne fragmenty z odpowiednimi komentarzami. Na pierwszy ogień sterowanie silnikami DC z enkoderami. W załączniku umieściłem kod programu na Arduino po usunięciu wszystkich zbędnych fragmentów. W kolejnych wpisach będę dodawał opisu kolejnych funkcji. Do napędu wykorzytuję 4 silniki z enkoderami (SJ02 120:1 6V 160RPM + enkoder). Umieszczone w dolnej części podstawy i mocowane za pomocą wsporników wydrukowanych na drukarce Ender 3D (pliki w formacie STL w załączniku - lewy i prawy) . Do paczki plików dodałem elementy osłony kabli, ochrony otworu w podstawie i podstawkę pod Arduino. Ponieważ wykorzystuje 4 silniki i do każdego należy utworzyć niezależne zmenne i metody, do osbługi utworzyłem klasę Motor. Opis znaczenia poszczególnych zmiennych i metod znajduje się w komentarzach kodu. Najważniejsze w programie są dwa elementy: obsługa enkodera i algorytm PID. Kluczowym elementem umożliwiającym odczyt pulsów z enkodera jest metoda podpięta pod odpowiednie przerwanie. Ponieważ liczba dostępnych przerwań jest zależna od modelu Arduino a ja potrzebowałem aż 4 wybrałem wersję Mega. Udostępnia ona aż 6 przerwań (https://www.arduino.cc/en/Reference/AttachInterrupt) . W moim przykładzie wykorzystuję przerwania 2,3,4,5 podpięte do pinów 21,20,19 i 18. void interrupt(int motorId) { int val = digitalRead(motors[motorId].getEncoderPinB()); if(val == LOW && motors[motorId].getDirection() == FORWARD) { motors[motorId].setDirection(BACKWARD); } else if(val == HIGH && motors[motorId].getDirection() == BACKWARD) { motors[motorId].setDirection(FORWARD); } if(motors[motorId].getDirection() == BACKWARD) motors[motorId].IncreasePulses(); else motors[motorId].DecreasePulses(); } Metoda interrupt() przy zmianie stanu na niski na odpowiednim pinie (port A enkodera) sprawdza stan na pinie portu B i w zależności od stanu pinu jest w stanie określić kierunek obrotu silnika. Każde wywołanie metody zwiększa lub zmniejsza licznik pulsów. Liczba ta jest istotna, ponieważ jest przekazywana na wejście do algorytmu PID. Do obsługi algorytmu wykorzytałem standardową bibliotekę Arduino-PID-Library. W każdym obiekcie utworzonym z klasy Motor jest jeden obiekt klasy PID. void calculateSpeed() { input = abs(pulses); int result=pid->Compute();//Po okresie ustalonym w parametrze, algorytm wylicza wymaganą prędkość silnika if (result) { motor->setSpeed(output); //ustawienie nowej prędkości silnika pulses = 0; //zerowanie licznika } } Algorytm PID jest wywoływany co 100 milisekund (pid->SetSampleTime(100)) w trybie automatycznym (pid->SetMode(AUTOMATIC)). Oznacza to, że co 0.1 sekundy na wejście algorytmu podawany jest aktualny stan licznika pulsów enkodera. Jeśli algorytm stwierdzi odchylenia od wymaganej prędkości obrotowej (speed), koryguje odpowiednio prędkość chwilową (output). Kluczowe są tutaj odpowiednie wielkości parametru proporcjonalnego, całkującego i różniczkującego (Kp, Ki, Kd). Testowałem wiele opcji i te podane w kodzie dają "miekkie" dochodzenie do prędkości wymaganej. Prędkość poszczególnych silników jest ustalana w programie Python uruchomionym na Raspberrypi. Wysyła od odpowiednie polecenia w zależności od ustalonego kierunku i ewentualnych od niego odchyleń. Ponieważ pojazd nie ma osi skrętnej, zakręty są realizowane odpowiednimi nastawami poszczególnych kół. Wspomnę tylko, że za kontrole kierunku odpowiedzialny jest moduł IMU (GY-801). Ale o tym w kolejnym wpisie. Pozdrawiam Zbigniew Włodarczyk AutonomicznyRobot-PID.zip Edytowano 18 marca przez ZbychuW 1 Cytuj Link to post Share on other sites
Gieneq 1 794 21 marca Udostępnij 21 marca @ZbychuW dziękuję za dodanie kodu i obszerne komentarze Cytuj Link to post Share on other sites
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
BananWszyscy 47 23 marca Udostępnij 23 marca Ja się chętnie dowiem sporo na temat obróbki wyników tego mapowania Cytuj Link to post Share on other sites
ethanak 2 933 2 kwietnia Udostępnij 2 kwietnia A ja tak z ciekawości - co poprawiałeś w espeaku? Pytam bo oryginalnie tabele translacji i parę funkcji specyficznych dla polskiego były moje, ale w ng ktoś to równo spaprał... Cytuj Link to post Share on other sites
ZbychuW 12 2 kwietnia Autor tematu Udostępnij 2 kwietnia Nie zmieniałem nic w pakietach. Jedynie podmieniłem pliki definicji dźwięków. Korzystałem z tutoriala na youtube: Cytuj Link to post Share on other sites
ZbychuW 12 2 kwietnia Autor tematu Udostępnij 2 kwietnia Rozwiązanie nie jest na razie doskonałe, bo przytyka mi trochę RPi, gdy generuję dźwięk. Ograniczam się do prostych komunikatów z informacjami o zmianach trasy więc jakość nie jest kluczowa. Jeśli masz jakieś doświadczenie i porady, chętnie skorzystam Cytuj Link to post Share on other sites
ethanak 2 933 3 kwietnia Udostępnij 3 kwietnia Czyli po prostu zmieniłeś głos z Klatta na Mbrolę. 15 godzin temu, ZbychuW napisał: Jeśli masz jakieś doświadczenie i porady, chętnie skorzystam A na przykład Kedrigern Też oparty na Mbroli. Działa bez problemu z Pythonem (tylko poczekaj na nową wersję softu, albo dziś wieczorem albo jutro wrzucę) bo te mają błąd. A tak przy okazji - Klatt jest chyba bardziej czytelny (przynajmniej w przypadku eSpeaka) niż kulejąca Mbrola. Cytuj Link to post Share on other sites
ZbychuW 12 3 kwietnia Autor tematu Udostępnij 3 kwietnia (edytowany) Uruchomiłem tą wersję, którą znalazłem na twoim repozytoriu. Muszę powiedzieć, że efekt jest bardzo dobry. Sprawdzę, jak wrzucisz coś nowego. Narazie uruchamiam polecenia z poziomu pythona wywołując linie poleceń import subprocess as cmdLine cmdLine.run("clear") speech = 'Uwaga, skręcam w prawo' command = 'milena_say ' + chr(34) + speech + chr(34) result = cmdLine.run(command, shell=True, capture_output=True, text=True) Nie udało mi sie uruchomić serwera ponieważ jest niezgodność wersji bibliotek. Edytowano 3 kwietnia przez ZbychuW Cytuj Link to post Share on other sites
ethanak 2 933 4 kwietnia Udostępnij 4 kwietnia Najlepiej skompilować wszystko samemu, wtedy biblioteki będą pasować. Zresztą począwszy od tych wersji nie będzie już plików deb (właśnie ze względu na biblioteki). Milena: ściągasz najnowszą wersję z http://milena.polip.com/download.shtml - aktualnie http://www.polip.com/files/milena-0.2.95.1.tar.gz Rozpakowujesz, wchodzisz w rozpakowany katalog i instalujesz przez: sudo bash install_rpi.sh Zresztą jeśli masz w miarę świeżą wersję Mileny to możesz na razie jej używać. Co do kedrigerna: ściągasz najnowszą wersję źródeł - aktualnie http://www.polip.com/files/raspberry/kedrigern_0.2.3.orig.tar.gz i http://www.polip.com/files/raspberry/libkedrigern_0.2.2.orig.tar.gz Dla każdego pliku rozpakowujesz go, wchodzisz do rozpakowanego katalogu i wykonujesz: make && sudo make install Reszta jak w opisie na stronie. Ważne aby użyć kedrigerna w wersji 0.2.3! Twój sposób oczywiście zadziała - pod warunkiem że nie będzie znaku " w tekście. Poza tym blokuje to działanie programu (kedrigern nie). Cytuj Link to post Share on other sites
ZbychuW 12 4 kwietnia Autor tematu Udostępnij 4 kwietnia dziękuję bardzo, pozdrawiam Cytuj Link to post Share on other sites
ethanak 2 933 4 kwietnia Udostępnij 4 kwietnia @ZbychuW jakby były dalej jakieś problemy to pisz - kedrigern był stworzony przede wszystkim do takich zastosowań jak Twoje i dobrze by było, aby działał bezbłędnie. Cytuj Link to post Share on other sites
ZbychuW 12 4 kwietnia Autor tematu Udostępnij 4 kwietnia (edytowany) Witam ethanak. Pobrałem wskazane biblioteki ale wydaje mi sie, że brakuje plików. Przy kompilacji dostaję komunikat: audio.c:27:10: fatal error: ao/ao.h: No such file or directory Szukałem tego pliku w pozostałych repozytoriach ale nie mogę znaleźć. Czy to z innej paczki, czy coś robię nie tak? To z pakietu libao ? Mam, przynajmniej teoretycznie, zainstalowany pi@raspberrypi:~ $ sudo apt search libaio Sorting... Done Full Text Search... Done libaio-dev/stable 0.3.112-9+rpi1 armhf Linux kernel AIO access library - development files libaio1/stable,now 0.3.112-9+rpi1 armhf [installed] Linux kernel AIO access library - shared library Edytowano 4 kwietnia przez ZbychuW Cytuj Link to post Share on other sites
ethanak 2 933 5 kwietnia Udostępnij 5 kwietnia libao-dev (potrzebny do kompilacji) Później napiszę więcej, wypadam do lekarza. Przepraszam za sklerozę Cytuj Link to post Share on other sites
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!