You are here

Relatório 3 - Clarion: Controlando o WorldServer3D

Atividade Teste 1: Buscando as jóias

Nessa atividade foi implementada uma solução para a criatura realizar a busca por jóias ( Thing.CATEGORY_JEWEL ).

Adicionamente, foi gerado um comportamento apetitivo na criatura para que também buscasse por comida, perecível ( Thing.categoryPFOOD ) ou não ( Thing.CATEGORY_NPFOOD ). Uma vez que o ítem, quer seja jóia ou comida, é detectado pelo sensor visual da critura, ela passa a buscar o ítem, como pode ser observado no vídeo abaixo.

Created by Freemake Video Converter

Podemos observar que, mesmo o ítem sendo movimentado para outras posições no World Server 3D, a criatura continua a perseguí-lo.

As "coisas" buscadas já estavam declaradas na classe Thing, permitindo o reuso do código destacado abaixo:

public class Thing
{
	( ... )
	public const int categoryPFOOD = 21;
	public const int CATEGORY_NPFOOD = 22;
	public const int CATEGORY_JEWEL = 3;
	( ... )
}

Para a implementação do novo comportamento, dois novos tipos de ações foram enumerados na classe ClarionAgent, a saber, GOTO_ITEM e GET_ITEM.

public enum ClarionAgentActionType
{
	DO_NOTHING,
	ROTATE_CLOCKWISE,
	GO_AHEAD,
	GOTO_ITEM,
	GET_ITEM
}

Ainda na classe ClarionAgent, duas novas constantes foram criadas, representando um ítem no campo visual ( DIMENSION_ITEM_AHEAD ) ou um ítem passível de ser guardado na mochila ( DIMENSION_SACK_ITEM ). Dois novos pares dimensão-valor foram criados como entrada da percepção visual e serão alimentados com as constantes DIMENSION_ITEM_AHEAD e DIMENSION_SACK_ITEM no construtor do ClarionAgent.

public class ClarionAgent
{
	#region Constants
	
	( ... )
	private const String DIMENSION_ITEM_AHEAD = "ItemAhead";
	private const String DIMENSION_SACK_ITEM = "SackItem";
	( ... )

	#region Perception Input

	( ... )
	private DimensionValuePair dvpInputItemAhead;
	private DimensionValuePair dvpInputSackItem;
	( ... )
}

Abaixo, o trecho do código retirado do construtor:

public ClarionAgent( )
{
	// Initialize the agent
	CurrentAgent = World.NewAgent( "Current Agent" );

	// Initialize input information
	InputWallAhead = World.NewDimensionValuePair( SENSOR_VISUAL_DIMENSION, DIMENSION_WALL_AHEAD );

	// Initialize output actions
	OutputRotateClockwise = World.NewExternalActionChunk( ClarionAgentActionType.ROTATE_CLOCKWISE.ToString( ) );
	OutputGoAhead = World.NewExternalActionChunk( ClarionAgentActionType.GO_AHEAD.ToString( ) );

	dvpInputItemAhead = World.NewDimensionValuePair( SENSOR_VISUAL_DIMENSION, DIMENSION_ITEM_AHEAD );
	dvpInputSackItem = World.NewDimensionValuePair( SENSOR_VISUAL_DIMENSION, DIMENSION_SACK_ITEM );

	( ... )

	//Create thread to simulation
	runThread = new Thread( RunThread );
	Console.WriteLine( "Agent started" );
}

Agora precisamos definir as ações externas que o agente irá realizar (neste caso, ir para o ítem e pegar o ítem) quando apresentado aos respectivos inputs. O método NewExternalActionChunk realiza isso:

eacOutputGotoItem = World.NewExternalActionChunk( ClarionAgentActionType.GOTO_ITEM.ToString( ) ); 
eacOutputGetItem = World.NewExternalActionChunk( ClarionAgentActionType.GET_ITEM.ToString( ) ); 

O próximo passo é instruir o avatar com as regras que serão usadas na seleção da ação. Para isso, criamos os seguintes métodos:

private double fixedRuleDelegateGoToItemAhead( ActivationCollection activationCollection, Rule rule )
{
	return activationCollection.Contains( dvpInputItemAhead, CurrentAgent.Parameters.MAX_ACTIVATION ) ? 1 : 0;
}

private double fixedRuleDelegateSackItem( ActivationCollection activationCollection, Rule rule )
{
	return activationCollection.Contains( dvpInputSackItem, CurrentAgent.Parameters.MAX_ACTIVATION ) ? 1 : 0;
}

Esses métodos serão assinalados como SupportCalculator e definidos como regras para o agente para serem selecionados no Action-Centered Subsystem:

SupportCalculator goToItem = fixedRuleDelegateGoToItemAhead;
FixedRule ruleGoToItem = AgentInitializer.InitializeActionRule( CurrentAgent, FixedRule.Factory, eacOutputGotoItem, goToItem );
CurrentAgent.Commit( ruleGoToItem );

SupportCalculator sackItem = fixedRuleDelegateSackItem;
FixedRule ruleSackItem = AgentInitializer.InitializeActionRule( CurrentAgent, FixedRule.Factory, eacOutputGetItem, sackItem );
CurrentAgent.Commit( ruleSackItem );

Como última modificação na classe ClarionAgent, precisamos fazer o agente perceber as novas situações. O método MakePerceptionFromSensorialInput foi alterado com duas novas informações sensoriais. Caso haja um ítem (jóia, comida perecível ou comida não perecível) no campo visual do agente, uma informação sensorial é adicionada. Caso esse ítem esteja a uma distância passível de ser capturado ( ITEM_SACKABLE_DISTANCE ), outra informação sensorial é adicionada ao SensoryInformation, como mostra o trecho abaixo:

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

	( ... )

	const int ITEM_SACKABLE_DISTANCE = 20;

	Boolean bItemAhead = sensorialInformation.Where( item => ( item.CategoryId == Thing.CATEGORY_JEWEL || item.CategoryId == Thing.CATEGORY_NPFOOD || item.CategoryId == Thing.categoryPFOOD ) ).Any( );

	double dItemAheadActivationValue = bItemAhead ? CurrentAgent.Parameters.MAX_ACTIVATION : CurrentAgent.Parameters.MIN_ACTIVATION;
	si.Add( dvpInputItemAhead, dItemAheadActivationValue );

	Boolean bSackItem = sensorialInformation.Where( item => ( ( item.CategoryId == Thing.CATEGORY_JEWEL || item.CategoryId == Thing.CATEGORY_NPFOOD || item.CategoryId == Thing.categoryPFOOD ) && item.DistanceToCreature <= ITEM_SACKABLE_DISTANCE ) ).Any( );

	double dSackItemActivationValue = bSackItem ? CurrentAgent.Parameters.MAX_ACTIVATION : CurrentAgent.Parameters.MIN_ACTIVATION;
	si.Add( dvpInputSackItem, dSackItemActivationValue );

	( ... )

	return si;
}

Finalmente, a classe Main precisa ser alterada para lidar com os tipos de ação ClarionAgentActionType.GOTO_ITEM e ClarionAgentActionType.GET_ITEM. Neste ponto é importante destacar que, se o ítem for uma jóia, ele é armazenado na mochila ( worldServer.SendSackIt( ) ) e, se o ítem for comida, é usado para alimentar a criatura ( worldServer.SendEatIt( ) ). O trecho abaixo demonstra a implementação desse comportamento.

case ClarionAgentActionType.GOTO_ITEM:

	foreach( Thing t in agent_OnNewVisualSensorialInformation( ) )
	{
		if( t.CategoryId == Thing.CATEGORY_NPFOOD || t.CategoryId == Thing.categoryPFOOD || t.CategoryId == Thing.CATEGORY_JEWEL )
		{
			Console.WriteLine( "I saw an item at [ " + t.comX + " , " + t.comY + " ]..." );
			worldServer.SendSetGoTo( creatureId, 1, 1, t.comX, t.comY );
		}
	}

break;

case ClarionAgentActionType.GET_ITEM:

	foreach( Thing t in agent_OnNewVisualSensorialInformation( ) )
	{
		if( t.CategoryId == Thing.CATEGORY_JEWEL )
		{
			Console.WriteLine( "It's close. I can take [ " + t.Name + " ]..." );
			worldServer.SendSackIt( creatureId, t.Name );
			Console.WriteLine( "I took [ " + t.Name + " ]!" );
		}
		else if( t.CategoryId == Thing.CATEGORY_NPFOOD || t.CategoryId == Thing.categoryPFOOD )
		{
			Console.WriteLine ("It's close. I can eat [ " + t.Name + " ]..." );
			worldServer.SendEatIt( creatureId, t.Name );
			Console.WriteLine( "I ate [ " + t.Name + " ]!" );
		}
	}

break;

Atividade Teste 2: Competição entre SOAR e Clarion

Neste teste, duas criaturas implementadas em diferentes arquiteturas cognitivas devem co-habitar um mundo virtual. A primeira criatura foi reaproveitada do Relatório 2 - SOAR: Controlando o WorldServer3D e a segunda criatura foi desenvolvida com a arquitetura cognitiva Clarion e pertence a Atividade Teste 1 descrita neste relatório.

As criaturas puderam co-existir, sendo que o comportamento da simulação 1 (SOAR) de gerar ítens randômicos foi preservado, assim como o comportamento da simulação 2 (Clarion) de criar paredes ao redor do mundo; todavia, a criatura desenvolvida com a arquitetura SOAR não se movimentou, ficando o trabalho de recolher os ítens a cargo da criatura criada com a arquitetura Clarion. A captura de tela abaixo ilustra a situação:

Competição entre as arquiteturas cognitivas SOAR e Clarion

Um arquivo com os executáveis do controlador Clarion está disponível aqui e, depois de descompactado, pode ser executado com o comando:

mono ClarionDEMO.exe

Por favor, certifique-se que o World Server 3D esteja rodando primeiro. O binário foi compilado para conectar-se ao mundo virtual em localhost:4011.

O código fonte está disponível aqui para fins de consulta e recompilação do controlador.

Para iniciar uma simulação conjunta com a arquitetura SOAR, faça o download desse arquivo, descompacte-o e execute o shell script. Após a inicialização do World Server, pressione uma tecla para inicializar o Demo SOAR. Após a inicialização do Demo SOAR, pressione novamente para inicializar a simulação Clarion.

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer