Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Nowa wersja
Poprzednia wersja
pl:miw:miw08_mindstormsdesign:labirynt [2008/05/19 22:11]
miw utworzono
pl:miw:miw08_mindstormsdesign:labirynt [2019/06/27 15:50] (aktualna)
Linia 1: Linia 1:
 ===== Labirynt ===== ===== 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 słowny ==== 
-      - jedź do przodu 
-      - jeżeli przeszkoda zatrzymaj się (wskaźnik echosondy poniżej progu) idź do (3) inaczej wróć do (1) 
-      - obróć się o 90<​sup>​0</​sup>​ w prawo 
-      - idź do (1) 
  
 ==== Zapis regułowy ==== ==== Zapis regułowy ====
 <code ada> <code ada>
 Rule: 1 Rule: 1
-if ultrasonic_sensor_Value > number +if listOfAddedNodes.has?​(current_node) == false  
-then robot_action is go_foward+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 Rule: 2
-if ultrasonic_sensor_Value ≤ number +if listOfAddedNodes.has?​(current_node) == true 
-then robot_action is turn_right_90_degrees+then goTo(Rule 5)
  
 Rule: 3 Rule: 3
-stop+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>​ </​code>​
  
 ==== Implementacja w Prologu ==== ==== Implementacja w Prologu ====
 <code prolog> <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 :- start :-
-      ​ultrasonic_sensor(Value), +      ​current_node(X,M), 
-      ​Value > number+      ​node(X,​Y,​Next,​U)
-      ​go(0,speed,force).+      ​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 :- start :-
-      ​ultrasonic_sensor(Value), +      ​current_node(X,M), 
-      Value =< number, +      node(X,​Y,​Next,​U),​ 
-      ​turn(90,speed).+      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 :- start :-
-      go(0,0,0).+      go(0).
 </​code>​ </​code>​
  
  
-==== XTT ==== 
-{{:​pl:​miw:​miw08_mindstormsdesign:​alg11.png|XTT}} 
  
  
 +==== 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.1211227917.txt.gz · ostatnio zmienione: 2019/06/27 15:59 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0