Sprawozdanie z zajęć laboratoryjnych realizowanych przez: Świerkosz, Wróbel, Kowalski.
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.
YouTube: Prison Break
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:
Jedź i szukaj czarnej linii.
Po natrafieniu na kolor czarny, pilnuj żeby nie zjechać z niej.
Jeśli robot zjechał, obracaj się tak, aby znaleźć linię.
Po natrafieniu na kolor czarny przerwij obrót i jedź prosto.
:- 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.