Skład zespołu:
Sławomir Goszcz
Tomasz Pięciak
1. Wstęp
Celem laboratorium było testowanie przykładów (pierwsze dwa) zaprezentowanych w ćwiczeniu wraz z porównaniem sytuacji, gdy ruchem robota kieruje jeden główny wątek, przez co niemożliwe jest wydanie innego polecenia robotowi oraz wątek osobny, dzięki czemu jest to możliwe,
Trzeci przykład to robot na przemiennie ruszający i zatrzymujący się na odpowiednie natężenie dźwięku (tutaj klaśnięcie),
Wreszcie, głównym celem laboratorium było zaprojektowanie, zaimplementowanie i dokonanie analizy jednego z algorytmów (wybrano algorytm Panikarza)
2. Konstrukcja robota
|
Rys. 1. Wygląd robota |
|
Rys. 2. Pierwsze testy programu panikarz |
3. Opracowanie algorytmów
Celem algorytmu Panikarz było opracowanie programu, w którym robot poruszałby się wolno przed siebie (przyjęto 200 stopni / sekundę); na głośny dźwięk (tutaj klaśnięcie) obracał się o losowy kąt i bardzo szybko podążał (przyjęto 700 stopni / sekundę); w kierunku w którym się obrócił (o kąt z przedziału od 150 do 240 stopni). Następnie po ucieczce, znów poruszał się wolno przed siebie.
Dobrano próg natężenia dźwięku równy 50, który jednocześnie eliminował klaśnięcia na stanowiskach oddalonych o kilka metrów
panikarz.pl
:- consult('plnxt.pl'). % załadowanie pliku plnxt.pl
%% Funkcja startująca program
start :-
nxt_open, % otworzenie połączenia
thread_create(go_on_buddy, _ ,[ detached(true) ]). % utworzenie wątku 'go_on_buddy'
%% Funkcja odpowiedzialna za powolny ruch robota
go_on_buddy :-
nxt_go(200), % poruszanie się bardzo wolno do przodu
sleep(1), % chwila przerwy, aby jedno klaśnięcie nie zostało rozpoznane jako dwa.
trigger_create(_, clap, escape), % wyzwalacz mający za zadanie sprawdzenie natężenia dźwięku
trigger_create(_, touch, stop). % wyzwalacz mający za zadanie sprawdzenie czy nie naciśnięto sensora dotyku
%% Funkcja odpowiedzialna za ucieczkę robota
escape :-
nxt_stop, % zatrzymanie robota
nxt_rotate(700, 150 + random(91)), % obrót o losowy kąt z zakresu (150; 240) stopni
nxt_go(700, 3000), % szybka ucieczka w stronę, w którą robot obrócił się
go_on_buddy. % wywołanie funkcji 'go_on_buddy'
%% Funkcja sprawdzająca, czy natężenie dźwięku przekracza progową wartość (50 - dobrane arbitralnie)
clap :-
nxt_sound(Value,force),
Value > 50.
%% Funkcja sprawdzająca, czy naciśnięto sensor dotyku
touch :-
nxt_touch(Touch, force),
Touch = 1.
%% Funkcja zatrzymująca program
stop :-
trigger_killall, % zabicie wszystkich wyzwalaczy
nxt_stop, % zatrzymanie pracy skryptu
nxt_close. % zakończenie połączenia z NXT Mindstorms
4. Algorytm w akcji
5. Napotkane problemy
?- stop.
Yes
Warning: [Thread 3] Thread running "trigger_start(nxt_is_stopped, thread_send_message(2, resume), 1)" died due to failure
?- halt.
1 threads wouldn't die
Podczas wydania predykatu stop. w przykładzie trzecim pojawił się natomiast poniższy komunikat. Wynika z tego, że dalej pozostał działający wątek 'clap' (odpowiedzialny za sprawdzenie, czy natężenie dźwięku przekracza progową wartość)
?- stop.
Yes
Warning: [Thread 2] Thread running "trigger_start(clap, go_on_buddy, 1)" died due to failure
ps aux|grep pl
W obydwu przypadkach przed uruchomieniem kolejnego przykładu należało opuścić środowisko SWI-Prolog i zabić proces za niego odpowiedzialny poleceniem:
kill NUMER_PID
6. Co rozszerzyć w laboratorium?
Dobrą rzeczą byłoby zrobienie obserwatora pracujących wątków (po stronie serwera) niezależnie od wykonywanych programów w języku Prolog. Miałby on za zadanie ciągłe śledzenie wątku (wątków) działających i zapobieganie sytuacjom, kiedy wątek działa w tle mimo iż formalnie zakończyliśmy pracę z urządzeniem NXT.
Ulepszeniem laboratorium byłoby zrobienie bardziej twórczej pracy, gdzie w przykładach samemu należałoby dobrać nie tylko parametry dla sensorów (w tym momencie są one dane a priori; np. natężenie dźwięku w przykładzie trzecim na 30), ale również sam algorytm w przykładzie ćwiczeniowym
7. Wnioski
Na laboratorium udało nam się zaimplementować ciekawy algorytm wykorzystujący kilka sensorów dostępnych w zestawie LEGO MINDSTORM, dodatkowo mieliśmy możliwość modyfikacji robota i bliższego zapoznania się z
API dostępnym w języku PROLOG a w szczególności z wielowątkowością i problemami z nią związanymi.
8. Pliki