You are here

Relatório 2 - SOAR: Controlando o WorldServer3D - Atividade 1

Atividade 1

Gerenciamento do código JNI

O SOAR necessita de algumas bibliotecas nativas para funcionar e estas bibliotecas são específicas para cada plataforma e sistema operacional.
O DemoSOAR por sua vez, precisa carregar estas bibliotecas para fazer uso do SOAR.
Este carregamento é feito através de uma chamada ao método: 
NativeUtils.loadFileFromJar()
Como o SOAR foi implementado em JAVA, espera-se que ele possa ser multi plataforma e para que ele funcione desta forma, será necessario descobrir a plataforma e o sistema operacional através das chamadas abaixo:

String osName = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
String osArch = System.getProperty("os.arch").toLowerCase(Locale.ENGLISH);

Tendo o nome do sistema operacional (osName) e o nome da plataforma (osArch), pode-se fazer o carregamento das bibliotecas específicas para cada ambiente:
 
if(osName.contains("win")){
    if(osArch.contains("64")) {
        System.out.println("Windows 64 bits");
        NativeUtils.loadFileFromJar("/win64/Soar.lib");
        NativeUtils.loadFileFromJar("/win64/Soar.dll");
        NativeUtils.loadFileFromJar("/win64/Java_sml_ClientInterface.dll");
    }
    else {
        System.out.println("Windows 32 bits");
        NativeUtils.loadFileFromJar("/win32/Soar.lib");
        NativeUtils.loadFileFromJar("/win32/Soar.dll");
        NativeUtils.loadFileFromJar("/win32/Java_sml_ClientInterface.dll");
    }   
} else if(osName.contains("mac")){
    System.out.println("MacOSX");
    NativeUtils.loadFileFromJar("/macos/libSoar.dylib");
    NativeUtils.loadFileFromJar("/macos/libJava_sml_ClientInterface.jnilib");
} else if(osName.contains("nix") || osName.contains("nux")){
    if(osArch.contains("64")) {
        System.out.println("Linux 64 bits");
        NativeUtils.loadFileFromJar("/linux64/libSoar.so");
        NativeUtils.loadFileFromJar("/linux64/libJava_sml_ClientInterface.so");
    }
    else {
        System.out.println("Linux 32 bits");
        NativeUtils.loadFileFromJar("/linux32/libSoar.so");
        NativeUtils.loadFileFromJar("/linux32/libJava_sml_ClientInterface.so");
    }
}

A Classe NativeUtils também é utilizada no DemoSOAR para carregar as regras do SOAR.

NativeUtils.loadFileFromJar("/soar-rules.soar");

 

Loop principal de simulação do DemoSOAR

Após a inicialização do ambiente e da criatura, o DemoSOAR entra em seu loop principal

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

Este loop executará uma simulação no SOAR indeterminadamente e a cada iteração realizará os seguintes passos:

1. Atualizar o status da criatura
2. Varrer os objetos no ambiente que são vistos pela criatura.
3. Transformar a estutura dos objetos percebidos em Working Memory Elements (WMEs)
4. Enviar os WMEs para o SOAR e executar as regras
5. Ao término da execução, o SOAR irá tomar uma decisão (MOVE, GET ou EAT) e retornar este comando e os seus argumentos.
6. Este comando então será traduzido e enviado ao 
WorldServer3D.

 

Acessando o WorldServer3D através do WS3DProxy.

O WorldServer3D é acessado através de um proxy responsavel por fazer a interface entre o SOAR e o WorldServer3D.

Este acesso se dá na classe SimulationTask através de classes de apoio como as classes World e Creature. Estas classes tornam possível a manipulação do ambiente e da criatura simulada no WorldServer.

Por exemplo, através da classe Creature, é possível obter os dados sensoriais como a visão e o combustível.

 

Captura dos dados sensorias do WorldServer3D e transferência para o SOAR.

Na classe SimulationTaskWorldServer3D é acessado primeiramente para obter os dados sensoriais e a situação da criatura no ambiente.
Estes dados são obtidos com a ajuda do WS3DProxy através da classe Creature:

Creature.getThingsInVision();  -> Obtem os elementos capturados pelo sensor visual.
Creature.getFuel() -> Obtem os dados do sensor de combustível.

Apos obter a informação sensorial, estes dados são enviados ao SOAR através da classe SoarBridge:

SoarBridge.setupStackHolder(StakeholderType.CREATURE, simulationCreature);

Na no método setupStackHolder, são criados os Working Memory Elements através da classe Agent:

Agent.CreateIdWME()  -> Cria um novo nó abaixo de um WME
Agent.CreateFloatWME()  -> Cria um atributo Float em um WME
Agent.CreateIntWME()  -> Cria um atributo Int em um WME
Agent.CreateStringWME() - > Cria um atributo String em um WME

 

Leitura das decisões tomadas pelo SOAR e envio dos comandos para o WorldServer3D

Após a execução da simulação através da chamada

soarBridge.runSimulation();

O SOAR irá decidir qual comando deverá ser executado. Este comando é obtido através do SoarBridge:

soarBridge.getReceivedCommands()

Os comandos enviados pelo soar poderão ser MOVE, GET ou EAT:

MOVE - Irá mover a criatura até determinado ponto x,y no ambiente. Para executar esta tarefa, os comandos abaixo são enviados ao WorldServer:

CommandUtility.sendGoTo()
CommandUtility.sendSetTurn()

GET - Irá pegar o cristal mais próximo e colocar na sacola. Para esta tarefa, o comando abaixo é enviado ao WorldServer:

Creature.putInSack()

EAT - Irá comer o alimento mais próximo através do comando abaixo:

Creature.eatIt()

 

Regras do SOAR (soar-rules.soar)

O programa de regras do DemoSOAR tem como funcionamento básico:

1º Adicionar na memória os elementos vistos pela criatura;
2º Se dirigir a um destes elementos (cristal ou comida);
3º Ao encostar neste elemento, ele deve ser capturado ou consumido.

Para realizar estas tarefas, foram criados alguns operadores que são responsáveis por decidir o que fazer em cada situação:

WANDER - Faz a criatura girar em seu eixo, para que seja possível ver todos os elementos a sua volta.

SEE ENTITY WITHOUT MEMORY COUNT Armazena na memória o primeiro elemento observado pelo sensor visual

SEE ENTITY WITH MEMORY COUNT - Armazena na memória da criatura até 7 elementos que foram observados pelo sensor visual

MOVE FOOD - Move a criatura até um alimento que foi observado e está em sua memória

EAT FOOD - Consome o alimento que está proximo a uma distância menor ou igual a 30.

MOVE JEWEL - Move a criatura até um alimento que foi observado e está em sua memória

GET JEWELColoca na sacola o cristal que está proximo a uma distância menor ou igual a 30.

AVOID BRICK - Ao se aproximar de uma parede, gira a criatura para evitar a colisão.

Preferência de operadores:

Move Jewel or Move Food vs See Entity - Ver elementos no ambiente tem preferência sobre Mover a uma comida ou cristal.

See Entity vs Avoid Brick - Evitar paredes tem preferência sobre ver elementos no ambiente.

Move Jewel vs Get Jewel - Pegar um cristal tem preferência sobre mover-se a outro cristal.

Get Jewel vs Avoid Brick - Pegar um cristal tem preferência sobre evitar uma parede.

Move Jewel vs Move Jewel - No caso de um impasse onde é proposto mover-se à dois cristais diferentes, tem preferencia o que estiver mais próximo.

Get Jewel vs Get Jewel Preferences  - No caso de um impasse onde é proposto pegar dois cristais diferentes, tem preferencia o que estiver mais próximo.

Move Food vs Eat Food - Comer a comida tem preferência sobre mover-se à outra comida.

Eat Food vs Avoid Brick - Comer uma comida tem preferência sobre evitar uma parede.

Move Food vs Move Food No caso de um impasse onde é proposto mover-se à dois alimentos diferentes, tem preferencia o que estiver mais próximo.

Eat Food vs Eat Food Preferences - No caso de um impasse onde é proposto consumir dois alimentos diferentes, tem preferencia o que estiver mais próximo.

Move Food vs Move Jewel - No caso de um impasse onde é proposto mover-se à um alimento e mover-se à um cristal. Terá preferência o alimento somente se o sensor de combustível estiver baixo.

Avoid Brick vs Avoid Brick - No caso de um impasse onde é proposto evitar duas paredes, terá preferência a que estiver mais próxima.

Avoid Brick vs Move Jewel vs Move Food - No caso de um impasse onde é proposto evitar uma parede e mover-se a um cristal ou comida, terá preferência evitar a parede.

Wander Preferences - O operador wander, terá preferência mínima em qualquer situação.

 

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer