You are here

Aula 9 - Clarion - Controlando o WorldServer3D

Para o desenvolvimento do controlador de uma criatura dentro do ambiente do WorldServer3D, foram utilizados os seguintes arquivos como input para o desenvolvimento do software proposto neste exercicio:

- Projeto do ClarionDEMO (versão desenvolvida na ferramenta Mono Development);

- WorldServer3D (versão compilada desenvolvida em Java);

Versão dos arquivos para rodar as simulações:

WorldServer3D: /gudwin/sites/faculty.dca.fee.unicamp.br.gudwin/files/users/2015-8/8-9aula/WS3DClarion/launch.jnlp

Código Fonte do ClarionDemoModificado: /gudwin/sites/faculty.dca.fee.unicamp.br.gudwin/files/users/2015-8/8-9aula/WS3DClarion/ver1.0.zip

Arquivo executável do ClarionDemoModificado + WorldServer3D: /gudwin/sites/faculty.dca.fee.unicamp.br.gudwin/files/users/2015-8/8-9aula/CompSoarClarion/ClarionExec.tar.gz

O ClarionDEMO possui 3 grandes classes:

- Main.cs: contém os códigos para chamada dos métodos para conexão com o WorldServer3D e preparação do ambiente para a simulação;

- ClarionAgent.cs: contém os métodos para definir os tipos de ação, percepção e regras para processamento de informações do agente;

- WorldServer.cs: contém os métodos para comunicação com o ambiente do WorldServer3D;

A Figura abaixo mostra a estrutura do código do ClarionDEMO:

O Clarion é uma toolkit que foi integrada no projeto, conforme pode ser visto na figura anterior.

A Figura abaixo mostra a estrutura básica do Clarion (extraído do site do Prof. Gudwin).

Código Main

Dentro do Main.cs, foi criado uma funcionalidade para criar jóas aleatórias dentro do ambiente, conforme pode ser visto neste trecho do código:

//adiciona os objetos no mundo
                    /*
                            ---------
                            |*        |
                            |        |
                            |        |
                            ---------
                    *(X0,Y0)
                    */

//Adiciona 20 jóias de cores aleatórias no ambiente
                    Random numRand = new Random();
                    for (int i=0;i<=20;i++){
                        int tipo=numRand.Next(0,6);
                        int x=numRand.Next(100,700);
                        int y=numRand.Next(100,500);
                        worldServer.NewJewel(tipo,x,y);
                    }

O main contém ainda as ações do agente. Este trecho é o responsável por estabelecer a lógica para a comunicação com o WorldServer3D.

  • ClarionAgentActionType.DO_NOTHING:
  • ClarionAgentActionType.ROTATE_CLOCKWISE:
  • ClarionAgentActionType.GOTOJEWEL:
  • ClarionAgentActionType.EXPLORE:
  • ClarionAgentActionType.GET_JEWEL:
  • ClarionAgentActionType.GO_AHEAD:

No GOTOJEWEL, foi implementado uma ação para que ele possa escolher a jóia que estiver mais proxima, à fim de otimizar a locomoção do agente pelo ambiente.

O EXPLORE, combinado com o ROTATE_CLOCKWISE faz com que o agente fique girando em um ponto do ambiente.

Código ClarionAgent

Nesta classe, foram incluidos primeiro os tipos de ação do agente:

 public enum ClarionAgentActionType
    {
        DO_NOTHING,
        GO_AHEAD,
        ROTATE_CLOCKWISE,
        EXPLORE,
        GOTOJEWEL,
        GET_JEWEL
    }

Depois disso foi implementado a seguinte classe:

 public class ClarionAgent
    {
        #region Constants

        /// <summary>
        /// Constant that represents the Visual Sensor
        /// </summary>
        private String SENSOR_VISUAL_DIMENSION = "VisualSensor";

        /// <summary>
        /// Constant that represents that there is at least one wall ahead
        /// </summary>
        
        private String DIMENSION_WALL_AHEAD = "WallAhead";
        private String DIMENSION_GOTOJEWEL = "GoToJewel";
        private String DIMENSION_JEWEL_AHEAD = "JewellAhead";
        private String DIMENSION_EXPLORE = "Explore";

Também foram incluidos os inputs, conforme mostrado no trecho de código abaixo:

#region Perception Input

        /// <summary>
        /// Perception input to indicates a wall ahead
        /// </summary>
        
        private DimensionValuePair InputWallAhead;

        private DimensionValuePair InputGoToJewel; 

        //# Declarar o input de entrada das joias
        private DimensionValuePair InputGetJewel;

        // #Declarar o input para ficar rotacionando
        private DimensionValuePair InputExplore;
        #endregion

Neste trecho de código foi declarado as ações possíveis para o agente:

#region Action Output

        /// <summary>
        /// Output action that makes the agent to rotate clockwise
        /// </summary>
        private ExternalActionChunk OutputRotateClockwise;
        
        /// <summary>
        /// Output action that makes the agent go ahead
        /// </summary>
        private ExternalActionChunk OutputGoAhead;

        //# Declarar a ação externa para pegar a joia
        private ExternalActionChunk OutputGetJewel;

        //# Ação de explorar o ambiente
        private ExternalActionChunk OutputExplore;

        //#Ação para andar até a joia
        private ExternalActionChunk OutputGoToJewel;

        #endregion

O trecho de código abaixo mostra parte do código para implementação do Setup de ACS da criatura. Esta parte estabelece as regras que serão inicializadas para a tomada de decisão do agente.

private void SetupACS()
        {     
            // Create Colission Wall Rule
            SupportCalculator avoidCollisionWallSupportCalculator = FixedRuleDelegateToAvoidColissionWall;
            FixedRule ruleAvoidCollisionWall = AgentInitializer.InitializeActionRule(CurrentAgent, FixedRule.Factory, OutputRotateClockwise, avoidCollisionWallSupportCalculator);
            // Commit this rule to Agent (in the ACS)
            CurrentAgent.Commit(ruleAvoidCollisionWall);
            // Create Colission To Go Ahead
            SupportCalculator goAheadSupportCalculator = FixedRuleDelegateToGoAhead;
            FixedRule ruleGoAhead = AgentInitializer.InitializeActionRule(CurrentAgent, FixedRule.Factory, OutputGoAhead, goAheadSupportCalculator);          
            // Commit this rule to Agent (in the ACS)
            CurrentAgent.Commit(ruleGoAhead);

            // #Criar uma regra para pegar as joias
            SupportCalculator getJewelSupportCalculator = FixedRuleDelegateToGetJewel;
            FixedRule ruleGetJewel = AgentInitializer.InitializeActionRule (CurrentAgent, FixedRule.Factory, OutputGetJewel, getJewelSupportCalculator);
            // Commit this rule to Agent (in the ACS)
            CurrentAgent.Commit(ruleGetJewel);

            //# Regra para explorar o ambiente em busca de uma jóia
            SupportCalculator exploreSupportCalculator = FixedRuleDelegateToExplore;
            FixedRule ruleExplore = AgentInitializer.InitializeActionRule (CurrentAgent, FixedRule.Factory, OutputExplore, exploreSupportCalculator);
            // Commit this rule to Agent (in the ACS)
            CurrentAgent.Commit(ruleExplore);

            //#Regra para ir até a joia
            SupportCalculator goToJewelSupportCalculator = FixedRuleDelegateGoToJewel;
            FixedRule ruleGoToJewel = AgentInitializer.InitializeActionRule (CurrentAgent, FixedRule.Factory, OutputGoToJewel, goToJewelSupportCalculator);
            // Commit this rule to Agent (in the ACS)
            CurrentAgent.Commit(ruleGoToJewel);

O trecho de código mostrado na sequencia mostra quais inputs serão acionados a partir das informações sensoriais recebidas pelo agente. Este trecho é o responsável por criar a percepção em função dos dados sensoriais do agente.

      private SensoryInformation MakePerceptionFromSensorialInput(IList<Thing> sensorialInformation)
        {
            // New sensory information
            SensoryInformation si = World.NewSensoryInformation (CurrentAgent);

            Creature creature = null;
            foreach (Thing item in sensorialInformation) {
                if (item.CategoryId == Thing.CATEGORY_CREATURE) {
                    creature = (Creature)item;
                }
            }

            if (sensorialInformation.Where (item => ((item.CategoryId == Thing.CATEGORY_JEWEL) && item.DistanceToCreature <= 28.0)).Any ()) {
                si.Add (InputWallAhead, 0.0);
                si.Add (InputGetJewel, 1.0);
                si.Add (InputExplore, 0.0);
                si.Add (InputGoToJewel, 0.0);
            } else {
                if (sensorialInformation.Where (item => ((item.CategoryId == Thing.CATEGORY_JEWEL) && item.DistanceToCreature > 28.0)).Any ()) {
                    si.Add (InputWallAhead, 0.0);
                    si.Add (InputGetJewel, 0.0);
                    si.Add (InputExplore, 0.0);
                    si.Add (InputGoToJewel, 1.0);
                } else {
                    if (sensorialInformation.Where (item => (item.CategoryId == Thing.CATEGORY_BRICK && item.DistanceToCreature <= 61)).Any ()) {
                        si.Add (InputWallAhead, 1.0);
                        si.Add (InputGoToJewel, 0.0);
                        si.Add (InputGetJewel, 0.0);
                        si.Add (InputExplore, 0.0);
                    } else {
                        if (sensorialInformation.Where (item => (item.CategoryId == Thing.CATEGORY_BRICK && item.DistanceToCreature > 61)).Any ()) {
                            si.Add (InputWallAhead, 1.0);
                            si.Add (InputGoToJewel, 0.0);
                            si.Add (InputGetJewel, 0.0);
                            si.Add (InputExplore, 0.0);
                        }
                    }
                }
            }

Comparativo Clarion vs SOAR

Neste exercício foi realizado um comparativo entre dois agentes dentro do WorldServer3D.

O primeiro agente sendo controlado através do SOAR e o segundo sendo controlado pelo Clarion.

Os arquivos para executar o comparativo estão neste link:

/gudwin/sites/faculty.dca.fee.unicamp.br.gudwin/files/users/2015-8/8-9aula/CompSoarClarion/Clarion.tar.gz

De maneira geral, os dois agentes estão preparados para agir de maneira muito similar dentro deste ambiente.

Os dois agentes andam em direção ao objeto do seu leaflet que está no seu campo de visão e não possuem nenhum tipo de aprendizado implementado. As regras de comportamento também estão implementadas de forma fixa para os dois agentes.

As principais vantagens do Clarion em relação ao SOAR observadas foram as seguintes:

- O Clarion, por ser um toolkit, apresentou uma curva de aprendizado muito menor do que o SOAR que está estruturado como um framework.

- O Clarion também apresenta de maneira geral uma estrutura em que possibilita lidar com o problema com um nível de abstração maior do que o SOAR;

- O Clarion também apresenta uma caracteristica em que é possivel, através de feedbacks, gerar suas próprias regras de comportamento. Como não é necessário colocar regras fixas no agente, isso torna o comportamento do agente mais dinâmico dentro de um ambiente;

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer