You are here

Atividade 1

 

Atividade 1

Na primeira parte desta atividade se executarão os programas do WorldServer3D (que foi modificado) e o programa DemoSOAR que é um cliente que opera com regras.

Depois foram descargados os arquivos-fonte dos dois programas e da biblioteca WS3DProxy que é uma libraria de apoio que faz a conexão como o WorldServer3d.

O código foi compilado e executado. Na seguinte imagem é apresentada o código executado no entorno NetBeans

Apos abrir o código da classe SimulationSOAR.java e localizar o método main a primeira coisa que o programa faz é estabelecer a pasta atual na classe NativeUtils depois são utilizados os seguintes métodos:

System.getProperties().getProperty("os.name")

e

System.getProperties().getProperty("os.arch")

O primeiro é para obter o tipo de sistema operacional que se está usando. O segundo comando obtém o tipo de arquitetura do computador.

No meu caso as saídas são:

OS:Linux Architecture: amd64

Depois são armazenadas o nome do sistema operativo e a arquitetura em duas variáveis: String osName e String osArch. As duas variáveis serão usadas para carregas as bibliotecas que correspondem ao sistema operativo e à arquitetura do computador que está usando o programa, assim é utilizada a estrutura if-else para determinar que arquivos são carregados.

Por exemplo, o primeiro if pergunta se a variável osName contem a palavra win (de windows), se a arquitetura atual é Windows, então o programa entra no segundo if e pergunta o tipo de arquitetura, se a variável osArch contém o número 64, então é determinado que o sistema operacional e a arquitetura é Windows de 64 bits e serão carregadas os arquivos chamados: /win64/Soar.lib , /win64/Soar.dll e /win64/Java_sml_ClientInterface.dll.

No meu casso, o meu sistema operacional é Linux e tenho uma arquitetura amd64 portanto serão carregados os arquivos: /linux64/libSoar.so e /linux64/libJava_sml_ClientInterface.so

Finalmente é carregado o arquivo /soar-rules.soar que contem as regras do Soar.

Após é estabelecida a variável String soarRulesPath = "soar-rules.soar" e depois a porta para o Debugger do soar:

Integer soarDebuggerPort = 12121;

Após carregar os arquivos e inicializar algumas variáveis o programa entra no loop principal:

while(true)
{
 simulationTask.runSimulation();
 Thread.sleep(100);
}

O método runSimulation() da classe simulationTask é executado indefinidamente enquanto o programa esteja em execução.

Toda vez que é executado o método runSimulation() são realizadas as seguintes tarefas:

  1. Atualiza o estado da criatura

  2. São obtidos os objetos “vistos” pela criatura.

  3. A informação de posição, pitch etc. da criatura e a informação dos objetos que ela consegui “ver” é traduzida na linguagem do SOAR, criando Working Memory Elements (WME)

  4. É enviada a estrutura de informação gerada no passo anterior ao SOAR. No SOAR são executadas as regras do arquivo soar-rules.soar e é obtida uma resposta, em forma de comando de saída que será enviada novamente ao programa cliente.

  5. O programa cliente recebe a saída do SOAR e processa a informação executando os comandos de resposta do SOAR na criatura, este processo de executar os comandos muda o estado atual da criatura e o processa começa de novo.

Em resumo, a criatura obtêm informação da sua posição e dos objetos que ela consegue ver, sintetiza a informação numa estrutura de dados que o SOAR consiga entender e são enviados para seu processamento. Em SOAR as regras do arquivo soar-rules.soar são executadas, é escolhido um operador e a regra de aplicação desse operador cria comandos no elemento output-link do estado.Depois da seleção dos comandos a serem enviado para o cliente, o programa cliente recebe os comandos de saída, provenientes do SOAR, e executa as ações modificando o estado da criatura.

O método que prepara a informação para ser enviada a SOAR é

prepareAndSetupCreatureToSimulation(...)

Aqui é criado o sensor visual e o sensor de constituível. Após de agregar ao objeto simulationCreature os sensores disponíveis.

Depois é chamado o método setupStackHolder(...) da classe soarBridge que é o encargado de criar a estrutura de dados para o SOAR a partir da informação da criatura é seu entorno.

No método setupStackHolder(...) é perguntado se o tipo de entidade é uma criatura, se assim for, então se gera a seguente estrutura de Working Memory Elements

 

Existem tantas ^ENTITY como elementos sejam vistos pela criatura no mundo virtual

A posição da criatura é obtida a partir de:

creatureParameter.getPosition().getX()

creatureParameter.getPosition().getY()

Uma lista dos sensores disponíveis é obtida a partir da função:

creatureParameter.getSensorsEnabled()

Para obter o valor do combustível e os elementos que são vistos pela criatura no mundo virtual é usada a função:

creatureParameter.getSensorHandler(<param>).getSensorReadings();

Onde <param> pode ser SensorType.FUEL ou SensorType.VISUAL, no primeiro caso é retornado o valor atual do combustível; no segundo casso é retornada uma lista com os objetos vistos pela criatura. Existem três tipos de elementos no mundo virtual: os tijolos (BRICK), joias (JEWEL) e comida (FOOD)

A execução da simulação é feita através do método runSimulation() da classe soarBridge.

Após a execução das regras no SOAR é completada, o método processResponseCommands() obtêm e processa a informação enviada desde SOAR.

A resposta do SOAR está constituída por uma lista de comandos a serem executados no robô. Existem três tipos de comandos: mover (MOVE), obter (GET) e comer (EAT). Os comandos são processados pelas funções:

  • processMoveCommand(...)
  • processGetCommand(...)
  • processEatCommand(...)

cada comando leva os argumentos necessários para processar a ordem, como direção de movimento, velocidade etc.

É possível executar o SoarDebbuger enquanto se está executado o programa cliente e o WorldServer3d:

A seguinte imagem apresenta a saída do SoarDebbuger enquanto se está executando a simulação:

 

Programa de regras de SOAR

No programa de regras do SOAR o primeiro operador a ser proposto é chamado de WANDER

Este operador permite à criatura se movimentar pelo entorno com uma velocidade VelR igual a 2

A seguir a regra de proposição do operador wander

# This operator will make the agent to walk ahead at the enviroment
# Propose*wander:
sp {propose*wander
   (state <s> ^attribute state
              ^impasse no-change
              ^superstate <ss>)
   (<ss> ^io.input-link <il>)
   (<ss> ^superstate nil)
   (<il> ^CREATURE <creature>)
   (<creature> ^SENSOR.VISUAL <visual>)
-->
   (<ss> ^operator <o> +)
   (<o> ^name wander)}

Esta é a regra de aplicação do operador wander

# Apply*wander:
# If the wander operator is selected, then generate an output command to it
sp {apply*wander
   (state <s> ^operator <o>
              ^io <io>)
   (<io> ^output-link <ol>)
   (<o> ^name wander)
-->
   (<ol> ^MOVE <command>)
   (<command> ^Vel 0)
   (<command> ^VelR 2)
   (<command> ^VelL 0)}

A seguinte regra elimina o comando se ele já esta completo

# If the wander operator is selected,
# and there is a completed move command on the output link,
# then remove that command.
sp {apply*wander*remove*move
   (state <s> ^operator.name wander
              ^io.output-link <out>)
   (<out> ^MOVE <move>)
   (<move> ^status complete)
-->
   (<out> ^MOVE <move> -)}

O operador seeEntityWithMemoryCount permite armazenar na memória entidades que a criatura pode ver no mundo virtual, este operador é proposto se o agente já possui alguma entidade na memória.

O operador seeEntityWithoutMemoryCount faz o mesmo trabalho do que o operador seeEntityWithMemoryCount mas é aplicado quando não existe entidade nenhuma no agente.

Depois são declarados os operadores de movimento em direção na comida (moveFood), o operador de pegar a comida (eatFood), o operador de ir na direção das joias (moveJewel), o operador de pegar as joias (getJewel) e o operador de evitar os tijolos (avoidBrick).

Finalmente são criadas as regras de controle de preferências e as regras que dão solução aos impasses.

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer