Autorzy:
Przygotowaliśmy plac manewrowy dla robota zdającego egzamin na prawo jazdy.
Szkielet robota został zbudowany w oparciu instrukcję dostarczoną razem z Lego Mindstorms. Dodatkowo wyposażyliśmy go w sensor sondy z przodu, sensor światła z tyłu (oba sensory służą do kierowania robotem i są żródłem informacji o przeszkodach z przodu i tyłu robota ), sensor dźwięku - wykorzystywany tylko przy hamowaniu awaryjnym. Budowę robota można zobaczyć na załączonych powyżej fotografiach.
Projekt został wykonany w środowisku Mac OS X versja 10.5 (Leopard). Konfiguracja połączenia pomiędzy robotem a komputerem dostępna jest tutaj.
Robot aby „zaliczyć” egzamin musi wykonać następujące manewry na placu manewrowym:
Przed przystąpieniem do tego manewru należy przygotować plansze po której będzie poruszał się robot, plansza ze względu na specyfikę wykorzystanych sensorów musi być otoczona czarną linią (potrzebne dla sensora światła) oraz ścianą (ściana musi znajdować się za czarną linią - dla sensora echosondy). Poniżej schemat planszy dla tego manewru:
* na zielono zaznaczone są miejsca gdzie konieczna jest ściana umożliwiająca sterowanie przy pomocy echo sondy
Reguły wykonuje się kolejno od pierwszej do ostatniej, jeżeli któraś reguła zostanie spełniona to wykonujemy reguły od początku.
Rule 1: if light_Value = BLACK and direction = BACK and angle >= 90 then STOP Rule 2: if ultrasonic_Value > 20 and direction = FORWARD then go = 1 Rule 3: if light_Value != BLACK and direction = BACK then go = -1 Rule 4: if ultrasonic_Value <= 20 and angle < 90 and direction = FORWARD then angle += 10 and rotate(10) Rule 5: if light_Value = BLACK and angle < 90 and direction = BACK then angle += 10 and rotate(-10) Rule 6: if ultrasonic_Value <=20 and angle >=90 and direction = FORWARD then direction = BACK and angle = 0
direction(forward). angle(0). start :- nxt_light(Value), Value = RGB_Black, direction(Direction), Direction = back, angle(Angle), Angle >= 90, nxt_stop, nxt_close. start :- nxt_ultrasonic(Value), Value > 20, direction(Direction), Direction = forward, nxt_go(1). start :- nxt_light(Value), Value \= RGB_Black, direction(Direction), Direction = back, nxt_go(-1). start :- nxt_ultrasonic(Value), Value <= 20, angle(Angle), Angle < 90, direction(Direction), Direction = forward, B is Angle + 10, retractall(angle(_)), assert(angle(B)), nxt_rotate(300,10). start :- nxt_light(Value), Value = RGB_Black, angle(Angle), Angle < 90, direction(Direction), Direction = back, B is Angle + 10, retractall(angle(_)), assert(angle(B)), nxt_rotate(300,-10). start :- nxt_ultrasonic(Value), Value <= 20, angle(Angle), Angle >= 90, direction(Direction), Direction = forward, retractall(angle(_)), assert(angle(0)), retractall(direction(_)), assert(direction(back)).
Podobnie jak w poprzednim przypadku do sterowania robotem zostaną użyte dwa sensory (echosonda z przodu, sensor światła z tyłu robota). Do przeprowadzenia manewru należy przygotować planszę wg załączonego schematu. Podobnie jak poprzednio, plansza musi być obmalowana czarną linią i otoczona ścianą (kolor zielony na schemacie).
Rule 1: if light_Value = BLACK and direction = BACK and angle >= 45 then STOP Rule 2: if ultrasonic_Value > 20 and direction = FORWARD then go = 1 Rule 3: if light_Value != BLACK and direction = BACK then go = -1 Rule 4: if ultrasonic_Value <= 20 and angle < 45 and direction = FORWARD then angle += 5 and rotate(5) Rule 5: if light_Value = BLACK and angle < 45 and direction = BACK then angle += 5 and rotate(-5) Rule 6: if ultrasonic_Value <=20 and angle >=45 and direction = FORWARD then direction = BACK and angle = 0
direction(forward). angle(0). start :- nxt_light(Value), Value = RGB_Black, direction(Direction), Direction = back, angle(Angle), Angle >= 45, nxt_stop, nxt_close. start :- nxt_ultrasonic(Value), Value > 20, direction(Direction), Direction = forward, nxt_go(1). start :- nxt_light(Value), Value \= RGB_Black, direction(Direction), Direction = back, nxt_go(-1). start :- nxt_ultrasonic(Value), Value <= 20, angle(Angle), Angle < 45, direction(Direction), Direction = forward, B is Angle + 5, retractall(angle(_)), assert(angle(B)), nxt_rotate(300,5). start :- nxt_light(Value), Value = RGB_Black, angle(Angle), Angle < 45, direction(Direction), Direction = back, B is Angle + 5, retractall(angle(_)), assert(angle(B)), nxt_rotate(300,-5). start :- nxt_ultrasonic(Value), Value <= 20, angle(Angle), Angle >= 45, direction(Direction), Direction = forward, retractall(angle(_)), assert(angle(0)), retractall(direction(_)), assert(direction(back)).
Do tego manewru została użyta plansza wg schematu. Manewr rozpoczyna się w miejscu oznaczonym „Start”, a kończy się po prawidłowym zaparkowaniu w „kopercie”. Manewr praktycznie rozpoczyna się po najechaniu na czarną linię prostopadłą do miejsca do markowania. Kolorem zielonym na schemacie jest zaznaczone miejsce gdzie musi zostać umieszczona ściana aby prawidłowo zadziałała echosonda.
Rule 1: if ultrasonic_Value < 10 then STOP Rule 2: if light_Value != BLACK and direction in (BACK, SLANT) then go = -1 Rule 3: if ultrasonic_Value > 10 and direction = FORWARD then go = 1 Rule 4: if light_Value = BLACK and manoeuvre NOT STARTED then manoeuvre = STARTED and rotate(45) and direction = SLANT Rule 5: if light_Value = BLACK and manoeuvre = STARTED and direction = SLANT then direction = BACK and rotate(-45) Rule 6: if light_Value = BLACK and manoeuvre = STARTED and direction = BACK then direction = FORWARD
direction(back). manoeuvre(not_started). start :- nxt_ultrasonic(Value), Value < 10, nxt_stop, nxt_close. start :- nxt_light(Value), Value \= RGB_Black, direction(Direction), in(Direction, [back, slant]), nxt_go(-1). start :- nxt_ultrasonic(Value), Value > 10, direction(Direction), Direction = forward, nxt_go(1). start :- nxt_light(Value), Value = RGB_Black, manoeuvre(Manoeuvre), Manoeuvre = not_started, retractall(manoeuvre(_)), assert(manoeuvre(started)), retractall(direction(_)), assert(direction(slant)), nxt_rotate(300,45). start:- nxt_light(Value), Value = RGB_Black, manoeuvre(Manoeuvre), Manoeuvre = started, direction(Direction), Direction = slant, retractall(direction(_)), assert(direction(back)), nxt_rotate(300,-45). start:- nxt_light(Value), Value = RGB_Black, manoeuvre(Manoeuvre), Manoeuvre = started, direction(Direction), Direction = back, retractall(direction(_)), assert(direction(forward)). in(X,[X|_]). in(X,[_|Tail) :- in(X,Tail).
Robot w tym przypadku wykonuje manewr hamowania awaryjnego, który jest wykonywany w części egzaminu zdawanego na mieście. W tym zadaniu wykorzystujemy dwa sensory: sensor dźwięku do wykonania hamowania awaryjnego i echosondę do zakończenia manewru. Manewr ten nie wymaga żadnych dodatkowych plansz i przygotowań.
Reguły są wykonywane sekwencyjnie od pierwszej do trzeciej. Po wykonaniu którejś z reguł następuje sprawdzania spełnienia kolejnej od początku.
Rule 1: if ultrasonic_Value < 10 then STOP Rule 2: if sound_Value > 40 then BRAKE and WAIT(3) Rule 3: go = 1
start :- nxt_ultrasonic(Value), Value < 10, nxt_stop, nxt_close. start :- nxt_sound(Value), Value > 40, nxt_stop, wait(3). start :- nxt_go(1).