Vous êtes sur la page 1sur 86

Universidade Federal do ABC ufabc

Andr Filipe de Moraes Batista e


andre.batista@ufabc.edu.br

Manual Complementar do Projeto de Pesquisa: Sistemas Multiagentes na Construo de um ca Middleware para Suporte a Ambientes Computacionais

Orientaao: c Profa Dra Maria das Graas Bruno Marietto c Santo Andr, Agosto de 2008 e

Prefcio a
Atingimos a perfeio no quando nada pode ca a acrescentar-se a um projeto, mas quando nada pode retirar-se Saint-Exupry e

A idia de escrever este manual teve incio nos meus estudos de iniciao cient e ca ca neste na Universidade Federal do ABC, sob a orientao da professora Graa Marietto. E ca c esp rito de aprendizado que este manual foi escrito. Desde o primeiro momento que descobri que iria trabalhar programando em Java, e que esta programao seria para sistemas ca multiagentes, a alegria e ansiedade foram estonteantes. E este o meu objetivo: ser o mais didtico possvel e fazer com que voc sinta um pouco das emoes que senti durante a e co as longas horas diante do computador, programando e ao mesmo tempo descobrindo a plataforma JADE e suas faanhas. c A programao de sistemas multiagentes uma tcnica de desenvolvimento de sistemas ca e e distribu dos, e neste contexto encontramos questes tais como: como distribuir?, como o fazer a comunicao entre as partes do sistema?, como administrar o sistema?, entre ca outras. Essas e outras perguntas foram respondidas ao longo do estudo desta plataforma. Alm de abstrair muitos recursos do programador, as facilidades de implementao fazem e ca com que esta seja uma das mais utilizadas plataformas de desenvolvimento de aplicaes co distribu das. Este manual no est nalizado e nunca estar. Ele contar sempre com um toque a a a a especial seu. Sim, voc!... Voc dever ao longo de sua leitura criar cenrios para suas e e a a aplicaes, buscar solues para as dvidas que surgiro, enm, nunca se contentar apenas co co u a com o que est escrito, tente sempre tirar suas prprias concluses. Fazendo isto voc a o o e aprender cada vez mais. a Andr Filipe de Moraes Batista e

ii

Aos meus pais.

Lista de Figuras
2.1 2.2 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 Ciclo de Execuo de um Agente. . . . . . . . . . . . . . . . . . . . . . . . 13 ca Exemplo de Mquina de Estado Finito. . . . . . . . . . . . . . . . . . . . . 28 a Situaao Problema - Incndio. . . . . . . . . . . . . . . c e Cenrio - Loja de Msica. . . . . . . . . . . . . . . . . a u Estrutura de uma Entrada no DF. . . . . . . . . . . . . Cenrio - Solicitando Ajuda. . . . . . . . . . . . . . . . a Interface Grca da Plataforma JADE. . . . . . . . . . a Agente Snier. . . . . . . . . . . . . . . . . . . . . . . Agente Pedinte na Plataforma. . . . . . . . . . . . . . Execuao do Agente Snier. . . . . . . . . . . . . . . . c Troca de Mensagens entre os Agentes. . . . . . . . . . . Pginas Amarelas - Noticaao. . . . . . . . . . . . . . a c Estrutura dos Protocolos Baseados no fipa-request. . Protocolo fipa-request. . . . . . . . . . . . . . . . . Plataforma Distribu JADE. . . . . . . . . . . . . . . da . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 41 48 53 59 60 61 61 62 66 69 71 77

iv

Lista de Tabelas
3.1 Valores Inteiros das Performatives. . . . . . . . . . . . . . . . . . . . . . . 33

Sumrio a
Lista de Figuras Lista de Tabelas 1 Instalao ca 1.1 Requisitos Bsicos . . . . . . . . . . a 1.2 Software de Instalaao da Plataforma c 1.3 Execuao do Ambiente . . . . . . . . c 1.4 Integraao com a IDE NetBeans . . . c iv v 1 1 1 2 3 5 5 6 8 10 12 12 17 18 19 19 21 21 23 27 32 32 32 33 34

. . . . JADE . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

2 Primeiros Programas 2.1 Hello World . . . . . . . . . . . . . . . 2.2 Identicadores de Agentes . . . . . . . 2.3 Passando Informaes a um Agente . . co 2.4 Comportamentos . . . . . . . . . . . . 2.4.1 Execuo dos Comportamentos ca 2.4.2 Bloqueando Comportamentos . 2.5 Comportamentos Pr-Denidos . . . . e 2.5.1 Comportamentos One-shot . . . 2.5.2 Comportamentos C clicos . . . 2.5.3 Comportamentos Temporais . . 2.5.4 Comportamentos Compostos . . 2.5.4.1 SequencialBehaviour . 2.5.4.2 ParallelBehaviour . . 2.5.4.3 FSMBehaviour . . . . 3 Comunicao entre Agentes ca 3.1 Envio e Recebimento de Mensagens 3.1.1 Classe ACLMessage . . . . . 3.1.2 Enviar uma Mensagem . . . 3.1.3 Receber uma Mensagem . . vi

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

SUMARIO 3.1.4 Exemplo de Troca de Mensagens . . . . Envio de Objetos . . . . . . . . . . . . . . . . . Seleao de Mensagens . . . . . . . . . . . . . . . c Pginas Amarelas . . . . . . . . . . . . . . . . . a 3.4.1 Registro . . . . . . . . . . . . . . . . . . 3.4.2 Busca . . . . . . . . . . . . . . . . . . . 3.4.3 Solicitando Ajuda . . . . . . . . . . . . . 3.4.4 Noticao . . . . . . . . . . . . . . . . ca Pginas Brancas . . . . . . . . . . . . . . . . . a Protocolos de Interaao . . . . . . . . . . . . . . c 3.6.1 Classe AchieveREInitiator . . . . . . . . 3.6.2 Classe AchieveREResponder . . . . . . . 3.6.3 Exemplo de Implementao do Protocolo ca

vii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . FIPA-Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 40 45 48 50 51 52 62 67 68 70 70 70 79

3.2 3.3 3.4

3.5 3.6

Referncias Bibliogrcas e a

Cap tulo 1 Instalao ca


Neste cap tulo ser demonstrado o processo de instalao da plataforma JADE. a ca

1.1

Requisitos Bsicos a

Por ser desenvolvida em Java, o requisito m nimo para executar a plataforma JADE o e run-time do Java. No caso Java Run-Time Environment (JRE) verso 1.4 ou superior. a

1.2

Software de Instalao da Plataforma JADE ca

Todos os software JADE, inclusive add-ons e novas verses, esto distribu o a dos sob as 1 limitaes da LGPL e dispon co veis para download no web site http://jade.cselt.it ou http://jade.tilab.com. A verso atual da plataforma JADE utilizada neste trabalho a 3.5. Para esta verso, a e a cinco arquivos so disponibilizados: a 1. jadeSrc.zip (1.8 MB) cdigo fonte do software JADE; o 2. jadeExamples.zip (270 KB) cdigo fonte dos exemplos de programas feitos em o JADE; 3. jadeDoc.zip (4.7 MB) toda a documentaao, incluindo o javadoc da API da c plataforma e manuais de referncia; e 4. jadeBin.zip (2.0 MB) o software JADE binrio, pronto para uso; a
A licena LGPL fornece alguns direitos e tambm deveres. Dentre os direitos esto o acesso ao c e a cdigo fonte do software, a permisso de fazer e distribuir cpias, permisso para fazer melhorias e o a o a funcionalidades etc. J alguns dos deveres so: no fazer modicaes privadas e secretas, no alterar a a a a co a licena do software e suas modicaes, dentre outros. c co
1

1.3. Execuao do Ambiente c 5. jadeAll.zip (5.8 MB) todos os arquivos anteriormente citados.

Recomenda-se o download do arquivo jadeAll.zip. Aps o download descompacta-se o o arquivo interno jade-Bin-3.5.zip em um diretrio, por exemplo o diretrio raiz (C:). o o Uma pasta denominada jade criada. Deve-se incluir as seguintes linhas na varivel de e a ambiente classpath: .;c:\jade\lib\jade.jar; c:\jade\lib\jadeTools.jar; c:\jade\lib\iiop.jar Com isto a plataforma JADE est instalada e congurada para rodar no ambiente a Windows.

1.3

Execuo do Ambiente ca

Aps os passos citados anteriormente, poss a execuao da plataforma JADE pelo o e vel c prompt de comando. A linha de execuao da plataforma JADE a seguinte: c e java jade.Boot [op~es] [agentes] co Esta linha de execuao ser abordada nas prximas sees com mais detalhes. Neste c a o co momento, para vericar se a instalaao e a congurao da plataforma foram feitas corc ca retamente, digite no prompt o seguinte comando: java jade.Boot Com este comando a plataforma JADE executada. Se tudo foi congurado corretae mente, a seguinte mensagem ser exibida: a INFO: ---------------------------------This is JADE 3.5 - revision 5988 of 2007/06/21 11:02:30 downloaded in Open Source, under LGPL restrictions, at http://jade.tilab.com/ ---------------------------------------11/11/2007 12:22:50 jade.core.BaseService init INFO: Service jade.core.management.AgentManagement initialized 11/11/2007 12:22:50 jade.core.BaseService init INFO: Service jade.core.messaging.Messaging initialized 11/11/2007 12:22:50 jade.core.BaseService init INFO: Service jade.core.mobility.AgentMobility initialized 11/11/2007 12:22:50 jade.core.BaseService init INFO: Service jade.core.event.Notification initialized

1.4. Integrao com a IDE NetBeans ca

11/11/2007 12:22:50 jade.core.messaging.MessagingService clearCachedSlice INFO: Clearing cache 11/11/2007 12:22:50 jade.mtp.http.HTTPServer <init> INFO: HTTP-MTP Using XML parser com.sun.org.apache.xerces.internal .parsers.SAXParser 11/11/2007 12:22:50 jade.core.messaging.MessagingService boot INFO: MTP addresses: http://lap:7778/acc 11/11/2007 12:22:50 jade.core.AgentContainerImpl joinPlatform INFO: -------------------------------------Agent container Main-Container@lap is ready. -------------------------------------------A exibiao da mensagem Agent container Main-Container@lap is ready indica c que a plataforma est em execuo. Para nalizar a execuao pressione as teclas CTRL+C. a ca c Existe um bug na verso 3.5 da JADE, onde um erro ligado aos sockets exibido a e pois a mquina que est executando a plataforma pode no estar em rede. Esta falha a a a s apareceu na verso 3.5 e sua correo ainda est em desenvolvimento. Recomenda-se o a ca a que quando uma mquina estiver fora da rede deve-se incluir o parmetro -detect-main a a false na linha de execuao da plataforma, da seguinte maneira: c java jade.Boot -detect-main false

1.4

Integrao com a IDE NetBeans ca

Vamos integrar as bibliotecas da plataforma JADE com a IDE Netbeans2 , para que seja poss vel o desenvolvimento de agentes contando com as ferramentas de uma IDE. No NetBeans abra o menu Ferramentas (Tools) e clique na opo Gerenciador de Biblioteca ca (Library Manager ). Uma janela ser aberta. a Na janela Gerenciador de Bibliotecas clique no boto Nova Biblioteca (new library). a Uma janela de dilogo ser aberta. No campo Nome da Biblioteca digite jade e deixe a a marcado o campo Tipo de Biblioteca como Bibliotecas da Classe. E clique em ok. A janela de Gerenciador de Bibliotecas agora apresentar a nova biblioteca adicionada. a Nesta mesma janela, na guia Classpath clique no boto Adicionar JAR/Pasta e adia cione os arquivos (localizados em C:/jade/lib/): http.jar, iiop.jar, jade.jar e jadeTools.jar. Na guia Javadoc adicione a pasta C:/jade/doc. Clique em ok e as bibliotecas JADE estaro integradas ao Netbeans. a Quando estiver desenvolvendo um projeto no NetBeans, v na guia Projetos e selea cione o item Bibliotecas. Com o boto direito do mouse selecione a opao Adicionar a c
2

A verso utilizada foi a 6.0, dispon em http://www.netbeans.org a vel

1.4. Integrao com a IDE NetBeans ca

Biblioteca. Ser aberta a janela Adicionar Biblioteca. Nesta, selecione a biblioteca a JADE e clique em OK. Com isto, o NetBeans passar a reconhecer os mtodos e atribua e tos fornecidos pela plataforma. A execuao de um agente no ser pela IDE3 . Voc dever executar os agentes a partir c a a e a de um prompt de comando.

Existem formas de se executar um agente pela IDE, mas estas no sero abordadas neste manual. a a

Cap tulo 2 Primeiros Programas


Neste cap tulo ser apresentada a estrutura bsica de uma implementaao na plataforma a a c JADE, com o uso de exemplos de implementaao. c

2.1

Hello World

Vamos comear com um programa clssico: um agente JADE que imprime na tela a frase c a Hello World. Agentes JADE so denidos como subclasses da classe Agent e seu cdigo a o inicial (o que o agente far ao ser executado) deve ser colocado dentro do mtodo setup(). a e O cdigo do Hello World mostrado na Caixa de Cdigo 2.1. o e o Herdando a classe jade.core.Agent os agentes j possuem as operaes bsicas dentro a co a da plataforma, como registro e conguraao e outro conjunto de mtodos para implemenc e tao de comportamentos pr-denidos, como mtodos de troca de mensagens. ca e e
import j a d e . c o r e . Agent ;
3

Cdigo 2.1: HelloAgent.java o

public c l a s s H e l l o A g e n t extends Agent { protected void s e t u p ( ) { System . out . p r i n t l n ( " Hello World . " ) ; System . out . p r i n t l n ( "Meu nome " + getLocalName ( ) ) ; e } } 

Devemos estar dentro do diretrio dos arquivos .java para que este agente seja execuo tado. Uma vez no diretrio, deve-se executar as seguintes linhas de comando no prompt: o javac HelloAgent.java java jade.Boot Andre:HelloAgent 5

2.2. Identicadores de Agentes

A primeira linha trata da compilao da classe HelloAgent.java, gerando o arquivo ca HelloAgent.class. A segunda linha de comando requer um pouco mais de explicao. ca Basicamente, agentes so como Java Applets na medida em que ambos no podem ser exea a cutados diretamente: eles so executados dentro de outro programa que prov os recursos a e necessrios para sua execuao. No caso dos applets, um browser ou um Applet Viewer a c e necessrio; para agentes JADE o ambiente de execuo fornecido pela classe jade.Boot. a ca e O parmetro Andre:HelloAgent indica a classe do agente (HelloAgent), e prov um nome a e unico ao agente (Andre). A classe Agent contm o mtodo getLocalName(), que retorna e e o nome do agente em seu container. Com a execuao das linhas de comando tem-se o seguinte resultado: c INFO: ---------------------------------This is JADE 3.5 - revision 5988 of 2007/06/21 11:02:30 downloaded in Open Source, under LGPL restrictions, at http://jade.tilab.com/ ---------------------------------------. . . INFO: -------------------------------------Agent container Main-Container@lap is ready. -------------------------------------------Hello World. Meu nome e Andre E importante lembrar que este agente ainda est em execuao. Para nalizaao do a c c agente e da plataforma pressione as teclas CTRL+C.

2.2

Identicadores de Agentes

De acordo com o padro FIPA cada instncia de agente identicada por um agent a a e identier. Na plataforma JADE um agent identier representado como uma instncia e a da classe jade.core.AID. O mtodo getAID() permite obter a identicaao completa e c (global, nome na plataforma, endereo, etc) do agente, armazenando estas informaes c co em uma lista. Um ID global aquele que representa o identicador do agente em toda a e plataforma. Um ID local refere-se ao conjunto de informaoes que representam o agente c em seu container. O nome global do agente unico na plataforma, e possui a seguinte estrutura: e

2.2. Identicadores de Agentes <nome_local>@<nome-plataforma>

Por exemplo o agente Pedro, localizado na plataforma Escola, ter seu nome global a denido por Pedro@Escola. A classe AID disponibiliza mtodos para obter o nome local (getLocalName()1 ), o e nome global (getName()) e os endereos de um agente (getAllAddresses()). Para visuc alizao destas funcionalidades, considere o cdigo exibido na Caixa de Cdigo 2.2. ca o o
import import import public

Cdigo 2.2: InfoAgentes.java o


j a d e . c o r e . Agent ; j a d e . c o r e . AID ; java . u t i l . I t e r a t o r ; c l a s s I n f o A g e n t e s extends Agent {

12

15

protected void s e t u p ( ) { System . out . p r i n t l n ( " Hello World . Eu sou um agente !" ) ; System . out . p r i n t l n ( " Todas as minhas informa ~ es : \n" + getAID ( ) ) ; co System . out . p r i n t l n ( "Meu nome local "+ getAID ( ) . getLocalName ( ) ) ; e System . out . p r i n t l n ( "Meu nome global (GUID) "+ getAID ( ) . getName ( ) ) ; e System . out . p r i n t l n ( "Meus endere os s~ o:" ) ; c a I t e r a t o r i t = getAID ( ) . g e t A l l A d d r e s s e s ( ) ; while ( i t . hasNext ( ) ) { System . out . p r i n t l n ( "- "+i t . next ( ) ) ; } } } 

18

Com a execuao da seguinte linha de comando: c java jade.Boot Ivan:InfoAgentes

Temos o seguinte resultado: Hello World. Eu sou um agente! Todas as minhas informaoes: c~ ( agent-identifier :name Ivan@lap:1099/JADE :addresses (sequence http://lap:7778/acc )) Meu nome local e Ivan Meu nome global (GUID) e Ivan@lap:1099/JADE Meus endereos s~o: c a - http://lap:7778/acc
1

A classe Agent tambm disponibiliza este mtodo. e e

2.3. Passando Informaes a um Agente co

O nome local do agente Ivan, conforme especicado na linha de comando. Uma vez e que no especicamos o nome da plataforma, JADE automaticamente atribui um nome a a esta, usando as informaes do host e da porta do container principal (no caso, o host co denominado lap e a porta do container principal 1099). Com isso, o nome global e e (GUID - Globally Unique Name) do agente Ivan@lap:1099/JADE. e Embora parea um endereo, o GUID no o endereo do agente. No caso, vemos c c a e c que o endereo do agente Ivan http://lap:7778/acc(Agent Communication Channel). c e Os endereos inclu c dos em uma AID so referentes ao MTP (Message Transport Protoa col ). Por padro, a plataforma JADE atribui um MTP HTTP ao main-container. Estes a endereos so usados na comunicaao entre agentes que esto em plataformas diferentes. c a c a Pode-se incluir endereos FTP, IIOP dentre outros. c Para designarmos um nome para a plataforma, devemos passar este nome como para metro na execuo da seguinte forma: ca java jade.Boot -name plataforma-de-teste Ivan:InfoAgentes Neste caso demos o nome de plataforma-de-teste a nossa plataforma e, com isso, ` na execuao do agente tem-se o seguinte resultado: c Hello World. Eu sou um agente! Todas as minhas informaoes: c~ ( agent-identifier :name Ivan@plataforma-de-teste:1099/JADE :addresses (sequence http://plataforma-de-teste:7778/acc )) Meu nome local e Ivan Meu nome global (GUID) e Ivan@plataforma-de-teste Meus endereos s~o: c a - http://lap:7778/acc

2.3

Passando Informaoes a um Agente c

Considere um agente comprador de livros, que deve saber quais livros ir comprar. Vamos a criar um agente em que ser poss indicar qual livro este agente ir comprar. Seu cdigo a vel a o est apresentado na Caixa de Cdigo 2.3. a o Cdigo o import j a d e . c o r e . Agent ; import j a d e . c o r e . AID ;
3

2.3: CompradorDeLivros.java

public c l a s s CompradorDeLivros extends Agent {


6

private S t r i n g l i v r o s C o m p r a r ;

2.3. Passando Informaes a um Agente co

protected void s e t u p ( ) { // imprime mensagem de BemVindo System . out . p r i n t l n ( "Ol !!! Eu sou o Agente Comprador "+ getLocalName ( ) a +" e estou pronto para comprar !" ) ; // c a p t u r a o t t u l o do l i v r o que comprar , que f o i p a s s a d o como a argumento de i n i c i a l i z a o ca Object [ ] a r g s = getArguments ( ) ; i f ( a r g s != null && a r g s . l e n g t h >0) { livrosComprar = ( String ) args [ 0 ] ; System . out . p r i n t l n ( " Pretendo comprar o livro : "+ l i v r o s C o m p r a r ) ; } else { // f i n a l i z a o a g e n t e System . out . p r i n t l n ( "Nao tenho livros para comprar !" ) ; d o D e l e t e ( ) ; // i n v o c a a e x e c u o do m todo takeDown ( ) ca e } }

12

15

18

21

24

27

protected void takeDown ( ) { System . out . p r i n t l n ( " Agente Comprador " + getAID ( ) . getName ( ) + " est finalizado " ) ; a }  }

30

Para executar o Cdigo 2.3 digitamos no prompt: o javac CompradorDeLivros.java java jade.Boot Jose:CompradorDeLivros("O-Pequeno-Principe") Com a execuao destas linhas tem-se o seguinte resultado: c Ol!!! Eu sou o Agente Comprador Jose e estou pronto para comprar! a Pretendo comprar o livro: O-Pequeno-Principe Caso no seja passado nenhum parmetro na execuao do agente, este imprimir a a a c a mensagem: Ol !!! Eu sou o Agente Comprador Jose e estou pronto para comprar! a Nao tenho livros para comprar! Agente Comprador Jose@lap:1099/JADE est finalizado a

2.4. Comportamentos

10

Observe que a frase Agente Comprador Jose@lap:1099/JADE est finalizado utia liza no cdigo o mtodo getAID().getName(), que retorna o nome global do agente. Por o e padro JADE adiciona o nmero da porta de comunicaao da plataforma (padro 1099) a u c a e e tambm adiciona a string /JADE ao nal, para indicar que trata-se de um agente JADE. e Para nalizar a execuo da plataforma pressione as teclas CTRL+C. ca

2.4

Comportamentos

Cada aao que um agente pode realizar representada como um comportamento deste c e agente. O cdigo que implementa esta funcionalidade deve estar em uma nova classe, que o deve herdar as funcionalidades da classe jade.core.behaviours.Behaviour. Uma vez implementado o cdigo referente ao comportamento, para que este seja exeo cutado necessria a invocao, no corpo de aao do agente, do mtodo addBehaviour e a ca c e pertencente ` classe Agent. Como exemplo considere a classe MeuAgente, cujo cdigo est a o a ilustrado na Caixa de Cdigo 2.4. o Cdigo 2.4: MeuAgente.java o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . Behaviour ; public c l a s s MeuAgente extends Agent {
protected void s e t u p ( ) { System . out . p r i n t l n ( "Ol , eu sou um agente ." ) ; a System . out . p r i n t l n ( " Estou disparando meu comportamento ..." ) ; addBehaviour (new MeuComportamento ( t h i s ) ) ; } } 

Quando um agente da classe MeuAgente inicializado seu mtodo setup() exee e e cutado. A linha de cdigo addBehaviour(new MeuComportamento(this)) indica a inio cializaao de um comportamento que est especicado na classe MeuComportamento. O c a parmetro this indica que o agente que executar este comportamento o prprio agente a a e o que est invocando o comportamento. a Toda classe que especica o comportamento de um agente deve possuir os seguintes mtodos: e action() - neste mtodo inclu e mos o cdigo referente ao comportamento a ser exeo cutado pelo agente; done() - este mtodo devolve um valor booleano, indicando se o comportamento foi e nalizado ou no. a A classe MeuComportamento est contida na Caixa de Cdigo 2.5. a o

2.4. Comportamentos Cdigo 2.5: MeuComportamento.java o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . Behaviour ;


3

11

public c l a s s MeuComportamento extends Behaviour { int i =0;


6

12

public MeuComportamento ( Agent a ) { super ( a ) ; } public void a c t i o n ( ) { System . out . p r i n t l n ( "* Ol Mundo ! ... Meu nome " + myAgent . a e getLocalName ( ) ) ; i=i +1; } public boolean done ( ) { // c a s o e s t e m todo r e t o r n e TRUE o comportamento s e r f i n a l i z a d o e a return i >3; } } 

15

18

O comportamento indicado nesta classe far com que sejam impressas quatro mensaa gens de texto. Neste cdigo, quando a varivel i assume um valor maior que 3, o mtodo o a e done() retorna true e a execuo do comportamento nalizada. ca e importante notar a utilizaao da varivel myAgent. Trata-se de uma varivel nativa E c a a de uma classe que herda jade.core.behaviours.Behaviour. Como um comportamento tem que ser codicado em outra classe, esta varivel oferece a capacidade de acessar todos a os mtodos e atributos do agente que est executando o comportamento. Isto justica e a a utilizao do mtodo super(a) no mtodo construtor da classe MeuComportamento. ca e e Atravs da invocaao do super(a) que indicamos o agente que ser representado pela e c e a varivel myAgent. a Observe tambm que a classe MeuComportamento.java lha da classe Behaviour e e (fazemos isto atravs do comando extends Behaviour). A mesma funcionalidade poe deria ser alcanada se esta fosse lha da classe SimpleBehaviour (e conseqentemente c u ter amos extends SimpleBehaviour). Logo, Behaviour possui a mesma funcionalidade de SimpleBehaviour, pois SimpleBehaviour uma classe-lha de Behaviour. e Aps compilar ambas as classes, podemos executar um agente: o java jade.Boot Agent1:MeuAgente O resultado desta execuo o seguinte: ca e Ol, eu sou um agente. a

2.4. Comportamentos Estou * Ol a * Ol a * Ol a * Ol a disparando Mundo! ... Mundo! ... Mundo! ... Mundo! ... meu Meu Meu Meu Meu comportamento ... nome Agent1 e nome Agent1 e nome Agent1 e nome Agent1 e

12

2.4.1

Execuo dos Comportamentos ca

Um agente pode executar vrios comportamentos concorrentemente com o uso de um a escalonador. Um comportamento executado at que seu mtodo action() chegue ao e e e m de sua execuao. O escalonador controla a execuo dos comportamentos de um c ca agente com as seguintes estruturas de dados: Uma la de comportamentos ativos; Uma la de comportamentos bloqueados. A Figura 2.1, adaptada de [Bellifemine, Caire e Greenwood 2007], ilustra a interao ca de um agente com estas las com o uso de uma anlise no ciclo de execuo de um agente. a ca A execuao de um agente na plataforma JADE constitu por trs n c e da e veis bsicos. a So eles: a 1. Inicializaao - Consiste na execuao do mtodo setup(); c c e 2. Realizao da tarefa - Representa o n de execuao dos comportamentos do agente. ca vel c O escalonador seleciona o primeiro comportamento da la e executa seu mtodo e action(). Aps a execuao deste mtodo, verica-se a nalizaao do comportao c e c mento no mtodo done(). Caso este comportamento ainda no esteja nalizado, o e a escalonador captura o prximo comportamento da lista de comportamentos ativos, o colocando este comportamento ainda no nalizado no nal da la, para ser postea riormente executado, ou seja, este comportamento bloqueado at que chegue sua e e vez de ser executado. Quando um comportamento nalizado, removido da lista e e de comportamentos ativos e enviado para a lista de comportamentos bloqueados; 3. Limpeza e nalizao - Consiste na execuao de mtodos espec ca c e cos para nalizao ca do agente (e.g takeDown()).

2.4.2

Bloqueando Comportamentos

Com o uso do mtodo block() poss e e vel bloquear um comportamento de um agente. Com a execuo deste mtodo, o comportamento em execuo movido para a lista ca e ca e

2.4. Comportamentos

13

Figura 2.1: Ciclo de Execuao de um Agente. c

de comportamentos bloqueados at que um evento ocorra. Este mtodo pode ser util e e na recepao de mensagens, por exemplo. No caso deste exemplo, um comportamento c espec co para recepo de mensagens ca aguardando ser ativado quando uma nova ca mensagem chegar ao agente. Um objeto da classe Behaviour tambm pode se bloquear durante uma certa quane tidade de tempo, denida na execuao do mtodo block(). E importante enfatizar que c e este mtodo no igual ao sleep() de uma thread. O mtodo block() no pra a exee a e e a a cuo de um comportamento no momento em que invocado. Ele aguarda a nalizaao ca e c do mtodo action(). Caso este comportamento ainda no esteja nalizado (done() ree a torna false), este colocado na la de comportamentos bloqueados. Como j foi dito, e a a permanncia deste comportamento na la de comportamentos bloqueados pode ser por e um determinado tempo, ou at que um evento ocorra. e Como exemplo de utilizao do block() considere um agente que imprime na tela seu ca nome local por 10 vezes, sendo que ele possui um intervalo entre as impresses na tela de o

2.4. Comportamentos

14

5 segundos. O cdigo deste agente est contido nas Caixas de Cdigo 2.6 e 2.7. o a o Cdigo 2.6: AgenteImpressor.java o import j a d e . c o r e . Agent ; public c l a s s A g e n t e I m p r e s s o r extends Agent {
3

protected void s e t u p ( ) {
6

System . out . p r i n t l n ( "Ol ! Eu sou um agente impressor !" ) ; a System . out . p r i n t l n ( "# Vou executar meu comportamento " ) ; addBehaviour (new ImprimeFrase ( this , 5 0 0 0 ) ) ; } } 

Cdigo 2.7: ImprimeFrase.java o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . Behaviour ;


3

public c l a s s ImprimeFrase extends Behaviour { int numExecu o =1; ca long d e l a y ; long t e m p o I n i c i a l = System . c u r r e n t T i m e M i l l i s ( ) ; public ImprimeFrase ( Agent a , long d e l a y ) { super ( a ) ; this . delay = delay ; } public void a c t i o n ( ) { block ( delay ) ; System . out . p r i n t l n ( "# Tempo " + ( System . c u r r e n t T i m e M i l l i s ( ) t e m p o I n i c i a l ) + ": Meu nome " + myAgent . getLocalName ( ) ) ; e numExecu o = numExecu o +1; ca ca } public boolean done ( ) { return numExecu o >10; ca }

12

15

18

21

24

public int onEnd ( ) {


27

System . out . p r i n t l n ( myAgent . getLocalName ( ) + ": Meu comportamento foi finalizado ! At mais ..." ) ; e

2.4. Comportamentos
return 0 ; }}

15

Na classe AgenteImpressor temos um agente que executa seu comportamento que est implementado na classe ImprimeFrase. a A linha de cdigo addBehaviour(new ImprimeFrase(this,5000)) passa os parmeo a tros necessrios para execuo do comportamento. O mtodo block recebe valores do a ca e tipo long, representados em milisegundos. Isto justica a utilizao do valor 5000, para ca indicar que o tempo entre cada frase impressa ser de 5 segundos. a Observe que o comando block() est no in a cio do bloco de comandos do mtodo e action() da classe ImprimeFrase. Isto no indica que o block() ser executado primeiro. a a Este ser executado ao m do bloco de comandos do mtodo action(). a e A classe ImprimeFrase tambm nos revela um novo mtodo: trata-se do mtodo e e e onEnd(). Este mtodo retorna um valor inteiro que representa um valor de nalizao e ca para o comportamento. Este mtodo invocado aps o comportamento estar conclu e e e o do aps este ser movido para a lista de comportamentos bloqueados, pois poss reiniciar o e vel poss este comportamento com a utilizaao do mtodo reset(). E c e vel, tambm, utilizar o e mtodo onStart() que acionado no in da execuao do comportamento. e e cio c Com a execuao do agente teste temos a seguinte sa c da:

java jade.Boot teste:AgenteImpressor ... Ol! Eu sou um agente impressor! a # Vou executar meu comportamento # Tempo 0: Meu nome e teste # Tempo 5015: Meu nome teste e # Tempo 10031: Meu nome e teste # Tempo 15046: Meu nome e teste # Tempo 20062: Meu nome e teste # Tempo 25078: Meu nome e teste # Tempo 30093: Meu nome e teste # Tempo 35109: Meu nome e teste # Tempo 40125: Meu nome e teste # Tempo 45140: Meu nome e teste teste: Meu comportamento foi finalizado! At mais... e Vamos aproveitar este momento para abordar o conceito de concorrncia entre agene tes. Cada agente JADE uma thread. Isto signica que a execuo destes agentes ser e ca a escalonada. Vamos testar a seguinte aplicao, iniciando trs agentes ao mesmo tempo na ca e

2.4. Comportamentos

16

plataforma. Cada agente passar como argumento seu tempo de impresso de mensagem a a na tela. O cdigo referente ` classe de agente que vamos utilizar est na Caixa de Cdigo o a a o 2.8. O comportamento dos agentes ser o mesmo descrito na Caixa de Cdigo 2.7. a o Cdigo o import j a d e . c o r e . Agent ; import j a d e . c o r e . ;
3

2.8: AgenteImpressorArgs.java

public c l a s s A g e n t e I m p r e s s o r A r g s extends Agent {


6

protected void s e t u p ( ) { Object [ ] a r g s = getArguments ( ) ; i f ( a r g s != null && a r g s . l e n g t h >0) { long v a l o r = Long . parseLong ( ( S t r i n g ) a r g s [ 0 ] ) ; System . out . p r i n t l n ( "Ol ! Eu sou um agente impressor !" ) ; a System . out . p r i n t l n ( "# Vou executar meu comportamento " ) ; addBehaviour (new ImprimeFrase ( this , v a l o r ) ) ; } else System . out . p r i n t l n ( "Voc^ n~ o passou argumentos " ) ; e a

12

15

18

}
21

} 

A linha de execuo no prompt ser a seguinte: ca a java jade.Boot Andre:AgenteImpressorArgs(200) Maria:AgenteImpressorArgs(400) Paulo:AgenteImpressorArgs(600) Isto implica que o agente Andre executar seu comportamento a cada 0.2 seg., o agente a Maria a cada 0,4 seg. e o agente Paulo a cada 0.6 seg. O resultado obtido o seguinte: e Ol! Eu sou um agente impressor! a # Vou executar meu comportamento # Tempo 0: Meu nome e Andre Ol! Eu sou um agente impressor! a # Vou executar meu comportamento # Tempo 0: Meu nome e Maria Ol! Eu sou um agente impressor! a # Vou executar meu comportamento # Tempo 0: Meu nome e Paulo # Tempo 203: Meu nome e Andre

2.5. Comportamentos Pr-Denidos e # Tempo 406: Meu nome e Maria # Tempo 406: Meu nome e Andre # Tempo 610: Meu nome e Paulo # Tempo 610: Meu nome e Andre # Tempo 813: Meu nome e Maria # Tempo 813: Meu nome e Andre # Tempo 1016: Meu nome Andre e # Tempo 1219: Meu nome Paulo e # Tempo 1219: Meu nome Maria e # Tempo 1219: Meu nome Andre e # Tempo 1422: Meu nome Andre e # Tempo 1625: Meu nome Maria e # Tempo 1625: Meu nome Andre e # Tempo 1828: Meu nome Paulo e # Tempo 1828: Meu nome Andre e Andre: Meu comportamento foi finalizado! At mais... e # Tempo 2031: Meu nome Maria e # Tempo 2438: Meu nome Paulo e # Tempo 2438: Meu nome Maria e # Tempo 2844: Meu nome Maria e # Tempo 3047: Meu nome Paulo e # Tempo 3250: Meu nome Maria e # Tempo 3657: Meu nome Paulo e # Tempo 3656: Meu nome Maria e Maria: Meu comportamento foi finalizado! At mais... e # Tempo 4266: Meu nome Paulo e # Tempo 4875: Meu nome Paulo e # Tempo 5485: Meu nome Paulo e Paulo: Meu comportamento foi finalizado! At mais... e

17

2.5

Comportamentos Pr-Denidos e

JADE conta com uma srie de comportamentos pr-denidos que auxiliam o desenvolvedor e e na construo de sistemas multiagentes. Pode-se agrupar os comportamentos oferecidos ca por JADE em quatro grupos: 1. Comportamentos one-shot: tipos de comportamentos que se executam de maneira quase instantnea, e apenas uma vez; a 2. Comportamentos c clicos: so aqueles comportamentos que nunca nalizam. O a

2.5. Comportamentos Pr-Denidos e

18

mtodo action() deste comportamento sempre executado pois done() sempre e e retorna false; 3. Comportamentos temporais: so comportamentos que incluem uma relaao tempoa c ral em sua execuao; c 4. Comportamentos compostos: so comportamentos que modelam situaoes espec a c cas, tais como comportamentos seqenciais, paralelos, etc. u A seguir tem-se uma breve introduao aos tipos de comportamentos pr-denidos. Os c e exemplos mais completos destes comportamentos so mostrados no decorrer deste manual, a juntamente com o avano das funcionalidades dos agentes e dos servios oferecidos pela c c plataforma.

2.5.1

Comportamentos One-shot

Neste comportamento o mtodo done() sempre retorna o valor true, fazendo com que e seja executado apenas uma vez. Para utilizaao deste comportamento deve-se importar a c classe jade.core.behaviours.OneShotBehaviour. A estrutura da implementao deste ca comportamento d-se conforme ilustrado na Caixa de Cdigo 2.9. Em seguida, na Figura a o 2.10, ilustra-se o cdigo de agente invocando este comportamento. o Cdigo 2.9: Exemplo OneShot Behaviour o import j a d e . c o r e . b e h a v i o u r s . OneShotBehaviour ; public c l a s s ComportamentoOneShot extends OneShotBehaviour { public void a c t i o n ( ) { // c d i g o a s e r e x e c u t a d o o } }  Cdigo 2.10: AgenteComportamentoOneShot.java o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . ;
3

public c l a s s AgenteComportamentoOneShot extends Agent { protected void s e t u p ( ) { addBehaviour (new ComportamentoOneShot ( t h i s ) ) ; } } 

2.5. Comportamentos Pr-Denidos e

19

2.5.2

Comportamentos C clicos

Neste comportamento o mtodo done() sempre devolve false. Este comportamento se e mantm ativo enquanto o agente estiver ativo na plataforma. Para utilizaao deste come c portamento deve-se importar a classe jade.core.behaviours.CyclicBehaviour. Sua estrutura de implementaao est ilustrada na Caixa de Cdigo 2.11. Em seguida, na c a o Figura 2.12, ilustra-se o cdigo de agente invocando este comportamento. o Cdigo 2.11: Exemplo Cyclic Behaviour o import j a d e . c o r e . b e h a v i o u r s . C y c l i c B e h a v i o u r ; public c l a s s ComportamentoCiclico extends C y c l i c B e h a v i o u r { public void a c t i o n ( ) { // c d i g o a s e r e x e c u t a d o o } }  Cdigo 2.12: AgenteComportamentoCiclico.java o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . ;
3

public c l a s s AgenteComportamentoCiclico extends Agent { protected void s e t u p ( ) { addBehaviour (new ComportamentoCiclico ( this , 3 0 0 ) ) ; } } 

2.5.3

Comportamentos Temporais

Neste tipo de comportamentos encontram-se os comportamentos WakerBehaviour e TickerBehaviour. Ambos possuem uma estreita relaao com o tempo durante sua execuao. c c Aos serem invocados, ambos aguardam at que se tenha cumprido um tempo denido e (time-out) para serem executados. A diferena que o WakerBehaviour executa apenas c e uma unica vez, enquanto que o TickerBehaviour realiza um comportamento c clico. Como exemplo de um comportamento WakerBehaviour, considere um agente que executa seu comportamento aps 1 minuto da invocaao do mesmo e depois no mais o c a e executado, conforme consta na Caixa de Cdigo 2.13. Para utilizao deste comportao ca mento deve-se importar a classe jade.core.behaviours.WakerBehaviour. O mtodo e 2 que executa a aao do agente do tipo WakerBehaviour o mtodo onWake() . Este c e e mtodo executado logo aps o time-out. e e o
Pode-se tambm utilizar o mtodo void handleElapsedTimeout(), cuja funcionalidade a mesma e e e do onWake().
2

2.5. Comportamentos Pr-Denidos e Cdigo 2.13: Exemplo Waker Behaviour o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . WakerBehaviour ; public c l a s s Waker extends Agent { protected void s e t u p ( ) { System . out . p r i n t l n ( " Adicionando waker behaviour " ) ;
addBehaviour (new WakerBehaviour ( this , 1 0 0 0 0 ) { protected void onWake ( ) { // r e a l i z a o p e r a o X ca } }) ;
12

20

} } 

O TickerBehaviour possui seus mtodos action() e done() pr-implementados, base e tando para o desenvolvedor implementar o mtodo onTick(). Um comportamento ticker e nunca termina ao menos que seja removido pelos mtodos removeBehaviour() ou stop(). e A Caixa de Cdigo 2.14 ilustra um agente que executa um TickerBehaviour, exibindo o a cada segundo o nmero de seu ciclo (tick ). Para utilizaao deste comportamento deve-se u c importar a classe jade.core.behaviours.TickerBehaviour. E poss obter o nmero vel u de ciclos atravs do mtodo getTickCount(), que retorna um valor inteiro que representa e e o ciclo do agente. Observe que aps 5 ciclos o comportamento interrompido com o o e mtodo stop(). Este tambm pode ser reiniciado com o o mtodo reset(), fazendo e e e com que o comportamento fosse novamente iniciado e o nmero de ciclos executados seja u zerado. Cdigo 2.14: Exemplo Ticker Behaviour o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . T i c k e r B e h a v i o u r ; public c l a s s T i c k e r extends Agent { protected void s e t u p ( ) { System . out . p r i n t l n ( " Adicionando TickerBehaviour " ) ;
addBehaviour (new T i c k e r B e h a v i o u r ( this , 1 0 0 0 ) { protected void onTick ( ) { i f ( getTickCount ( ) >5){ stop () ; } else // g e t T i c k C o u n t ( ) r e t o r n a o n mero de e x e c u e s u co // do comportamento . System . out . p r i n t l n ( " Estou realizando meu " + getTickCount ( ) + " tick" ) ; } }) ;

12

15

2.5. Comportamentos Pr-Denidos e


}
18

21

} 

Tem-se como resultado da execuao deste agente: c

Adicionando TickerBehaviour Estou realizando meu 1 tick Estou realizando meu 2 tick Estou realizando meu 3 tick Estou realizando meu 4 tick Estou realizando meu 5 tick

2.5.4

Comportamentos Compostos

Comportamentos compostos so aqueles formados por sub-comportamentos. A pol a tica de seleao de comportamentos lhos est implementada em trs subclasses: SequencialBehac a e viour, ParallelBehaviour e FSMBehaviour. Os trs tipos de comportamentos compostos e sero apresentados nas prximas sees. a o co 2.5.4.1 SequencialBehaviour

Este comportamento executa seus sub-comportamentos de maneira seqencial e termina u quando todos seus sub-comportamentos estiverem conclu dos. A pol tica de escalonamento dos sub-comportamentos est descrita a seguir. O comportamento inicia execua tando seu primeiro sub-comportamento. Quando este sub-comportamento nalizado e (isto , seu mtodo done() retorna true), o segundo sub-comportamento executado e e e e assim por diante. Quando o ultimo sub-comportamento nalizado, o comportamento e composto seqencial nalizado. u e Os sub-comportamentos so adicionados ao comportamento composto com o mtodo a e addSubBehaviour(). A ordem em que estes sub-comportamentos so adicionados indica a a ordem de execuo dos mesmos. Na Caixa de Cdigo 2.15 tem-se um exemplo de um ca o agente que executa seqencialmente trs comportamentos. u e Cdigo 2.15: o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . ; ;
3

AgenteSequencial.java

public c l a s s A g e n t e S e q u e n c i a l extends Agent {


6

protected void s e t u p ( ) {

2.5. Comportamentos Pr-Denidos e

22

//mensagem de i n i c i a l i z a o do a g e n t e ca System . out . p r i n t l n ( "Ol ! Meu nome " + getLocalName ( ) ) ; a e System . out . p r i n t l n ( "Vou executar tr^ s comportamentos :" ) ; e // criamos um o b j e t o da c l a s s e S e q u e n t i a l B e h a v i o u r S e q u e n t i a l B e h a v i o u r comportamento = new S e q u e n t i a l B e h a v i o u r ( t h i s ) { public int onEnd ( ) { myAgent . d o D e l e t e ( ) ; return 0 ; }

12

15

18

21

24

}; // adicionamos seu p r i m e i r o comportamento comportamento . addSubBehaviour (new WakerBehaviour ( this , 5 0 0 ) { long t 0 = System . c u r r e n t T i m e M i l l i s ( ) ; protected void onWake ( ) { System . out . p r i n t l n ( ( System . c u r r e n t T i m e M i l l i s ( ) t 0 ) +": Executei meu primeiro comportamento ap s meio segundo !" ) o ; } }) ; // adicionamos seu segundo comportamento comportamento . addSubBehaviour (new OneShotBehaviour ( t h i s ) {

27

30

public void a c t i o n ( ) { System . out . p r i n t l n ( " Executei meu segundo comportamento " ) ;
33

} }) ;

36

39

42

45

// adicionamos seu t e r c e i r o comportamento comportamento . addSubBehaviour (new T i c k e r B e h a v i o u r ( this , 7 0 0 ) { int e x e c =0; long t 1 = System . c u r r e n t T i m e M i l l i s ( ) ; protected void onTick ( ) { i f ( e x e c ==3) s t o p ( ) ; else { System . out . p r i n t l n ( ( System . c u r r e n t T i m e M i l l i s ( )t 1 )+ ": Estou executando meu terceiro comportamento " ) ; e x e c ++; } } }) ; // acionamos sua e x e c u o ; ca addBehaviour ( comportamento ) ;

48

2.5. Comportamentos Pr-Denidos e

23

51

}
54

protected void takeDown ( ) { System . out . p r i n t l n ( "Fui finalizado com sucesso " ) ;
57

} } 

Este agente adiciona trs sub-comportamentos para seu comportamento composto. e Podemos ter estes trs comportamentos em classes separadas e apenas adicion-las ao e a comportamento composto. Executando no prompt a linha java jade.Boot Nick:AgenteSequencial, tem-se a seguinte execuo: ca Ol! Meu nome e Nick a Vou executar tr^s comportamentos: e 515: Executei meu primeiro comportamento aps meio segundo! o Executei meu segundo comportamento 1218: Estou executando meu terceiro comportamento 1921: Estou executando meu terceiro comportamento 2625: Estou executando meu terceiro comportamento Fui finalizado com sucesso 2.5.4.2 ParallelBehaviour

O ParallelBehaviours implementa um comportamento composto que escalona seus subcomportamentos em paralelo. Toda vez que o mtodo action() do comportamento pae ralelo executado, o mtodo action() de seus sub-comportamentos executado. e e e Um comportamento paralelo pode ser instru para ser nalizado quando todos os do comportamentos paralelos estiverem completos, ou quando algum deles nalizado. Alm e e disto, poss denir a nalizao do comportamento composto para quando um certo e vel ca nmero n de sub-comportamentos estiverem nalizados. Essas condies so denidas u co a no construtor da classe, passando como parmetro as constantes when all, quando for a todos, when any, quando for algum, ou um valor inteiro que especica o nmero de u sub-comportamentos que so necessrios para nalizar o ParallelBehaviour. a a A seguir tem-se um exemplo de um agente com comportamento paralelo. O cdigo o deste agente est na Caixa de Cdigo 2.16. a o Cdigo 2.16: o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . ; AgenteCompParalelo.java

2.5. Comportamentos Pr-Denidos e

24

public c l a s s AgenteCompParalelo extends Agent {


6

protected void s e t u p ( ) { System . out . p r i n t l n ( "Ol ! Eu sou o agente " + getLocalName ( ) ) ; a System . out . p r i n t l n ( "Vou executar tr^ s comportamentos concorrentemente " ) ; e P a r a l l e l B e h a v i o u r s = new P a r a l l e l B e h a v i o u r ( this ,WHEN ALL) {

12

15

public int onEnd ( ) { System . out . p r i n t l n ( " Comportamento Composto Finalizado com Sucesso !" ) ; return 0 ; } }; addBehaviour ( s ) ; s . addSubBehaviour (new S im pl eB e ha vio u r ( t h i s ) { int qtd =1; public void a c t i o n ( ) { System . out . p r i n t l n ( " Comportamento 1: Executando pela " + qtd + " vez" ) ; qtd = qtd +1; }

18

21

24

27

30

33

36

public boolean done ( ) { i f ( qtd==4) { System . out . p r i n t l n ( " Comportamento 1 - Finalizado " ) ; return true ; } else return f a l s e ; } }) ; s . addSubBehaviour (new S im pl eB e ha vio u r ( t h i s ) { int qtd =1; public void a c t i o n ( ) { System . out . p r i n t l n ( " Comportamento 2: Executando pela " + qtd + " vez" ) ; qtd = qtd +1; }

39

42

45

2.5. Comportamentos Pr-Denidos e

25

48

51

54

public boolean done ( ) { i f ( qtd==8) { System . out . p r i n t l n ( " Comportamento 2 - Finalizado " ) ; return true ; } else return f a l s e ; } }) ; s . addSubBehaviour (new S im pl eB e ha vio u r ( t h i s ) { int qtd =1;

57

60

63

public void a c t i o n ( ) { System . out . p r i n t l n ( " Comportamento 3: Executando pela " + qtd + " vez" ) ; qtd = qtd +1; }

66

69

72

75

public boolean done ( ) { i f ( qtd==10) { System . out . p r i n t l n ( " Comportamento 3 - Finalizado " ) ; return true ; } else return f a l s e ; } }) ; }

78

} 

Executando a linha de comando java jade.Boot Azul:AgenteCompParalelo tem-se o seguinte resultado: Ol! Eu sou o agente Azul a Vou executar tr^s comportamentos e Comportamento 1: Executando pela Comportamento 2: Executando pela Comportamento 3: Executando pela Comportamento 1: Executando pela Comportamento 2: Executando pela Comportamento 3: Executando pela Comportamento 1: Executando pela

concorrentemente 1 vez 1 vez 1 vez 2 vez 2 vez 2 vez 3 vez

2.5. Comportamentos Pr-Denidos e Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento Comportamento 1 - Finalizado 3: Executando pela 3 vez 2: Executando pela 3 vez 3: Executando pela 4 vez 2: Executando pela 4 vez 3: Executando pela 5 vez 2: Executando pela 5 vez 3: Executando pela 6 vez 2: Executando pela 6 vez 3: Executando pela 7 vez 2: Executando pela 7 vez 2 - Finalizado 3: Executando pela 8 vez 3: Executando pela 9 vez 3 - Finalizado Composto Finalizado com Sucesso!

26

Observe na linha 11 que o comando ParallelBehaviour s = new ParallelBehaviour (this, ParallelBehaviour.WHEN_ALL) constri o objeto s da classe ParallelBehaviour. o Em seu construtor passamos o parmetro inteiro ParallelBehaviour.WHEN_ALL. Este a parmetro indica que aps todos os sub-comportamentos estarem conclu a o dos, o comportamento composto ser nalizado, ativando seu mtodo onEnd(). a e Vamos mudar este parmetro para ParallelBehaviour.WHEN_ANY. Isto indica que a quando qualquer um dos sub-comportamentos for nalizado, o comportamento composto nalizado. Executando novamente o agente obtemos o seguinte resultado: e Ol! Eu sou o agente Azul a Vou executar tr^s comportamentos concorrentemente e Comportamento 1: Executando pela 1 vez Comportamento 2: Executando pela 1 vez Comportamento 3: Executando pela 1 vez Comportamento 1: Executando pela 2 vez Comportamento 2: Executando pela 2 vez Comportamento 3: Executando pela 2 vez Comportamento 1: Executando pela 3 vez Comportamento 1 - Finalizado Comportamento Composto Finalizado com Sucesso! Como prev amos, o comportamento composto foi nalizado aps a nalizao de um o ca dos sub-comportamentos. Podemos tambm denir que o comportamento composto e nalize aps um certo nmero de nalizaes de seus sub-comportamentos. Podemos o u co

2.5. Comportamentos Pr-Denidos e

27

utilizar como parmetro um valor inteiro, por exemplo: ParallelBehaviour s = new a ParallelBehaviour(this, 2), onde 2 indica que aps dois sub-comportamentos serem o nalizados o comportamento composto ser nalizado. O resultado da execuao do agente a c com esse novo parmetro de comportamento exibido a seguir: a e Ol! Eu sou o agente Azul a Vou executar tr^s comportamentos concorrentemente e Comportamento 1: Executando pela 1 vez Comportamento 2: Executando pela 1 vez Comportamento 3: Executando pela 1 vez Comportamento 1: Executando pela 2 vez Comportamento 2: Executando pela 2 vez Comportamento 3: Executando pela 2 vez Comportamento 1: Executando pela 3 vez Comportamento 1 - Finalizado Comportamento 3: Executando pela 3 vez Comportamento 2: Executando pela 3 vez Comportamento 3: Executando pela 4 vez Comportamento 2: Executando pela 4 vez Comportamento 3: Executando pela 5 vez Comportamento 2: Executando pela 5 vez Comportamento 3: Executando pela 6 vez Comportamento 2: Executando pela 6 vez Comportamento 3: Executando pela 7 vez Comportamento 2: Executando pela 7 vez Comportamento 2 - Finalizado Comportamento Composto Finalizado com Sucesso!

2.5.4.3

FSMBehaviour

Este comportamento baseado no escalonamento por uma mquina nita de estados e a (Finite State Machine). O FSMBehaviour executa cada sub-comportamento de acordo com uma mquina de estados nitos denido pelo usurio. Mais especicamente, cada a a sub-comportamento representa um estado denido na mquina de estados nitos. Ela a fornece mtodos para registrar estados (sub-comportamentos) e transioes que denem e c como dar-se- o escalonamento dos sub-comportamentos. Os passos bsicos para se denir a a um FSMBehaviour so: a 1. Registrar um comportamento unico como estado inicial, passando como parmetros a o comportamento e uma String que nomeia este estado. Para isto utiliza-se o mtodo e

2.5. Comportamentos Pr-Denidos e registerFirstState();

28

2. Registrar um ou mais comportamentos como estados nais, utilizando o mtodo e registerLastState(); 3. Registrar um ou mais comportamentos como estados intermedirios utilizando o a mtodo registerState(); e 4. Para cada estado, registrar as transioes deste com os outros estados utilizando o c mtodo registerTransition(). Por exemplo, suponha que voc tenha um estado e e denido como X e outro estado denido como Y e voc deseja informar que a transiao e c ser feita do estado X para o Y, quando o estado X retornar o valor 1. O mtodo a e seria denido como registerTransition(X,Y,1). Considere um agente que realiza um determinado comportamento x. Ao nal deste comportamento vericada se sua operao foi conclu e ca da. Caso esta operaao no seja c a conclu da, um comportamento z efetuado. Ao trmino do comportamento z, o compore e tamento x executado novamente e toda a vericao ocorre novamente. Na execuao e ca c em que o comportamento x estiver conclu do, ser invocado o ultimo comportamento do a agente, o comportamento y. Este algoritmo est ilustrado na Figura 2.2 e o cdigo deste a o agente encontra-se Caixa de Cdigo 2.17. o

Figura 2.2: Exemplo de Mquina de Estado Finito. a

2.5. Comportamentos Pr-Denidos e Cdigo 2.17: AgenteFSM.java o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . ; public c l a s s AgenteFSM extends Agent {
protected void s e t u p ( ) {
6

29

FSMBehaviour compFSM = new FSMBehaviour ( t h i s ) {


9

12

public int onEnd ( ) { System . out . p r i n t l n ( " Comportamento FSM finalizado com sucesso !" ) ; return 0 ; } }; // r e g i s t r a m o s o p r i m e i r o comportamento X compFSM . r e g i s t e r F i r s t S t a t e (new OneShotBehaviour ( t h i s ) { int c =0; public void a c t i o n ( ) { System . out . p r i n t l n ( " Executando Comportamento X" ) ; c++; }

15

18

21

24

27

public int onEnd ( ) { return ( c >4? 1 : 0 ) ; } } , "X" ) ; // r e g i s t r a m o s o u t r o e s t a d o Z compFSM . r e g i s t e r S t a t e (new OneShotBehaviour ( t h i s ) {

30

33

public void a c t i o n ( ) { System . out . p r i n t l n ( " Executando Comportamento Z" ) ;


36

} public int onEnd ( ) { return 2 ; } } , "Z" ) ;

39

42

// r e g i s t r a m o s o u l t i m o e s t a d o Y compFSM . r e g i s t e r L a s t S t a t e (new OneShotBehaviour ( t h i s ) {


45

2.5. Comportamentos Pr-Denidos e

30

48

public void a c t i o n ( ) { System . out . p r i n t l n ( " Executando meu ltimo comportamento ." ) ; u } } , "Y" ) ; // d e f i n i m o s as t r a n s i e s co compFSM . r e g i s t e r T r a n s i t i o n ( "X" , "Z" , 0 ) ; do X r e t o r n e 0 compFSM . r e g i s t e r T r a n s i t i o n ( "X" , "Y" , 1 ) ; do X r e t o r n e 1

51

//X > Z , c a s o onEnd ( ) //X > Y, c a s o onEnd ( )

54

57

// d e f i n i m o s uma t r a n s i o padr o ( n o importa t i p o de r e t o r n o ) ca a a //como a m quina f i n i t a , temos que z e r a r os e s t a d o s X e Z > new a e S t r i n g [ ] { X , Z} compFSM . r e g i s t e r D e f a u l t T r a n s i t i o n ( "Z" , "X" , new S t r i n g [ ] { "X" , "Z" } ) ; //Podemos tambm r e g i s t r a r uma t r a n s i o quando o e s t a d o Z r e t o r n a r e ca 2 //compFSM . r e g i s t e r T r a n s i t i o n ( Z , X , 2) ; // acionamos o comportamento addBehaviour (compFSM) ;

60

63

} }

Ao executarmos java jade.Boot Caio:AgenteFSM obtemos o seguinte resultado: Executando Comportamento X Executando Comportamento Z Executando Comportamento X Executando Comportamento Z Executando Comportamento X Executando Comportamento Z Executando Comportamento X Executando Comportamento Z Executando Comportamento X Executando meu ltimo comportamento. u Comportamento FSM finalizado com sucesso! Observe que o comportamento X foi executado 5 vezes e ao nal de cada execuao o c comportamento Z era invocado. Quando c>4, a execuao de X estava completa e com isto, c o ultimo comportamento foi invocado. Observe no cdigo deste agente que denimos um o estado com o mtodo registerState(Comportamento, Nome do Comportamento). As e transies denimos com registerTransition(Origem, Destino, Retorno da Origem). co O mtodo registerDefaultTransition() dene uma transiao padro, ou seja, uma e c a

2.5. Comportamentos Pr-Denidos e

31

transio que ocorre sempre de um estado para o outro independente do retorno obtido ca na execuao do estado de origem. c importante enfatizar que a linha de cdigo compFSM.registerDefaultTransition("Z", E o "X", new String[]{"X", "Z"}) registra uma transiao padro entre Z e X, mas como c a ambos estados j foram executados e como so comportamentos one-shot s poderiam a a o executar uma vez. Por isto, temos o argumento new String[]{"X", "Z"} zerando as informaes sobre estes estados, possibilitando que possam ser novamente executados. co

Cap tulo 3 Comunicao entre Agentes ca


A comunicao entre agentes fundamental para a execuao de sistemas multiagentes. ca e c Ela determina o comportamento em uma sociedade, permitindo que um agente no seja a apenas um programa que executa seus comportamentos, mas tambm um programa que e recebe e envia pedidos aos demais agentes.

3.1

Envio e Recebimento de Mensagens

A troca de mensagens na plataforma JADE realiza-se mediante mensagens FIPA-ACL. JADE disponibiliza um mecanismo ass ncrono de mensagens: cada agente possui uma la de mensagens (caixa de entrada), onde este agente decide o momento de ler estas mensagens. No momento desejado pelo agente este pode ler apenas a primeira mensagem, ou ler as mensagens que satisfazem algum critrio. e As mensagens trocadas so instanciadas da classe jade.lang.acl.ACLMessage. A a seguir apresenta-se como os agentes podem enviar e receber estas mensagens.

3.1.1

Classe ACLMessage

A classe ACLMessage disponibiliza uma srie de mtodos para manipulaao das mensagens. e e c Dentre os mtodos mais utilizados cita-se: e setPerformative(int): recebe como parmetro uma constante que representa o a ato comunicativo da mensagem. Por exemplo, uma mensagem msg que tenha o ato agree ser escrita como: msg.setPerformative(ACLMessage.AGREE). Os cdigos a o das performatives esto contidos na Tabela 3.1; a getPerformative(): devolve um inteiro equivalente ` constante que representa o a ato comunicativo da mensagem;

32

3.1. Envio e Recebimento de Mensagens

33

Tabela 3.1: Valores Inteiros das Performatives.

createReply(): cria uma mensagem de resposta para uma mensagem recebida, capturando automaticamente alguns campos tais como: receiver, conversation-id, etc; addReceiver(AID): recebe como parmetro um objeto AID (Agent Identier ) e o a adiciona a lista de receptores; ` getAllReceiver(): devolve um objeto iterator contendo a lista de receptores; setContent(String): recebe como parmetro uma String e a coloca como contedo a u da mensagem; getContent(): devolve o contedo da mensagem; u setContentObject(Serializable s): recebe como parmetro um objeto de uma a classe que implementa serializao. Por meio deste mtodo poss ca e e vel transmitir objetos como contedos das mensagens; u getContentObject(): devolve o objeto que est no contedo da mensagem. a u

3.1.2

Enviar uma Mensagem

Existem alguns passos a serem seguidos para envio de mensagens. So eles: a 1. Crie um objeto ACLMessage; 2. Use os mtodos dispon e veis para preencher os campos necessrios (contedo, ontoa u logia, receptor, etc);

3.1. Envio e Recebimento de Mensagens

34

3. Invoque o mtodo send() da classe Agent. Este mtodo recebe como parmetro e e a um objeto ACLMessage e adiciona automaticamente o campo do remetente com a identicaao do agente, e envia a mensagem aos destinatrios. c a Por exemplo, considere que desejamos enviar a seguinte mensagem: (QUERY-IF :receiver (set (agent-identifier :name pcseller) ) :content "(pc-offer (mb 256) (processor celeron) (price ?p))" :language Jess :ontology PC-ontology ) Esta mensagem de exemplo representa um pedido de um agente para o outro, onde o solicitante deseja obter o preo (que ser armazenado na varivel p) de um computador c a a com processador Celeron e 256 MB de memria. Para o envio desta mensagem escreva o o cdigo contido na Caixa de Cdigo 3.1. o o Cdigo 3.1: Envio de Mensagem o ACLMessage msg = new ACLMessage ( ACLMessage . QUERY IF) ; msg . s e t O n t o l o g y ( "PC - ontology " ) ; msg . setL ang uag e ( "Jess" ) ; msg . a d d R e c e i v e r (new AID( " pcseller " , AID .ISLOCALNAME) ; msg . s e t C o n t e n t ( "(pc - offer (mb 256) ( processor celeron ) ( price ?p))" ) ; send ( msg ) ;  Observe que utilizamos o mtodo addReceiver() pois podemos adicionar vrios ree a ceptores. Quando sabemos o nome de um agente e queremos que ele seja o receptor da mensagem devemos criar um objeto da classe AID. Um objeto da classe AID crie ado passando as seguintes informaes: AID agente1 = new AID("Nome do Agente", co AID.ISLOCALNAME), onde o segundo parmetro indica que o nome que estamos passando a no se trata do nome global do agente, mas sim de seu nome local. a

3.1.3

Receber uma Mensagem

Para receber uma mensagem deve-se utilizar o mtodo receive() da classe Agent. Este e mtodo captura a primeira mensagem da la de mensagens (se no houver mensagens, o e a mtodo retorna null). Na Caixa de Cdigo 3.2 tem-se um agente que imprime todas as e o mensagens que recebe.

3.1. Envio e Recebimento de Mensagens Cdigo 3.2: Receiver.java o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . C y c l i c B e h a v i o u r ; import j a d e . l a n g . a c l . ACLMessage ;

35

public c l a s s R e c e i v e r extends Agent { protected void s e t u p ( ) { addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) { public void a c t i o n ( ) { ACLMessage msg = r e c e i v e ( ) ; i f ( msg!= null ) System . out . p r i n t l n ( " - " + myAgent . getLocalName ( ) + " <- " + msg . g e t C o n t e n t ( ) ) ; // i n t e r r o m p e e s t e comportamento a t que c h e g u e uma nova mensagem e block () ; } }) ; } } 

12

15

18

Observe o uso do comando block() sem um argumento de time-out. Este mtodo e coloca o comportamento na lista de comportamentos bloqueados at que uma nova mene sagem chegue ao agente. Se no invocamos este mtodo, o comportamento car em um a e a looping e usar muito a CPU. a

3.1.4

Exemplo de Troca de Mensagens

Considere a situaao representada na Figura 3.1. Nela, o agente Alarmado nota que est c a acontecendo um incndio e avisa ao agente Bombeiro para que este tome as providncias e e necessrias. a Vamos desenvolver esta situaao problema criando duas classes: a classe AgenteAlarmado c e a classe AgenteBombeiro. O agente Alarmado envia uma mensagem informando ao agente Bombeiro que est acontecendo um incndio. Ao receber a mensagem, o agente a e Bombeiro ativa os procedimentos para combate do incndio. Os cdigos esto nas Caixas e o a de Cdigo 3.3 e 3.4. o
import import import import public

Cdigo 3.3: AgenteAlarmado.java o


j a d e . c o r e . Agent ; j a d e . c o r e . b e h a v i o u r s . OneShotBehaviour ; j a d e . l a n g . a c l . ACLMessage ; j a d e . c o r e . AID ; c l a s s AgenteAlarmado extends Agent {

3.1. Envio e Recebimento de Mensagens

36

Figura 3.1: Situaao Problema - Incndio. c e

protected void s e t u p ( ) { addBehaviour (new OneShotBehaviour ( t h i s ) { public void a c t i o n ( ) { ACLMessage msg = new ACLMessage ( ACLMessage .INFORM) ; msg . a d d R e c e i v e r (new AID( " Bombeiro " ,AID .ISLOCALNAME) ) ; msg . setL ang uag e ( " Portugu^ s " ) ; e msg . s e t O n t o l o g y ( " Emerg^ ncia " ) ; e msg . s e t C o n t e n t ( "Fogo" ) ; myAgent . send ( msg ) ; }

12

15

18

}) ; } } 

Cdigo 3.4: AgenteBombeiro.java o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . C y c l i c B e h a v i o u r ; import j a d e . l a n g . a c l . ACLMessage ;


public c l a s s AgenteBombeiro extends Agent {

protected void s e t u p ( ) { addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) {


9

12

public void a c t i o n ( ) { ACLMessage msg = myAgent . r e c e i v e ( ) ; i f ( msg != null ) {

3.1. Envio e Recebimento de Mensagens

37

15

18

21

24

S t r i n g c o n t e n t = msg . g e t C o n t e n t ( ) ; //com e q u a l s I g n o r e C a s e fazemos uma compara o ca // n o cases e n s i t i v e . a i f ( c o n t e n t . e q u a l s I g n o r e C a s e ( "Fogo" ) ) { System . out . p r i n t l n ( "O agente " + msg . g e t S e n d e r ( ) . getName ( ) + " avisou de um inc^ ndio " ) ; e System . out . p r i n t l n ( "Vou ativar os procedimentos de combate ao inc^ ndio !" ) ; e } } else block () ; } // fim do a c t i o n ( ) } ) ; // fim do addBehaviour ( ) } } 

Observe na classe AgenteAlarmado que escolhemos o receptor da mensagem com a linha de comando: msg.addReceiver(new AID("Bombeiro",AID.ISLOCALNAME)). Quando conhecemos o nome de um agente, no caso Bombeiro, adicionamos este nome em um objeto AID e informamos com o parmetro AID.ISLOCALNAME que trata-se do nome local a do agente. Execute no prompt a linha: java jade.Boot Bombeiro:AgenteBombeiro A1:AgenteAlarmado Obter o seguinte resultado: a O agente A1@lap:1099/JADE avisou de um inc^ndio e Vou ativar os procedimentos de combate ao inc^ndio! e Vamos agora incrementar nossos agentes. O agente Alarmado envia uma mensagem para o agente Bombeiro. O agente Bombeiro recebe e processa esta mensagem. Agora, o agente Bombeiro ir responder ao agente Alarmado. a Os cdigos desta nova funcionalidade esto nas Caixas de Cdigo 3.5 e 3.6, respectio a o vamente.
import import import import import public

Cdigo 3.5: AgenteAlarmado2.java o


j a d e . c o r e . Agent ; j a d e . c o r e . b e h a v i o u r s . OneShotBehaviour ; jade . core . behaviours . CyclicBehaviour ; j a d e . l a n g . a c l . ACLMessage ; j a d e . c o r e . AID ; c l a s s AgenteAlarmado2 extends Agent {

3.1. Envio e Recebimento de Mensagens


protected void s e t u p ( ) {
9

38

addBehaviour (new OneShotBehaviour ( t h i s ) {


12

15

18

public void a c t i o n ( ) { ACLMessage msg = new ACLMessage ( ACLMessage .INFORM) ; msg . a d d R e c e i v e r (new AID( " Bombeiro " ,AID .ISLOCALNAME) ) ; msg . setL ang uag e ( " Portugu^ s " ) ; e msg . s e t O n t o l o g y ( " Emerg^ ncia " ) ; e msg . s e t C o n t e n t ( "Fogo" ) ; myAgent . send ( msg ) ; } }) ; addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) {

21

24

27

30

33

public void a c t i o n ( ) { ACLMessage msg = myAgent . r e c e i v e ( ) ; i f ( msg != null ) { S t r i n g c o n t e n t = msg . g e t C o n t e n t ( ) ; System . out . p r i n t l n ( " --> " + msg . g e t S e n d e r ( ) . getName ( ) + ": " + content ) ; } else //Com o b l o c k ( ) bloqueamos o comportamento a t que uma nova e //mensagem c h e g u e ao a g e n t e e assim e v i t a m o s consumir c i c l o s // da CPU. block () ; } }) ;

36

39

42

}  }

Cdigo 3.6: AgenteBombeiro2.java o import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . C y c l i c B e h a v i o u r ; import j a d e . l a n g . a c l . ACLMessage ;


public c l a s s AgenteBombeiro2 extends Agent {

3.1. Envio e Recebimento de Mensagens


protected void s e t u p ( ) { addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) {
9

39

public void a c t i o n ( ) { ACLMessage msg = myAgent . r e c e i v e ( ) ;


12

15

18

21

24

i f ( msg != null ) { ACLMessage r e p l y = msg . c r e a t e R e p l y ( ) ; S t r i n g c o n t e n t = msg . g e t C o n t e n t ( ) ; i f ( c o n t e n t . e q u a l s I g n o r e C a s e ( "Fogo" ) ) { r e p l y . s e t P e r f o r m a t i v e ( ACLMessage .INFORM) ; r e p l y . s e t C o n t e n t ( " Recebi seu aviso ! Obrigado por auxiliar meu servi o " ) ; c myAgent . send ( r e p l y ) ; System . out . p r i n t l n ( "O agente "+ msg . g e t S e n d e r ( ) . getName ( ) +" avisou de um inc^ ndio " ) ; e System . out . p r i n t l n ( "Vou ativar os procedimentos de combate ao inc^ ndio !" ) ; e } } else block () ; } }) ; } } 

27

Observe o uso do mtodo createReply() na classe AgenteBombeiro2. Este mtodo e e auxilia na resposta de mensagens recebidas, encapsulando automaticamente no objeto reply o endereo do destinatrio da resposta. c a Vamos executar estes agentes de um modo diferente do que estamos fazendo at agora: e vamos executar os agentes a partir de prompts diferentes. Para que um agente JADE possa ser criado este deve estar em um container. Este container deve ser criado no mesmo instante em que o agente criado. Quando executvamos a linha java jade.Boot e a agente:ClassedoAgente agente2:ClassedoAgente estvamos criando agentes em um a container nativo, o Main Container. Neste caso, vamos iniciar o agente Bombeiro no main container e criar o agente Alarmado em outro container. Criamos o agente Bombeiro com a seguinte linha: java jade.Boot Bombeiro:AgenteBombeiro2 At agora nada mudou na nossa maneira de iniciar um agente. Como vamos iniciar e outro agente, poder amos pensar em executar novamente a ultima linha de comando. No entanto, agora precisamos passar o parmetro -container para que o agente Alarmado a seja criado. Assim:

3.2. Envio de Objetos java jade.Boot -container A1:AgenteAlarmado2 Executando esses agentes, obtemos os seguintes resultados: No prompt do Agente Bombeiro: O agente A1@lap:1099/JADE avisou de um inc^ndio e Vou ativar os procedimentos de combate ao inc^ndio! e No prompt do Agente Alarmado A1: --> Bombeiro@lap:1099/JADE: Recebi seu aviso! Obrigado por auxiliar meu servio c

40

Observe que durante o desenvolvimento de nosso agente utilizamos o mtodo block() e para evitar o consumo da CPU. Existe uma peculiaridade da plataforma JADE que deve ser observada durante o desenvolvimento de um agente. Quando uma mensagem chega a um determinado agente, todos os seus comportamentos que esto bloqueados so desa a bloqueados. Logo, se um agente possui um comportamento ou mais comportamentos bloqueados, todos sero desbloqueados com a chegada de uma mensagem. Pode-se usar a como correo desta peculiaridade condioes (if-elses) da linguagem JAVA para que um ca c comportamento no seja executado e volte a se bloquear novamente. E importante lembrar a que os comportamentos CyclicBehaviour, TickerBehaviour e WakerBehaviour j foram a implementados com estas funcionalidades.

3.2

Envio de Objetos

Em muitas situaoes costuma-se transferir uma grande quantidade de informaoes. Passar c c essas informaoes como strings requer um pouco mais de tempo de execuao da aplicaao, c c c e a implementaao pode perder ecincia na transmisso das informaes. c e a co A linguagem JAVA possui um recurso que permite o envio de objetos pela stream de dados. Este processo denominado de serializaao. Tecnicamente falando, serializar e c e transformar um objeto em uma seqncia de bytes, que poder ser armazenado em algum ue a local (arquivo de dados, por exemplo) e futuramente ser deserializado para seu estado original. A plataforma JADE disponibiliza mtodos que permitem a transmisso de objetos e a como contedo de mensagens. Estes mtodos so setContentObject(Serializable s) u e a e getContentObject(). Para exemplo de utilizaao destas funcionalidades considere a c

3.2. Envio de Objetos

41

seguinte situaao problema. Em uma loja de msica temos dois funcionrios: o agente c u a Estoque e o agente Contador. O agente Estoque deve informar ao agente Contador os msicos contidos no estoque da loja. Para isto, devem ser informados o nome do msico, u u sua idade e a banda que este compe, caso participe de uma. Este cenrio est ilustrado o a a na Figura 3.2. Nela, o agente Estoque envia as informaoes para o agente Contador que c lista as informaoes recebidas. c

Figura 3.2: Cenrio - Loja de Msica. a u

Vamos desenvolver este cenrio aplicando as utilidades da serializaao de objetos, a c para que estes objetos possam ser o contedo das mensagens. Para informaoes sobre os u c msicos temos a classe Musicos, cujo cdigo est descrito na Caixa de Cdigo 3.7. u o a o O agente Estoque criar cinco objetos da classe Musicos contendo as informaoes soa c bre os msicos, e esses objetos sero enviados para o agente Contador. As funcionalidades u a do agente Estoque esto na Caixa de Cdigo 3.8. a o

Cdigo 3.7: Musicos.java o import j a d e . u t i l . l e a p . S e r i a l i z a b l e ; / Uma c l a s s e que t e r s e u s o b j e t o s a s e r i a l i z a d o s d e v e implementar a i n t e r f a c e S e r i a l i z a b l e /


public c l a s s Musicos implements S e r i a l i z a b l e { S t r i n g nome ; int i d a d e ; S t r i n g banda ;

3.2. Envio de Objetos


public Musicos ( S t r i n g nome , int idade , S t r i n g banda ) { t h i s . nome = nome ; this . idade = idade ; t h i s . banda = banda ; } public void Imprimir ( ) { System . out . p r i n t l n ( " ----------------------------" ) ; System . out . p r i n t l n ( "Nome ...: " + nome ) ; System . out . p r i n t l n ( " Idade ...: " + i d a d e ) ; System . out . p r i n t l n ( " Banda ...: " + banda ) ; System . out . p r i n t l n ( " ----------------------------\n" ) ; } }  import import import import import

42

12

15

18

21

Cdigo 3.8: AgenteEstoque.java o


j a d e . c o r e . Agent ; j a d e . c o r e . b e h a v i o u r s . Si mp le B e ha v io u r ; j a d e . l a n g . a c l . ACLMessage ; j a d e . c o r e . AID ; j a v a . i o . IOException ;

public c l a s s AgenteEstoque extends Agent {


9

Musicos [ ] mus = new Musicos [ 5 ] ; protected void s e t u p ( ) {

12

15

mus [ 0 ] mus [ 1 ] mus [ 2 ] mus [ 3 ] mus [ 4 ]

= = = = =

new new new new new

Musicos ( " Cl udia Leite " , 3 0 , " Babado Novo" ) ; a Musicos ( " Paula Toller " , 4 5 , "Kid Abelha " ) ; Musicos ( " Rog rio Flausino " , 3 7 , "Jota Quest " ) ; e Musicos ( " Laura Pausini " , 3 3 , null ) ; Musicos ( "Bono Vox" , 4 7 , "U2" ) ;

18

addBehaviour (new S impl eB e ha vio u r ( t h i s ) { // i n c i o do comportamento


21

int c o n t = 0 ; public void a c t i o n ( ) { try { ACLMessage msg = new ACLMessage ( ACLMessage .INFORM) ; msg . a d d R e c e i v e r (new AID( " Contador " , AID .ISLOCALNAME) ) ; msg . s e t C o n t e n t O b j e c t ( mus [ c o n t ] ) ; myAgent . send ( msg ) ; // e n v i a a mensagem cont = cont + 1 ; // b l o c k ( 1 0 0 ) ; } catch ( IOException ex ) {

24

27

30

3.2. Envio de Objetos

43
System . out . p r i n t l n ( "Erro no envio da mensagem " ) ;

33

} }

36

public boolean done ( ) { i f ( cont > 4) { myAgent . d o D e l e t e ( ) ; // f i n a l i z a o a g e n t e return true ; } else { return f a l s e ; } } } ) ; // fim do comportamento } // fim do m todo s e t u p ( ) do a g e n t e e //A i n v o c a o do m todo d o D e l e t e ( ) a c i o n a o m todo takeDown ( ) ca e e protected void takeDown ( ) { System . out . p r i n t l n ( " Todas as informa ~ es foram enviadas " ) ; co } } 

39

42

45

48

51

O agente Contador receber as mensagens enviadas pelo agente Estoque e os objea tos recebidos tero suas informaoes impressas na tela. As funcionalidades do agente a c Contador esto na Caixa de Cdigo 3.9. a o

Cdigo 3.9: AgenteContador.java o

import j a d e . c o r e . Agent ; import j a d e . c o r e . b e h a v i o u r s . C y c l i c B e h a v i o u r ; import j a d e . l a n g . a c l . ACLMessage ; public c l a s s AgenteContador extends Agent { protected void s e t u p ( ) { System . out . p r i n t l n ( " Agente Contador inicializado .\n " + " Aguardando informa ~ es ..." ) ; co addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) { // i n c i o do comportamento

12

15

Musicos [ ] m us i c o s = new Musicos [ 5 ] ; // v e t o r da c l a s s e Musicos int c o n t = 0 ; public void a c t i o n ( ) {

18

ACLMessage msg = r e c e i v e ( ) ; // c a p t u r a nova mensagem

3.2. Envio de Objetos

44

21

24

27

30

i f ( msg != null ) { // s e e x i s t e mensagem try { // e x t r a i o o b j e t o m u s ic o s [ c o n t ] = ( Musicos ) msg . g e t C o n t e n t O b j e c t ( ) ; // imprime as i n f o r m a e s do o b j e t o co m u s ic o s [ c o n t ] . Imprimir ( ) ; cont = cont + 1 ; } catch ( E x c e p t i o n e ) { } } else b l o c k ( ) ; // aguarda nova mensagem } } ) ; // t rmino do comportamento e } // fim do m todo s e t u p ( ) do a g e n t e e } 

33

Executando o agente Contador com a seguinte linha: java jade.Boot Contador:AgenteContador Obtemos o seguinte resultado: Agente Contador inicializado. Aguardando informaoes... c~

Vamos executar agora o agente Estoque, com a seguinte linha: java jade.Boot -container Estoque:AgenteEstoque Quando o agente Estoque iniciado, este envia as mensagens para o agente Contador e e aps o trmino do envio obtemos o seguinte resultado: o e Todas as informa~es foram enviadas. co

E no prompt do agente Contador obtemos o seguinte resultado: ---------------------------Nome...: Cludia Leite a Idade...: 30 Banda...: Babado Novo ------------------------------------------------------Nome...: Paula Toller

3.3. Seleao de Mensagens c Idade...: 45 Banda...: Kid Abelha ------------------------------------------------------Nome...: Rogrio Flausino e Idade...: 37 Banda...: Jota Quest ------------------------------------------------------Nome...: Laura Pausini Idade...: 33 Banda...: null ------------------------------------------------------Nome...: Bono Vox Idade...: 47 Banda...: U2 ----------------------------

45

3.3

Seleo de Mensagens ca

Para selecionar as mensagens que um agente deseja receber podemos utilizar a classe jade.lang.acl.MessageTemplate. Esta classe permite denir ltros para cada atributo da mensagem ACLMessage e estes ltros podem ser utilizados como parmetros do mtodo a e receive(). Nesta classe se dene um conjunto de mtodos estticos que retornam como resultado e a um objeto do tipo MessageTemplate. As opoes para ltragem das mensagens so: c a MatchPerformative(performative ): permite selecionar os tipos de atos comunicativos das mensagens que sero aceitos; a MatchSender(AID): permite selecionar um ou um grupo de agentes cujas mensagens enviadas por estes sero lidas; a MatchConversationID(String): permite que apenas mensagens de um determinado tpico sejam lidas. Um tpico nada mais do que uma String denido por um o o e

3.3. Seleao de Mensagens c

46

agente. Todas as mensagens relacionadas a este tpico contm essa string, e sero o e a lidas baseadas neste ltro; and(MessageTemplate1, MessageTemplate2): realiza um E lgico entre dois lo tros; or(MessageTemplate1, MessageTemplate2): realiza um OU lgico entre dois o ltros; not(MessageTemplate): inverte o ltro; MatchOntology(String): permite que mensagens com uma determinada ontologia sejam lidas; MatchProtocol(String): permite que mensagens envolvidas em um protocolo sejam lidas; MatchLanguage(String): permite que mensagens em uma certa linguagem sejam lidas; MatchContent(String): permite que mensagens com um determinado contedo u sejam lidas; MatchReplyWith(String): permite que um ltro seja realizado de acordo com o campo replywith. Existe tambm o mtodo match(ACLMessage) que retorna um valor booleano verdae e deiro caso a mensagem que est em seu parmetro respeite os ltros denidos pelo objeto a a MessageTemplate. O nosso agente Bombeiro, citado na Seao 3.1.4 (pgina 35), poderia estar interessado c a em receber apenas mensagens do tipo inform e cuja linguagem seja o Portugu^s. Seu e cdigo caria como mostrado na Caixa de Cdigo 3.10. o o
import import import import

Cdigo 3.10: AgenteBombeiroFiltro.java o


j a d e . c o r e . Agent ; jade . core . behaviours . CyclicBehaviour ; j a d e . l a n g . a c l . ACLMessage ; j a d e . l a n g . a c l . MessageTemplate ;

public c l a s s A g e n t e B o m b e i r o F i l t r o extends Agent { protected void s e t u p ( ) { addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) { // I n c i o do Comportamento public void a c t i o n ( ) {

3.3. Seleao de Mensagens c

47

12

15

18

// d e f i n i m o s o p r i m e i r o f i l t r o MessageTemplate MT1 = MessageTemplate . MatchPerformative ( ACLMessage .INFORM) ; // d e f i n i m o s o segundo f i l t r o MessageTemplate MT2 = MessageTemplate . MatchLanguage ( " Portugu^ s " ) ; e // Realizamos um E l g i c o e n t r e os d o i s f i l t r o s o MessageTemplate MT3 = MessageTemplate . and (MT1, MT2) ; // Recebe a mensagem de acordo com o f i l t r o ACLMessage msg = myAgent . r e c e i v e (MT3) ; i f ( msg != null ) { S t r i n g c o n t e n t = msg . g e t C o n t e n t ( ) ; i f ( c o n t e n t . e q u a l s I g n o r e C a s e ( "Fogo" ) ) { System . out . p r i n t l n ( "O agente " + msg . g e t S e n d e r ( ) . getName ( ) + " avisou de um inc^ ndio " ) ; e } }

21

24

27

30

} } ) ; //Fim do Comportamento } } 

3.4. Pginas Amarelas a

48

3.4

Pginas Amarelas a
J vimos como ocorre a comunicaao entre agentes. Agora temos um a c novo dilema: como um agente pode localizar outros agentes que oferecem um determinado servio, e obter seus identicadores para que possam se c

comunicar? Para que isto possa ser feito, a plataforma JADE implementa o servio de pginas c a amarelas em um agente: o agente Directory Facilitator (DF), seguindo as especicaoes c do padro FIPA. Agentes que desejam divulgar seus servios registram-se no DF, e os a c demais podem ento buscar por agentes que provm algum servio desejado. a e c O DF nada mais do que um registro centralizado cuja entradas associam a ID do e agente aos seus servios. Para criaao e manipulaao (busca) dessas entradas utilizamos c c c um objeto DFAgentDescription. Para registrar o servio de um agente devemos fornecer c uma descriao deste servio e a AID do agente. Para uma busca, basta fornecer a descrio c c ca do servio. Essa busca retornar um array com IDs dos agentes que oferecem o servio c a c buscado.

Figura 3.3: Estrutura de uma Entrada no DF.

Na Figura 3.3 tem-se a estrutura de uma entrada no registro do DF. Ela parece ser complexa, mas seu uso se torna simples pois apenas alguns dos campos fornecidos so a

3.4. Pginas Amarelas a

49

utilizados. Para cada servio publicado devemos fornecer(obrigatoriamente) a AID do c agente, o tipo e o nome do servio. Podemos tambm fornecer os protocolos, linguagens e c e ontologias que um agente manipula para que os demais possam conhecer e interagir com este agente. Para manipulao destes dados, os seguintes mtodos esto dispon ca e a veis: static DFAgentDescription register: registra os servios de um agente no DF; c static void deregister: elimina o registro do DF os servios fornecidos pelo c agente; Os servios so denidos com os mtodos da classe ServiceDescription: c a e void setName: denimos o nome do servio; c void setOwnership: denimos o proprietrio do servio; a c void setType: denimos o tipo do servio. Este valor denido pelo desenc e volvedor, no existem tipos pr-denidos; a e void addLanguages: adicionamos linguagens ao servio; c void addOntologies: adicionamos ontologias ao servio; c void addProtocols: adicionamos protocolos ao servio; c void addProperties: adicionamos propriedades ao servio. Este valor dec e nido pelo desenvolvedor, no existem propriedades pr-denidas. a e A descrio do agente que oferece o servio realizada com o uso dos mtodos da ca c e e classe DFAgentDescription: void setName: denimos o AID do agente; void addServices: adicionamos o servio passado como parmetro deste mc a e todo a descriao do agente; ` c void removeServices: removemos um servio oferecido da descrio deste c ca agente; void addLanguages: adicionamos linguagens que o agente entende; void addOntologies: adicionamos ontologias que o agente manipula; void addProtocols: adicionamos protocolos que o agente manipula.

3.4. Pginas Amarelas a

50

3.4.1

Registro

Para que um agente divulgue seus servios, este deve se registrar nas pginas amarelas c a da plataforma, isto , deve se registrar no DF. Costuma-se denir o registro no DF como e a primeira aao do agente em seu mtodo setup(). Para isto, utilizamos o mtodo c e e register() fornecendo como parmetro um objeto DFAgentDescription. Este mtodo a e deve ser envolvido por um bloco de exceao. c Por exemplo, considere que um agente oferea um determinado servio. Este agente c c poderia se registrar no DF da maneira descrita na Caixa de Cdigo 3.11. o
import import import import import

Cdigo 3.11: Registro.java o


j a d e . c o r e . Agent ; j a d e . c o r e . AID ; j a d e . domain . DFService ; j a d e . domain . FIPAAgentManagement . ; j a d e . domain . FIPAException ;

public c l a s s R e g i s t r o extends Agent { protected void s e t u p ( ) { // Criamos uma e n t r a d a no DF DFAgentDescription dfd = new DFAgentDescription ( ) ; dfd . setName ( getAID ( ) ) ; // Informamos a AID do a g e n t e //Vamos c r i a r um s e r v i o c S e r v i c e D e s c r i p t i o n sd = new S e r v i c e D e s c r i p t i o n ( ) ; sd . setType ( "Tipo" ) ; // Tipo do S e r v i o c sd . setName ( " Servi o1 " ) ; //Nome do S e r v i o c c // adicionamos o S e r v i o 1 c dfd . a d d S e r v i c e s ( sd ) ; //Vamos c r i a r o u t r o s e r v i o c sd = new S e r v i c e D e s c r i p t i o n ( ) ; sd . setType ( "Tipo de Servi o " ) ; c sd . setName ( " Servi o2 " ) ; c dfd . a d d S e r v i c e s ( sd ) ; //Vamos r e g i s t r a r o a g e n t e no DF try { // r e g i s t e r ( a g e n t e que o f e r e c e , d e s c r i o ) ca DFService . r e g i s t e r ( this , dfd ) ; } catch ( FIPAException e ) { e . printStackTrace () ; } } } 

12

15

18

21

24

27

30

33

3.4. Pginas Amarelas a

51

protected void takeDown ( ) { try { DFService . d e r e g i s t e r ( t h i s ) ; } catch ( FIPAException e ) { e . printStackTrace () ; } } 

Uma boa prtica remover o registro do agente quando este termina sua execuao. a e c Quando um agente nalizado, automaticamente seu registro removido das pginas e e a brancas, mas no removido das pginas amarelas. Por isto, costuma-se remover o a e a registro do agente no mtodo takeDown(). O mtodo takeDown() ca implementado da e e seguinte maneira:

3.4.2

Busca

Para buscar no DF devemos criar um objeto DFAgentDescription, agora sem a AID do agente. O processo muito semelhante ao de registro, pois criamos a descrio do e ca servio buscado da mesma maneira que criamos a descrio de um servio oferecido por c ca c um agente. A implementao de um agente que realiza a busca no DF est contida na ca a Caixa de Cdigo 3.12. o
import import import import import import

Cdigo 3.12: Busca.java o


j a d e . c o r e . Agent ; j a d e . c o r e . AID ; j a d e . domain . DFService ; j a d e . domain . FIPAAgentManagement . ; j a d e . domain . FIPAException ; java . u t i l . I t e r a t o r ;

public c l a s s Busca extends Agent {


9

protected void s e t u p ( ) {
12

// c r i o uma e n t r a d a no DF DFAgentDescription t e m p l a t e = new DFAgentDescription ( ) ; // c r i o um o b j e t o contendo a d e s c r i o do s e r v i o ca c S e r v i c e D e s c r i p t i o n sd = new S e r v i c e D e s c r i p t i o n ( ) ; sd . setType ( "Tipo" ) ; // d e f i n o o t i p o de s e r v i o c / N est e momento p o d e r i a d e f i n i r o u t r a s c a r a c t e r s t i c a s do s e r v i o bu s c a d o para f i l t r a r melhor a b u s c a . c No caso , vamos b u s c a r por s e r v i o s do t i p o Tipo / c

15

18

21

3.4. Pginas Amarelas a


// a d i c i o n o o s e r v i o na e n t r a d a c t e m p l a t e . a d d S e r v i c e s ( sd ) ; try {

52

24

27

30

//Vou b u s c a r p e l o s a g e n t e s //A b u s c a r e t o r n a um a r r a y DFAgentDescription //O par metro t h i s i n d i c a o a g e n t e que e s t r e a l i z a n d o a b u s c a a a DFAgentDescription [ ] r e s u l t = DFService . s e a r c h ( this , t e m p l a t e ) ; // Imprimo os r e s u l t a d o s f o r ( int i = 0 ; i < r e s u l t . l e n g t h ; i ++) { // r e s u l t [ i ] . getName ( ) f o r n e c e a AID do a g e n t e S t r i n g out = r e s u l t [ i ] . getName ( ) . getLocalName ( ) + " prov^ " ; e // Para o b t e r os s e r v i c o s do a g e n t e invocamos // o m todo g e t A l l S e r v i c e s ( ) ; e Iterator iter = result [ i ] . getAllServices () ; while ( i t e r . hasNext ( ) ) { // Extra mos os s e r v i c o s para um o b j e t o S e r v i c e D e s c r i p t i o n S e r v i c e D e s c r i p t i o n SD = ( S e r v i c e D e s c r i p t i o n ) i t e r . next ( ) ; // Capturamos o nome do s e r v i o c out += " " + SD . getName ( ) ; } //Os s e r v i o s de cada a g e n t e s o i m p r e s s o s na t e l a c a System . out . p r i n t l n ( out ) ; } // fim do l a o f o r c

33

36

39

42

45

48

51

54

} catch ( FIPAException e ) { e . printStackTrace () ; } } } 

3.4.3

Solicitando Ajuda

Considere a seguinte situaao: um agente solicitante observa uma situaao problema c c em seu ambiente, tal como um assalto, uma pessoa doente e um incndio. Este agente e ento busca por outros agentes que possam resolver estes problemas. No caso um agente a policial, um agente mdico e um agente bombeiro. Aps encontrar estes agentes, o agente e o solicitante comunica o que est acontecendo. Este cenrio est ilustrado na Figura 3.4. a a a No contexto multiagentes, o agente solicitante busca nas pginas amarelas da plataa forma por agentes que ofeream determinado servio. Estes agentes devem, ao iniciar, c c cadastrar seus servios nas pginas amarelas. Para a implementaao deste contexto tec a c

3.4. Pginas Amarelas a

53

Figura 3.4: Cenrio - Solicitando Ajuda. a

mos as classes Solicitante, Bombeiro, Medico e Policial. A primeira refere-se ao agente solicitante e as demais aos agentes prestadores de servios. Estas classes esto nas c a Caixas de Cdigo 3.13, 3.14, 3.15 e 3.16, respectivamente. o
import import import import import import import

Cdigo 3.13: Solicitante.java o


j a d e . c o r e . Agent ; jade . core . behaviours . ; j a d e . c o r e . AID ; j a d e . domain . DFService ; j a d e . domain . FIPAAgentManagement . ; j a d e . domain . FIPAException ; j a d e . l a n g . a c l . ACLMessage ;

public c l a s s S o l i c i t a n t e extends Agent { protected void s e t u p ( ) { // Captura argumentos Object [ ] a r g s = getArguments ( ) ; i f ( a r g s != null && a r g s . l e n g t h > 0 ) { S t r i n g argumento = ( S t r i n g ) a r g s [ 0 ] ;

12

15

3.4. Pginas Amarelas a

54

18

21

24

27

30

33

36

39

// Se o argumento f o g o e i f ( argumento . e q u a l s I g n o r e C a s e ( "fogo" ) ) { S e r v i c e D e s c r i p t i o n s e r v i c o = new S e r v i c e D e s c r i p t i o n ( ) ; //O s e r v i o apagar f o g o c e s e r v i c o . setType ( " apaga fogo" ) ; // b u s c a por quem f o r n e c e o s e r v i o c busca ( s e r v i c o , "fogo" ) ; } // Se o argumento l a d r a o e i f ( argumento . e q u a l s I g n o r e C a s e ( " ladr~ o " ) ) { a S e r v i c e D e s c r i p t i o n s e r v i c o = new S e r v i c e D e s c r i p t i o n ( ) ; //O s e r v i o p r e n d e r o l a d r o c a s e r v i c o . setType ( " prende ladr~ o " ) ; a busca ( s e r v i c o , " ladr~ o " ) ; a } // Se o argumento d o e n t e e i f ( argumento . e q u a l s I g n o r e C a s e ( " doente " ) ) { S e r v i c e D e s c r i p t i o n s e r v i c o = new S e r v i c e D e s c r i p t i o n ( ) ; //O s e r v i o s a l v a r v i d a s c e s e r v i c o . setType ( " salva vidas " ) ; busca ( s e r v i c o , " doente " ) ; } // Comportamento para r e c e b e r mensagens addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) { public void a c t i o n ( ) { ACLMessage msg = r e c e i v e ( ) ; i f ( msg != null ) { System . out . p r i n t l n ( msg . g e t S e n d e r ( ) + " : " + msg . getContent ( ) ) ; } else block () ; } }) ; } } // Mtodo que r e a l i z a a b u s c a nas p a g i n a s a m a r el a s da p l a t a f o r m a e protected void busca ( f i n a l S e r v i c e D e s c r i p t i o n sd , f i n a l S t r i n g Pedido ) { //A cada minuto t e n t a b u s c a r por a g e n t e s que fornecem // o s e r v i o c addBehaviour (new T i c k e r B e h a v i o u r ( this , 6 0 0 0 0 ) { protected void onTick ( ) { DFAgentDescription dfd = new DFAgentDescription ( ) ; dfd . a d d S e r v i c e s ( sd ) ;

42

45

48

51

54

57

60

3.4. Pginas Amarelas a

55

63

66

69

72

try { DFAgentDescription [ ] r e s u l t a d o = DFService . s e a r c h ( myAgent , dfd ) ; i f ( r e s u l t a d o . l e n g t h != 0 ) { ACLMessage msg = new ACLMessage ( ACLMessage .INFORM) ; msg . a d d R e c e i v e r ( r e s u l t a d o [ 0 ] . getName ( ) ) ; msg . s e t C o n t e n t ( Pedido ) ; myAgent . send ( msg ) ; s t o p ( ) ; // f i n a l i z a comportamento } } catch ( FIPAException e ) { e . printStackTrace () ; } } }) ;

75

} }  import import import import import import import

Cdigo 3.14: Bombeiro.java o


j a d e . c o r e . Agent ; jade . core . behaviours . ; j a d e . c o r e . AID ; j a d e . domain . DFService ; j a d e . domain . FIPAAgentManagement . ; j a d e . domain . FIPAException ; j a d e . l a n g . a c l . ACLMessage ;

public c l a s s Bombeiro extends Agent {


12

15

18

protected void s e t u p ( ) { // D e s c r i o do S e r v i c o ca S e r v i c e D e s c r i p t i o n s e r v i c o = new S e r v i c e D e s c r i p t i o n ( ) ; // Seu s e r v i o s a l v a r v i d a s c e s e r v i c o . setType ( " apaga fogo" ) ; s e r v i c o . setName ( t h i s . getLocalName ( ) ) ; registraServico ( servico ) ; RecebeMensagens ( "fogo" , "Vou apagar o inc^ ndio " ) ; e } // m todo para r e g i s t r a r s e r v i o e c protected void r e g i s t r a S e r v i c o ( S e r v i c e D e s c r i p t i o n sd ) { DFAgentDescription dfd = new DFAgentDescription ( ) ; dfd . a d d S e r v i c e s ( sd ) ; try { DFService . r e g i s t e r ( this , dfd ) ;

21

24

27

3.4. Pginas Amarelas a


} catch ( FIPAException e ) { e . printStackTrace () ; }

56

30

33

36

} // Mtodo para a d i c i o n a r um comportamento para r e c e b e r mensagens e protected void RecebeMensagens ( f i n a l S t r i n g mensagem , f i n a l S t r i n g r e s p ) { addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) { public void a c t i o n ( ) { ACLMessage msg = r e c e i v e ( ) ; i f ( msg != null ) { i f ( msg . g e t C o n t e n t ( ) . e q u a l s I g n o r e C a s e ( mensagem ) ) { ACLMessage r e p l y = msg . c r e a t e R e p l y ( ) ; reply . setContent ( resp ) ; myAgent . send ( r e p l y ) ; } } else block () ; } }) ; }

39

42

45

48

51

}  import import import import import import import

Cdigo 3.15: Medico.java o


j a d e . c o r e . Agent ; jade . core . behaviours . ; j a d e . c o r e . AID ; j a d e . domain . DFService ; j a d e . domain . FIPAAgentManagement . ; j a d e . domain . FIPAException ; j a d e . l a n g . a c l . ACLMessage ;

public c l a s s Medico extends Agent {


12

15

18

protected void s e t u p ( ) { // D e s c r i o do S e r v i c o ca S e r v i c e D e s c r i p t i o n s e r v i c o = new S e r v i c e D e s c r i p t i o n ( ) ; // Seu s e r v i o s a l v a r v i d a s c e s e r v i c o . setType ( " salva vidas " ) ; s e r v i c o . setName ( t h i s . getLocalName ( ) ) ; registraServico ( servico ) ; RecebeMensagens ( " doente " , "Vou salvar o doente " ) ; }

21

3.4. Pginas Amarelas a

57

24

27

30

// m todo para r e g i s t r a r s e r v i o e c protected void r e g i s t r a S e r v i c o ( S e r v i c e D e s c r i p t i o n sd ) { DFAgentDescription dfd = new DFAgentDescription ( ) ; dfd . a d d S e r v i c e s ( sd ) ; try { DFService . r e g i s t e r ( this , dfd ) ; } catch ( FIPAException e ) { e . printStackTrace () ; } } // Mtodo para a d i c i o n a r um comportamento para r e c e b e r mensagens e protected void RecebeMensagens ( f i n a l S t r i n g mensagem , f i n a l S t r i n g r e s p ) { addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) { public void a c t i o n ( ) { ACLMessage msg = r e c e i v e ( ) ; i f ( msg != null ) { i f ( msg . g e t C o n t e n t ( ) . e q u a l s I g n o r e C a s e ( mensagem ) ) { ACLMessage r e p l y = msg . c r e a t e R e p l y ( ) ; reply . setContent ( resp ) ; myAgent . send ( r e p l y ) ; } } else block () ; } }) ; }

33

36

39

42

45

48

51

}  import import import import import import import

Cdigo 3.16: Policial.java o


j a d e . c o r e . Agent ; jade . core . behaviours . ; j a d e . c o r e . AID ; j a d e . domain . DFService ; j a d e . domain . FIPAAgentManagement . ; j a d e . domain . FIPAException ; j a d e . l a n g . a c l . ACLMessage ;

public c l a s s P o l i c i a l extends Agent {


12

protected void s e t u p ( ) { // D e s c r i o do S e r v i c o ca S e r v i c e D e s c r i p t i o n s e r v i c o = new S e r v i c e D e s c r i p t i o n ( ) ;

3.4. Pginas Amarelas a


// Seu s e r v i o s a l v a r v i d a s c e s e r v i c o . setType ( " prende ladr~ o " ) ; a s e r v i c o . setName ( t h i s . getLocalName ( ) ) ; registraServico ( servico ) ; RecebeMensagens ( " ladr~ o " , "Vou prender o ladr~ o " ) ; a a } // m todo para r e g i s t r a r s e r v i o e c protected void r e g i s t r a S e r v i c o ( S e r v i c e D e s c r i p t i o n sd ) { DFAgentDescription dfd = new DFAgentDescription ( ) ; dfd . a d d S e r v i c e s ( sd ) ; try { DFService . r e g i s t e r ( this , dfd ) ; } catch ( FIPAException e ) { e . printStackTrace () ; }

58

15

18

21

24

27

30

33

36

} // Mtodo para a d i c i o n a r um comportamento para r e c e b e r mensagens e protected void RecebeMensagens ( f i n a l S t r i n g mensagem , f i n a l S t r i n g r e s p ) { addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) { public void a c t i o n ( ) { ACLMessage msg = r e c e i v e ( ) ; i f ( msg != null ) { i f ( msg . g e t C o n t e n t ( ) . e q u a l s I g n o r e C a s e ( mensagem ) ) { ACLMessage r e p l y = msg . c r e a t e R e p l y ( ) ; reply . setContent ( resp ) ; myAgent . send ( r e p l y ) ; } } else block () ; } }) ; }

39

42

45

48

51

} 

Vamos rodar este cenrio de uma nova maneira: utilizando ferramentas grcas da a a plataforma JADE. A plataforma JADE possui um agente que fornece uma interface grca a de administrao da plataforma. Trata-se do agente RMA (Remote Management Agent). ca Existe um atalho para execuao deste agente: basta incluir o parmetro -gui na linha de c a execuo da plataforma (e.g, java jade.Boot -gui ...). ca Com a invocao deste agente exibida a interface grca ilustrada na Figura 3.5. ca e a Automaticamente com o comando -gui, os agentes AMS e DF tambm so carregados. e a

3.4. Pginas Amarelas a

59

Figura 3.5: Interface Grca da Plataforma JADE. a

Ao longo deste manual as funcionalidades desta interface sero abordadas. Mas no a momento estamos interessados em estudar apenas uma destas funcionalidades: o Agente Sniffer. Este agente intercepta mensagens ACL e as mostra gracamente usando uma notaao semelhante aos diagramas de seqncia UML. A Figura 3.6 ilustra a atividade c ue deste agente.

3.4. Pginas Amarelas a

60

Figura 3.6: Agente Snier.

Vamos iniciar nosso agente Solicitante com a seguinte linha de comando: java jade.Boot -gui Pedinte:Solicitante(fogo) Com esta execuo criamos um agente Pedinte que solicita `s pginas amarelas um ca a a agente que combate o fogo, no caso o Bombeiro. A tela grca desta execuo est a ca a ilustrada na Figura 3.7.

3.4. Pginas Amarelas a

61

Figura 3.7: Agente Pedinte na Plataforma.

Vamos iniciar o agente Sniffer. Clique sobre algum container ou sobre alguma plataforma. Agora vamos no menu Tools -> Start Sniffer. A tela do Sniffer ser aberta, a onde teremos a lista de agentes na plataforma. Para vericar o uxo de mensagens entre agentes temos que selecion-los, e para tanto basta clicar com o boto direito do mouse e a a escolher a opo Do sni this agent(s). Estes passos esto ilustrados na Figura 3.8. ca a

Figura 3.8: Execuao do Agente Snier. c

Vamos adicionar os agentes Pedinte e DF. Observe que a cada minuto o Pedinte envia uma mensagem para o DF buscando por agentes Bombeiros, e recebe uma mensagem de resposta que no caso est vazia, pois no temos agente Bombeiro na plataforma. a a Vamos adicionar o agente Bombeiro a plataforma, com a seguinte linha: `

3.4. Pginas Amarelas a java jade.Boot -container Bombeiro:Bombeiro

62

Adicionalmente, vamos adicionar este agente ao Snier. Agora, quando o agente Pedinte enviar uma mensagem para o DF, este responder com uma mensagem contendo a a AID do agente Bombeiro e ento, o agente Pedinte envia uma mensagem diretamente a para o agente Bombeiro. O resultado do contexto apresentado est ilustrado na Figura a 3.9.

Figura 3.9: Troca de Mensagens entre os Agentes.

3.4.4

Noticao ca

Podemos tambm utilizar o servio de noticaao do DF para resolver este problema. e c c Ao invs do agente Pedinte car realizando uma busca de novos agentes que oferecem e determinado servio a cada minuto, este pode pedir para que o DF notique-o sempre c quando um novo agente que oferece o servio desejado se registrar nas pginas amarelas. c a Para que isto seja poss vel, a plataforma JADE disponibiliza um servio denominado c DF Subscription Service que implementa um protocolo subscribe entre os agentes envolvidos. O cdigo desta funcionalidade est descrito na Caixa de Cdigo 3.17. Todo o o a o cdigo fonte est comentado para que seja plaus o entendimento da implementaao. o a vel c

3.4. Pginas Amarelas a Cdigo 3.17: Solicitante2.java o


j a d e . c o r e . Agent ; jade . core . behaviours . ; j a d e . c o r e . AID ; j a d e . domain . DFService ; j a d e . domain . FIPAAgentManagement . ; j a d e . domain . FIPAException ; j a d e . domain . FIPANames ; j a d e . l a n g . a c l . ACLMessage ; j a d e . l a n g . a c l . MessageTemplate ; jade . proto . S u b s c r i p t i o n I n i t i a t o r ;

63

import import import import import import import import import import

12

public c l a s s S o l i c i t a n t e 2 extends Agent { protected void s e t u p ( ) { //Nada mudou n e s t e m todo , apenas o m todo Busca ( ) e e // p a s s o u a s e chamado de P e d e N o t i f i c a o ( ) ca Object [ ] a r g s = getArguments ( ) ; i f ( a r g s != null && a r g s . l e n g t h > 0 ) { S t r i n g argumento = ( S t r i n g ) a r g s [ 0 ] ; i f ( argumento . e q u a l s I g n o r e C a s e ( "fogo" ) ) { S e r v i c e D e s c r i p t i o n s e r v i c o = new S e r v i c e D e s c r i p t i o n ( ) ; s e r v i c o . setType ( " apaga fogo" ) ; P e d e N o t i f i c a c a o ( s e r v i c o , "fogo" ) ; } i f ( argumento . e q u a l s I g n o r e C a s e ( " ladr~ o " ) ) { a S e r v i c e D e s c r i p t i o n s e r v i c o = new S e r v i c e D e s c r i p t i o n ( ) ; s e r v i c o . setType ( " prende ladr~ o " ) ; a P e d e N o t i f i c a c a o ( s e r v i c o , " ladr~ o " ) ; a } i f ( argumento . e q u a l s I g n o r e C a s e ( " doente " ) ) { S e r v i c e D e s c r i p t i o n s e r v i c o = new S e r v i c e D e s c r i p t i o n ( ) ; s e r v i c o . setType ( " salva vidas " ) ; P e d e N o t i f i c a c a o ( s e r v i c o , " doente " ) ; } // Comportamento para r e c e b e r mensagens addBehaviour (new C y c l i c B e h a v i o u r ( t h i s ) { /As mensagens de n o t i f i c a o do DF atendem ao p r o t o c o l o ca FIPA S u b s c r i b e , e e l a s possuem um m todo e x c l u s i v o para e sua r e c e p o . ( S u b s c r i p t i o n I n i t i a t o r ) ca Ent o , devemos l e r t o d a s as mensagens , e x c e t o as que a obdecem o p r o t o c o l o FIPA S u b c r i b e . / // Fa o um f i l t r o para r e c e b e r mensagens do p r o t o c o l o c Subscribe

15

18

21

24

27

30

33

36

39

42

3.4. Pginas Amarelas a

64

45

MessageTemplate f i l t r o = MessageTemplate . MatchProtocol ( FIPANames . I n t e r a c t i o n P r o t o c o l . FIPA SUBSCRIBE) ; // Crio um novo f i l t r o que r e a l i z a uma i n v e r s o l g i c a no a o f i l t r o anterior . // ou s e j a , n o a c e i t a mensagens do p r o t o c o l o S u b s c r i b e a MessageTemplate f i l t r o 2 = MessageTemplate . not ( f i l t r o ) ; public void a c t i o n ( ) { // S r e c e b e mensagens do f i l t r o 2 o ACLMessage msg = r e c e i v e ( f i l t r o 2 ) ; i f ( msg != null ) { System . out . p r i n t l n ( msg . g e t S e n d e r ( ) + " : " + msg . getContent ( ) ) ; } else block () ; } }) ; } } protected void P e d e N o t i f i c a c a o ( f i n a l S e r v i c e D e s c r i p t i o n sd , f i n a l S t r i n g Pedido ) { // Crio d e s c r i o da e n t r a d a no r e g i s t r o ca DFAgentDescription dfd = new DFAgentDescription ( ) ; dfd . a d d S e r v i c e s ( sd ) ; // Crio mensagem de n o t i f i c a o ca ACLMessage mgs = DFService . c r e a t e S u b s c r i p t i o n M e s s a g e ( this , getDefaultDF ( ) , dfd , null ) ;

48

51

54

57

60

63

66

69

// Agora i n i c i a m o s o comportamento que f i c a r e s p e r a n d o p e l a a n o t i f i c a o do DF ca


72

75

78

81

addBehaviour (new S u b s c r i p t i o n I n i t i a t o r ( this , mgs ) { //A mensagem de n o t i f i c a o uma mensagem INFORM, e n t o ca e a // u t i l i z o o m todo padr o h a n d l e I n f o r m ( ) . E s t e um m todo pr e a e e e d e f i n i d o para // manipular mensagens do t i p o INFORM. protected void h a n d l e I n f o r m ( ACLMessage i n f o r m ) { try { // Retorna a r r a y de AIDs dos Agentes DFAgentDescription [ ] d f d s = DFService . d e c o d e N o t i f i c a t i o n ( inform . getContent ( ) ) ; // Crio mensagem ACLMessage mensagem =new ACLMessage ( ACLMessage .INFORM) ; // Capturo AID do a g e n t e

3.4. Pginas Amarelas a


mensagem . a d d R e c e i v e r ( d f d s [ 0 ] . getName ( ) ) ; // Def i n o c o n t e u d o da mensagem mensagem . s e t C o n t e n t ( Pedido ) ; // Envio a mensagem myAgent . send ( mensagem ) ; } catch ( FIPAException e ) { e . printStackTrace () ; } }
93

65

84

87

90

}) ; } } 

Vamos executar o agente Pedinte, solicitando ajuda para um doente, e posteriormente um agente Mdico. A troca de mensagens entre esses agentes e o DF est ilustrada na e a Figura 3.10. java jade.Boot Pedinte:Solicitante2(doente) java jade.Boot Medico:Medico

3.4. Pginas Amarelas a

66

Figura 3.10: Pginas Amarelas - Noticaao. a c

Observe que o pedido de noticaao ao DF ocorre com a seguinte linha de cdigo: c o ACLMessage mgs = DFService.createSubscriptionMessage(this, getDefaultDF(), dfd, null); Da mesma maneira que pedimos a noticaao, podemos pedir para que no sejamos c a mais noticados quando um determinado agente se registrar. Neste caso basta executar o mtodo createCancelMessage(Agent a, AID dfName, ACLMessage subscribe), onde e os parmetros so respectivamente o agente noticado, a AID do DF, e a mensagem de a a noticao inicial. No nosso exemplo, o objeto msg da classe ACLMessage ser a menca a sagem de noticaao e podemos pedir que no sejamos noticados com a seguinte linha c a (considerando que estamos dentro de um comportamento): DFService.createCancelMessage(myAgent, getDefaultDF(), msg);

3.5. Pginas Brancas a

67

3.5

Pginas Brancas a

Podemos consultar os agentes existentes na plataforma com uma busca nas pginas brana cas da plataforma. De acordo com o padro FIPA, quem realiza este servio o AMS a c e (Agent Management Service). Para realizarmos a busca temos que importar as bibliotecas jade.domain.AMSService, jade.domain.FIPAAgentManagement e jade.domain.AMSService, para que os mtodos de interao com o AMS estejam dispon e ca veis. Uma busca nas pgia nas brancas d-se pelo mtodo search() da classe AMSService. Este mtodo retorna um a e e vetor de objetos AMSAgentDescription. Por padro o resultado desta busca retorna apenas um agente na plataforma. Para a que possamos informar que desejamos obter todos os agentes da plataforma, devemos passar como parmetro do mtodo search() um objeto da classe SearchConstraints. a e Na Caixa de Cdigo 3.18 temos um agente que busca por todos os agentes contidos na o plataforma. A explicao da implementaao est contida nos comentrios do cdigo. ca c a a o
import import import import import

Cdigo 3.18: AgenteBuscaAMS.java o


j a d e . c o r e . Agent ; j a d e . c o r e . AID ; j a d e . domain . AMSService ; j a d e . domain . FIPAAgentManagement . ; j a d e . domain . FIPAException ;

public c l a s s AgenteBuscaAMS extends Agent {


9

12

15

18

21

24

27

protected void s e t u p ( ) { try { // Quero b u s c a r q u a i s a g e n t e s e s t a o na p l a t a f o r m a AMSAgentDescription [ ] a g e n t e s = null ; // Crio o b j e t o S e a r c h C o n s t r a i n t s para d e f i n i r // que d e s e j o t o d o s os r e s u l t a d o s S e a r c h C o n s t r a i n t s c = new S e a r c h C o n s t r a i n t s ( ) ; //O m todo s e t M a x R e s u l t s i n d i c a o n mero de r e s u l t a d o s e u // que d e s e j o o b t e r . Por d e f i n i o , 1 s i g n i f i c a t o d o s . ca c . s e t M a x R e s u l t s (new Long ( 1) ) ; // b u s c o p e l o s a g e n t e s // AMSService . s e a r c h ( a g e n t e que busca , v e t o r de r e t o r n o , c a r a c t e r s t i c a s ) a g e n t e s= AMSService . s e a r c h ( this , new AMSAgentDescription ( ) , c ) ; // Capturo minha AID AID myAID = getAID ( ) ; f o r ( int i =0; i <a g e n t e s . l e n g t h ; i ++) { AID agenteID = a g e n t e s [ i ] . getName ( ) ; // Imprimo t o d o s os a g e n t e s // E s t e a g e n t e s e r i d e n t i f i c a d o com para d i f e r e n c i a r a

3.6. Protocolos de Interaao c

68

30

// dos demais System . out . p r i n t l n ( ( agenteID . e q u a l s (myAID) ? "***" : " + i + ": " + agenteID . getName ( ) ) ; } } catch ( FIPAException ex ) { ex . p r i n t S t a c k T r a c e ( ) ; } // F i n a l i z o a g e n t e doDelete () ; // F i n a l i z o a p l i c a o ca System . e x i t ( 0 ) ; }

" )

33

36

39

42

} 

Vamos executar a seguinte linha de comando: java jade.Boot -gui Com esta linha, conforme j vimos, executamos as ferramentas grcas da plataforma. a a Mas tambm temos trs agentes que so criados com o parmetro -gui: o AMS, o DF e o e e a a RMA. Vamos agora executar o agente Buscador, que ir buscar nas pginas brancas quais a a agentes que esto na plataforma e imprimir a lista de agentes encontrados. Executamos a o agente Buscador com a seguinte linha de comando: java jade.Boot -container Buscador:AgenteBuscaAMS E obtemos o seguinte resultado: ***0: Buscador@lap:1099/JADE 1: RMA@lap:1099/JADE 2: df@lap:1099/JADE 3: ams@lap:1099/JADE

3.6

Protocolos de Interao ca

O padro FIPA especica um conjunto de protocolos que podem ser empregados na padroa nizaao das conversas entre os agentes. Para cada conversa, a plataforma JADE distingue c entre dois papis: o papel do iniciador, atribu ao agente que inicia a conversa, e o papel e do do participante, representando o agente que responde ao ato comunicativo executado pelo iniciador. JADE proporciona as classes AchieveREIniciator e AchieveREResponder para a implementaao dos protocolos no estilo do fipa-request, tais como: c

3.6. Protocolos de Interaao c fipa query; fipa request-when; fipa subscribe.

69

Figura 3.11: Estrutura dos Protocolos Baseados no fipa-request.

O comportamento dessas classes baseado em uma mquina de estados nito, semee a lhante ao FSMBehaviour. A Figura 3.11 ilustra a estrutura dos protocolos de interaao c do tipo fipa-request. O iniciador envia uma mensagem com um determinado ato comunicativo. O participante pode responder um not-understood ou um refuse, assim como pode enviar uma mensagem agree indicando que est disposto a realizar a ao a ca do ato comunicativo.

3.6. Protocolos de Interaao c

70

O participante executa a aao e, nalmente, deve responder com uma mensagem inc form indicando o resultado da aao, ou com uma mensagem failure caso algo de errado c ocorra.

3.6.1

Classe AchieveREInitiator

O iniciador envia uma mensagem aos agentes participantes e espera por suas respostas. Ainda que esteja esperando uma mensagem inform como resposta, deve estar tambm e preparado para um refuse, not understood ou failure. Por exemplo, considere um agente que inicia um protocolo fipa-request. Este deve construir uma mensagem ACL indicando a performativa (request) e o protocolo empregado. Com isto, basta informar o receptor o contedo da mensagem. Finalmente, o u agente adiciona um comportamento do tipo AchieveREInitiator passando como referncia o agente iniciador (ele, no caso) e a mensagem a ser enviada. Neste caso, nosso e agente est preparado para receber mensagens inform deste protocolo, por isto o mesmo a possui implementado o mtodo handleInform(). Esta implementaao est na Caixa de e c a Cdigo 3.19. o Cdigo 3.19: AchieveREInitiator o ACLMessage r e q u e s t = new ACLMessage ( ACLMessage .REQUEST) ; r e q u e s t . s e t P r o t o c o l ( FIPAProtocolNames . FIPA REQUEST) ; r e q u e s t . a d d R e c e i v e r (new AID( " receptor " , AID .ISLOCALNAME) ; myAgent . addBehaviour ( new A c h i e v e R E I n i t i a t o r ( myAgent , r e q u e s t ) { protected void h a n d l e I n f o r m ( ACLMessage i n f o r m ) { System . out . p r i n t l n ( " Protocolo Finalizado ." ) ; } }) ; 

3.6.2

Classe AchieveREResponder

Esta classe proporciona a implementao do papel do participante. E muito importante ca passar as conguraoes da mensagem como argumento no construtor desta classe, pois c assim ser poss saber quais tipos de mensagens ACL sero recebidas. Utiliza-se um a vel a MessageTemplate para criar o padro de mensagens a ser recebida, informando o protocolo a em que esta mensagem deve estar envolvida para poder ser lida. A utilizaao da classe AchieveREResponder ser implementada a seguir com a utilic a zaao de um exemplo. c

3.6.3

Exemplo de Implementao do Protocolo FIPA-Request ca

O protocolo request utilizado quando um agente solicita a outro que execute alguma e aao. O participante pode aceitar ou recusar o pedido, e em caso de aceit-lo, dever c a a

3.6. Protocolos de Interaao c

71

Figura 3.12: Protocolo fipa-request.

realizar o que lhe foi pedido e indicar ao iniciador quando a execuao do pedido estiver c conclu da. A Figura 3.12 ilustra a troca de mensagens entre os agentes iniciador e participante no protocolo request. Observe que existe um mtodo que representa uma ou mais respostas e neste protocolo. Vamos desenvolver uma aplicaao mais robusta do nosso exemplo do agente Alarmado c e do agente Bombeiro. Nesta aplicao no existe mais um agente Bombeiro e sim um ca a agente Central de Bombeiros. A comunicaao entre estes agentes ser regida pelo proc a tocolo request. O agente Alarmado (instncia da classe FIPARequestAlarmado) avisa da a existncia de um incndio a uma determinada distncia aos agentes Bombeiro, que agora e e a esto na Central de Bombeiros instncia da classe FIPARequestCentraldeBombeiros. a a As centrais esto sempre alertas sobre chamadas informando sobre incndios. Recebido a e

3.6. Protocolos de Interaao c

72

o aviso, cada central possui uma certa distncia mxima que pode atuar e se a distna a a cia estiver dentro do limite permitido, a central ir apagar o fogo. Existe tambm uma a e probabilidade de 20% de faltar gua para o combate ao incndio. a e O cdigo das classes FIPARequestAlarmado e FIPARequestCentraldeBombeiros eso to nas Caixas de Cdigo 3.20 e 3.21, respectivamente. Para auxiliar o entendimento dos a o mtodos, consulte a Figura 3.12 para entender o que cada mtodo representa dentro do e e protocolo e seu momento de execuao. c

import import import import // para import

Cdigo 3.20: FIPARequestAlarmado.java o


j a d e . c o r e . Agent ; j a d e . c o r e . AID ; j a d e . l a n g . a c l . ACLMessage ; jade . proto . AchieveREInitiator ; implementar o p r o t o c o l o r e q u e s t importamos a s e g u i n t e c l a s s e : j a d e . domain . FIPANames ;

public c l a s s FIPARequestAlarmado extends Agent {


9

protected void s e t u p ( ) {
12

15

18

21

24

27

Object [ ] a r g s = getArguments ( ) ; i f ( a r g s != null && a r g s . l e n g t h > 0 ) { System . out . p r i n t l n ( " Solicitando ajuda a v rias centrais de a bombeiros ..." ) ; \\ montando a mensagem a s e r e n v i a d a p o s t e r i o r m e n t e ACLMessage msg = new ACLMessage ( ACLMessage .REQUEST) ; f o r ( int i = 0 ; i < a r g s . l e n g t h ; i ++) { msg . a d d R e c e i v e r (new AID ( ( S t r i n g ) a r g s [ i ] , AID .ISLOCALNAME) ) ; } msg . s e t P r o t o c o l ( FIPANames . I n t e r a c t i o n P r o t o c o l . FIPA REQUEST) ; msg . s e t C o n t e n t ( "Fogo a 5 kms" ) ; / A c l a s s e I n i c i a d o r ( a b a i x o ) e x t e n d e a c l a s s e AchieveREInitiator , ela a t u a como o i n i c i a d o r do p r o t o l o c o . Seu m todo c o n s t r u t o r e n v i a e automaticamente a mensagem que e s t no o b j e t o msg / a addBehaviour (new I n i c i a d o r ( this , msg ) ) ; } else { System . out . p r i n t l n ( " Especifique o nome de pelo menos uma central de bombeiros " ) ; } } c l a s s I n i c i a d o r extends A c h i e v e R E I n i t i a t o r {

30

33

3.6. Protocolos de Interaao c

73

36

39

42

// e n v i a a mensagem r e q u e s t para os r e c e p t o r e s que foram e s p e c i f i c a d o s no o b j e t o msg public I n i c i a d o r ( Agent a , ACLMessage msg ) { super ( a , msg ) ; // p a r met ro s = a g e n t e que e s t enviando , a a mensagem a s e r e n v i a d a } //Os m todos a s e g u i r tratam a r e s p o s t a do p a r t i c i p a n t e e // Se o p a r t i c i p a n t e concordar , i s t o , e n v i a r uma mensagem AGREE e protected void handleAgree ( ACLMessage a g r e e ) { System . out . p r i n t l n ( " Central de bombeiros " + a g r e e . g e t S e n d e r ( ) . getName ( ) + " informa que saiu para apagar o fogo" ) ; } // Se o p a r t i c i p a n t e s e negar , e n v i a n d o uma mensagem REFUSE protected void h a n d l e R e f u s e ( ACLMessage r e f u s e ) { System . out . p r i n t l n ( " Central de bombeiros " + r e f u s e . g e t S e n d e r ( ) . getName ( ) + " responde que o fogo est muito longe " + a "e n~ o pode apag -lo" ) ; a a } // Se o p a r t i c i p a n t e n o entendeu , e n v i a n d o uma mensagem NOT a UNDERSTOOD protected void handleNotUnderstood ( ACLMessage notUnderstood ) { System . out . p r i n t l n ( " Central de bombeiros " + notUnderstood . g e t S e n d e r ( ) . getName ( ) + "por algum motivo n~ o entendeu a a solicita ~ o " ) ; ca } // Se houve uma f a l h a na e x e c u o do p e d i d o ca protected void h a n d l e F a i l u r e ( ACLMessage f a i l u r e ) { // V e r i f i c a i n i c i a l m e n t e s e f o i um e r r o nas p g i n a s b r a n c a s a i f ( f a i l u r e . g e t S e n d e r ( ) . e q u a l s ( getAMS ( ) ) ) { System . out . p r i n t l n ( " Alguma das centrais de bombeiro n~ o a existe " ) ; } / O c o n t e u d o de uma mensagem e n v o l v i d a n e s t e p r o t o c o l o automaticamente e c o l o c a d o e n t r e p a r n t e s e s . Com o m todo s u b s t r i n g ( ) podemos l e r apenas e e o que e s t d e n t r o d e l e s . / a else { System . out . p r i n t l n ( " Falha na central de bombeiros " + f a i l u r e . g e t S e n d e r ( ) . getName ( ) + ": " + f a i l u r e . g e t C o n t e n t ( ) . s u b s t r i n g ( 1 , f a i l u r e . g e t C o n t e n t ( ) . length ( ) 1) ) ; } }

45

48

51

54

57

60

63

66

3.6. Protocolos de Interaao c

74

69

72

//Ao f i n a l i z a r o p r o t o c o l o , o p a r t i c i p a n t e e n v i a uma mensagem inform protected void h a n d l e I n f o r m ( ACLMessage i n f o r m ) { System . out . p r i n t l n ( " Central de bombeiros " + i n f o r m . g e t S e n d e r ( ) . getName ( ) + " informa que apagou o fogo" ) ; } } }  import import import import import import import import import import import

75

Cdigo 3.21: FIPARequestCentraldeBombeiros.java o


j a d e . c o r e . Agent ; j a d e . c o r e . AID ; j a d e . l a n g . a c l . ACLMessage ; jade . proto . AchieveREInitiator ; j a d e . domain . FIPANames ; j a d e . domain . FIPAAgentManagement . NotUnderstoodException ; j a d e . domain . FIPAAgentManagement . R e f u s e E x c e p t i o n ; j a d e . domain . FIPAAgentManagement . F a i l u r e E x c e p t i o n ; j a d e . l a n g . a c l . MessageTemplate ; j a d e . p r o t o . AchieveREResponder ; java . u t i l . StringTokenizer ;

12

public c l a s s FIPARequestCentraldeBombeiros extends Agent {


15

public double DISTANCIA MAX ; protected void s e t u p ( ) {

18

21

24

DISTANCIA MAX = ( Math . random ( ) 1 0 ) ; System . out . p r i n t l n ( " Central " + getLocalName ( ) + ": Aguardando alarmes ..." ) ; //Meu a g e n t e c o n v e r s a s o b o p r o t o c o l o FIPA REQUEST MessageTemplate p r o t o c o l o = MessageTemplate . MatchProtocol ( FIPANames . I n t e r a c t i o n P r o t o c o l . FIPA REQUEST) ; MessageTemplate p e r f o r m a t i v a = MessageTemplate . MatchPerformative ( ACLMessage .REQUEST) ; MessageTemplate padrao = MessageTemplate . and ( p r o t o c o l o , performativa ) ; addBehaviour (new P a r t i c i p a n t e ( this , padrao ) ) ;

27

} c l a s s P a r t i c i p a n t e extends AchieveREResponder {

30

public P a r t i c i p a n t e ( Agent a , MessageTemplate mt) { // D e f i n e a g e n t e e p r o t o c o l o de comunica o ca

3.6. Protocolos de Interaao c


super ( a , mt) ; }
36

75

33

/ Mtodo que aguarda uma mensagem REQUEST, d e f i n i d a com o uso do e o b j e t o mt , u t i l i z a n d o no c o n s t r u t o r d e s t a c l a s s e . O r e t o r n o d e s t e m todo uma mensagem que e n v i a d a automaticamente e e e para o i n i c i a d o r . / protected ACLMessage p r e p a r e R e s p o n s e ( ACLMessage r e q u e s t ) throws NotUnderstoodException , R e f u s e E x c e p t i o n { System . out . p r i n t l n ( " Central " + getLocalName ( ) + ": Recebemos uma chamada de " + r e q u e s t . g e t S e n d e r ( ) . getName ( ) + " dizendo que observou um inc^ ndio " ) ; e

39

42

45

/A c l a s s e S t r i n g T o k e n i z e r p e r m i t e que v o c s e p a r e e ou e n c o n t r e p a l a v r a s ( t o k e n s ) em q u a l q u e r formato . / S t r i n g T o k e n i z e r s t = new S t r i n g T o k e n i z e r ( r e q u e s t . g e t C o n t e n t ( ) ) ; S t r i n g conteudo = s t . nextToken ( ) ; // pego p r i m e i r o t o k e n i f ( conteudo . e q u a l s I g n o r e C a s e ( "fogo" ) ) { // s e f o r f o g o s t . nextToken ( ) ; // p u l o o segundo int d i s t a n c i a = I n t e g e r . p a r s e I n t ( s t . nextToken ( ) ) ; // c a p t u r o DIST i f ( d i s t a n c i a < DISTANCIA MAX) { System . out . p r i n t l n ( " Central " + getLocalName ( ) + ": Saimos correndo !" ) ; ACLMessage a g r e e = r e q u e s t . c r e a t e R e p l y ( ) ; a g r e e . s e t P e r f o r m a t i v e ( ACLMessage .AGREE) ; return a g r e e ; // e n v i a mensagem AGREEE } else { // Fogo e s t l o n g e . Envia Mensagem R e f us e com o motivo a System . out . p r i n t l n ( " Central " + getLocalName ( ) + ": Fogo est longe demais . N~ o podemos atender a a a solicita ~ o ." ) ; ca throw new R e f u s e E x c e p t i o n ( "Fogo est muito longe " ) ; a } } // e n v i a mensagem NOT UNDERSTOOD else { throw new NotUnderstoodException ( " Central de Bombeiros n~ o a entendeu sua mensagem " ) ; } }

48

51

54

57

60

63

66

69

// Prepara r e s u l t a d o f i n a l , c a s o t e n h a a c e i t a d o

3.6. Protocolos de Interaao c

76

72

75

78

81

protected ACLMessage p r e p a r e R e s u l t N o t i f i c a t i o n ( ACLMessage r e q u e s t , ACLMessage r e s p o n s e ) throws F a i l u r e E x c e p t i o n { i f ( Math . random ( ) > 0 . 2 ) { System . out . p r i n t l n ( " Central " + getLocalName ( ) + ": Voltamos de apagar o fogo." ) ; ACLMessage i n f o r m = r e q u e s t . c r e a t e R e p l y ( ) ; i n f o r m . s e t P e r f o r m a t i v e ( ACLMessage .INFORM) ; return i n f o r m ; // e n v i a mensagem INFORM } else { System . out . p r i n t l n ( " Central " + getLocalName ( ) + ": Ficamos sem gua" ) ; a throw new F a i l u r e E x c e p t i o n ( " Ficamos sem gua" ) ; a } } }  }

84

Na classe FIPARequestCentraldeBombeiros existe os seguintes cdigos em seu mo e todo setup():

MessageTemplate protocolo = MessageTemplate.MatchProtocol (FIPANames.InteractionProtocol.FIPA_REQUEST); MessageTemplate performativa=MessageTemplate.MatchPerformative (ACLMessage.REQUEST); MessageTemplate padrao=MessageTemplate.and(protocolo, performativa); Um agente da classe FIPARequestCentraldeBombeiros implementa o papel de participante do protocolo request e, por isto, o mesmo implementa a classe AchieveREResponder, e no construtor desta classe faz-se necessrio passar qual o padro de mensagens que ele a e a est aguardando. Estas linhas de cdigo criam um objeto padrao da classe MessageTemplate a o que ir fazer com que o agente aceite apenas mensagens do protocolo request e mensaa gens do tipo request. Para execuo deste cenrio vamos utilizar um ambiente distribu ca a do. Conforme j a vimos, a plataforma JADE trabalha com o conceito de containers, representando um ambiente onde os agentes podem executar seu ciclo de vida. Onde os agentes esto a rodando, deve possuir uma JRE e as bibliotecas da plataforma JADE para que estes funcionem perfeitamente. A Figura 3.13 ilustra este conceito. Em uma plataforma sempre temos o main-container, aquele iniciado primeiro, composto pelo DF e AMS, alm de outros agentes. Observe que quando inicivamos outro e a agente em um mesmo computador, inclu amos o parmetro -container, isto representa a a criao de outro container. ca

3.6. Protocolos de Interaao c

77

Figura 3.13: Plataforma Distribu JADE. da

O que vamos fazer nesta execuo alocar alguns agentes em uma mquina e outros ca e a em outra que esto ligadas em rede. O nosso agente Alarmado executar em um container a a em uma mquina da plataforma. As centrais dos bombeiros estaro na outra mquina da a a a rede. Vamos denir que a mquina que contar o main-container da plataforma a mquina a a e a 1, que contm as centrais. Vamos iniciar as centrais no main-container. Para isto, em e nossa mquina 1 (denominada de PC-1) executamos a seguinte linha: a java jade.Boot C1:FIPARequestCentraldeBombeiros C2:FIPARequestCentraldeBombeiros C3:FIPARequestCentraldeBombeiros Com isto, temos o seguinte resultado: Central C1: Aguardando Alarmes...

3.6. Protocolos de Interaao c Central C2: Aguardando Alarmes... Central C3: Aguardando Alarmes...

78

Na outra mquina da rede (PC-2) executamos o agente Alarmado, com a seguinte linha a de comando: java jade.Boot -host PC-1 -container Alarmado:FIPARequestAlarmado(C1 C2 C3) Com esta linha de comando, informamos onde o main-container est, no caso o paa rmetro -host indica que este est no computador PC-1. Com a execuo do agente a a ca Alarmado, observamos no prompt da mquina PC-1: a Central C1: Recebemos uma chamada de Alarmado@PC-1:1099/JADE dizendo que observou um inc^ndio. e Central C2: Recebemos uma chamada de Alarmado@PC-1:1099/JADE dizendo que observou um inc^ndio. e Central C3: Recebemos uma chamada de Alarmado@PC-1:1099/JADE dizendo que observou um inc^ndio. e Observe que mesmo estando na mquina PC-2, as mensagens indicam que o agente a Alarmado est no PC-1. Isto ocorre pois o nome padro de uma plataforma o nome a a e da mquina onde est o main-container. Mas o agente Alarmado est executando na a a a mquina PC-2. a Agora temos o seguinte resultado, de acordo com as probabilidades denidas para nossos agentes centrais: Central C1: Saimos correndo! Central C2: Fogo est longe demais. N~o podemos atender a solicitaao. a a c~ Central C3: Fogo est longe demais. N~o podemos atender a solicitaao. a a c~ Neste mesmo instante, no prompt do PC-2 observamos o seguinte: Central de bombeiros C1@PC-1:1099/JADE informa que saiu para apagar o fogo. Central de bombeiros C2@PC-1:1099/JADE informa que o fogo est muito longe e n~o pode apag-lo. a a a Central de bombeiros C3@PC-1:1099/JADE informa que o fogo est muito longe e n~o pode apag-lo. a a a Agora, como a Central de Incndio C1 aceitou apagar o fogo, ela notica que o fogo e est apagado para o agente alarmado. Obtemos a seguinte linha: a Central de bombeiros C1@PC-1:1099/JADE informa que apagou o fogo.

Referncias Bibliogrcas e a
[Bellifemine, Caire e Greenwood 2007]BELLIFEMINE, F. L.; CAIRE, G.; GREENWOOD, D. Developing Multi-Agent Systems with JADE (Wiley Series in Agent Technology). [S.l.]: John Wiley & Sons, 2007. ISBN 0470057475. [Blaya 2005]BLAYA, J. A. B. Tutorial bsico de JADE. [S.l.], Febrero 2005. a [JADE Wikispaces]JADE WIKISPACES. Programacon JADE. [S.l.]. Dispon vel em: <http://programacionjade.wikispaces.com>. Acesso em: 22 Dez 2007. [Vaucher e Ncho]VAUCHER, J.; NCHO, A. JADE Tutorial and Primer. [S.l.]. Dispon vel em: <www.iro.umontreal.ca/ vaucher/Agents/Jade/JadePrimer.html>. Acesso em: 22 Dez 2007.

79

Vous aimerez peut-être aussi