You are here

Aula 7

Aula 7 - SOAR: Controlando o WorldServer3D

 

Objetivo

Nas aulas anteriores, seguimos os tutoriais básicos do Soar para entender seu funcionamento. Para isso, nos servimos de alguns exemplos de interfaceamento do Soar com outros programas (Eaters e TankSoar), que já estavam preparados. Na aula de hoje, utilizaremos o Soar para controlar uma aplicação externa por meio da interface SML. O sistema que desenvolveremos será a mente artificial de um agente capaz de controlar o robô no ambiente WorldServer3D que utilizamos na primeira aula.

Atividade 1

Para essa atividade, o código do WorldServer3D, que foi utilizado na primeira aula foi modificado. Veja o programa funcionando, acessando os seguintes links:

Os arquivos com o código fonte desses mesmos programas podem ser feitos aqui:

O WS3DProxy é uma library de apoio, que faz toda a conexão com o WorldServer3D, e envia e recebe comandos em objetos de alto nível. Seu código fonte está sendo adicionado, para auxiliar o estudo.

Abra o código fonte do DemoSOAR no Netbeans, e faça uma análise de seu funcionamento. Para tanto, siga o roteiro a seguir, registrando as eventuais respostas a perguntas em seu relatório.

Abra o código da classe SimulationSOAR.java, que contém o método main. Observe o uso da classe NativeUtils para resolver o problema do gerenciamento do código JNI para diferentes versões de sistema operacional. Entenda como esse gerenciamento é feito e registre em seu relatório.

Observe que essa solução é estendida ao carregamento de arquivos com código SOAR, para uso do controlador. Como isso é implementado no Demo ?

O loop principal de simulação do DemoSOAR também se encontra no método main. Explique seu funcionamento.

Acesse o código da classe SimulationTask.java, para compreender em mais detalhes o que está acontecendo. Observe que essa classe já se utiliza das classes de apoio em WS3DProxy. Entenda e explique como é feito o acesso ao WorldServer3D, por meio do WS3DProxy.

Observe que a classe SimulationTask utiliza-se da classe SoarBridge, para ter acesso ao SOAR. Explique como é feita a leitura do estado do ambiente no WorldServer3D, e como esses dados sensoriais são enviado para o SOAR. Da mesma forma, explique como os dados enviados pelo SOAR são aproveitados para controlar a criatura no WorldServer3D. Registre suas conclusões no relatório de atividades.

Acesse o conteúdo do arquivo de regras SOAR: soar-rules.soar e tente entender seu funcionamento. Explique o princípio lógico de seu funcionamento.

Atividade 2

Cada criatura no WorldServer3D possui um "leaflet", ou seja, uma meta na obtenção de jóias. Modifique o programa DemoSOAR (e também o soar-rules.soar), de tal forma que ele leve em consideração o leaflet de cada criatura para o controle da criatura.

Disponibilize o seu programa DemoSOAR na forma de um Java WebStart em seu relatório.

Coloque duas criaturas competindo em um mesmo ambiente, para ver qual delas consegue completar seu "leaflet" com mais rapidez.

Escolha um colega de turma que já tenha concluído essa atividade, e efetue uma competição entre o seu controlador e o desenvolvido por ele.

Relatório

Após executar o WorldServer3D e o DemoSoar foi possível ver o comportamento da criatura no ambiente, onde pela visão ele buscava elementos no mapa.

Figura1 - Execução Inicial - Soar controlando criatura no WorldServer3D

 

Ao estudar o código do DemoSoar podemos ver dois pacotes principais de arquivos:

  • Simulation
  • SoarBridge

Em resumo o pacote de Simulation é responsável por toda a lógica da nossa codificação na camada Java, enquanto o SoarBridge faz a interface entre o Java e o Soar.

A parte inicial do main do Simulation consiste na identificação do Sistema Operacional por meio de uma propriedade da JVM. Após identificar a plataforma correta (linux 32/64bits, windows 32/64 bits ou até mesmo MacOSX) é registrado na camada do SoarBridge as bibliotecas/arquivos a ser utilizada. Os arquivos são copiados dinamicamente do JAR para arquivos temporários, que são apagados ao finalizar a execução.

Em seguida é registrado o arquivo Soar a ser utilizado (nesse caso soar-rules.soar) durante a inicialização do nosso agente e ambiente. As rotinas responsáveis pelas inicializações da criatura e do ambiente tem os seguintes cabeçalhos:

  • initializeCreatureAndSOAR(String rulesPath, Boolean runDebugger, String soarDebuggerPath, Integer soarDebuggerPort)

- Cria a criatura e pega a informação do mundo visto pela criatura

- inicializa a criatura (comando start)

- "cresce" elementos no mundo (comidas e jóias) de maneira exporádica e aleatórias mediante algoritmo de distribuição de Poisson

- carrega as informações do Soar como arquivo de regras, agente, configuração de debugger e carrega a produção

  • initializeEnviroment(Boolean prepareEnviromentAndStartGame)

- no exemplo atual ela não faz nada

Em seguida, um laço é implementado para a execução da simulação. Em nosso exercício, o laço é infinito pois não foi definida uma condição de parada (em outro caso, um exemplo seria parar o laço assim que o objetivo é alcançado).

Dentro do laço, a rotina responsável por executar as instruções tem o seguinte fluxo:

  1. Atualizar informações da criatura (getcreaturestate)
  2. identifica os objetos na visão
  3. prepara os dados para simulação
  4. roda a simulação esperando o resultado
  5. trata o resultado (resultados esperados MOVE, GET ou EAT)

Um pacote muito importante é o WS3DProxy. Ele é responsável por fazer a comunicação com o World Server 3D. Nesse pacote podemos ver classes de abstração para cada elemento a ser utilizado em nossa lógica. Essa camada estabelece a conexão TCP ao WorldServer e trata o envio e recebimento dos comandos.

Por exemplo a criação da criatura. Em nosso SimulationTask dentro de DemoSoar temos um objeto c do tipo Criatura (do pacote WS3DProxy).

Ao instanciar a criatura c, atribuimos o resultado de CreateCreature de proxy, que em um determinado momento encapsula na camada de CommandUtility, que envia o comando propriamente dito

  • c = proxy.createCreature(100,100,0);
    • CommandUtility.sendNewCreature(x, y, pitch);
      • controlMessage = "new " + X + " " + Y + " " + pitch;
      • return sendCmdAndGetResponse(controlMessage);
        • SocketUtility.sendMessage(formattedCmd);

Por fim foi possível executar com o Debugger

Figura2 - Execução da aplicação com o debugger

 

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer