You are here

Aulas 10 e 11 - Clarion: Controlando o WorldServer3D

 

Atividade: Controlar a criatura levando em conta o Leaflet.

Nesta atividade tomamos como base o projeto fornecido pelo professor, ClarionDemo, como visto na seguinte tela.

O programa é uma demonstração básica de como controlar uma criatura no WorldServer3D e conta com a ajuda de dois projetos auxiliares, o WorldServerLibrary (Equivalente ao Proxy do relatório anterior) e o WorldServerAgent que possui o controlador propriamente dito do Clarion. O projeto ClarionDEMO por sua vez trata da inicialização do ambiente e da ponte entre os dois outros projetos, passando informações do ambiente para o clarion e vice-versa.

Diferente da demonstração do SOAR, o código fonte não inclui a criação do leaflet e estrutura de dados do leaflet na criatura, sendo assim começamos a alteração no arquivo WorldServer.cs, do projeto WorldServerLibrary, com a inclusão do comando "SendGenLeaflet()".

No W3DProxy havia uma classe chamada "ResourcesGenerator" que era responsável por preencher de forma aleatória o ambiente de simulação com jóias e comida a cada 3 minutos. Para simular este mesmo comportamento de maneira simplificada o seguinte código foi adicionado ao WorldServer.cs, ressaltando a necessidade de se utilizar de um lock para evitar problemas de concorrencia na leitura de dados de resposta do servidor durante o parse do estado corrente da criatura. O mesmo lock foi utilizado no parse para garantir o acesso sincrono e evitar crashes na hora de parsear os resultados, já que poderia haver uma resposta de criação de recurso (food ou jewel) enquanto o parser aguardava a resposta do pedido de estado feito.

O arquivo Main.cs do projeto ClarionDemo também foi alterado na fase de inicialização do ambiente para incluir a geração do leaflet para a criatura e para adicionar aleatoriamente os recursos no simulador (metódos sendGenLeaflet e GrowWorld) :

Além disso, foi necessário também incluir um parser das informações de leaflet vindas do servidor, dentro da classe WorldServer, no método ParseGetCreatureStateResponse.O código do W3DProxy  foi utilizado como referencia para realizar esta implementação.

 

Uma classe Leaflet contendo as informações parseadas foi adicionada aos modelos do projeto WorldServerLibrary. (Também o W3DProxy foi utilizado como referencia para esta implementação).

Na classe Creature, uma lista de Leaflets foi criada para guardar as informações parseadas a partir do estado lido do servidor:

Com o intuito de permitir que o Agente realize as ações de Sack e GoTo, a ultima informação sensorial obtida foi disponibilizada em um membro publico da classe ClarionAgent (CurrentSensorialInfo), assim no callback agent_OnNewExternalActionSelected foi possivel direcionar a posição para o GoTo e indicar qual era o nome da Jewel a ser pega.

 

Para controlar a criatura, optou-se por criar regras fixas que podem ser descritas da seguinte forma:

  1. Se não houver joias no campo de visão sensorial da criatura, gire em sentido horario para buscar novas joias.
  2. Se houver joias no campo de visão, vá em direção à joia mais proxima pertencente ao Leaflet. Se não houver joias pertencentes ao leaflet, vá até a jóia mais próxima.
  3. Se uma jóia estiver a menos de 30 unidades de distância da criatura, pegue a joia.
  4. Se um alimento estiver a menos de 40 unidades de distância da criatura, coma o alimento. 
  5. Se o leaflet já está completo, então nao faça nada.

A classe ClarionAgent reflete toda a implementação desta regras fixas, pondendo destacar o construtor da classe:

E também os métodos SetupACS e MakePerceptionFromSensorialInput : 

Além destes, é importante ressaltar na classe Main.cs, o callback agent_OnNewExternalActionSelected onde as ações escolhidas pelo Clarion são enviadas para o WorldServer3D.

Uma dificuldade encontrada foi que o WorldServer3D nao está enviado os dados de elementos do tipo FOOD para a perpepção no ClarionAgent, sendo assim quando a criatura encontrava um elemento desse tipo a sua frente, a mesma ficava "travada". Inicialmente criou-se uma regra para enviar o comando de EAT, mas como não havia a percepção por parte dos sensores da criatura, a solução para evitar essa limitação foi remover os elementos do tipo FOOD do ResourcesGenerator.

Depois de conversar com o professor, atualizei o código para levar em conta as categorias NPFOOD e PFOOD ao inves de FOOD, e assim o controlador funcionou corretamente na seleção das regras, considerando a regra de EAT também.

Além disso, quando uma Jóia era pega com o comando Sack, o leaflet da mesma nao era atualizado pelo servidor na resposta parseada no método ParseGetCreatureStateResponse. Outro empecilho foi o fato de que o ParseGetCreatureStateResponse recria o objeto Creature a cada nova leitura sensorial, tornando difícil o controle correto da quantidade de leaflets faltantes.

Estas dificuldades foram contornadas com estruturas auxiliares no ClarionAgente e Creature além do Leaflet:

Por fim o agente foi capaz de se comportar da maneira esperada, indo atrás preferencialmente de joias em seu leaflet e pegando também joias que não estao em seu leaflet mas estão ao seu alcançe como forma de atrapalhar o adversário.

 

Alguns outros problemas de sincronismo e conectividade foram notados durante o desenvolvimento. Em alguns casos o código fica travado no mecanismo de lock por falta de resposta do WorldServer para a criação dos recursos no ResourceGenerator e é necessário reniciar a simulação e limpar o ambiente do WorldServer3D. Para isso foram adicionados alguns sleeps no código para tentar evitar que o lock fique preso.

O código fonte de para compilação pode ser encontrado AQUI.

O a pasta com os executáveis gerados pelo XamarinStudio pode ser encontrada AQUI.

============= Melhorias ==============

Uma possivel melhoria seria identificar quando o agente fica "preso" a joias ou alimentos que estão ao seu lado (fora do seu campo de visão), nesses casos o agente acaba não conseguindo se desvencilhar da coisa e prosseguir na busca do objetivo.

 

 

 

 

 

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer