LIDA: Exemplos de Implementação Prática
O projeto basicAgentExercises cria um agente simples que habita o ambiente "Button". Esse ambiente exibe aleatoriamente um quadrado vermelho, um círculo azul, ou nenhuma figura. O ambiente também apresenta dois "botões": o botão 1 deve ser pressionado pelo agente quando um quadrado vermelho for exibido, e, o botão 2 que deve ser pressionado na ocorrência de um círculo azul.
Basic Agent Exercise 0
O projeto está fundamentado em classes Java e arquivos (XML) de configuração. A classe myagent.Run roda a aplicação. A classe myagent.modules.ButtonEnvironment implementa o Ambiente Button. A classe myagent.modules.ButtonSensoryMemory implementa a Memória Sensória do agente. A classe myagent.featuredetectors.ColorFeatureDetector é responsável pela detecção da feature Color (cor). A classe myagent.featuredetectors.ShapeFeatureDetector é responsável pela detecção da feature Shape (forma). O arquivo lidaConfig.properties é o arquivo de configuração principal que possui referências para outros arquivos de configuração usados pelo projeto do agente. O arquivo basicAgent.xml é o arquivo de declaração do agente que define a arquitetura do agente, inclusive os módulos e processos que a aplicação do agente utilizará. O arquivo factoryData.xml contém as definições dos elementos que podem ser obtidos do ElementFactory; dentre estes, Nodes, Links, Strategies, e os tipos de Tasks. O arquivo guiPanels.properties é o arquivo de configuração dos GUIPanels usados pela GUI do LIDA Framework.
Basic Agent Exercise 1
A figura acima exibe a tela do Ambiente Button do agente LIDA criado neste projeto. O botão "Start/Pause" roda (e pausa) a simulação do agente. O botão "Step mode" roda a aplicação durante um certo número de ticks e depois pausa o agente; a caixa de texto ao lado do botão especifica esse número de ticks. O campo "Tick duration (ms)" especifica o tempo de duração, em milisegundos, de um tick; esse valor controla a velocidade com que a aplicação roda. O campo "Logger", no painel (Logging) inferior da tela, permite configurar as informações que serão exibidas sobre a aplicação; o campo "Logging level" configura o nível de detalhamento das informações exibidas: a configuração desses dois campos permite visualizar (na figura acima) as imagens que são exibidas e as ações do agente (botões pressionados). O painel "Configuration files" exibe (não mostrado nesta figura) as informações sobre os arquivos de configuração correntemente usados pela aplicação.
Basic Agent Exercise 2
Neste exercício, o arquivo lidaConfig.properties foi modificado: a propriedade lida.agentdata agora referencia o arquivo configs/basicAgent_ex2.xml. Essa modificação faz o agente deixar de "perceber" o círculo azul; conseqüentemente, o agente não pressionará o botão 2. A figura abaixo exibe a guia "PAM Table"; nota-se que as features square e red possuem níveis de ativação que decaem com o tempo. Quando um círculo azul (blue circle) é exibido para o agente, as features circle e blue não são ativadas (não mostrado aqui); isso ocorre porque, neste caso, o agente não possui um detector de feature para esses PAM nodes (blue e circle).
A próxima figura exibe o conteúdo da guia "Perceptual Buffer". Quando um quadrado vermelho é exibido, os nodes red e square aparecem dentro deste painel; no entanto, a ocorrência de um círculo azul deixa o seu conteúdo vazio (não mostrado aqui).
O Perceptual Buffer pertence ao módulo Workspace (Memória de Trabalho) do LIDA Model. Os seus nodes provêm do módulo PAM (Perceptual Associative Memory). Esses nodes não são exatamente os mesmos nodes provenientes do módulo PAM, sendo instanciações (cópias) desses nodes. Apenas os nodes detectados pelo módulo PAM, e que possuem níveis de ativação, serão repassados para o Perceptual Buffer. A figura a seguir exibe a guia "Global Workspace". Pode-se observar as informações sobre as coalisões formadas, inclusive os attentional codelets. A parte inferior desse painel exibe um histórico com as coalisões vencedoras que ganharam o foco de atenção do agente.
As coalisões do Global Workspace provêm do módulo Workspace, sendo direcionadas (broadcast) para os outros módulos da arquitetura LIDA. Pode-se observar, na figura acima, que as coalisões deste agente compreendem os nodes formados pelas features square e red.
Uma nova modificação neste agente inclui um GUIPanel, na GUI do LIDA Framework, responsável por exibir o conteúdo do Modelo Situacional Corrente, que é um sub-módulo do módulo Workspace. A próxima figura exibe o novo painel criado. A guia "CSM" exibe as informações atuais do agente sobre sua percepção do seu mundo. O arquivo que será modificado é o guiPanels.properties. Basta incluir a seguinte linha de código:
csm=CSM,edu.memphis.ccrg.lida.framework.gui.panels.NodeStructurePanel,B,7,Y,Workspace.CurrentSituationalModel
O conteúdo do Modelo Situacional Corrente é formado a partir das informações do Perceptual Buffer que provêm dos nodes criados no módulo PAM. Os codelets que atuam no módulo Workspace são responsáveis pela geração do modelo.
Basic Agent Exercise 3
Neste exercício, o arquivo lidaConfig.properties foi modificado: a propriedade lida.agentdata agora referencia o arquivo configs/basicAgent_ex3.xml. Neste exemplo serão adicionados os seguintes elementos do LIDA Framework, descritos na figura abaixo, representados por pontos tracejados:
O arquivo configs/basicAgent_ex3.xml deverá ser modificado para implementar a detecção do círculo azul. Um novo módulo e um novo listener deverão ser acrescentados nesse arquivo; além de um detector de feature e um attentional codelet. O seguinte trecho de código será acrescentado nesse arquivo:
<module name="Environment">
<class>myagent.modules.ButtonEnvironment</class>
<param name="height" type="int"> 10 </param>
<param name="width" type="int">10 </param>
<taskspawner>defaultTS</taskspawner>
</module>
Ao rodar novamente a aplicação, o agente ainda não consegue detectar a ocorrência de um círculo azul (ainda não há detectores de fetures para circle e blue no módulo PAM); apenas os nodes do quadrado vermelho possuem ativação. Embora haja detectores para as features do quadrado vermelho, essas informações não estão disponíveis no Perceptual Buffer do agente; ainda não existe uma conexão entre PAM e Workspace. Para efetuar essa tarefa, será necessário acrescentar um PamListener no arquivo de declaração do agente, conforme o trecho de código abaixo:
<listener>
<listenertype>edu.memphis.ccrg.lida.pam.PamListener</listenertype>
<modulename>PerceptualAssociativeMemory</modulename>
<listenername>Workspace</listenername>
</listener>
Agora a guia "Perceptual Buffer" exibe as informações sobre o quadrado vermelho percebido pelo agente, mas, ainda não há informações sobre o círculo azul (ainda não detectado). Dentro da declaração do módulo PAM (PerceptualAssociativeMemory) deve-se incluir as seguintes linhas de código:
<task name="BlueDetector">
<tasktype>ColorDetector</tasktype>
<ticksperrun>3</ticksperrun>
<param name="color" type="int">-16776961</param>
<param name="node" type="string">blue</param>
</task>
<task name="CircleDetector">
<tasktype>ShapeDetector</tasktype>
<ticksperrun>3</ticksperrun>
<param name="area" type="int">31</param>
<param name="backgroundColor" type="int">-1</param>
<param name="node" type="string">circle</param>
</task>
Agora o agente consegue perceber a ocorrência de um círculo azul, no seu ambiente, porém, o agente ainda não executa a ação de pressionar o botão 2. Isso ocorre porque ainda não há attentional codelets, relacionados a esses nodes, para adicioná-los (como coalisões) ao Global Workspace. Dentro da declaração do módulo AttentionModule, devem ser inseridas as seguintes linhas de código para permitir que o agente execute a tarefa relacionada ao surgimento do círculo azul:
<task name="BlueCircleCodelet">
<tasktype>BasicAttentionCodelet</tasktype>
<ticksperrun>5</ticksperrun>
<param name="nodes" type="string">blue,circle</param>
<param name="refractoryPeriod" type="int">30</param>
<param name="initialActivation" type="double">1.0</param>
</task>
Agora o agente executa devidamente suas tarefas, conforme mostra a figura abaixo:
Advanced Exercise 1
O LIDA Framework pode rodar sem exibir a GUI. Para habilitar ou desabilitar a exibição da GUI, basta modificar a propriedade lida.gui.enable do arquivo lidaConfig.properties. Desabilitando a GUI, o agente continua rodando, e pressionando os devidos botões, porém, nenhuma tela é exibida junto com a operação do agente; porque a parte visual da aplicação foi desenvolvida sobre a GUI. O Logging gerado durante a execução do agente LIDA pode ser salvo num arquivo, se necessário. As informações sobre o Logging estão disponíveis no arquivo logging.properties, definido no arquivo lidaConfig.properties.
Advanced Exercise 2
Ao rodar a aplicação do agente, a guia "Global Workspace" normalmente exibe algumas coalisões, na parte superior do painel, além das coalisões que estão sendo compartilhadas por broadcast. O parâmetro ticksPerRun influencia diretamente as coalisões formadas e aquelas compartilhadas. Pode-se perceber isso alterando-se, por exemplo, esse parâmetro do codelet responsável pela detecção do quadrado vermelho. Dentro do arquivo basicAgent.xml, no módulo AttentionModule, está a declaração do codelet RedSquareCodelet. Alterando-se seus parâmetros ticksperrun e refractoryPeriod para 50 e 300, respectivamente, nota-se que houve uma modificação no modo operacional do agente: agora, na guia "Global Workspace", aparecem menos coalisões quando surge um quadrado vermelho na tela. Também haverá menos coalisões sendo enviadas por broadcast.
Advanced Exercise 3
Neste exercício serão abordadas a criação de um feature detector, um attentional codelet e um scheme. O objetivo desta tarefa será fazer o agente perceber a ocorrência de uma "tela em branco" e então executar a tarefa de "soltar" o botão que foi pressionado anteriormente.
O primeiro passo será criar uma nova classe para permitir a detecção da nova feature. A classe myagent.featuredetectors.BlankFeatureDetector será responsável pela detecção da "tela em branco" (Image cleared). Após criar essa classe, será necessário modifcar o arquivo basicAgent.xml. Na declaração do módulo PerceptualAssociativeMemory, deve-se acrescentar um novo node chamado empty (<param name="nodes">red,blue,square,circle,empty</param>); também deve-se acrescentar uma nova task, conforme código abaixo:
<task name="EmptyDetector">
<tasktype>BlankDetector</tasktype>
<ticksperrun>3</ticksperrun>
<param name="area" type="int">40</param>
<param name="backgroundColor" type="int">-1</param>
<param name="node" type="string">empty</param>
</task>
Essa task referencia a task BlankDetector que será criada no arquivo factoryData.xml. Na declaração do módulo AttentionModule, deve-se criar um novo attentional codelet para a nova feature empty, conforme o código abaixo:
<task name="BlankCodelet">
<tasktype>BasicAttentionCodelet</tasktype>
<ticksperrun>5</ticksperrun>
<param name="nodes" type="string">empty</param>
<param name="refractoryPeriod" type="int">30</param>
<param name="initialActivation" type="double">1.0</param>
</task>
No módulo ProceduralMemory cria-se um novo scheme com a ação action.releasePress, responsável pela liberação do botão que foi pressionado, conforme a linha de código abaixo:
<param name="scheme.3">if empty, release 1,2|(empty)()|action.releasePress|()()|0.01</param>
No módulo SensoryMotorMemory deve-se relacionar a ação releasePress ao algoritmo responsável por executar essa ação no ambiente do agente, conforme a linha de código a seguir:
<param name="smm.3">action.releasePress,algorithm.releasePress</param>
Finalmente, no arquivo factoryData.xml, cria-se uma nova task (BlankDetector) responsável pelo uso da classe myagent.featuredetectors.BlankFeatureDetector para efetuar a detecção da nova feature desejada, conforme o código abaixo:
<task name="BlankDetector">
<class>myagent.featuredetectors.BlankFeatureDetector</class>
<ticksperrun>5</ticksperrun>
<associatedmodule>SensoryMemory</associatedmodule>
<associatedmodule>PerceptualAssociativeMemory</associatedmodule>
<param name="area" type="int">40</param>
<param name="backgroundColor" type="int">-1</param>
<param name="node" type="string">empty</param>
</task>
Ao rodar novamente o agente, agora o botão pressionado será liberado sempre que não houver nenhuma figura sendo exibida para o agente, conforme ilustra a figura abaixo: