Sprawozdanie z zajęć laboratoryjnych realizowanych przez: Świerkosz, Wróbel, Kowalski.
Po przyjściu na stanowisko zastaliśmy zbudowanego robota. Przebudowaliśmy go trochę zmieniając układ sensorów, po czym przystąpiliśmy do realizacji właściwej części laboratorium.
Na początku przystąpiliśmy do kalibracji czujnika przy pomocy prostego programu:
:- consult('plnxt.pl'). :- nxt_open, nxt_light_LED(activate), % włącz oko repeat, nxt_light(Light,force), write(Light), nl, fail.
Czujnik rozróżniał biały kolor na planszy od czarnego, jednak na czerwony reagował tak samo jak w przypadku białego, być może jasność w pokoju była duża (stanowisko koło okna). Nie mieliśmy pod ręką niczego, co mogłoby stanowić klucz dla robota, dlatego zrealizowaliśmy jedynie algorytm krążenia po więzieniu.
:- consult('plnxt.pl'). % uruchamia algorytm start :- nxt_open, nxt_play_tone(1000,200), % daj znać, że działasz nxt_light_LED(activate), % włącz oko trigger_create(_,check_light,[isawsomething]), nxt_go(200). % patrzy pod koła check_light :- nxt_light(V,force), V < 45. isawsomething :- nxt_stop, nxt_go_cm(-200,10), % wycofaj Angle is 30 + random(160), nxt_rotate(300,Angle), % obróc o losowy kąt trigger_create(_,check_light,[isawsomething]), nxt_go(200). % jedź dalej % zatrzymuje robota stop :- nxt_play_tone(1000,200), trigger_killall, nxt_stop, nxt_close.
Na to zadanie poświęciliśmy najwięcej czasu, jednak efekty są odwrotnie proporcjonalne do poświęconego czasu.
Chcieliśmy zaimplementować wariant bardzo prosty tj. robot obraca się i jeśli trafi na śmiecia zaczyna go sprzątać - jedzie 40cm do przodu przesuwając obiekt, następnie się cofa 40cm i ponownie sprawdza teren obracając się, jeśli zastanie porządek w swoim obszarze, to zatrzymuje się.
Na początku przystąpiliśmy do kalibracji czujnika przy pomocy prostego programu:
:- consult('plnxt.pl'). :- nxt_open, nxt_rotate(150,900), % obracaj repeat, nxt_ultrasonic(Distance,force), write(Distance), nl, fail.
Mieliśmy trochę problemów z ustaleniem wartości, bo nasze stanowisko było za małe na testy i nie mieliśmy odpowiednich rekwizytów do testowania. Niestety piłki dostarczone z robotem były dość kiepsko wykrywane.
Powstał poniższy program.
:- consult('.plnxt.pl'). % uruchamia algorytm start :- nxt_open, nxt_play_tone(1000,200), % daj znać, że działasz xsearch. % sprawdza odległość od potencjalnej przeszkody check_distance :- nxt_ultrasonic(Distance,force), Distance < 20. % sprawdź, czy jest porządek xsearch :- nxt_rotate(150,800), % obracaj trigger_create(_,check_distance,[xdestroy]). % sprzątaj xdestroy :- nxt_stop, nxt_play_tone(200,500), % ogłoś rozpoczęcie sprzątania nxt_go_cm(300,15), % przesuń śmiecia nxt_go_cm(-300,15), % wróc się xsearch. % skontroluj efekt końcowy % zatrzymuje robota stop :- nxt_play_tone(1000,200), trigger_killall, nxt_stop, nxt_close.
Niestety powyższy kod nie działa. Robot reaguje na śmieci, jednak nie chce się cofać - jedzie cały czas do przodu, więcej niż ma zadane.
Stwierdziliśmy, że należy poczekać aż robot się zatrzyma i dopiero go cofać. Znaleźliśmy do tego celu odpowiedni predykat nxt_is_stopped/0 i w rezultacie powstał poniższy program.
:- consult('plnxt.pl'). % uruchamia algorytm start :- nxt_open, nxt_play_tone(1000,200), % daj znać, że działasz xsearch. % sprawdza odległość od potencjalnej przeszkody check_distance :- nxt_ultrasonic(Distance,force), Distance < 20. % sprawdź, czy jest porządek xsearch :- nxt_rotate(150,800), % obracaj trigger_create(_,check_distance,[xdestroy]). % sprzątaj xdestroy :- nxt_stop, nxt_play_tone(200,500), % ogłoś rozpoczęcie sprzątania nxt_go_cm(300,15), % przesuń śmiecia trigger_create(_,nxt_is_stopped,[xdestroy_back]). xdestroy_back :- nxt_go_cm(-300,15), % wróc się trigger_create(_,nxt_is_stopped,[xsearch]). % skontroluj efekt końcowy % zatrzymuje robota stop :- nxt_play_tone(1000,200), trigger_killall, nxt_stop, nxt_close.
Z bliżej nieokreślonych przyczyn ten program w ogóle nie chciał działać. Otrzymany błąd:
?- start. ERROR: source_sink `/dev/rfcomm8' does not exist (Software caused connection abort) Exception: (11) open('/dev/rfcomm8', write, _L190, [buffer(false)]) ? abort % Execution Aborted
Wobec tego zadaliśmy testowy cel (po wcześniejszym załadowaniu plnxt oraz zrobieniu nxt_open):
nxt_go_cm(300,15),repeat,nxt_is_stopped,nxt_go_cm(-300,15),repeat,nxt_is_stopped,write('YAY'), nl.
Który działał stochastycznie, raz robot w ogóle się nie ruszał, czasem jechał do przodu, a jeszcze rzadziej nawet się wracał… Powyższy przykład był powtarzany kilka razy. Za każdym razem interpreter prologu był resetowany, a robot wyłączany i włączany (have you tried to turn it off and on again?)…
Zredukowaliśmy nasz cel do tej postaci:
?- nxt_go_cm(300,150),nxt_is_stopped. ERROR: Arithmetic: `angle/1' is not a function ^ Exception: (20) _L3685 is angle(3086)//256 ?
Za każdym razem otrzymywaliśmy powyższy błąd.
Ze względu na brak czasu nie udało nam się przetestować programu. Opis działania:
:- consult('plnxt.pl'). % uruchamia algorytm start :- nxt_open, nxt_play_tone(1000,200), % daj znać, że działasz nxt_light_LED(activate), % włącz oko trigger_create(_,check_light,[isawsomething]), nxt_go(200). % patrzy pod koła - reaguje na czarny check_light :- nxt_light(V,force), V < 45. % robot natrafił na czarną linię isawsomething :- trigger_create(_,check_light2,[rotate]). % patrzy pod koła - reaguje na biały check_light2 :- nxt_light(V,force), V > 45. % szuka czarnej linii rotate :- nxt_rotate(300,90), % obracaj robota trigger_create(_,check_light,[isawsomething2]). % aż trafi na czarną linie % jedzie prosto isawsomething2 :- nxt_stop, % zatrzymaj obrót trigger_create(_,check_light2,[rotate]), % pilnuj żeby być na czarnym nxt_go(200). % jedź % zatrzymuje robota stop :- nxt_play_tone(1000,200), trigger_killall, nxt_stop, nxt_close.