Robot: Henio
Grupa: środa 12.30
Autorzy: Jakubas , Kozera, Płaszowski
Wstęp
Celem laboratoriów było zapoznanie się z interfejsem programistycznym PLNXT i budowa prostego algorytmu.
W czasie wykonywania zadania korzystaliśmy z następujących narzędzi:
zestaw LEGO
adapter BT
PLNXT
Kod programu
Algorytm 2
start :-
nxt_open,
trigger_create(_,check_distance,[obrot]),
nxt_go(300).
%trigger_create(_,check_distance2,[chodzenie]).
die :-
nxt_stop,
trigger_killall,
sleep(2),
nxt_stop,
nxt_close.
obrot :-
nxt_stop,
nxt_rotate(300,60),
sleep(2),
trigger_create(_,check_distance,[obrot]),
nxt_go(300).
chodzenie :-
nxt_go(300).
check_distance :-
nxt_ultrasonic(Distance,force),
Distance < 23.
check_distance2 :-
nxt_ultrasonic(Distance),
Distance >= 23.
Spostrzeżenia, napotkane problemy, wnioski.
Przygotowanie stanowiska pracy
Po pierwszych nieudanych próbach połączania się z robotem konieczne okazało się przeprowadzanie ponownej konfiguracji połączenia ( zgodnej z opisem ). W tym celu wykonaliśmy pomyślnie poniższe kroku:
Następnie przeszliśmy do wykonania kolejnych czynności:
Budowa robota
Praca w powłoce SWIPL
Wykonaliśmy podstawowe polecenia w celu sprawdzenia poprawności połączenia oraz przetestowania sensorów.
nxt_open.
nxt_go(100).
nxt_rotate(350,360).
nxt_voltage_millivolt(Voltage).
nxt_close.
Po udanej próbie działania naszego robota przeszliśmy do tworzenia algorytmu programu.
Realizacja algorytmu 2
Spostrzeżenia
Po paru próbach okazało się, że najlepsze efekty osiąga się jeżeli wykrywa się przeszkoda znacznie wcześniej. Odległość minimalną na jaką nasz robot mógł zbliżyć się do przeszkody ustawiliśmy na 23cm. Taki odstęp pozostawiał nam możliwość bezproblemowego obrócenia robota nawet o 180 stopni, bez zawadzania okablowaniem o przeszkodę.
Kolejnym parametrem, który postanowiliśmy wyregulować był kąt obrotu po napotkaniu przeszkody. Początkowy kąt obrotu wynoszący 90 stopni nie sprawdzał się najlepiej przy napotkaniu paru kolejnych przeszkód. Ostatecznie ustawiliśmy kąt obrotu na 60 stopni co pozwalało na płynne ale i w miarę szybkie pokonanie przeszkód.
Napotkane problemy
Problem: Ciągłe działanie
Najwięcej problemów przysporzyło nam napisanie algorytmu, który wykonywał by się ciągle przy jednoczesnym wykorzystaniu triggerów.
Rozwiązanie
Rekurencja, pierwszy trigger odpalał sam siebie. Co skutecznie rozwiązało problem z ciągłym działaniem algorytmu. Niestety zrodziło to kolejny problem.
Problem: Zawieszanie wątków
Problem z „uśmierceniem” wszystkich rekurencyjne kreowanych wątków. Bez poprawnego zamknięcia wszystkich stworzonych triggerów konieczne było resetowanie powłoki SWIPL, przed dalszą praca.
Rozwiązanie
Użycie funkcji zabijającej wszystkie stworze wątki + uśpienie wykonywania programu, udostępniające czas na zabicie wszystkich wątków.
trigger_killall,
sleep(2),
Dopiero użycie takiej zabójczej kombinacji pozwoliło na w miarę płynną pracę z triggerami.
Problem: Niepełne obroty
Po wykryciu przeszkody uruchamiał się trigger odpowiedzialny za wykonanie obrotu oraz dalszy ruch. Niestety przed wykonaniem zadanego obrotu wykonywał się kolejny trigger, który wykrywał tę samą przeszkodę i przejmował robota. Efekt był dość zabawny ponieważ robot zamiast 1 obrotu o 90 stopni wykonywał ich 5-7 zanim się zatrzymał. Nie pomogło użycie „force” dla polecenia nxt_rotate.
Rozwiązanie
Uśpienie wątku odpowiedzialnego za obrót, w taki sposób aby dać czas robotowi na wykonanie polecenia.
nxt_rotate(300,60),
sleep(2),
Wnioski
Z przedstawionych wyżej przykładów wynika, że mechanizm „force” w połączaniu z triggerami nie działa poprawnie, umożliwiając przejęcie robota przez inny trigger w czasie wykonywania polecenia z użyciem atrybutu „force”.
Wydaje się nam też, że ulepszyć można polecenie trigger_killall, w taki sposób aby nie było konieczne usypianie programu dla lepszego efektu.
Uwagi
Załączniki
Link do filmu
Link do filmu
Kod programu