Cieľom tejto stránky je opísať proces spracovania high skillov a low skillov (spravidla býva jeden low skill na jeden XML súbor, čiže to čo my voláme “pohyb” je low skill) od načítania až po vykonanie plánovačom. Kód ktorý sa na tom podieľa je dosť roztrúsený a veľmi zle alebo vôbec okomentovaný. Tento dokument by mal tvoriť základ pre návrh procesu plánovania a tvorby zložitejších pohybov - high skillov.
Určité veci sa od napísania tohto dokumentu zmenili a nestihol byť ešte updatnutý. Konkrétne sa jedná o:
Niektoré z tried existujú aj v Jave a rovnaké alebo podobné triedy sú aj v Ruby skriptoch. Preto u každej z tried pri prvom spomenutí uvediem, v akom jazyku je napísaná. Pri triedach LowSkill a HighSkill to budem uvádzať vždy. V nasledovnom zozname vidno čo budem písať a čo tým myslím:
Diagram týchto a niektorých ďalších tried vidno na nasledovnom obrázku
Nevidno tu kompletné diagramy tried, sú vybrané len časti (metódy atď.) relevantné pre tento dokument.
Z XML sú načítané Java-LowSkill a Phase, pričom sa k nim dá dostať pomocou ich jedinečného mena.
Tieto podmienky sa kontrolujú pri načítavaní z XML
Hlavný cyklus, bežiaci po inicializácii a načítaní všetkých potrebných vecí, prebieha zjednodušene nejak takto
XML súbory s low skillmi a fázami musia pre použitie v high skilloch okrem vyššie uvedených požiadaviek spĺňať nasledovné
Pri skončení každej isFinal fázy sa volá pickLowSkill. V prípade, že sa vráti null (čo značí koniec celého high skillu), alebo iný než súčasný low skill, finalizuje sa súčasný low skill a následne sa vyberie nový. V prípade že pickLowSkill vráti súčasný low skill, pokračuje sa next fázou a finalizácia sa nevykoná.
LowSkill vždy pri druhom a ďalšom volaní pickLowSkill vracia null, takže vždy finalizuje pohyb pri prvej príležitosti. Toto dokonca viedlo k odtráneniu isFinal vlastností z mnohých XML súborov - tie tam treba vrátiť.
Na testovanie cyklických pohybov ako je chôdza bol vytvorený nový HighSkill s názvom CyclicHighSkill, ktorého metóda pickLowSkill vždy vracia ten istý lowSkill. Tiež som vytvoril testovací high skill s názvom LinkedHighSkill, ktorý používa pole pohybov.
walk.rb bol upravený aby využíval nové pohyby
High skilly sa dajú písať v ruby aj v jave. Musia dediť triedu Java-HighSkill
Hlavou úlohou je implementácia metódy pickLowSkill. Tá sa bude volať na začiatku vykonávania pohybu a zakaždým, keď skončí fáza s isFinal=true.
Vrátiť musí objekt triedy Java-LowSkill.
Metóda checkProgress sa volá aj počas priebehu fázy, ak fáza ešte neskončila. Vyhodením výnimky by mala môcť ukončiť high skill bez čakania na finalizáciu fázy low skillu. To je použíteľné napríklad ak agent spadol.
privatevoidplan(Trajectory t)
Pred úpravou sa trajektória plánovala znovu bez ohľadu na úspešnosť po prejdení ¾ vzdialenosti. Robot vďaka strate stability často spadol a celkový čas na dosiahnutie cieľa sa tak iba zväčšil.
int walkNum = (int) distance/stdWalk.getMove().getX().getAvg() * 0.75;
Tento parameter sme jednoducho odstránili. Hráč takto vykoná celú plánovanú trasu a následne vypočíta prípadnú úpravu k cieľu.
int walkNum = (int) distance/stdWalk.getMove().getX().getAvg( );
Nadväznosť pohybov sa realizuje volaním metódy sequenceCheck v rámci metódy walk. Overí sa, či vybraný krok môže nadväzovať na už vypočítanú trajektóriu v tejto metóde. Ak áno, metóda sequenceCheck vráti hodnotu true, inak false.
Podmienky:
public staticbooleansequenceCheck(Annotation first,Annotation second){ \\booleanvalid =true;
\\ check if agent is lying \\if(first.end.lying.compareTo(second.preconditions.lying) !=0){
valid =false; \\}
\\ check of ball's position against agent's position
range of position at the end of movement has to be in range at the start of next movement \\if1)){ \\if(!2)) &&
(first.end.ball.getX().getMax() ⇐ second.preconditions.ball.getX().getMax()) &&
(first.end.ball.getY().getMin() >= second.preconditions.ball.getY().getMin()) &&
(first.end.ball.getY().getMax() ⇐ second.preconditions.ball.getY().getMax()))){
valid =false; \\}
}
\\ check of joint's flexibility \\for(inti=0;i<second.preconditions.joints.size();i++){ \\for(intj=0;j<first.end.joints.size();j++){ \\if(second.preconditions.joints.get(i).name.compareTo(first.end.joints.get(j).name) ==0){ \\if(second.preconditions.joints.get(i).value!= first.end.joints.get(j).value){
valid =false; \\}
}
}
}
\\returnvalid;
}
Ak nasledujúci pohyb trajektórie splní niektorú z podmienok 1.-3. je vyhodnotený ako nemožný / nevhodný pre pokračovanie pohybu a hľadá a iný zo zoznamu pohybov, ktorý podmienku spĺňa.
Navrhované riešenie:
Navrhujeme upraviť podmienku jedna a doplniť do nej pridanie pohybu vstávania (čiže podmienka 1. bude true).
Podmienku 2. nechať nezmenenú (ak sa agent ocitne z nejakého dôvodu mimo plánovanú trajektóriu, je treba nájsť iný pohyb)
Podmienku 3. upraviť na kontrolu polohy kĺbov a ich nastavenie pre daný pohyb, nie je dôvod pre hľadanie iného potenciálne menej vhodného pohybu v trajektórií
Plánovanie trajektórie je z pohľadu vykonávania a efektivity dosiahnutia cieľa v poriadku. Odstránením podmienky o vykonaní ¾ trajektórie sme skrátili čas pohybu na dlhšie trasy o približne 1/5 v priemere. Nadväznosť pohybov riešená v metóde sequenceCheck sme navrhli upraviť nasledovne:
Navrhujeme upraviť podmienku 1. a doplniť do nej pridanie pohybu vstávania (čiže podmienka 1. bude true).
Podmienku 2. nechať nezmenenú (ak sa agent ocitne z nejakého dôvodu mimo plánovanú trajektóriu, je treba nájsť iný pohyb)
Podmienku 3. upraviť na kontrolu polohy kĺbov a ich nastavenie pre daný pohyb, nie je dôvod pre hľadanie iného potenciálne menej vhodného pohybu v trajektórií