Różnice

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

Odnośnik do tego porównania

Both sides previous revision Poprzednia wersja
pl:miw:miw08_mindstormsdesign:labirynt [2008/05/27 00:23]
miw
pl:miw:miw08_mindstormsdesign:labirynt [2019/06/27 15:50] (aktualna)
Linia 1: Linia 1:
 +===== 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.
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