====== Skład zespołu: ======
* Sławomir Goszcz
* Tomasz Pięciak
* Maciej Żywioł
====== 1. Wstęp ======
* Celem laboratorium było opracowanie algorytmu poruszania się robota wzdłuż czarnego owalu, zamykającego obszar na planszy.
* Algorytm miał zostać zaimplementowany w języku prolog.
* Robot miał za zadanie odnaleźć linię, a następnie poruszać się wzdłuż niej, naciśnięcie sensora dotyku powodowało zakończenie pracy robota.
====== 2. Konstrukcja robota ======
*
| {{{:pl:dydaktyka:piw2009:sprawozdania:agatka.jpg?640|Rys. 1. Wygląd robota}} |
| Rys. 1. Wygląd robota |
| {{:pl:dydaktyka:piw2009:sprawozdania:20090429_001_.jpg?640|Rys. 1. Robot w akcji - wypróbowywanie algorytmu}} |
| Rys. 1. Robot w akcji - wypróbowywanie algorytmu |
====== 3. Opracowanie algorytmów ======
* Algorytm //Śledzenie linii// miał działać następująco: Robot umieszczony na planszy testowej dojeżdża do grubej czarnej linii, następnie obraca się w stronę prawą o 30 stopni po czym jadąc przed siebie, aż do ponownego najechania na grubą czarną linię.
* Schemat ten jest powtarzany do momentu, aż nie zostanie wciśnięty sensor dotyku.
* Próg natężenia oświetlenia równy 50 dobraliśmy po serii testów i pomiarów natężenia światła w obszarze czarnym i białym, w świetle oraz cieniu. Ponieważ bez dodatkowego źródła światła pomiary były chaotyczne i nie udało nam się określić konkretnego progu, uruchomiliśmy diodę doświetlającą.
sledzenie.pl
:- consult('plnxt.pl'). % załadowanie pliku plnxt.pl
%% Funkcja startująca program
start :-
nxt_open, % otworzenie połączenia
nxt_light_LED(activate), % aktywacja diody w celu oświetlenia podłoża
thread_create(go_slowly, _ ,[ detached(true) ]). % utworzenie wątku 'go_on_buddy'
%% Funkcja odpowiedzialna za ruch robota wewnątrz owalu, wyzwalacz przejścia białe->czarne oraz wyzwalacz stopu
go_slowly :-
nxt_stop, % zatrzymanie robota
nxt_go(100), % poruszanie się bardzo wolno do przodu
trigger_create(_, black_sensor, black_line), % wyzwalacz mający za zadanie sprawdzenie czy nie najechano na czarną linię
trigger_create(_, touch, stop). % wyzwalacz mający za zadanie sprawdzenie czy nie naciśnięto sensora dotyku, co jest równoznaczne z zatrzymaniem robota
%% Funkcja sprawdzająca, czy wartość oświetlenia jest mniejsza od wartości progowej (50 - dobrane arbitralnie)
%% Nieprzekroczenie wartości progu jest równoznaczne ze zjechaniem z białego podłoża na czarną linię
%% Raportowanie wartości posłużyło do stworzenia przebiegów zmian odczytu sensora
black_sensor :-
nxt_light(Value,force),
Value < 50,
write(Value),
nl.
%% Funkcja sprawdzająca, czy wartość oświetlenia przekracza progową wartość (50 - dobrane arbitralnie)
%% Przekroczenie wartości progu jest równoznaczne ze zjechaniem z linii czarnej na białe podłoże
black_lost_sensor :-
nxt_light(Value,force),
Value >= 50,
write(Value),
nl.
%% Funkcja odpowiedzialna za obrócenie robota o 30 stopni w prawo, wyzwalacz przejścia czarne->białe oraz wyzwalacz stopu
black_line :-
nxt_stop, % zatrzymanie robota
nxt_rotate(100, 30), % obrót robota o 30 stopni w prawo
trigger_create(_, black_lost_sensor, go_slowly), % wyzwalacz mający za zadanie sprawdzenie czy nie najechano na czarną linię
trigger_create(_, touch, stop). % wyzwalacz mający za zadanie sprawdzenie czy nie naciśnięto sensora dotyku, co jest równoznaczne z
%% 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 ======
Działanie algorytmu można obejrzeć pod adresami:
* http://www.youtube.com/watch?v=0OYMJwqpbKM
* http://www.youtube.com/watch?v=JkZKyypKg6M
====== 5. Napotkane problemy ======
* Podczas naciśnięcia sensora dotyku mimo, iż robot zatrzymywał się w konsoli wyświetlał się następujący komunikat:
Yes
?- Warning: [Thread 5] Thread running "trigger_start(touch, stop, 1)" died due to failure
* Receptą na to jest ponowne uruchomienie środowiska SWI-Prolog. W systemie **nie pozostają** żadne działające procesy w tle.
* Problemem napotkanym w ćwiczeniu było dobranie wysokości na jakiej czujnik światła powinien się znajdować. Początkowo znajdował się on bardzo nisko planszy (< 1 cm), przez co nie było możliwe odróżnienie linii czarnej od białego wnętrza. Ostatecznie czujnik zamontowano na wysokości 2 cm
* Innym problemem w algorytmie //Śledzenie linii// było ustalenie wartości progu dla sensora światła. Początkowo nie użyto oświetlenia diodą LED, co sprawiło kłopoty z odróżnieniem linii czarnej od białego wnętrza toru w sytuacji, gdy robot był odwrócony tyłem do zewnętrznego źródła światła (okna) i rzucał swój własny cień na czujnik światła. Rozwiązano to dodając stałe oświetlenie w postaci włączonej diody LED i dobraniem progu dla sensora światła równego 50.
* W algorytmie dokonano zapisu zmian wartości odczytu sensora przy przekraczaniu podłoża **białe->czarne** oraz **czarne->białe** co przedstawia poniższy wykres.
| {{:pl:dydaktyka:piw2009:sprawozdania:przebieg.png|Rys. 2. Przebieg odczytanych wartości sensora}} |
| Rys. 2. Przebieg odczytanych wartości sensora |
* Bazując na tym można dobrać wartość sensora światła wyznaczając średnią wartości parzystych (przekroczenie progu **czarne->białe**), średnią wartości nieparzystych (przekroczenie progu **białe->czarne**) oraz możliwości odchyłek poprzez wyznaczenie odchylenia standardowego dla obu przypadków.
Przekroczenie progu **czarne->białe**:
| Wartość średnia: | 55.44 |
| Odchylenie standardowe: | 4.51 |
Przekroczenie progu **czarne->białe**:
| Wartość średnia: | 46.76 |
| Odchylenie standardowe: | 1.68 |
* Z poniższego rysunku przebiegów przekraczania progu **czarne->białe** i **białe->czarne** można stwierdzić, że odchylenie standardowe jest umiarkowane:
| {{:pl:dydaktyka:piw2009:sprawozdania:przebieg2.png|Rys. 3. Przebieg odczytanych wartości sensora przy przekraczaniu progu **czarne->białe** (próbki parzyste) i **białe->czarne** (próbki nieparzyste)}} |
| Rys. 3. Przebieg odczytanych wartości sensora przy przekraczaniu progu **czarne->białe** (próbki parzyste) i **białe->czarne** (próbki nieparzyste) |
* Wobec czego najbardziej optymalną wartością progu dla sensora światła jest: round( (55.44 + 46.76) / 2 ) = 51
====== 6. Co rozszerzyć w laboratorium? ======
* Mając większą planszę można byłoby zrobić mini zawody żużlowe na owalnym torze, w których roboty mogłyby mieć zaprogramowane algorytmy jechania wewnątrz toru nie wjeżdżając w bandę (zjazd na zewnętrzną), albo na murawę (zjazd na wewnętrzną). Dodatkowo czujniki ultradźwiękowe mogłyby by reagować na odległości między nimi co zapobiegałoby kraksom ;)
* Możliwość dodania ciągłego w czasie podglądu wartości sensorów poprzez osobny zestaw funkcji.
====== 7. Wnioski ======
Opracowując algorytm śledzenia linii możemy stwierdzić, że było to zadanie niełatwe ale bardzo przyjemne. Dzięki zastosowaniu języka Prolog byliśmy w stanie w stosunkowo łatwy sposób zaimplementować dość zaawansowany algorytm śledzenia linii. Niestety zadanie laboratoryjne nauczyło nas również, że zastosowane w zestawie LEGO MINDSTORMS sensory nie są doskonałe i np. nieprawidłowe dobranie parametrów progowych czujnika światła może zniweczyć całą pracę algorytmiczną przez co robot przez dość długi czas nie zachowywał się tak jak tego od niego oczekiwaliśmy. Podsumowując zadanie było bardzo ciekawe i pokazało nam potencjał kryjący się w połączeniu LEGO MINDSTORMS i PROLOGA.
====== 8. Pliki ======
{{:pl:dydaktyka:piw2009:sprawozdania:goszcz_pieciak_zywiol_lab4.tar.bz2|}}