Sprawozdanie z laboratorium - zapoznanie z PLNXT
Celem laboratorium było zapoznanie się z PLNXT. Ponieważ zastaliśmy złożonego robota
mogliśmy przystąpić to prac programistycznych.
Zapoznanie z API PLNXT
Przez pierwszą część laboratorium zapoznawaliśmy się z możliwościami API, wykonaliśmy uruchomiliśmy na naszym robocie przykładowe, zamieszczone na wiki fragmenty programów. Sprawdziliśmy jak robot reaguje na dane polecenia. Z taką wiedzą rozpoczęliśmy implementowanie zdanych algorytmów
Algorytm 1
Robot porusza się dowolnie wewnątrz obszaru na planszy testowej ograniczonego czarną linią. Nie może poza niego wyjechać! Gdy najedzie na czarną linię, powinien zawrócić. Niekoniecznie o 180 stopni. Np. Angle is 120 + random(120) zunifikuje Angle z liczbą z przedziału od 120 do 240. Można jej użyć jako kąt obrotu robota.
Oto nasze rozwiązanie:
:- consult('plnxt.pl').
start:-
nxt_open,
nxt_light_LED(activate),
go_on_buddy,
trigger_create(_,pushed,[nxt_stop,nxt_close]).
go_on_buddy :-
nxt_go(200),
trigger_create(_,check_light,[nxt_stop, rotate, go_on_buddy]).
rotate :-
Angle is 20 + random(120),
nxt_rotate(-200, Angle, force).
% Sprawdzenie, czy sensor dotyku jest wcisniety.
pushed :-
nxt_touch(Value,force),
Value=1.
% sprawdza dystans
check_light :-
nxt_light(LightValue,force),
LightValue < 30.
:- start.
Problemy i uwagi:
Po nauczeniu się jak sterować i skręcać robotem problemem było odnalezienie właściwej wartości granicznej dla sensora. Na początku mieliśmy z tym pewnie problemy, ale po uruchomieniu diody w sensorze wyniki poprawiły się. Po kilku testach doszliśmy do wniosku, że odpowiednią wartością będzie 30.
Algorytm 2
Robot przemieszcza się po pomieszczeniu i zmienia kierunek poruszania się, gdy przed sobą napotka przeszkodę.
Oto nasze rozwiązanie:
:- consult('plnxt.pl').
start:-
nxt_open,
go_on_buddy,
trigger_create(_,pushed,[nxt_stop,nxt_close]).
go_on_buddy :-
nxt_go(200),
trigger_create(_,check_distance,[nxt_stop, rotate, go_on_buddy]).
rotate :-
Angle is 60 + random(120),
% nxt_go_cm(-200,20),
nxt_rotate(-600, Angle, force).
% sprawdza dystans
check_distance :-
nxt_ultrasonic(Distance,force),
Distance < 15.
% Sprawdzenie, czy sensor dotyku jest wcisniety.
pushed :-
nxt_touch(Value,force),
Value=1.
:- start.
Link do filmu prezentującego Henia w akcji:
http://student.agh.edu.pl/~kacper/robot.mp4
Algorytm działa na prawie takiej samej zasadzie jak w wersji pierwszej, z tą różnicą że wykorzystywany jest sensor ultradźwiękowy. Ustawiliśmy wartość po przekroczeniu której zaczyna obrót na 15.
Ogólne uwagi do laboratorium
Po zakończeniu każdego programu pojawiały się warningi:
Warning: [Thread 4] Thread running „trigger_start(pushed, [nxt_stop, nxt_close], 1)” died on exception: source_sink `nxt_close' does not exist
Warning: [Thread 2] Thread running „trigger_start(check_distance, change_direction, 1)” died due to failure
Pomocne tutaj były restarty zarówno samego SwiPL, a także czasami Brixa.
Zauważyliśmy także pewien problem z wątkami, które niejednokrotnie zapętlały się gdzieś w Brix'ie i mimo wydania polecenia nxt_stop i ogólnego zakończenia skryptu, sprawiały że robot „sam” jeździł.