Jakubowski Gniadek-Zając Michałek
1) W momencie rozpoczęcia zajęć robot wyglądał następująco:
2) Pierwszym krokiem było zweryfikowanie czy robot jest poprawnie podłączony i skonfigurowany. W tym celu wykonaliśmy test wykonując kilka poleceń ntx_go, ntx_rotate.
3) Następnie przystąpiliśmy do realizacji poleceń z laboratorium. Na początku uruchomiliśmy program który powoduje jazdę robota po kwadracie. Wykonanie programu odbywało się w głównym wątku stąd konsola w trakcie wykonywania była zablokowana. Przerwanie wykonania możliwe było tylko poprzez wyłączenie robota. Zaobserwowaliśmy, że robot nie jeździ po idealnym kwadracie - kąt każdego skrętu miał więcej niż 90 stopni. Mogło to wynikać z niedokładności silnika wykonującego skręt lub z niefortunnej konstrukcji robota (tylne koło powodowało trudności przy skręcaniu).
4) W dalszej części dokonaliśmy uruchomienia zmodyfikowanego programu, w którym jazda po kwadracie realizowana była w osobnym wątku. W tym wypadku konsola nie była zablokowana w trakcie jezdy robota - możlie było wpisanie komendy zatrzymującej robota. Jednakże wykonanie polecenia stop
spowodowało wyświetlenie się komunikatu:
Warning: [Thread 3] Thread running „trigger_start(nxt_is_stopped, thread_send_message(2, resume), 1)” died due to failure
Yes
?- Warning: [Thread 2] Thread running „rectangle_loop” died on exception: Out of global stack
Następnie dokonaliśmy modyfikacji kodu programu (zmniejszyliśmy odległość jazdy do przodu z 40 na 20 cm), po czym wykonaliśmy polecenie consult
aby wprowadzić zmiany do prologa, oraz polecenie start
. Niestety robot nie reagował, konsola prologa zawiesiła się. Adapter bluetooth w tym czasie intensywnie migał. Próba zatrzymania wykonania w konsoli poprzez wciśnięcie kombinacji ctrl+c
spowodowała wyświetlenie komunikatu
% Execution Aborted
?- halt.
1 threads wouldn't die
Konieczny okazał się restart robota i prologa. Od tej pory każdorazowa modyfikacja kodu programu wymagała restartu obu elementów.
5) Kolejnym krokiem było przetestowanie programu powodującego zatrzymanie się robota przy pierwszym klaśnięciu, oraz wznowienie jazdy przy następnym. Koniecznym było dobranie wartości progu dźwięku tak aby robot nie był wrażliwy na hałas z otoczenia. Ostatecznie ustaliliśmy tą wartość na 50
. Dalsze testy przebiegły bez problemu.
6) W dalszej części laboratorium przystąpiliśmy do implementacji własnych programów. Zaczęliśmy od programu OMIJANIE PRZESZKÓD, ponieważ program PIŁKA wymagał sporych zmian konstrukcyjnych w robocie, a ponadto nie dysponowaliśmy planszą testową. Ostatecznie opracowaliśmy program, którego kod znajduje się poniżej:
:- consult('../plnxt.pl').
start :-
nxt_open,
trigger_create(_,clap,stop),
thread_create(go,_,[detached(true)]).
clap :-
nxt_sound(Value,force),
Value > 550.
stop :-
trigger_killall,
nxt_stop,
nxt_close.
go :-
trigger_create(_,check_distance,[omin_przeszkode]),
nxt_go(200).
check_distance :-
nxt_ultrasonic(Distance,force),
Distance < 15.
omin_przeszkode :-
nxt_stop,
Angle is random(2),
nxt_rotate(360,90-Angle*180),
nxt_go_cm(300,20),
nxt_rotate(360,-90+Angle*180),
move.
move :-
trigger_create(_,check_distance,[omin_przeszkode]),
nxt_go(300).
Program powoduje, że robot jedzie do przodu, aż do napotkania przeszkody w odległości nie większej niż 15cm. Wówczas zatrzymuje się i dokonuje skrętu w prawo lub w lewo, po czym przejeżdża 20 cm, i skręca w przeciwną do pierwszego skrętu stronę. Jeśli w czasie zwykłej jazdy prosto (nie podczas omijania) wystąpi klaśnięcie, wówczas program zakończy się i robot się zatrzyma. W czasie tworzenie programu zaobserwowaliśmy, że polenienie nxt_go(30) nie działa, ponieważ wartość argumentu jest za mała - robot nie jedzie do przodu. Dopiero zmiana wartości na większą (ustaliliśmy 200) spowodowała, że robot ruszał z miejsca.
7) Na koniec dokonaliśmy implementacji programu PANIKARZ, którego kod znajduje się poniżej:
:- consult('../plnxt.pl').
start :-
nxt_open,
trigger_create(_,touch,stop),
thread_create(go,_,[detached(true)]).
go :-
nxt_go(200),
trigger_create(_,sound,run_away).
sound :-
nxt_sound(Value,force),
Value > 50.
run_away :-
nxt_stop,
Angle is random(5)-10,
nxt_rotate(360,Angle*30),
nxt_go_cm(720,30),
go.
touch :-
nxt_touch(Value,Force),
Value > 0.
stop :-
trigger_killall,
nxt_stop,
nxt_close.
Program powoduje, że robot jedzie powoli do przodu. Po wystąpieniu klaśnięcia obraca się o losowy kąt i jedzie z dużą szybkością 30 cm przed siebie. Po czym zwalnia i jedzie znów powoli. Po wciśnięci czujnika dotyku program kończy się, a robot się zatrzymuje.