Skocz do zawartości

Wojcik98

Użytkownicy
  • Zawartość

    151
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    3

Wojcik98 wygrał w ostatnim dniu 9 kwietnia 2014

Wojcik98 ma najbardziej lubianą zawartość!

Reputacja

28 Bardzo dobra

O Wojcik98

  • Ranga
    5/10

Informacje

  • Płeć
    Mężczyzna
  • Lokalizacja
    Tarnów
  • Zainteresowania
    robotyka, fizyka, astronomia

Ostatnio na profilu byli

Blok z ostatnio odwiedzającymi jest wyłączony i nie jest wyświetlany innym użytkownikom.

  1. Po półtora miesiąca przerwy czas coś napisać. Większość tego czasu spędziłem na ogarnięciu, czemu ROS2 nie działa i to była faktycznie jego, a nie moja wina . Na początku po jakiejś aktualizacji okazało się, że przestała działać główna jego funkcjonalność, czyli protokół porozumiewania się między węzłami (osobnymi programami). Nawet przykładowe programy nie działały, publisher wysyłał wiadomości w eter a do subscribera już nic nie docierało. Nareszcie po kilku dniach przyszła kolejna aktualizacja, która naprawiała ten problem i mogłem pisać dalej, tylko pojawił się kolejny problem. ROS2 nie widział paczek napisanych w Pythonie. W ROS2 struktura prjektu wygląda tak, że jest folder z folderem `src`, w którym w osobnych folderach znajdują się poszczególne paczki. Każda paczka zdefiniowana jest przez plik `package.xml` i do tego paczka C++ wymaga `CMakeList.txt`, a paczka Pythona `setup.py`, więc przy budowaniu projektu faktycznie są inaczej traktowane. Problem był o tyle trudny do zdebugowania, że paczki przy budowaniu się pokazywały, ale ROS2 ich nie widział przy próbie uruchomienia programów z tych paczek, mówił, że nie istnieją. Okazało się, że w pliku `setup.py` należy dołożyć dodatkowy krok budowania, który polega na skopiowaniu pustego pliku o nazwie takiej, jak paczka do folderu, który ROS2 wykorzystuje do indeksowania paczek. Nie wiem, czemu wcześniej działało wszystko bez tego i nagle przestało, ale chwilę na to poświęciłem. Jeśli ktoś byłby zainteresowany, to takie linijki są potrzebne w `setup.py`: data_files=[ ('share/ament_index/resource_index/packages', ['resource/' + package_name]), ('share/' + package_name, ['package.xml']), ], Oprócz tego miałem problem ze stworzeniem własnego typu serwisu, który korzystał z typów wbudowanych w ROS2 (z paczki geometry_msgs), najwyraźniej dlatego, że było coś nie tak w implemetacji tych typów. Tutaj już mi się nie chciało dochodzić do przyczyny w kodzie źródłowym ROSa i po prostu zdefiniowałem własny typ, który miał dokładnie takie same informacje (tj. informacje o pozycji). Po pokonaniu przeciwności ze strony ROSa mogłem nareszcie wziąć się do właściwego kodzenia. Zaimplemetowałem to, co deklarowałem w poprzednim poście, czyli ustawianie nóg i ciała względem "świata", zamiast względem siebie. Do przejścia między układami bazy nogi i bazy świata używałem serwisu ROSa, który sam się tym zajmuje, a do przejścia z bazy świata do końcówki nogi mnożyłem macierze, bo nie publikowałem ich pozycji, tylko trzymałem je w pamięci programu. Robot teraz potrafi poruszać ciałem względem świata z nogami stojącymi nieruchomo, ogarnia zarówno translację, jak i rotację ciała (choć na filmiku poniżej jest tylko translacja, bo rotację zaimplemetowałem jakieś dwie godziny później). Z rzeczy, których nie ma na filmiku, to zmieniłem nieco ułożenie kolana. Na filmiku robot nie może go zginać mniej niż 90*, bo inaczej dochodzi do kolizji z udem. Wystarczyło przestawić na drugą stronę mocowania, podobnie jak to widać na mocowaniu "biodrowym". Dzięki temu już mu lepiej wychodzi kucanie. Co chcę zrobić w najbliższym czasie: 1) Umieścić dane o charakterystyce nóg w jednym globalnym pliku, teraz jest to zahardkodowane w kodzie i nie sprzyja zmianom. 2) Poprawić odwrotną kinematykę dla nowych danych i uwzględniać przesunięcie osi w biodrze, bo wcześniej tego nie brałem pod uwagę i niby działało, ale przyda się dokładna pozycja końcówki nogi. 3) Prosty chód w stylu: idź do przodu. @deshipu czy dobrze rozumiem: przez analogię do regulatorów, pojazd wirtualny to jest pozycja zadana robota, którą rzeczywisty układ powinien osiągnąć? Jeśli tak, to przy zachowywaniu równowagi statycznej (nie ma potrzeby balansowania, robot się nie potyka) te układy powinny się cały czas pokrywać i różnice powinny się pojawić się tylko w przypadku zewnętrznych sił, np. kopiących panów z Boston Dynamics?
  2. Czy funkcja constrain() działa w jakimkolwiek przypadku? Bo tutaj nie wygląda, powinno być 10 ≤ beta2 ≤ 170, a tutaj masz przed i po ograniczeniu równą -0.61 albo - 16.59 (oprócz 12.59, które już jest w prawidłowym zakresie przed ograniczaniem).
  3. Cześć, tak bez możliwości przetestowania samemu kodu trudno coś powiedzieć, ale zauważyłem dwie rzeczy: 1) Dlaczego "if(beta <= -1) beta = -0.99;"? beta jest w radianach, dlaczego jest ograniczasz ją z dołu do akurat -1? 2) Czy beta4 może być równa 0? Najpierw robisz beta2 = constrain(beta2, 10, 170), a potem beta3 = constrain(beta3, 10, 160), czyli minimalna wartość beta4 to 10+110=20? Czy funkcja constrain działa inaczej, niż się domyślam? Spróbuj wypisać wartości zmiennych beta2, 3, 4 przed i po wprowadzeniu ograniczeń, żeby można było zawęzić obszar poszukiwań buga. Napisz tutaj, co jest wypisywane.
  4. Dopracowałem już model i sterowanie serw, żeby obydwa pokazywały to samo i udało mi się zakodzić prosty "chód", a właściwie czołganie się, czym się pochwalę: Na razie to jest bardzo proste, bo od strony implementacyjnej wygląda to tak, że końcówką każdej nogi zakreślam okrąg. I teraz chciałem zadać pytanie o "poprawne" sterowanie, ale w trakcie jego formułowania przyszło mi do głowy rozwiązanie Moja definicja poprawnego sterowania: sterowanie pozycją nóg i robota względem otoczenia, zamiast względem robota. Aktualnie w wizualizacji mam nieruchomego robota, który przebiera w powietrzu nogami. Chciałbym mieć nieruchome otoczenie, względem którego przemieszcza się robot i po postawieniu nogi nie przesuwa się ona względem otoczenia. I wcześniej wspomniane rozwiązanie jest takie: 1) ustalam zadaną pozycję nóg względem otoczenia (gdzie je postawić) 2) ustalam zadaną pozycję robota względem otoczenia (gdzie ma być i jak ma być zorientowany) 3) znam pozycję nóg względem otoczenia i robota względem otoczenia, więc mogę przekształcić współrzędne końcówek nóg do układu robota 4) z tego już liczę odwrotną kinematykę i ustawiam serwa według niej Dzięki temu wiem, że nogi się nie ruszą względem otoczenia , a i robot będzie tam, gdzie będę tego chciał. Teraz pozostaje problem, gdzie w otoczeniu stawiać nogi, ale to brzmi jak problem generowania chodu, którym się zajmę później, na razie zaimplementuję powyższy algorytm.
  5. Dzisiaj skończyłem tworzyć model robota w URDF. Mam skrypt, który czyta paramtery w notacji Denavita-Hartenberga i zamienia je na współrzędne używane w URDF. Na razie jest zrobione tak, żeby było i będę musiał jeszcze przysiąść, żeby to "czysto" napisać. Oprócz tego napisałem odwrotną kinematykę, też na razie trochę brzydko, ale chciałem sprawdzić obliczenia i wydają się być dobre. Poniżej wstawiam filmik z działania i moje obliczenia, dość chaotycznie spisane. Wiem, że model nie za piękny, ale na razie mi tyle wystarcza do wizualizacji Pozycja końcówki jest zadawana z joysitcka, który był kupowany po taniości i ma bardzo wąski i trudny do wychwycenia zakres "analogowości", przez co ruchy końcówki nie są zbyt płynne. Obsługę joysticka ogarnia węzeł ROSa, który jest dołączany do instalacji. Przy okazji dowiedziałem się, że mój sterownik serw w przypadku komunikacji po UART ma maksymalny baudrate 9600, co przy formacie komend sterownika daje mi maksymalną częstotliwość odświeżania ~10Hz. Szczerze mówiąc liczyłem na trochę więcej i może kiedyś pokombinuję z USB, bo na tym może już ponoć działać nawet na 115200. Ponadto ten sterownik dość często błędnie odbiera dane i dopiero po wysłaniu po raz któryś komendy ogarnia. No i przygód z korzystaniem z niedokończonego systemu ciąg dalszy. ROS2 jeszcze nie ma w pełni zaimplementowanego programu do wizualizacji RVIZ (który jest właśnie na filmiku), w związku z czym nie można mu podać modelu robota automatycznie przy jego odpalaniu, ale trzeba ręcznie wprowadzić ścieżkę w programie. Na szczęście ustawienia są zapamiętywane i nie trzeba za każdym razem tego robić. Teraz planuję nieco "upiększyć" model robota, bo w tym momencie jest to skopiowany 4 razy opis jednej nogi z niewielkimi zmianami, chcę zrobić jedną templatkę na nogę, która będzie automatycznie wklejana do głównego pliku modelu. W ROS1 istniało coś, co się nazywało xacro i robiło to w miarę samo, ale 1) pewnie jeszcze tego nie ma w ROS2 2) i tak potrzebuję programu do konwersji z notacji DH, więc mogę od razu to wpisać do templatki. Do tego chcę jeszcze "upiększyć" kinematykę odwrotną, bo jest zhardkodowana na przednią lewą nogę. Muszę wymyślić sposób na jakąś generalizację tego. I wrzuciłem kod na githuba. Jeszcze nie cały, bo większość kodu jest na razie w wersji "żeby się ruszało, potem będę to robił porządnie" i głupio publikować, ale coś już tam jest. Link: https://github.com/Wojcik98/Quadrupel
  6. Dzisiaj skończyłem pisać węzeł do komunikacji z sterownikiem serw. Węzeł odbiera, jakie kąty powinien ustawić w serwach i wylicza dla nich długość impulsu potrzebną sterownikowi. Bierze przy tym pod uwagę, dla jakiego impulsu serwo jest ustawione na 0°, co musiałem sam sprawdzić i wpisać w plik csv. Poniżej krótki filmik, na którym robot już rusza nogami. Przy okazji pierwsza część "hejtu" na ROS2. W ROS1 (formalnie tam nie ma 1, ale dla widoczności) konfigurację paczki ustawiało się w pliku CMakeLists.txt i package.txt, niezależnie, czy kod mieliśmy w Pythonie czy C++. W ROS2 natomiast paczki w C++ dalej mają package.xml i CMakeLists.txt, ale paczki w Pythonie zamiast CMakeLists.txt mają plik setup.py. I to by było spoko, gdyby tylko istniała tego dokumentacja . Na podstawie tutoriali da się napisać własną paczkę, którą da się odpalić z terminala, ale jak chcemy napisać własny plik launch do odpalenia kilku węzłów naraz lub własną wiadomość czy serwis, to zaczynają się schody. Wszystkie tutoriale, przykłady i dokumentacja opisują tylko, jak dodać te pliki w CMakeLists. Dobry dzień mi zajęło, jak to zrobić w setup.py, ale w końcu się udało. Bo swoją drogą pliki launch nie są w xmlu, jak w ROS1, ale są to skrypty w Pythonie, co jest moim zdaniem na plus. Ale zdziwiło mnie, że wszystkie przykłady pokazują, jak to dodać w projekcie C++ . Ale, tu jeszcze zabawa się nie kończy, bo są też własne typy wiadomości i serwisów. Tutaj oczywiście też nie ma dokumentacji do setup.py, ale tym razem nie marnowałem całego dnia, tylko stworzyłem nową paczkę w C++ o nazwie custom, wrzuciłem tam tylko definicje wiadomości. Działa i to jest chyba najprostszy sposób na to. Można też tworzyć paczki z mieszanym kodem (i C++ i Python), ale dla mnie to nie jest zbyt "czyste" rozwiązanie. No, to teraz biorę się za model.
  7. Cześć wszystkim! Po dość długiej nieobecności na forum powracam z nowym projektem. Jest to robot kroczący, którego planowałem zrobić już od dwóch lat, ale nie miałem do tej pory czasu przez łączenie studiów z pracą. Do tego nie umiałem za bardzo zaprojektować mechaniki i dopiero niedawno mnie olśniło, że można kupić gotową Mechanika Robot ma cztery nogi, każda ma 3 stopnie swobody. Rozważam późniejsze dołożenie czwartego, bo jeszcze mi zostało serw, ale na razie zostawię go w tej konfiguracji. Do sklecenia konstrukcji użyłem platikowej obudowy jako korpusu i gotowych uchwytów na serwa przykręconych do siebie. Troszkę pójście na łatwiznę, ale ja wolę zajmować się częścią programistyczną Muszę jeszcze pomyśleć nad jakimiś końcówkami do nóg, bo na razie nie będą stabilne w każdej orientacji. Serwa to PDI-6221MG kupione na Banggood, ze względu na atrakcyjną cenę i jak na razie nie wydają się być złe. Staty: 0.16s/60°, 20kg*cm. Elektronika Układ zasilam przerobionym zasilaczem komputerowym. Na jego wyjściu mam 12V, żebym potem mógł to bezproblemowo zastąpić baterią LiPo. Napięcie jest potem obniżane na 5V do zasilania RPi i sterownika serw, oraz na 6V do zasilania serw. Układ jest zrobiony przez mojego brata i szczerze mówiąc nie wiem, co tam jest Rzekomo ma wydajność do 3A, przez co będę go w niedługim czasie zmieniał, mam już na oku przetwornicę na 15A, choć może jakąś mniejszą dam. W dodatku dzisiaj się przekonałem, że słabe kable potrafią naprawdę przeszkadzać: do zasilania RPi używałem zwykłych kabli do płytki stykowej, dopóki nie zauważyłem problemów z wyświetlaczem. Zmierzyłem napięcie na układzie zasilającym: 4.9V, zmierzyłem na RPi: 4.2V, zmierzyłem na kablach: 0.4V. Ich rezystancja była na tyle duża, że odkładały się tam niemałe napięcia, do tej pory myślałem, że to tylko teoretyczny problem, a tu proszę. Z tego powodu zasilam RPi w tym momencie z ładowarki do telefonu. Sterownik na 24 serwa też kupiłem na Banggood czy Aliexpress, tu jest opis. Komunikuje się po UART. Jeszcze nie robiłem mu testów wydajnościowych, ale nie wydaje się zły. Kupiłem specjalnie na większą liczbę serw, jakbym jeszcze chciał dołożyć nogom dodatkowe stopnie swobody albo dać jakiś manipulator na wierzchu. Mózgiem jest Raspberry Pi 3b, system to Ubuntu Core 64bit z Xubuntu. Do tego jest wyświetlacz dotykowy LCD 5" z obudową. Oprogramowanie Cały system planuję uruchomić na ROS2. Od razu ponarzekam, że ten system jest jeszcze w fazie dużego rozwoju i nie wszystkie funkcjonalności pierwszego ROSa są jeszcze zaimplementowane, m.in. odpalenie w pliku launch programów na kilku maszynach, z czego akurat chciałem skorzystać Mimo wszystko zdecydowałem się na ROS2, ponieważ ROS wspiera tylko Pythona 2, który traci wsparcie 1 stycznia 2020 (pythonclock.org/). Opiszę później w komentarzach kilka problemów w ROS2 i jak je rozwiązałem, bo dokumentacja praktycznie nie istnieje i może oszczędzi to komuś parę(naście) godzin w przyszłości. Ponadto, mimo iż na stronie jest napisane, że na RPi trzeba budować ROS2, bo paczki z repozytorium nie działają, mi się udało je zainstalować bez żadnego problemu. Jest tak może dlatego, że Ubuntu zainstalowałem w wersji ARM64 i to jakoś działa na ARMv7? Szkielet systemu mam mniej więcej zrobiony, bo w poprzednim semestrze na studiach miałem programowanie manipulatora w ROSie, będę musiał to jeszcze przeportować na ROS2 i trochę doszlifować. Udało mi się też już skomunikować z sterownikiem serw, choć nie jest to jeszcze idealne. Miałem też przy tym kilka problemów, wrzucę w komentarzu co i jak. Większość programów planuję uruchamiać na swoim laptopie i tylko sterowanie hardwarem na malince, żeby jej zbytnio nie obciążać. Może w przyszłości będę chciał bardziej usamodzielnić bota, wtedy mu dam może lepszy komputer i lżejszy system. Na wyświetlaczu planuję wyświetlać jakieś wizualizacje, aczkolwiek jeszcze nie wiem, czego Po napisaniu jakiegoś chodu chcę go sterować padem do gier. Plany na najbliższy czas Zmienić układ stabilizujący napięcie i kable Ustalić kąt 0 dla wszystkich serw Zrobić model robota w ROS Uruchomić kinematykę odwrotną (obliczaną geometrycznie) Zaimplementować prosty chód Końcówki do nóg Zacząć używać gita w tym projekcie i wrzucić kod na githuba Dalsze plany Kto to wie Ale chciałbym dać mu więcej samodzielności, mam sporo czujników w domu i wykrywanie przeszkód, czy gruntu pod nogami byłoby fajne. Chciałbym też zrobić własne zdalne sterowanie, na początku będę używał pada, ale mam też nakupione sporo joysticków i przełączników, jakbym chciał dołożyć różne bajery. Nawet mam lasery, więc włączanie ich też chcę zrobić Chciałbym też na nim pobawić się jakimiś sieciami neuronowymi i reinforcement learningiem, może jakaś nauka chodzenia, ale to już bardzo na przyszłość. Jak na razie to tyle, postaram się w miarę aktualizować tutaj postępy w pracach. Fajnie jest znowu robić robotykę Pozdro!
  8. Pomyliłeś znaki mniejszości i większości, w drugim warunku chcesz, żeby x był jednocześnie mniejszy od 10 i większy od 100, podobnie z resztą.
  9. szerwi, niekoniecznie. Chumanista prosił na razie o poprawki, a nie nowe funkcjonalności, a w tym zawiera się poprawienie aktualnego kodu, wykrycie błędów itd. Osobiście trochę mnie razi zakomentowany fragment "NEW" przy if(enforceSlope). System kontroli wersji jest też po to, żeby nie zakomentowywać niedziałającego kodu, tylko trzymać go w commitach i gałęziach. Podczas testowania na swoim komputerze sam tak robię, ale wysłałbym commita albo jeszcze bez tego, albo na inną gałąź, albo z opcją, żeby przy kompilacji definiowało się odpowiedni parametr i odpowiednia wersja by się kompilowała, coś takiego: #ifdef NEW_ENFORCE_SLOPE ... #else ... #endif Można by jeszcze poprawić trochę nazewnictwo, żeby zmienne więcej mówiły o samych sobie. Poza tym są jeszcze TODO, które bezpośrednio mówią, co jest do zrobienia.
  10. Cześć, na tej stronie z silniczkiem masz podany przykładowy kod, niby na Arduino, ale ogólny algorytm powinieneś ogarnąć. Po pierwsze, sygnał z enkoderów nie jest w postaci PWM, tylko wyjść kwadraturowych. Nie jestem pewny, czy Twój program mierzy wypełnienie PWM, czy częstotliwość częstotliwość sygnału wejściowego, ale oba podejścia są złe. Sygnał kwadraturowy przy stałej prędkości będzie miał stałe "wypełnienie" 50%, a częstotliwość można uzyskać bardzo dużą drgając kołem tak, żeby czujnik magnetyczny ciągle zmieniał sygnał, a koło będzie praktycznie stać w miejscu. Żeby mierzyć prawidłowo prędkość musisz skorzystać z obu wyjść enkodera i musisz liczyć zarówno częstotliwość sygnału, jak i przesunięcie jednego sygnału względem drugiego. Jak dostajesz impulsy na zmianę, to wszystko spoko, jak dostajesz dwa razy impuls z jednego wejścia, to zmienił się kierunek obrotu. Jeśli stm ma sprzętowe wsparcie enkoderow, to lepiej go używać, ale dla ćwiczenia możesz samemu napisać obsługę. W tym linku masz wytłumaczoną nieco obsługę enkoderow (na stmf4, ale nie powinno się rożnić bardzo): http://www.micromouseonline.com/2013/02/16/quadrature-encoders-with-the-stm32f4/ Co do stabilizatora prędkości, to poczytaj o regulatorze PID. W skrocie: odpalasz regulator co jakiś ustalony czas (np. 10ms) i mierzysz, ile dostałeś impulsow z enkodera w tym czasie (prędkość rzeczywista), porownujesz z docelową prędkością i odpowiednio zmieniasz PWM na silniku.
  11. Ja się przyznam jeszcze do Ziomusia, który jest tak naprawdę samouczącym Trzewikodziobem . Musiałem zmienić nazwę, bo właściwie do dnia przed wyjazdem nie wiedziałem, czy pojadę z nim, czy zdążę zrobić nowego robota, no i niestety nie zdążyłem. Jak skończę go już teraz na spokojnie to opiszę na forum.
  12. mosi2, rozpoznawanie obrazu inaczej niż przez uczenie maszynowe nie da się chyba zrobić, więc raczej będzie kłuć coś co przypomina rozgwiazdę, a nie zupełnie nie podobnego człowieka. Nawet jeśli błąd programu będzie na tyle duży, że będzie mógł zaatakować człowieka, to raczej nie w rozpoznawaniu błąd i wszystko inne po drodze też powinien, a wtedy będzie widać, że coś jest nie tak i będzie go można wyłączyć. Błędu skierowanego tylko przeciwko ludziom jakoś nie potrafię sobie wyobrazić, ale jakich to niespodziewanych błędów się w kodzie nie znajdywało
  13. mafish95, tak, jest to normalny programator ST-Link/V2, trzeba tylko zworki ściągnąć. Ja sam korzystam z takiego z płytki Discovery, bo mi stary ST-link nie chciał działać na nowym laptopie.
  14. Treker, rozwijania tego w sumie nie planowałem. Chciałem to uczenie przetestować, sprawdzić w praktyce, a że miałem linefollowera pod ręką to spróbowałem z tym . W przyszłości zrobię może jakiegoś robota balansującego, można by też było sprawdzić, jak to zadziała w *sumo. Ustawianie nastaw w PIDzie jest chyba nawet lepszym pomysłem od uczenia się prędkości dla każdej pozycji, spróbuję może kiedyś to zrobić. Nagrody mogłyby być dawane dla każdego przejazdu, proporcjonalnie do prędkości robota.
×
×
  • Utwórz nowe...