Skip to content
zeljko-bal edited this page Dec 4, 2015 · 14 revisions

#Javascript API

Na ovoj stranici će se nalaziti kompletan API koji se može koristiti za vreme pisanja taskova.

Svaki task mora sadržati minimum 2 funkcije: onRun i onPause. Pomoću ove dve funkcije zadatak se obaveštava da je prešao u aktivno stanje (trenutno se izvršava) i pauzirano stanje.

##Logger: Mehanizam za logovanje je dostupan i u javascriptu preko globalnog objekta Logger i metoda:

  1. Logger.debug(message)
  2. Logger.warning(message)
  3. Logger.error(message)

#Slanje komandi

Komanda se šalje tako što se prvo kreira objekat koji opisuje akciju i pozove se funkcija Command.send, funkciji se moraju proslediti i dva parametra - funkcije koje će biti pozvane u slučaju uspešnog ili neuspešnog izvršavanja komande. Moguće je dodati i treću opcionu funkciju koja služi za progress.

##Spisak dostupnih komandi Ovde se nalazi spisak objekata koje je moguće kreirati i poslati kao komandu.

  1. MoveForward(distance) Robot se kreće napred za distance milimetara.
  2. RotateFor(angle) Robot se rotira za angle stepeni.
  3. RotateTo(angle) Robot se rotira na ugao `angle stepeni.
  4. MoveToPosition(x, y) Robot odlazi na poziciju sa koordinatama x i y.
  5. MoveArc(x,y,angle) Robot se krece oko tacke x,y za ugao angle.
  6. StopMovement(hard) Robot prekida kretanje, moguce je poslati true ili false koji oznacavaju da li je soft ili hard reset. Ako se nista ne prosledi bice hard reset.
  7. SetSpeedMotion(speed) Setuje se brzina kretanja robota. Vrednost moze biti od 1-255. Normalna brzina je 100.
  8. SetPosition(x, y) Postavlja se pozicija robota na x,y koordinatu.
  9. GetMotionState() Salje se robotu zahtev za ocitavanje trenutnog stanja
  10. ActuatorCommand("executor","action") Salje executoru ( oderenjen parametrom) akciju ( odrenjenu parametrom)
  11. SleepCommand(milliseconds) Napravi se delay za zadati broj milisekundi i posle toga se pozove success funkcija.

Parametri za ActuatorCommand

executor:

  1. LiftLeft
  2. LiftRight
  3. Popcorn
  4. Flap
  5. EnemyDetector
  6. Carpet
  7. LiftCenter

action za lift executore:

  1. StartGetting
  2. StopGetting
  3. Unload

action za flap executor:

  1. KickLeft
  2. KickRight
  3. UnkickLeft
  4. UnkickRight

action za popcorn executor:

  1. Get
  2. Unload

action za enemy detector executor:

  1. StartBrkon
  2. StopBrkon
  3. StartBeacon
  4. StopBeacon

action za Carpet executor:

  1. Leave

action za LiftCenter executor:

  1. Get
  2. Unload

##Odgovori na komande sa poljima Neki odgovori na komande se pozivaju bez parametara a kod nekih je moguće i isčitati vrednosti. Spisak polja koja se mogu isčitati kao odgovor od komandi.

  1. GetMotionState. Progress: direction, orientation, x, y, speed, state.

#Prijem notifikacija Notifikacije služe za sakupljanje informacija o stanju na terenu. Task može da se prijavi da prima notifikacija tako što će pozvati funkciju Notification.subscribe sa imenom notifikacije i funkcijom koja će obraditi to. Svaki objekat notifikacije ima polja koja je moguće isčitati.

##Lista polja za svaku notifikaciju sa njenim imenom.

MotionNotification

direction, orientation, x, y, speed, state.

EnemyDetectedNotification

type (Brkon=1, Beacon=2, Sensor=3), angle (0 stepeni je pravo ispred robota), detected (true, false)

LiftNotification

side (right=1, left=2), count.

#Podešavanje stanja taska Svaki task mora da bi se mogao pokrenuti mora obavestiti sistem o svom trenutnom stanju. Na osnovu stanja koje task sam odredi i prioriteta koji je zadat task manager će odlučiti koji task da pokrene. Postavljanje željenog stanja se radi pozivom funkcije Manager.updateState(stanje).

Stanja mogu biti:

  • Ready - svi uslovi su ispunjeni da bi se task izvrsavao
  • Finished - task je zavrsio sve sto je mogao
  • Impossible - task nije zavrsio, ali saznao je da je nemoguce da odradi svoj zadatak
  • Suspended - task ne moze trenutno da se izvrsi jer mu nedostaju neki uslovi

Da bi task ušao u red za izvršavanje potrebno je uraditi Manager.updateState("Ready");. Task počinje uvek u stanju Suspended.

#Utils api U utils.js se nalaze metode i objekti koji omogućuju jednostavnije pisanje taskova i dostupni su u svakoj skripti.

##Geometry Postoji definisana klasa Point2D koja sadrži x i y koordinate. U Geometry objektu se nalaze par korisnih metoda za rad sa 2D tačkama:

  • euclid_dist(point1, point2) - Vraća rastojanje među tačkama point1 i point2.
  • nearest_point(current_position, points) - Vraća tačku iz niza tačaka points koja je najbliža tački current_position.
Geometry.nearest_point(new Point2D(0,0), [new Point2D(1,1), new Point2D(50,50)]); // vraca {'x':1, 'y':1} (najblizu iz niza)

##Motion Motion objekat poseduje metodu invert_x(points) koja prima objekat (mapu) imenovanih tačaka i vraća isti takav objekat u kome su sve x koordinate pomnožene sa -1.

var yellow_positions =
{
	'prva_tacka':{'x':-790, 'y':1050},
	'druga_tacka':{'x':123, 'y':234},
};
var green_points = Motion.invert_x(yellow_positions); 

Ako se centar koordinatnog sistema uzme tako da je teren simetričan u odnosu na y osu, moguće je zadati tačke samo za jednu stranu, dok se za drugu samo invertuje x koordinata. Napomena: Zbog fizičkih nepravilnosti stola, on često nije potpuno simetričan, tako da, ukoliko je potrebna veća preciznost, moraju se izvršiti određene korekcije koordinata ili zadati poseban set tačaka za različite strane.

Motion poseduje i set konstanti koje se mogu proslediti komandi za kretanje i koje određuju smer, a to su FORWARD, BACKWARD i AUTO. AUTO bi trebalo da zadaje smer kretanja na tačku, tako da se robot rotira za najmanji ugao od trenutne orijentacije ka odredišnoj tački (ova funkcionalnost nije još implementirana u C++, tako da je ova konstanta za sada jednaka FORWARD).

##Config i setup Na početku svakog taska se poziva funkcija onSetup(color) kojoj se prosleđuje boja (strana) sa koje robot kreće u tekućem meču. Ova funkcija je već definisana u utils.js (uključena u svaki task) i na početku taska smešta vrednost boje u Config objekat i potom poziva funkciju Config.setup() ukoliko je definisana. Objekat Config služi kao pomoćni objekat za skladištenje raznih parametara zadatka na jednom mestu. U ovaj objekat se u samom tasku mogu dodavati razni parametri radi grupisanja. Config takođe sadrži i promenljivu default_speed definisanu u utils.js koja je na taj način zajednička za sve zadatke. Napomena: Svaki zadatak se izvršava izolovano, tako da promene koje se izvrše u samim skriptama zadataka nisu vidljive ostalim zadacima (za delenje stanja među zadacima videti set_world_state i get_world_state komande ispod).

var yellow_positions =
{
	'prva_tacka':{'x':-790, 'y':1050},
	'druga_tacka':{'x':123, 'y':234},
};
var green_points = Motion.invert_x(yellow_positions);
var positions_colored={'YELLOW':yellow_positions, 'GREEN':green_points};

/* 
zada se funkcija koja ce se izvrsiti na pocetku zadatka, pre pokretanja samog zadataka (onRun), 
a nakon izvlacenja startnog dzampera (zbog podesavanja prekidaca za boju)
*/
Config.setup = function() 
{
	// dodaju se podesavanja za tacke i uglove u zavisnosti od vrednosti Config.color
	Config['positions'] = positions_colored[Config.color];
	Config['orientations'] = orientations_colored[Config.color];
}

// *** kasnije u kodu
Logger.debug("boja je: "+Config.color);
Logger.debug("x koordinata prve tacke je: "+Config.positions.prva_tacka.x);
Logger.debug("default brzina je : "+Config.default_speed); 
// zgodno kada treba vratiti brzinu nazad na default, ista je za sve zadatke i podesava se na jednom mestu u utils.js
// ***

##CommandChain Radi lakšeg pisanja logike i zadavanja komandi može se koristiti lanac komandi. Prva komanda u lancu se zadaje pozivom CommandChain() funkcije kojoj se prosledi komanda (može biti komanda kao u Command.send() ili funkcija). CommandChain() vraća CommandChainNode objekat koji poseduje skup metoda pomoću kojih se kreira lanac (većina takođe vraćaju CommandChainNode tako da je moguće ulančavanje). Pozivom execute() metode počinje izvršavanje lanca od početka, kada se komanda uspešno izvrši izvršava se sledeći čvor ako postoji. Ukoliko se komanda ne izvrši uspešno poziva se failure_callback ako je definisan, a preostale komande se odbacuju (ako nije definisan failure_callback izvršava se naredni čvor kao da je komanda uspela).

CommandChain(new SetSpeedMotion(50))
.then(new MoveToPosition(x,y))
.then(new RotateTo(90))
.execute();

Kada je komanda objekat (kao u Command.send()) moguće je podesiti progress_callback pozivom metode progress nad odgovarajućim čvorom.

CommandChain(new MoveToPosition(x,y))
.progress(function(msg)
{
    Logger.debug(msg.x+' '+msg.y);
})
.execute();

Kada je komanda funkcija ona se izvršava kada čvor dođe na red za izvršavanje i kada se izvrši komanda se tretira kao uspela. Može biti bez parametara ili može da sadrži parametar result koji predstavlja rezultat prethodne komande. Takođe funkcija može vratiti rezultat koji će biti prosleđen narednoj komandi. Ako funkcija baci izuzetak 'command_error' tretiraće se kao da komanda nije uspešno izvršena, a ukoliko slučajno baci neki drugi izuzetak, ovaj zadatak će se prebaciti u stanje 'Impossible' i suspendovati. this u funkciji predstavlja čvor trenutne komande, tako da je moguće izmeniti lanac komandi unutar nje. Moguće je umetnuti komande pozivom then(), prekinuti izvršavanje lanca pozivom abort() ili izmeniti ostatak lanca pozivom alter(). Ovo je korisno kada je potrebno zadati različite komande na osnovu senzora ili trenutnog stanja na terenu u određenom trenutku u sred lanca komandi (napomena: zadavanje komandi je asinhrono i neblokirajuće, tako da, da bi se deo koda izvršio u sred lanca mora se zadati na ovaj način).

CommandChain(new MoveToPosition(x,y))
.then(GetMotionState())
.then(function(motion_state)
{
    if(motion_state.x > 1000)
    {
        this
        .then(new MoveToPosition(x,y)); // umetni komandu u lanac
    }
    else
    {
        throw 'command_error'; // failure
    }
})
.execute();

U funkciji koja predstavlja failure_callback this takođe predstavlja trenutni čvor, tako da je moguće vršiti izmene na lancu i vratiti 'continue' nakon čega će se nastaviti izvršavanje lanca od sledeće komande (kao da je komanda zapravo uspela).

CommandChain(new MoveToPosition(x,y))
.failure(function() // ako ne uspe MoveToPosition
{
    if(uslov)
    {
        this
        .then(new MoveForward(750)); // idi jos napred 750
        return 'continue';
    }
})
.execute();

Moguće je i pokrenuti izvršavanje komandi paralelno tako što se pokrenu dva lanca komandi u isto vreme.

CommandChain(new ActuatorCommand('LiftLeft','Unload')).execute();
CommandChain(new ActuatorCommand('LiftRight','Unload')).execute();

Metode koje postoje u CommandChainNode su sledeće:

  • then(next_object) - Dodaje sledeću komandu (next_object) u lanac nakon trenutnog čvora i vraća novi čvor. next_object može biti komanda kao u Command.send(), funkcija ili drugi lanac komandi. Ukoliko se vrši ulančavanje u sredinu lanca (unutar neke komandne funkcije u sred lanca) komanda se umeće u lanac i nasleđuje failure_callback prethodne komande (osim ako se umeće novi lanac komandi, u tom slučaju se failure_callback ne nasleđuje).
  • failure(failure_callback) - Podešava failure_callback za trenutni čvor i vraća trenutni čvor.
  • progress(progress_callback) - Podešava progress_callback za trenutni čvor i vraća trenutni čvor.
  • catch(failure_callback) - Podešava failure_callback za trenutni čvor i sve prethodne ukoliko nemaju već podešen i vraća trenutni čvor.
CommandChain(new SetSpeedMotion(50))
.then(new MoveToPosition(x,y))
.then(new RotateTo(90))
.failure(function()
{
   // ako bas ne uspe na RotateTo(90)
})
.then(new MoveForward(100))
.catch(error) // pozovi error ako ne uspe bilo šta sem RotateTo(90)
.execute();
  • ignore_failure() - Ignoriše se neuspeh za ovu komandu, poziva se sledeća komanda bez obzira na ishod.
CommandChain(new SetSpeedMotion(50))
.then(new MoveForward(100)).ignore_failure() // nastavi dalje cak i ako ne stigneš 100 napred
.then(new RotateTo(90))
.catch(error) // za ostale neuspehe pozovi error
.execute();
  • abort() - Prekida dalje izvršavanje lanca.
CommandChain(new MoveForward(750))
.then(function()
{
    if(should_abort)
    {
        this.abort(); // prekini dalje izvršavanje
    }
}
.then(new RotateTo(90)) // neće se izvršiti ako je should_abort
.execute();
  • alter(next_object) - Menja lanac, ostatak lanca se odbacuje i nadovezuje se nova komanda ili lanac komandi (kao abort(), pa onda then()).
CommandChain(new MoveForward(750))
.then(function()
{
    if(should_alter)
    {
        this.alter(new RotateTo(270)); // rotiraće se na 270 umesto na 90
    }
}
.then(new RotateTo(90)) // neće se izvršiti ako je should_alter
.execute();
  • execute() - Počinje izvršavanje lanca od početka.

##Task Objekat koji sadrži metode za lakše rukovanje stanjima zadatka.

  • sleeping - boolean da li je task uspavan pomoću metoda u Task objektu.
  • wake_up_after(timeout, wake_up) - Suspenduje task i pokreće wake_up funkciju nakon određenog vremena (timeout), sleeping je true u međuvremenu.
  • ready_after(timeout) - Suspenduje task i prebacuje ga u "Ready" stanje nakon određenog vremena, sleeping je true u međuvremenu.

##Commands Pomoćni objekat koji sadrži metode koje se mogu proslediti u lanac komandi.

  • do_nothing() - Prazna funkcija.
  • finish_task() - Prebacuje stanje taska u "Finished".
  • suspend_task() - Prebacuje stanje taska u "Suspended".
  • wake_up_after(timeout, wake_up) - Isto kao Task.wake_up_after.
  • ready_after(timeout) - Isto kao Task.ready_after.
  • set_world_state(key, value) - Podešava promenljivu u world_state skupu promenljivih koje opisuju trenutno stanje sveta (terena) i dostupne su u ostalim taskovima i u raspoređivaču. Ove promenljive mogu predstavljati šta je robot pokupio sa terena, šta trenutno drži u sebi, gde je šta istovario itd. i mogu koristiti drugim taskovima ili raspoređivaču za donošenje odluka.
  • get_world_state(key) - Preuzima vrednost promenljive iz world_state.
  • pf_move(point, direction) - Zadaje komandu za kretanje korišćenjem path finding algoritma za obilaženje prepreka. Default vrednost parametra direction je Motion.AUTO.
  • log_position() - Ispisuje trenutnu poziciju (x,y) u Logger.debug.
CommandChain(new MoveForward(750))
.then(new RotateTo(90))
.then(Commands.finish_task) // kad završiš rotaciju završi zadatak
.catch(Commands.ready_after(5000)) // ako dođe do greške suspenduj na 5 sekundi
.execute();