Zadanie wykonałem sam (Konrad Dzwinel), przypisany (wg. rozpiski) do mojej grupy Norbert pracował w innym zespole.
Wstęp
Celem laboratorium była:
budowa (w moim przypadku - jedynie modyfikacje) robota
połączenie się z nim poprzez bluetooth
napisanie prostego programu z wykorzystaniem PLNXT
API
uruchomienie programu na robocie
testy
Przygotowanie stanowiska
Pracę rozpocząłem od lektury „przygotowanie stanowiska”, jak się szybko okazało wszystkie kroki zostały wykonane już przez grupę poprzednią. Wykonałem z powodzeniem na robocie opisany program testowy (Pierwsze Kroki).
Wykonanie zadań
LEGO
Do robota pozostawionego przez grupę poprzednią domontowałem czujnik nacisku tak żeby znajdował się na przodzie robota, czujnik odległości przeniosłem do góry kierując go również w kierunku przodu robota.
PROLOG
Przeanalizowałem przykład, wprowadziłem własne modyfikacje i przekonałem się, że triggery należy „odnawiać” po każdym ich wywołaniu. Oznaczało to w praktyce dodanie w funkcji wywoływanej jako reakcja na trigger ponowną definicję tego triggera.
W związku z tym, że sam wykonywałem laboratorium wybrałem tylko jeden algorytm do wykonania (Algorytm 2). Mój robot miał poruszać się w jednym kierunku aż do napotkania przeszkody, po napotkaniu przeszkody powinien zmienić kierunek. Chciałem rozbudować powyższe zadanie o następujące funkcję:
pobieranie informacji o przeszkodzie z dwóch czujników (nacisk i odległość) - nacisk był umieszczony na wysokości kół i mógł wykryć niskie przeszkody których nie wykrywał czujnik odległości
wydawanie dźwięku gdy napotkamy przeszkodę
zmiana kierunku losowa
Losowa zmiana kierunku i zagranie melodii okazały się bardzo proste do wykonania. Problem z którym nie mogłem sobie poradzić przez dłuższy czas to zdefiniowanie przeze mnie dwóch triggerów (nacisk,odległość). Program kompilował się jednak robot po wywołaniu któregokolwiek zdarzenia wpadał w „szał” - obracał się tak jak gdyby cały czas był wywołany jeden z triggerów. Nie przechodził w stan „jazda”. Mój program wyglądał następująco:
:- consult('plnxt.pl').
start :-
nxt_open,
trigger_create(_,check_distance,[run_away]),%zdefinowanie triggerów
trigger_create(_,check_presure,[run_away]),
nxt_go(300).
check_distance :-
nxt_ultrasonic(Distance,force),
Distance < 15.
check_presure :-
nxt_touch(Presure,force),
Presure = 1.
run_away :-
nxt_stop,
nxt_play_tone(1000,1000),nxt_play_tone(1500,1000),nxt_play_tone(2000,1000),%melodyjka
random(0,60,Rand),
Agle is Rand +180,%kąt skrętu <180,240> stopni
nxt_rotate(350,Agle),
trigger_create(_,check_distance,[run_away]), %zdefiniowanie na nowo triggerów
trigger_create(_,check_presure,[run_away]),
nxt_go(300).
Próbowałem wielu rzeczy aby zmusić ten kod do poprawnego działania. Stworzyłem osobną kopię „run_away” dla każdego z triggerów tak aby po wywołaniu „check_distance” nie był tworzony kolejny „check_presure” i na odwrót - niestety to również nie pomogło. W efekcie zrezygnowałem z drugiego triggera, kod bez „check_presure” stanowi moje rozwiązanie zadania 2.
Wnioski, Uwagi
- informacja o „FORCE” występuje dwa razy w dwóch różnych wersjach tutaj i tutaj.
- programy które pisałem i testowałem nie miały żadnej funkcji stopu, musiałem wyłączać robota ręcznie aby zaprzestał wykonywania poleceń. Prawdopodobnie z tego powodu co chwilę miałem problem z przegraniem programu na robota. Występowały błędy przy próbie połączenia. Restartowałem wówczas całe środowisko prologa (niejednokrotnie używając polecenia „killall” ponieważ środowisko nie chciało się zamknąć (jakieś działające w tle wątki)) i samego robota.
- nxt_voltage_millivolt(Voltage) - nigdzie nie jest napisane co właściwie powinno zostać zwrócone, jedno jest pewne: procenty to to nie były.