Popularny post Wojcik98 Napisano Listopad 30, 2024 Popularny post Udostępnij Napisano Listopad 30, 2024 Cześć wszystkim! Po kolejnej kilkuletniej przerwie w udzielaniu się na forum postanowiłem się podzielić się postępami prac nad moim nowym projektem: robotem typu micromouse Aether. Projekt jest na razie w dość wstępnych etapach i dużo może się jeszcze zmienić. Planuję początkowo pracować sobie w symulacji i obserwować jak się tam robot zachowuje, a potem dopiero zabierać się za prawdziwą konstrukcję. Mikrokontroler Pomysł na projekt pojawił się jak dowiedziałem się, że ESP32 są dwurdzeniowe i posiadają wbudowane moduły Wi-Fi. Marzyło mi się wtedy, żeby na jednym rdzeniu robił się główny kod robota, a drugi rdzeń by publikował wizualizację przez Wi-Fi do ROSa. Jak jednak przyszło mi do programowania ESP, to jednak się nie polubiłem z nim. Ekosystem wydał mi się jeszcze niedojrzały i procesor nie miał takiej dobrej obsługi peryferiów, jak bardziej mi znane STM32, na które się ostatecznie przerzuciłem. Jednym z głównych powodów jest dobra obsługa DMA, przez co będę mógł łatwo pobierać dane ze wszystkich czujników i procesor będzie o tym myślał tylko przez bardzo krótki czas. Ostatecznego modelu jeszcze nie mam wybranego, ale na razie celuję w STM32F446RE, bo mam z nim płytkę Nucleo. Trochę się zastanawiam na dodaniem jakiegoś modułu bezprzewodowego, żeby móc streamować dane z robota na bieżąco, ale nie jestem jeszcze przekonany. Czujniki We wcześniejszych robotach używałem prostych czujników LED + fototranzystor, które na podstawie jasności odbieranego światła szacowały odległość do ścianek. Używanie ich było dość upierdliwe, bo były one wrażliwe na zewnętrzne oświetlenie, odbijalność ścianek, itd. W tym projekcie postanowiłem spróbować czujników Time-of-Flight (ToF), które mierzą czas pomiędzy wysłaniem wiązki światła i jej powrotem (oczywiście planuję używać gotowych modułów, nie podejmuję się mierzenia taki krótkich odcinków czasu). Odczyt z nich zależy już głównie od odległości do obiektu i nie są tak wrażliwe na inne zakłócenia (kolor, oświetlenie). Z drugiej strony, nie widziałem ich też za bardzo w innych robotach tego typu, więc być może mają jakąś inną wadę, która mi sprawi niespodziankę. Obecnie planuję użyć czujników VL53L4CD. Mają zasięg od 1 do 1300 mm z precyzją 1mm, z pomiarami do 100 Hz. Mają dość duży kąt widzenia (FoV) 18°, który może potencjalnie sprawiać problemy z np. wykrywaniem podłogi, ale zobaczę jak będą mi wypadały testy. Zastanawiam się też, czy nie będzie zakłóceń pomiędzy dwoma czujnikami znajdującymi się obok siebie, będę to musiał przetestować. Nie są one turbo drogie, bo kosztują ~12 zł/szt. przy zakupie samych sensorów (bo gotowe płytki z nimi chodzą już po ~90). Jeśli będą źle wypadały, to rozglądnę się za czymś innym. Myślę też o użyciu jakiegoś IMU, głównie do mierzenia prędkości obrotowej żyroskopem, ale być może użyję też akcelerometru. Do testów na razie wziąłem LSM6DS3. Dodatkowo jakieś enkodery na koła, też konkretów jeszcze nie mam, ale pewnie coś typu AS5040. Mechanika Pod tym względem jest chyba jeszcze najmniej ustalone. Na pewno chcę, żeby mysz była w stanie jeździć po przekątnej, co stawia górne ograniczenie na szerokość na ~110 mm. Będę też pewnie celował w konstrukcję czterokołową, bo nie jest bardzo skomplikowana mechanicznie, a dużo dobrych konstrukcji tego używa. Będę prawdopodobnie używał względnie popularnych opon Mini-Z z wydrukowanymi felgami. Silników i przekładni jeszcze nie wybrałem. Jak patrzę na ceny silników Faulhabera czy Maxona, których używają co lepsi zawodnicy, to trochę mnie słabi, więc możliwe że zostanę na razie ze starymi dobrymi Pololu i w kolejnych konstrukcjach będę celował w wyższą półkę. Nie planuję tutaj turbinki przyciągającej do podłoża, za dużo nowego (i drogiego) na raz by było. Oprogramowanie Czyli to, co Wojcik98 lubi najbardziej. Kod, który napiszę, chciałbym móc jakoś przetestować razem z wizualizacją, dlatego główna logika robota będzie zamknięta w bibliotece C++, którą będę mógł potem skompilować do użytku na kompie albo na mikrokontrolerze. Do developmentu używam VS Code z Dockerem, gdzie już mam wszystko poinstalowane (zmuszenie GUI do działania było upierdliwe, ale działa). Całość kodu trzymam w repo na GitHubie: Wojcik98/aether. Na kompie korzystam z frameworku ROS 2 Jazzy, który ułatwia komunikację między programami. Wykorzystuję go głównie dla jego wizualizacji, co umożliwi weryfikację tego co “myśli” mysz o labiryncie i ułatwi debugowanie. Poniżej screen z wizualizacją robota (wstępny model) i pomiarami z czujników. Do symulacji używam Gazebo, głównie ze względu na dobrą integrację z ROSem. Wydaje mi się, że do względnie prostej i wstępnej symulacji jest on wystarczający, a fine-tuning i tak trzeba będzie robić na prawdziwym robocie. Domyślnie nie ma w nim zwykłych jednowymiarowych czujników odległości, dlatego zastępuję je lidarami z tylko jedną wiązką pomiarową, i później po prostu konwertuję typ wiadomości wysyłanej do reszty systemu. Nie pozwala to symulować dużego FoV rzeczywistych czujników, ale na początek chyba wystarczy. Zamierzam dorobić skrypty do tworzenia symulacji z konkretnymi labiryntami i z losowymi. Poniżej screen z symulacji (na razie niezbyt ciekawy). Głównym problemem micromouse nie jest zmapowanie labiryntu, ale potem przejechanie go jak najszybciej. Dlatego zaczynam kodzenie od modułu lokalizacji, zakładając że już znam cały labirynt. Na razie rozważam PF (particle filter) lub UKF (unscented Kalman filter) do śledzenia lokalizacji robota. Dlaczego nie jakiś zwykły filtr Kalmana? Wyobraźmy sobie bardzo długą prostą w labiryncie, bez żadnych zakrętów. Robot dość szybko zgubi pewność, gdzie dokładnie wzdłuż tego korytarza jest i dopiero gdy zauważy pierwszy zakręt będzie mógł się znowu odnaleźć. Zaimplementowanie tego w zwykłym KF byłoby dość trudne, jeśli nie niemożliwe, tymczasem przy metodach samplujących liczę na to, że wtedy jeden z wylosowanych punktów będzie znajdował się przy zakręcie i będzie mógł wyraźnie dać znać, że to on jest prawdziwą lokalizacją. Czy wybiorę UKF czy PF to przetestuję, PF pozwala na większą nieliniowość całego systemu, ale może być cięższe obliczeniowo. Jeśli będę mógł dokładnie śledzić położenie robota w labiryncie, to przejdę do znajdywania najkrótszej ścieżki i przejechania jej. Dużo nad tym jeszcze nie myślałem, zacznę pewnie od prostych zakrętów pod kątem prostym, a potem zacznę się bawić ze skosami i łukami. I na koniec to, co się dzieje na początku, czyli mapowanie. Formalnie, to lokalizacja tutaj może być bardziej skomplikowana, bo jednocześnie się lokalizujemy w mapie i tworzymy mapę na podstawie naszej lokalizacji (SLAM). Ale myślę, że powinna zadziałać prosta strategia jeżdżenia powoli, przez co będę mógł ufać, że odczyty enkoderów pokrywają się z rzeczywiście przejechaną odległością. Problemem tutaj znowu mogą być długie korytarze, ale będę się tym przejmował jak faktycznie coś nie będzie działać. Na razie pozwalam sobie korzystać z dobroci C++ i używam jakichś fajnych konstrukcji typu obiektowość. Mam nadzieję, że nie okaże się to zbyt wolne, bo będę musiał wtedy zacząć optymalizować. Na razie to chyba tyle. Mam nadzieję, że nie znudzi mi się ten projekt po miesiącu i że jednak uda mi się go dokończyć 😅. Będę się starał wrzucać tutaj aktualizacje przy większych postępach. Wszelkie opinie, uwagi i pytania dotyczące projektu mile widziane 🙂 5 Link do komentarza Share on other sites More sharing options...
Wojcik98 Grudzień 17, 2024 Autor tematu Udostępnij Grudzień 17, 2024 Krótki update: Napisałem filtr cząsteczkowy i w prostych testach wydaje się on działać. Bierze on odczyty z IMU i enkoderów i na ich podstawie liczy o ile się robot przemieścił (+ zakłócenia). Potem dla każdej cząsteczki przewiduje, jakie powinny być odczyty z czujników odległości przy danej pozycji w labiryncie i porównuje je z rzeczywistymi odczytami. Jeśli się zgadzają, to duże prawdopodobieństwo, że cząsteczka dobrze estymuje prawdziwą pozycję robota. Na razie zrobiłem tylko testy jednostkowe dla lokalizacji przy samym IMU+enkoderach i dla jazdy na wprost dodatkowo z czujnikami odległości. Ręczne generowanie bardziej skomplikowanych testów z czujnikami ToF byłoby już dość upierdliwe. W najbliższych dniach zintegruję to z ROSem, żeby móc przetestować lokalizację w symulatorze. Do tego napisałem jeszcze automatyczne generowanie labiryntu w symulacji na podstawie pliku tekstowego z konfiguracją, korzystając z EmPy. Bardzo się to przyda do szybkiej zmiany ustawień. Na razie labirynty trzeba generować "z ręki", ale może w przyszłości pomyślę nad jakimś losowym generowaniem. Czeka mnie jeszcze sparsowanie tego pliku tekstowego w C++, żeby utworzyć znaną mapę labiryntu. Sam plik tekstowy wydaje się trochę niewygodny do edycji, bo trzeba jednocześnie uwzględniać ściany, słupki i puste miejsca. Zastanawiam się nad bardziej graficznym sposobem edycji, ale nie wiem czy to już nie będzie strzelanie z armaty do muchy. Przy okazji chciałbym bardzo pochwalić ChatGPT i GitHub Copilot. ChatGPT potrafi ładnie wytłumaczyć skomplikowane zagadnienia, jak np filtr cząsteczkowy i pomóc przy implementacji. Copilot szalenie się przydaje przy generowaniu względnie powtarzalnego kodu, np. postawienie jednakowych ścian w kilku miejscach. Oczywiście trzeba krytycznie podchodzić do wygenerowanego outputu, ale łatwiej/szybciej zweryfikować ich prawdziwość niż samemu wymyślać/pisać + wiadomo już co potem dokładniej googlować. 2 Link do komentarza Share on other sites More sharing options...
Treker (Damian Szymański) Grudzień 22, 2024 Udostępnij Grudzień 22, 2024 @Wojcik98 już sama symulacja robi wrażenia. Zapowiada się ciekawy projekt, chyba jeszcze nie było tutaj robota MM, którego autor zaczynał od tej strony. Dzięki, że dzielisz się takimi szczegółami! Link do komentarza Share on other sites More sharing options...
Wojcik98 Grudzień 22, 2024 Autor tematu Udostępnij Grudzień 22, 2024 @Treker dzięki, zdobyłem trochę wiedzy i doświadczenia na studiach i w pracy, to chciałem to jakoś produktywnie wykorzystać 😛 Kolejny update: Zintegrowałem lokalizację z ROSem i po paru poprawkach coś tam działa. Filmik: Pozycja robota w RViz (po lewej) jest obliczana z filtru cząteczkowego, a ten drugi latający układ współrzędnych jest brany z czystej odometrii z kół. Można zauważyć, że odometria się rozjeżdża po jakimś czasie, a filtr dzięki odczytom z czujników ToF potrafi z powrotem dopasować się do mapy labiryntu. Nie działa to jeszcze jakoś super i na pewno dużo trzeba będzie zmienić przed zmierzeniem się z szybszą jazdą, ale już fajnie widzieć jakieś postępy. Być może spróbuję to uruchomić teraz na mikrokontrolerze, żeby wiedzieć, jaki rząd czasu zajmują obliczenia. Filtr cząsteczkowy działa lepiej z większą liczbą cząsteczek, więc tutaj głównym ograniczeniem są zasoby obliczeniowe. Zastanowię się też nad UKF, bo on inteligentniej sampluje punkty, przez co potrzebuje ich mniej. 1 Link do komentarza Share on other sites More sharing options...
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
Egzekutor27 Grudzień 27, 2024 Udostępnij Grudzień 27, 2024 Ciekawy projekt. Można zastosować do różnych "potrzeb" albo do dalszego "rozwoju" programu. Link do komentarza Share on other sites More sharing options...
Popularny post Wojcik98 3 stycznia Autor tematu Popularny post Udostępnij 3 stycznia Cześć w Nowym Roku! W ostatnim czasie dalej popracowałem nad robotem. 1) Zmieniłem nieco opis labiryntów, żeby był taki sam jak w https://github.com/micromouseonline/mazefiles, dzięki czemu mogę korzystać z mnóstwa labiryntów stamtąd. 2) Przy okazji wykorzystania większych labiryntów wyszły problemy z symulacją. Mianowicie, generowałem każdą ściankę i słupek osobno, co było dość ładne i pokrywające się z rzeczywistością, ale przy labiryncie 16x16 wydajność symulacji spadła do 16% (real time factor). W pierwszej kolejności zamiast tworzenia nowego obiektu dla każdego słupka/ściany, stworzyłem jeden obiekt ze słupkami i jeden ze ścianami, które zawierały osobne "linki" dla każdego elementu. Wywaliłem też czerwony kolor na górze ścianek, który pełnił funkcję tylko ozdobną. Przyspieszyło to do 34%, więc dalej niezbyt. Następnie wywaliłem prawie wszystkie słupki (zostawiłem tylko jeden w środkowym kwadracie) i przedłużyłem wszystkie ścianki, żeby wypełniły ich miejsca. Przyspieszyło to symulację do 75%, więc już o niebo lepiej, ale dalej chciałem być bliżej 100%. Ostatnią (na razie) optymalizacją było zastąpienie brzegów labiryntu jednymi, ciągłymi ścianami. Dzięki temu osiągnąłem wydajność 95%, która już jest dla mnie wystarczająca (nawet przy idealnych warunkach ciężko wyciągnąć 100%). W razie potrzeby mogę jeszcze wykrywać kiedy jest kilka ścianek z rzędu i zastępować je jedną długą, ale na razie tej potrzeby nie czuję. 3) Napisałem sobie algorytm Dijkstry do znajdywania najkrótszej ścieżki w labiryncie. Na razie z prostym sposobem poruszania się, bez kar za zakręty, bez jeżdżenia po przekątnych. 4) Z ścieżki następnie generuję trajektorię, która mówi w jakim miejscu, z jaką orientacją i jaką prędkością powinienem być w danym momencie. Na razie generuję trajektorię ze stałą prędkością liniową, która robi zakręty po łukach. Jest dość prosta i ładnie wygląda, ale przy zakrętach (a w szczególności przy slalomie) powoduje dość duże przyspieszenia kątowe, które nie są zbyt przyjazne rzeczywistym warunkom. W przyszłości zmodyfikuję nieco generowaną trajektorię, żeby ją nieco wygładzić. 5) Następnie porównuję obecną lokalizację robota z wartością zadaną z trajektorii i na podstawie tego steruję silnikami. Na razie jest to proste sterowanie proporcjonalne, ale w zasadzie nawet to działa. Łącząc wszystko do kupy, mam już symulowanego robota, który jest w stanie pokonać (prawie) dowolny zmapowany labirynt. Na filmiku nawet udało się złapać, jak robot uderzył w ścianę, ale potem udało mu się ponownie zlokalizować i kontynuować jazdę. (Symulacja na filmiku ma wydajność ~80% przez to, że program nagrywający zamula komputer) Następne do zrobienia będzie prawdopodobnie mapowanie labiryntu. Jak będę miał już działającą całość, to zajmę się generowaniem lepszej trajektorii i fine-tuningiem. Za niedługo będę też wreszcie zaczynał pracę, więc mogę już nie mieć tyle czasu/sił do pracy nad tym projektem, ale będę się starał dalej działać. 4 Link do komentarza Share on other sites More sharing options...
invent4tech 9 stycznia Udostępnij 9 stycznia @Wojcik98 Witam Czy umiesz stworzyć system lokalizacji obiektu w obszarze 3D 200 m x 200 m x 200 m? Chodzi mi o lokalizację obiektu lub obiektów z nadajnikiem oraz dokonanie pomiarów trajektorii lotu tych obiektów. start obiektu - start pomiaru pomiar przemieszczenia się obiektu - odczyt ciągły z zapisem parametrów lotu przy czym punktem odniesienia są nadajniki radiowe stop pomiaru przez zdalny wyłącznik Możliwość użycia danych do aplikacji na komórkę Proszę o kontakt Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »