Návod/Monitorovanie

Z RoboCupTP wiki

Prejsť na: navigácia, hľadanie

Späť na Návod

Obsah

Monitorovanie servera v test frameworku

Základy

Test framework je pripojený k serveru na porte 3200, odkiaľ od neho prijíma správy o aktuálnom stave kompletnej simulácie. Tieto správy sú podľa protokolu SimSparku S-výrazy obsahujúce niekoľko špecifických údajov a popisujúce graf scény. Test framework z tohto grafu vyberá pre seba zaujímavé informácie (poloha lopty, poloha hráčov).

Implementácia a použitie

Monitorovanie beží v samostatnom threade v triede RobocupMonitor, ktorej inštancia sa dá získať metódou getMonitorInstance(). Táto trieda sa pri každej príchodzej správe zo serveru pozrie do hlavičky správy, na základe čoho určí o aký typ správy sa jedná.

Celý stav simulácie - informácie z oboch typoch správ a kompletná scéna - je uložený v objekte triedy SimulationState. Takýto objekt s aktuálnym stavom vlastní trieda RobocupMonitor, ktorá ho priebežne updatuje na základe príchodzých správ. Dá sa z nej získať metódou getSimulationState.

Takisto je možné sledovať všetky updaty týchto údajov zaregistrovaním observeru implementujúceho ISimulationStateObserver v objekte triedy SimulationState.

Parsovanie správ

Každá správa zo servera prijatá triedou RobocupMonitor je najprv rozparsovaná

  • environment message - obsahuje informácie o veľkosti ihriska, lopty a pod. (viď protokol), je parsovaná triedou EnvironmentMessageParser
  • game state message - obsahuje informácie o stave hry, napr. o skóre, čase a pod., je parsovaná triedou GameStateMessageParser

Po oboch typoch správ vždy nasleduje graf scény, buď kompletný, alebo len čiastočný (vyjadrujúci zmenu oproti predchádzajúcemu stavu). Tento je rozparsovaný pomocou tried SceneGraphHeaderPartParser a SceneGraphPartParser

Aplikovanie rozparsovaných údajov

Trieda RobocupMonitor teda rozparsuje správy príslušným parserom do objektov podtried triedy Message. Tieto dáta sú následne aplikované triedou MessageInterpreter. Okrem informácií z environment správ a game state správ, ktoré sa uložia do aktuálneho stavu simulácie, je treba spracovať graf scény, čo sa deje vnútri triedy SceneUpdater. Táto okrem vytvorenia celého grafu z neho vyberie uzol reprezentujúci loptu (uloží sa do jednoduchého 3D vektora Scene.ballLocation) a uzly reprezentujúce hráčov (objekty triedy Player), ktoré sú prepojené s objektami agentov AgentJim. Toto prepojenie je popísané v nasledovnej podkapitole.

Ako už bolo uvedené, s týmito údajmi sa dá pracovať pomocou objektu triedy SimulationState získanej volaním getSimulationState z RobocupMonitor. Zmeny je možné sledovať pomocou observeru ISimulationStateObserver.

Pre jednoduchšiu prácu so stavmi simulácie v rôznych časoch možno použiť aj triedu MeasurableInformation, ktorá si skopíruje aktuálny stav simulácie a neskôr možno dva takéto objekty porovnať.

Prepojenie grafu scény a objektov agentov

Server posiela graf scény len vo forme 3D objektov, informácia o tom ku ktorému pripojenému agentovi ktorý objekt patrí sa tam priamo nenachádza, treba ju teda získať iným spôsobom. Jedna z možností by možno (?) bola zistenie podľa materiálov (farba určí tím, číslo na drese hráča?). Ja sa však spolieham na fakt, že modely sú posielané v poradí, v akom sa hráči pripojili. Toto síce nie je priamo popísané v protokole, takže to možno nie je 100% spoľahlivé, no podľa mojich testov to v praxi funguje. TODO:: pridať poznámku do príslušnej časti kódu, že ak to prestane fungovať, treba overiť toto.

Na využitie týchto informácií je treba ukladať informácie o poradí pripojenia agentov. Toto je uložené v AgentManager.orderedAgents. Pretože objekt grafu scény bude pri pripojení agenta vytvorený skôr než objekt AgentJim, treba túto asociáciu vytvoriť oneskorene. To funguje tak že

  • Pri vytvorení objektu grafu scény (trieda Player) sa do neho uloží jeho poradie. Ak príslušný AgentJim objekt už existuje, priradí sa mu (podľa poradia daného AgentJim objektu). V opačnom prípade sa zaradí do frontu v triede AgentManager, aby sa prepojenie vytvorilo pri vytvorení objektu AgentJim
  • Po vytvorení AgentJim sa pozrie či sú nejaké Player objekty vo fronte, ak áno, vyberie sa prvý a vytvorí sa asociácia.

Teoreticky to nemusí byť úplne spoľahlivé, hlavne keď sa pripojí viac agentov vo veľmi krátkom časovom úseku (prakticky naraz). V praxi to ale funguje relatívne dobre.

Objekt triedy Player sa dá z objektu triedy AgentJim získať pomocou metódy getSceneGraphPlayer. Tá vráti poradie Player objektu v zozname vrátanom metódou getPlayers triedy Scene. Objekt triedy Scene sa získa metódou getScene z objektu triedy SimulationState. V prípade, že prepojenie medzi agentom a objektom hráča v dátach z monitora ešte nebolo vytvorené, vráti getSceneGraphPlayer číslo -1.

Objekt triedy AgentJim sa z objektu triedy Player dá získať metódou getAssociatedAgent.

Podrobnosti o životnom cykle AgentJim objektov sú v sekcii Spúšťanie a riadenie agentov.

Osobné nástroje