[[
✎ pl:miw:2009:nxt_api_demo
]]
aiWiki
Pokaż stronę
Ostatnie zmiany
Indeks
Zaloguj
Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić.
====== Opis ====== Take the PlNXT API. Build tutorial and demo cases. Łukasz Bandała - feanaro@student.agh.edu.pl ====== Spotkania ====== ===== 20090XYZ ==== ====== Projekt ====== ===== Założenia ===== Celem projektu było przygotowanie demonstracji zastosowania PlNXT API. Zastanawiając się nad licznymi możliwościami prezentacji potencjału połączenia języka prolog oraz klocków NXT, ostatecznie zdecydowałem się na budowę i oprogramowanie robota umożliwiającego układanie kostki rubika. Język prolog doskonale nadaje się do rozwiązywania tego typu problemów. {{:pl:miw:2009:miw09_nxt_api_demo:kostka.png?100x100}} {{:pl:miw:2009:miw09_nxt_api_demo:lego_nxt_logo.png?250x50}} ===== Konstrukcja ===== Podstawowym problemem była ograniczona ilość silników i elementów konstrukcyjnych. W pierwszej kolejności należało sprecyzować zadania robota: - Zmiana orientacji kostki w przestrzenii - Ruch kostki - Badanie rozmieszczenia kolorów na kostce Posiadając tylko 3 silniki można się spodziewać sporych problemów z wykonaniem wszystkich tych czynności. Okazuje się jednak, że problemem tym zajął się ktoś już kiedyś. Konstrukcja [[http://www.tiltedtwister.com|Tilted Twister]] jest dokładnie tym czego poszukiwałem. Wykorzystująca wszelkie elementy w podstawowym zestawie NXT w sposób wysoce optymalny, umożliwia wykonywanie wszystkich wymienionych powyżej czynności. Można to zobaczyć [[http://www.youtube.com/watch?v=5fAn5A0HbhU|tutaj]]. {{:pl:miw:2009:miw09_nxt_api_demo:dsc00242.jpg|Zbudowany Titled Twister}} Kompletną instrukcję budowy można pobrać ze [[http://www.tiltedtwister.com/download.html|strony projektu]]. Ponadto znajdują się tam również kody źródłowe dla C++. ===== Oprogramowanie ===== ==== Wstęp ==== Posiadając już zbudowaną konkretną konstrukcję, nie pozostało mi nic innego jak przystąpić do próby napisania oprogramowania w języku Prolog z wykorzystaniem biblioteki [[pl:plnxt:start|PlNXT]]. Biblioteka składa się z kilku modułów. Najbardziej zewnętrznymi (z punktu widzenia użytkownika) z nich są 3 następujące: nxt_movment, threads oraz nxt_sensomoto. Pierwszy jest skierowany do podstawowych robotów jeżdżących. Stąd jego mała przydatność w tym projekcie. Druga dotyczy wywoływaczy (triggers) oraz liczników. Jak okazało się podczas prac, również ten moduł jest mało użyteczny przy oprogramowywaniu twistera. Trzecia natomiast posiada podstawowe czynności związane z komponentami NXT, co okazało się zdecydowanie nabardziej przydatne. ==== Ruchy i obroty ==== W celu ujednoznacznienia wykorzystywanych zwrotów, wprowadziłem drobny podział w nazewnictwie: * Kostka zbudowana jest z klocków ( 8 trójściennych, 6 jednościennych oraz 12 dwuściennych). To daje w sumie 54 kolorowe kwadraty na kostce. * **Ruchem** nazywać będę zmianę rozmieszczenia kolorowych kwadratów na kostce. Tym samym **ruch** zmienia rozmieszczenie klocków w kostce. Odpowiednia sekwencja **ruchów** powodować może rozwiązanie kostki. * **Obrotem** nazywać będę zmianę jedynie orientacji kostki w przestrzenii. Tym samym nie umożliwiają one rozwiązania kostki. **Uwaga!** Początkowa próba wykorzystania wbudowanego w biblotece predykatu //nxt_motor(Motor,Speed,angle(Angle))// nie przyniosła oczekiwanego rezultatu. Obroty silników o ustalony kąt były zdecydowanie nieprecyzyjne i pozostawiały bardzo dużo do życzenia jeżeli chodzi o jakikolwiek determinizm. Ratunkiem w ów sytuacji okazał się predykat nxt_motor_get_rotations(Motor,Rot_count). Umożliwił on zaimplementowanie prostego regulatora P. Jak wiadomo, zdecydowanie najlepiej budować serwomechanizmy w oparciu o regulator typu PD. Jednakże w tej sytuacji lekko zmodyfikowane P okazało się wystarczające. Pobierając dane o pozycji silnika, wypracowywane jest odpowiednie sterowanie. Pojawił się niestety jeszcze jeden kłopot. Otóż ze względu na zbliżanie się silnika do zadanej wartości, stopniowo jest mu zadawana coraz mniejsza prędkość (w założeniu jest ona z przedziału 900 do 0). Niestety przy bardzo niskich wartościach i jakimkolwiek obciążeniu silnika, nie jest w stanie się on poruszyć. Konieczne zatem było dodanie pewnej tolerancji błędu pozycji oraz przełączenie na regulację dwupołożeniową w bliskim otoczeniu wartości zadanej. Wprowadzenie tej tolerancji wymogło również stosowanie pomiaru pozycji absolutnej (od włączenia układu) zamiast o wiele łatwiejszego w implementacji, pomiaru pozycji względnej ( w stosunku do poprzedniej pozycji - powoduje to stopniową kumulację błędu). Skomplikowało to zdecydowanie predykaty odpowiedzialne za wszelki ruch. === Obrót względem osi pionowej - silnik A=== Jest to podstawowy obrót. Może odbywać się zgodnie z ruchem wskazówek zegara lub odwrotnie. Zakładając prawidłową pozycję obrotowej platformy, obrót ten odbywa się głównie o 90 stopni. Wyjątkiem jest sytuacja analizy rozmieszczenia kolorowych kwadratów na kostce. W tym przypadku wykorzystywany jest również obrót o 45 stopni. Z tego powodu zaimplementowane są w zasadzie 4 predykaty obrotu platformy. 2 z nich odpowiadają za obroty o 90 stopni (jeden z pozycji początkowej plus wielokrotność kąta 90 stopni, drugi z pozycji początkowej przesuniętej o 45 stopni plus wielokrotność kąta 90 stopni). Kolejne 2 natomiast odpowiadają za ruch o 45 stopni (przejście i powrót z pozycji początkowej do pozycji przesuniętej). W sposób empiryczny sprawdziłem ilość obrotów silnika odpowiadających za 90 stopniowy obrót (można to również próbować przeliczyć na podstawie stosunku ilości zębów zębatek - patrz: [[http://pl.wikipedia.org/wiki/Przek%C5%82adnia|przekładnia]] ). **Na obrót o kąt 90 stopni platformy przypada 315 kroków**. Poniżej prezentuję kody źródłowe poszczególnych obrotów: * Obrót o 90 stopni z pozycji początkowej - niewiadoma 'Z' jest mnożnikiem opowiedzialnym za kierunek (wartości to +1 lub -1). Niewiadoma 'M' odpowiada jest współczynnikiem P regulatora. Obrót ten wykorzystywany jest również przy ruchach kostką, stąd większe obciążenie i konieczność zwiększenia współczynnika. <code prolog> % rotacje calej kostki rr :- wait_till(wolny), retract(wolny), ruch_A(-1,1.7), sleep(0.3), assert(wolny). rl :- wait_till(wolny), retract(wolny), ruch_A(+1,1.7), sleep(0.3), assert(wolny). % wzmocnione rotacje calej kostki rrs :- wait_till(wolny), retract(wolny), ruch_A(-1,2.3), sleep(0.3), assert(wolny). rls :- wait_till(wolny), retract(wolny), ruch_A(+1,2.3), sleep(0.3), assert(wolny). ruch_A(Z,M) :- nxt_motor_get_rotations('A',V1), % badanie polozenia w odniesienniu do absolutnej poczatkowej pozycji V2 is V1+157 ,V3 is V2-(V2 mod 315), repeat, nxt_motor_get_rotations('A',R), X is (R-V3), P is (Z*315-X)*M, dwupolozeniowy(P,P2,25), % zmiana regulatora przy odpowiednim progu nxt_motor('A',P2), A is abs(X), % tolerancja roznicy polozenia A =< 317, A >= 315, nxt_motor('A',0). </code> * Obrót o 90 stopni z pozycji przesuniętej - niewiadoma 'Z' podobnie jak wyżej. <code prolog> ar :- wait_till(wolny), retract(wolny), ruch_A_45(-1), sleep(0.3), assert(wolny). al :- wait_till(wolny), retract(wolny), ruch_A_45(+1), sleep(0.3), assert(wolny). ruch_A_45(Z) :- nxt_motor_get_rotations('A',V1), % badanie polozenia w odniesienniu do absolutnej poczatkowej pozycji V2 is V1+315 ,V3 is V2-(V2 mod 315), repeat, nxt_motor_get_rotations('A',R0), R is R0+157, X is (R-V3), P is (Z*315-X)*1.7, dwupolozeniowy(P,P2,25), % zmiana regulatora przy odpowiednim progu nxt_motor('A',P2), A is abs(X), % tolerancja roznicy polozenia A =< 316, A >= 314, nxt_motor('A',0). </code> * Obroty dopełniające do pozycji początkowej i pozycji przesuniętej. <code prolog> dopelnienie_do_90 :- nxt_motor_get_rotations('A',V), G is V - (V mod 315), repeat, nxt_motor_get_rotations('A',R), P is (G-R)*1.5, dwupolozeniowy(P,P2,25), % zmiana regulatora przy odpowiednim progu nxt_motor('A',P2), A is abs(R), % tolerancja roznicy polozenia B is abs(G), A =< B+1, A >= B-1, nxt_motor('A',0),sleep(0.1). dopelnienie_do_45 :- nxt_motor_get_rotations('A',V), G is V - ((V+157) mod 315), repeat, nxt_motor_get_rotations('A',R), P is (G-R)*1.5, dwupolozeniowy(P,P2,25), % zmiana regulatora przy odpowiednim progu nxt_motor('A',P2), A is abs(R), % tolerancja roznicy polozenia B is abs(G), A =< B+1, A >= B-1, nxt_motor('A',0),sleep(0.1). </code> === Obrót względem osi poziomej === ==== Czujniki ==== ===== Algorytm ===== ===== Realizacja ===== ====== Sprawozdanie ====== ====== Prezentacja ====== ====== Materiały ======
pl/miw/2009/nxt_api_demo.1249471288.txt.gz
· ostatnio zmienione: 2019/06/27 15:58 (edycja zewnętrzna)
Pokaż stronę
Poprzednie wersje
Menadżer multimediów
Do góry