[[
✎ pl:miw:miw08_mindstormsdesign:labirynt
]]
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ć.
===== Labirynt ===== {{ :pl:miw:miw08_mindstormsdesign:labirynt.png?200|Labirynt}} Przed przystąpieniem do zadania należy przygotować labirynt (makietę). W celu lepszego sterowania robotem dobrze jest również pozbyć się kleszczy z przodu (patrz budowa robota TriBot). Kleszcze mogą utrudniać poruszanie się robota po planszy. W ramach prezentowanego niżej algorytmu przyjęto: - pola makiety po jakich poruszać się będzie robot są na tyle duże, że robot może się swobodnie obrócić - przyjmujemy budowę robota TriBot bez przednich kleszczy - robot nie wie nic o planszy - w algorytmie przyjęto ruch co określoną długość, w celu uproszczenia za długość kroku przyjęto szerokość jednego pola planszy (patrz rys. Labirynt) - każdej nowej pozycji przypisywany jest numer oraz parametry związane z tą pozycją Opis pozycji robota: {{ :pl:miw:miw08_mindstormsdesign:pomiar.png|Pomiar}} - pozycja robota zostaje opisana przez 8 pomiarów echosondy pobieranych co kąt 45<sup>0</sup>. Otrzymane wyniki są zapisywane w bazie wiedzy robota o planszy. Kolejne pozycje są numerowane. Każda nowa pozycja znajduje się w odległości N cm od pozostałej (gdzie N jest szerokością jednego pola planszy). - Taka struktura danych mogłaby wyglądać następująco: pole(nr_pola,[nr_pomiaru,następne_pole,ultrasonic_value]) * nr_pola - numer pola dla którego przeprowadzane są pomiary * nr_pomiaru - numer przeprowadzanego pomiaru * następne_pole - jest to informacja o polu jakie znajduje się w danym kierunku * utrasonic_value - wartość echosondy w danym kierunku {{ :pl:miw:miw08_mindstormsdesign:pomiar2.png|Przechodzenie do następnego pola}} W ten sposób zdefiniowane pola można łączyć i budować prostą bazę wiedzy o otoczeniu robota. Czarne cyfry na rysunku przedstawiają numery poszukiwań. Pomiary przeprowadzane są co 45<sup>0</sup> więc jest ich 8. Czerwone cyfry oznaczają numery pól. Niebieskie cyfry są przypisanym numerem pola, do którego można się dostać podążając w kierunku pomiaru np. 3. Żółta cyfra 0 oznacza z kolei ścianę (przeszkodę), którą napotkamy w zadanym kierunku. Wartość ściany definiuje pomiar echosondy. Jeżeli odległość jest mniejsza niż ustalona wartość to wówczas przyjmujemy, że jest w tym miejscu ściana lub inna przeszkoda. Poniżej zaprezontowano algorytm, który przy wykorzystaniu takiej postaci wiedzy steruje robotem TriBot. ==== Zapis słowny === - Zbadaj otoczenie. - Spośród zbadanych wartości **ultrasonic_v** wybierz tą, która jest największa i nie ma przypisanego węzła. Obróć się tam, gdzie ona jest. - Jeżeli znaleziono wartość największą to: - Przypisz tej galezi jako nr następnego węzła kolejny wolny nr węzła. - Rusz się do przodu o N cm. - Jeżeli wszyskie pozostałe połaczenia są zablokowane to: - Wybierz kierunek z zaznaczonym węzłem następnym. - Rusz się do przodu o N cm. - Po przejściu do wezła zablokuj dostęp do węzła, z ostatniej pozycji robota. - Idź do (2). - Zbadaj otoczenie dla pomiaru 5 przypisz numer wcześniejszego węzła. ==== Zapis regułowy ==== <code ada> Rule: 1 if listOfAddedNodes.has?(current_node) == false then listOfAddedNodes.add(current_node) and node.add(current_node,[1,0,ultras_v]) then turn = 45 and node.add(current_node,[2,0,ultras_v]) then turn = 45 and node.add(current_node,[3,0,ultras_v]) then turn = 45 and node.add(current_node,[4,0,ultras_v]) then turn = 45 and node.add(current_node,[5,previous_node,ultras_v]) then turn = 45 and node.add(current_node,[6,0,ultras_v]) then turn = 45 and node.add(current_node,[7,0,ultras_v]) then turn = 45 and node.add(current_node,[8,0,ultras_v]) Rule: 2 if listOfAddedNodes.has?(current_node) == true then goTo(Rule 5) Rule: 3 if messure_no in [0;8] then messure_no++ and goTo(Rule 5) Rule: 4 if messure_no not in [0;8] then messure_no := 0 and goTo(Rule 7) Rule: 5 if ultras_v(current_node,messure_no) > X and next_node(current_node,messure_no) == 0 then turn = messure_no*45 and goStepFoward and node_counter++ and node.update(current_node,[messure_no,node_counter,ultras_v]) and current_node = node_counter and goTo(Rule 1) else goTo(Rule 3) Rule: 6 if messure_no in [0;8] then messure_no++ and goTo(Rule 7) else STOP Rule: 7 if ultras_v(current_node,messure_no) > X and next_node(current_node,messure_no) > 0 then turn = messure_no*45 and goStepFoward and current_node = next_node(current_node,messure_no) and node.update(current_node,[messure_no,-1,0]) and goTo(Rule 2) else goTo(Rule 6) </code> ==== Implementacja w Prologu ==== <code prolog> messured_nodes(node_no). node(node_no,messure_no,next_node,ultrasonic_val,messured). current_node(node_no,messure_no). current_messure(number). %---------------------- % dokonywanie pomiarów %---------------------- start :- current_node(X,_), node(X,Y,_,_), messured_nodes(Q), X \= Q, nxt_ultrasonic_sensor(port,Value1), assert(node(X,1,0,Value1), nxt_turn(speed,45), nxt_ultrasonic_sensor(port,Value2), assert(node(X,2,0,Value2), nxt_turn(speed,45), nxt_ultrasonic_sensor(port,Value3), assert(node(X,3,0,Value3), nxt_turn(speed,45), nxt_ultrasonic_sensor(port,Value4), assert(node(X,4,0,Value4), nxt_turn(speed,45), nxt_ultrasonic_sensor(port,Value5), assert(node(X,5,0,Value5), nxt_turn(speed,45), nxt_ultrasonic_sensor(port,Value6), assert(node(X,6,0,Value6), nxt_turn(speed,45), nxt_ultrasonic_sensor(port,Value7), assert(node(X,7,0,Value7), nxt_turn(speed,45), nxt_ultrasonic_sensor(port,Value8), assert(node(X,8,0,Value8) assert(messured_nodes(X)). %--------------------------- % szukanie najlepszej drogi %--------------------------- start :- current_node(X,M), node(X,Y,Next,U), messured_nodes(X), Next = 0, U <= number, % wartość progowa, ponad którą dokonywane jest przeszukiwanie retract(node(X,Y,_,_)), assert(node(X,Y,1000,U), % blokowanie połączenia current_messure(A), B is A + 1, retractall(current_messure(_)), assert(current_messure(B)). start :- current_node(X,M), node(X,Y,Next,U), messured_nodes(X), Next = 0, U > number, % wartość progowa, ponad którą dokonywane jest przeszukiwanie retract(node(X,Y,_,_)), nxt_ultrasonic_sensor(port,Value), assert(node(X,Y,X+1,Value), abs(M-Y,N), nxt_turn(speed,45*N), % przemieszczenie do nowego punktu nxt_go(1), retractall(current_node(X,_)), W is X + 1, assert(current_node(W,1)), assert(current_messure(1)). start :- current_node(X,M), node(X,Y,Next,U), messured_nodes(X), Next > 0, U > number, % wartość progowa, ponad którą dokonywane jest przeszukiwanie current_messure(D), D <= 8, % pominięcie punktu, zwiększenie licznika o 1 B is A + 1, retractall(current_messure(_)), assert(current_messure(B)). start :- current_node(X,M), node(X,Y,Next,U), messured_nodes(X), Next > 0, U > number, % wartość progowa, ponad którą dokonywane jest przeszukiwanie current_messure(D), D > 8, abs(M-Y,N), nxt_turn(speed,45*N), % przejscie do punktu, który już był wcześniej badany nxt_go(1), node(Next,P,X,U2), retractall(current_node(X,_)), assert(current_node(Next,P)), retractall(node(Next,P,_,_)), assert(node(Next,P,1000,U2)). % zablokowanie powrotu do poprzedniego punktu start :- go(0). </code> ==== XTT ==== {{:pl:miw:miw08_mindstormsdesign:labirynt222.png|XTT}} FIXME * przy większych algorytmach pojawia się problem z zapętlaniem * podział na atrybuty, nie jest taki oczywisty, zwłaszcza w przypadku, gdy argumentami jest tablica argumentów * ponadto, nie jest oczywiste jak odczytywać argumenty. W tym algorytmie założyłem, że wszystkie atrybuty są odwzorowaniem jednego rekordu z tablicy atrybutów. Atrybuty zmieniają się w przypadku zwiększenia atrybutu current_node * nie jest jasne wykorzystanie akcji assert i retract. I pobieranie z nich wartości.
pl/miw/miw08_mindstormsdesign/labirynt.txt
· ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
Pokaż stronę
Poprzednie wersje
Menadżer multimediów
Do góry