sábado, 29 de marzo de 2008

Manejo de comportamientos en JADE

Las tareas o servicios que un agente hace se especifican a través de comportamientos. Un comportamiento (behaviour) hace referencia a una funcionalidad que incorpora el agente. Para que un agente pueda crear uno o más comportamientos debe heredar la clase jade.core.behaviours.Behaviour. Una vez que se ha implementado, el agente puede ejecutar ese comportamiento cada vez que sea invocado dentro del método setup del agente, el cual los anexa al agente a través del metodo addBehaviour perteneciente a la clase Agent.
Se puede pensar que los comportamientos son como los hilos de ejecución en Java (threads), ya que al igual que estos, en un agente pueden ejecutarse a la vez tantos comportamientos como sea necesario. Sin embargo, a diferencia de los hilos, el decidir que comportamiento se ejecuta en cada momento es tarea del desarrollador del agente. Esto es así para que cada agente sea equivalente únicamente a un único hilo, con el consiguiente ahorro de ciclos de CPU y memoria que esto implica.
La creación de los comportamientos se realiza extendiendo la clase jade.core. Behaviours, para lo cual la clase Agent tiene dos métodos para poder agregar o eliminar comportamientos:
  • addBehaviour
  • removeBehaviour

Estos comportamientos pueden ser anexados dentro del método setup (lo habitual), desde cualquier comportamiento, o desde otros agentes. Algunos métodos con los que cuentan los comportamientos son:

  • action: Método que implementa la tarea a realizar.
  • done: Método booleano que comprueba si la tarea ha acabado, eliminándola si retorna true.
  • block: Método que bloquea la ejecución del comportamiento. El bloqueo se hace efectivo cuando el método action retorna, el cual puede ser configurado con un determinado tiempo.
  • restar: Se reinicia explícitamente un comportamiento bloqueado.
  • reset: Retorna el comportamiento a su estado inicial.
  • onStart: Acciones antes de iniciar el comportamiento.
  • onEnd: Acciones antes de finalizar el comportamiento.

JADE no guarda el estado de los comportamientos, razón por la cual es responsabilidad del desarrollador guardar el último estado de este.

Los comportamientos pueden ser agrupados en tres grandes grupos:

  • Comportamientos one-shot: Son aquellos que se ejecutan de manera casi instantánea, y solamente una vez.
  • Comportamientos cíclicos: Son aquellos que nunca son sacados del conjunto de comportamientos del agente y cuyo método action siempre ejecuta el mismo código. Por lo tanto, nunca finalizan.
  • Comportamientos genéricos: Un poco más complejos ya que el código que se ejecuta en ellos depende del estatus del agente, y eventualmente analizan su ejecución.

Otro tipo de comportamientos en JADE son los compuestos, que permiten combinar comportamientos previamente definidos de manera conveniente para aplicarles un orden de ejecución determinado; estos son:

  • Secuenciales a través de SequentialBehaviour.
  • En paralelo a través de ParallelBehaviour.
  • Guiados mediante un autómata finito deterministico a través de FSMBehaviour.

Existen comportamientos a los cuales se les puede definir su ejecución a través de un tiempo de espera; estos son WakerBehaviour y TickerBehaviour, los cuales tienen en común que su ejecución es diferida. Se invocan y aguardan hasta que se ha cumplido un determinado tiempo. El primero de estos solamente se ejecuta una vez y el segundo es un comportamiento cíclico.

Los objetos behaviour describen pequeñas tareas que debe realizar el agente ejecutándose según un planificador que se encuentra implementado en la clase Agent. El planificador va ejecutando según una política round-robin (o por turnos rotatorios) de los objetos behaviour que se encuentran en una cola FIFO.

Los objetos behaviour tienen dos métodos que se deben reescribir, action() y done(). El método action() es en donde se deben desarrollar las tareas que debe realizar el agente, mientras que el método done() es llamado cuando el action() finaliza. El planificador va ejecutando uno a uno los métodos action() de la cola y cuando el método action() de un objeto finaliza se llama al método done(), el cual debe retornar un valor booleano. Si retorna true, el objeto es sacado fuera del planificador ya que se da por concluida su tarea, mientras que si retorna false se vuelve a planificar.

Si en algún momento de la ejecución del método action() se requiere esperar por la llegada de un mensaje, existe el método block() para mandar a una cola de bloqueados cuando el método action() finaliza (no cuando se llama a block()). Cuando se produce la llegada de un mensaje, todos los objetos en la cola de bloqueados se planifican y deben comprobar si el mensaje llegado es para ellos o no. En caso de que un objeto no sea el destinatario del mensaje este debe volver a bloquearse.

Es importante que los métodos action() sean cortos, de esta forma se permite un cierto grado de paralelismo. Si se necesita realizar una tarea que va a requerir un largo periodo de tiempo, entonces el desarrollador deberá dividir la tarea en subtareas y cada una de ellas implementarla mediante un objeto behaviour. Con el fin de ayudar en esta labor, JADE proporciona una jerarquía de clases behaviour, que permite incluso simular maquinas de estados finitos.

  • SimpleBehaviour: Representa un comportamiento atómico.
  • OneShotBehaviour: Representa un comportamiento que se debe ejecutar solo una vez, por eso su método done() retorna true, si no es redefinido.
  • CyclicBehaviour: Representa un comportamiento que debe ejecutarse una serie de veces. El método done, si no es redefinido, devuelve false.
  • SenderBehaviour: Encapsula la acción de envió de un mensaje ACL. Este mensaje debe ser especificado en el constructor.
  • ReceiverBehaviour: Encapsula la acción de recepción de un mensaje ACL. Termina cuando se recibe el mensaje o cuando pasa una cierta cantidad de tiempo especificada en el constructor.
  • WakerBehaviour: Implementa un comportamiento OneShot que se ejecuta justo después de que haya pasado un tiempo especificado.
  • CompositeBehaviour: Esta clase se compone de diferentes sub-behaviours que se pueden ejecutar siguiendo diferentes políticas de planificación, las cuales vienen determinadas por la subclase elegida, las que pueden ser: SequentialBehaviour, ParallelBehaviour y FSMBehavior.
  • SequentialBehaviour: Esta clase deriva de CompositeBehaviour y ejecuta sub-behaviours de forma secuencial, y termina cuando todos los métodos action() han terminado.





  • ParallelBehaviour: Esta clase deriva de CompositeBehaviour y ejecuta los sub-behaviours de manera concurrente. En el constructor de la clase se puede especificar cuando se desea que acabe la ejecución: cuando todos los sub-behaviours lo han hecho, cuando uno termine, o cuando un numero especificado lo logre.





  • FSMBehaviour: Esta clase permite definir una maquina de estados finita mediante sub-behaviours. Cada sub- comportamiento representa un estado de la maquina, y las transiciones se van produciendo según la salida de dichos estados. La finalización se alcanza cuando se termine de ejecutar algún sub-behaviour que se haya registrado como estado final.


Adjunto dos codigos de ejemplo para que vean lo facil que es agregar comportamientos a un agente.

En el proximo post veremos mensajeria y ACL.



viernes, 14 de marzo de 2008

Conceptos básicos de programación de un agente en JADE

Hasta el momento hemos visto parte de la especificación FIPA y algunas de las funcionalidades básicas de JADE….pero falta lo mas importante, la programación de un agente, para luego continuar con un SMA!!!

Para crear un agente en JADE se debe extender la clase jade.core.Agent. Esta contiene dos métodos muy importantes que tienen que ser implementados necesariamente. Estos son setup() y takedown(), los cuales permiten inicializar y finalizar el agente respectivamente.

La siguiente figura muestra la estructura de un agente:






Cada agente del sistema multiagente será una instancia de una clase java que sea subclase de la clase Agent. Esta clase se compondrá básicamente de un método setup, que se ejecutara al iniciarse el agente y que contendrá código de inicialización, incluyendo instrucciones que especificaran la ontología a utilizar y los comportamientos asociados al agente. Además del método setup, se dispondrá de una clase interna a la clase del agente por cada uno de los comportamientos asociados al agente.

Estos comportamientos básicamente se utilizan para el envió y recepción de mensajes, aunque también se podrían realizar otras tareas

A continuación se muestra el código del agente EstructuraBasica, correspondiente a un agente simple al que no se ha asociado ningún comportamiento ni ninguna ontología, y que se tomara como base para implementar los futuros ejemplos de agentes:

package ejemplo1;

import jade.core.Agent;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.DFService;
import jade.domain.FIPAException;

public class EstructuraBasica extends Agent {

protected void setup() {
/* Registrarse con el agente DF */
DFAgentDescription dfd = new DFAgentDescription();
ServiceDescription sd = new ServiceDescription();
sd.setType("EstructuraBasica");
sd.setName(getName());
dfd.setName(getAID());
dfd.addServices(sd);
try {
DFService.register(this,dfd);
}
catch (FIPAException e) {
System.err.println("Problemas : " +e.getMessage());
doDelete();
}
}

}

En este ejemplo se observa como el agente EstructuraBasica es una subclase de Agent y por lo tanto se pueden crear agentes de la clase EstructuraBasica utilizando "java jade.Boot". Todos los agentes heredan la clase jade.core.Agent, para lo cual cada uno de estos al momento de ser creado tiene un identificador único el cual es un objeto de la clase jade.core.AID. El AID que se genera es del tipo:

nombre_agente@host:puerto/JADE

Al momento de crearse el agente se realizan varias tareas automáticamente; algunas de estas son:

  • Se llama al constructor del agente
  • Se crea un identificador del agente (AID)
  • Se registra el agente en el AMS
  • Se ejecuta el método setup

En el método setup se pueden realizar las siguientes operaciones:

  • Modificar el registro del AMS
  • Registra el agente en el DF
  • Agregar los comportamientos (Behaviours) que ejecutara el agente

Otros métodos con los que cuenta la clase Agent son:

  • doDelete: Finaliza la ejecución del agente.
  • TakeDown: Se ejecuta antes de que el agente finalice. Un uso común es el de desregistrar al agente del DF.

La siguiente figura muestra el ciclo de ejecución de un agente:


El acceso a los métodos del DF se realiza importando la clase jade.domain.DFService con la cual se construyen dos tipos de objetos:
  • DFAgentDescription: Permite guardar el nombre del agente y el o los tipos de servicios que este desea registrar.
  • ServiceDescription: Permite guardar el nombre y tipo de servicio que el agente desea registrar.

Hay que recordar que el AMS es un agente de gestión que controla el estado y el acceso a la plataforma. También proporciona un servicio de ”páginas blancas” que permite la localización de agentes a partir de sus nombres, y que el DF proporciona un servicio de “páginas amarillas” al resto de los agentes. Los agentes usan el DF para registrar sus servicios o para obtener los servicios de los demás agentes.

Estos serán unos puntos muy importantes al momento de desarrollar un SMA.

Con esto hasta el momento hemos visto la estructura básica de un agente, los métodos mas importantes que componen las estructura de un agente y una pequeña descripción de estos.

Para que sea mas claro les adjunto un video en el cual se detalla la ejecución de cuatro agentes básicos de ejemplo, estos son:

  • BuscarAMS: Permite obtener una lista de todos los agentes que se encuentren registrados en el AMS.
  • RegistrarDF: Permite registrar un servicio en el directorio facilitador.
  • BuscarDF: Permite obtener un listado de todos los servicios registrados en el directorio facilitador.
  • EjemploCompletoDF: Permite registrar un servicio en el directorio facilitador y obtener un listado de los agentes registrados en el DF que presten un servicio determinado.

En el próximo post veremos los distintos tipos de comportamientos (Behaviours) y comenzaremos a programar nuestros primeros SMA.



viernes, 7 de marzo de 2008

Herramientas de JADE

Hasta el momento hemos visto parte del estándar FIPA, ahora veremos como este se encuentra implementado en JADE.
JADE dispone de un conjunto de herramientas para ayudar en la administración y monitorización de los procesos de depuración del sistema.
Para poder iniciar una sesión y crear los agentes, se debe escribir el siguiente comando en alguna consola de sistema:

java jade.Boot -platform [opciones] [lista de agentes]

En el campo de opciones se puede especificar por ejemplo si se quiere ejecutar el entorno grafico, para lo cual se debe escribir el parámetro “-gui”. Respecto a la lista de agentes, esta debe ser una cadena de texto, donde cada uno de ellos se debe encontrar separado por un espacio en blanco y seguir el siguiente formato:

[Nombre_Agente]:ClasseJava

La siguiente figura muestra la ejecución de la pantalla principal de JADE:

Cuando se ejecuta el entorno grafico, aunque no se inicie ningún agente propio, se crearan tres agentes automaticamente:

  • El agente RMA: El cual se encuentra encargado de controlar la interfaz.
  • El agente DF: En donde se suscribirán los servicios de los agentes.
  • El agente AMS: En donde se guardaran las direcciones de los agentes.

En la parte superior de la interfaz se encuentra la barra de menu, la cual contiene las siguientes opciones:

File:

  • Close RMA Agent: Cierra la interfaz anteriormente mostrada, aunque la plataforma de agentes continuara funcionando, así como todos aquellos agentes que estuvieran activos.
  • Exit this container: Destruye el container donde el agente RMA se aloja, matando a este agente y todos aquellos que le acompañaran dentro del container. Si dicho container es el MainContainer será toda la plataforma la que se desactivara.
  • Shutdown Agent Platform: Cierra totalmente la plataforma, eliminando todos los agentes y containers.

Actions:

  • Start New Agent: Esta acción crea un agente. Al usuario se le preguntara por el nombre del agente y la clase a la cual se instanciara (los agentes son instancias de alguna clase). Si hubiera algún container seleccionado, este será en el que dicho agente se alojara. También se puede indicar el nombre del container en el que se desea ejecutar el agente.
  • Kill: Mata a todos los agentes y elimina todos los containers seleccionados. Si el MainContainer estuviera seleccionado, la plataforma entera seria cerrada.
  • Suspend: Suspende los agentes seleccionados.
  • Resume: Este comando vuelve a poner en estado de activo los agentes seleccionados que estuvieran suspendidos.
  • Send Message: Este comando permite enviar un mensaje ACL a un agente.
  • Migrate Agent: Esta acción permite migrar un agente. Cuando se selecciona, un dialogo es mostrado en donde el usuario debe especificar el container de la plataforma donde el agente seleccionado debe migrar. No todos los agentes pueden ser migrados debido a una falta de serializacion en su implementación.
  • Clone Agent: Esta opción permite clonar un agente. Cuando es seleccionado, un cuadro de dialogo es mostrado donde el usuario debe introducir el nombre del nuevo agente y el container donde será alojado.

Tools:

  • Start Sniffer: Crea un agente de tipo Sniffer. El agente Sniffer es una de las herramientas que proporciona la JADE para la depuración durante el proceso de desarrollo del sistema multiagente. Básicamente permite comprobar como se produce la interacción e intercambio de mensajes entre los agentes que se seleccionen.

Para iniciar el agente Sniffer primero se debe seleccionar el contenedor donde se alojara, y tras ello seleccionar dentro del menú Tools la opción Start Sniffer o pulsar el botón correcto de la barra de botones.

Tras hacer esto se creara un nuevo agente en el contenedor seleccionado. Se le asignara automaticamente un nombre sniffer0 como se muestra en la siguiente imagen de ejemplo:


Asociado al agente Sniffer se dispone de una interfaz grafica en la que se irán viendo los mensajes enviados y recibidos por los distintos agentes que se hayan decidido inspeccionar.

La siguiente figura muestra la interfaz del agente Sniffer:



En la parte superior se dispone de una barra de menús, con una barra de botones debajo correspondiendo cada uno de estos botones con las distintas opciones del primero de los menús. En la parte inferior se dispone de dos paneles. En el de la izquierda se muestra el árbol de plataformas, contenedores y agentes. En la parte derecha se puede ver el intercambio de mensajes entre los agentes seleccionados. Las opciones del menú Actions más importantes, que van a permitir realizar la depuración de la plataforma multiagente que se este desarrollando, son las siguientes:

  • Do sniff this agent(s): Añade el o los agentes seleccionados al panel de la derecha donde se visualiza el intercambio de mensajes.
  • Do not sniff this agent(s): Elimina el agente o los agentes seleccionados del panel de la derecha donde se visualiza el intercambio de mensajes.
  • Show only agent(s): Añade el agente o agentes seleccionados al panel donde se visualiza el intercambio de mensajes, pero solo mostrara el agente, no los mensajes que lleguen hasta el o provengan de el.
  • Clear Canvas: Borra todos los mensajes que estuvieran dibujados hasta el momento en el panel. Se continúa con el proceso de depuración.

Una vez elegidos los agentes para los que se desea observar su intercambio de mensajes, la ventana tendrá un aspecto similar al siguiente:



Los mensajes enviados y recibidos aparecen en orden cronológico comenzando desde la parte superior. Si queremos analizar los distintos campos de un mensaje no tenemos mas que hacer dobleclick sobre el mensaje que deseemos.

Otra opcion es el DummyAgent:

  • Start DummyAgent: Crea un agente de tipo DummyAgent. El agente DummyAgent es otra de las herramientas proporcionadas por JADE para la depuración del sistema multiagente. Se trata de un agente enviador de mensajes que tiene asociado una interfaz grafica que permite indicar los distintos campos del mensaje a enviar, así como visualizar los mensajes enviados y recibidos. Lo primero que se debe hacer para crear un agente de este tipo es seleccionar el contenedor donde se alojara. Después seleccionar la opción Start DummyAgent del menú Tools, o el botón correspondiente de la barra de botones.

Al nuevo DummyAgent se le asignara automaticamente un nombre y se desplegara un cuadro de dialogo con el que se puede acceder a todas las funcionalidades de este, como se muestra en la siguiente figura:


Básicamente se trata de un agente que permite enviar mensajes y visualizar la cola de mensajes enviados y recibidos, ası como los detalles de cada uno de estos mensajes. En la parte superior se dispone de la barra de menús, con una barra de iconos que representan las distintas acciones disponibles. Bajo esta se encuentra una serie de botones cuya funcionalidad coincide con la de las distintas opciones de los menús superiores. La parte principal de la ventana esta dividida en dos. En la izquierda se dispone de una serie de campos donde se puede introducir el valor de los campos del mensaje a enviar. En la parte derecha se muestra la cola de mensajes enviados y recibidos. Haciendo doble-click sobre alguno de estos mensajes se puede ver el valor de cada uno de sus campos. Con respecto a los menús, a continuación se muestra la función de cada una de sus opciones:

Menu General:

  • Exit: Cierra el dialogo del agente DummyAgent, eliminándolo de la plataforma.

Menu Current message:

  • Reset: Vacía todos los campos del mensaje a enviar.
  • Send: Envia el mensaje con los valores de los campos especificados en la parte izquierda del dialogo. Al hacerlo, se mostrara el mensaje, enviado en la cola de mensajes, en la parte derecha de la ventana, así como las contestaciones, en el caso de que las hubiera.
  • Open: Abre un mensaje almacenado en disco.
  • Save: Guarda el mensaje en disco.

Menu Queued message:

  • Open queue: Abre una cola de mensajes almacenados en el disco.
  • Save queue: Guarda la cola de mensajes en disco.
  • Set as current: Toma los valores de los campos del mensaje seleccionado en la cola de mensajes y rellena los campos de la parte izquierda de la ventana correspondientes al mensaje a enviar con dichos valores.
  • Reply: Permite crear un mensaje de respuesta.
  • View: Muestra un cuadro de dialogo donde se puede examinar los valores de los campos del mensaje seleccionado de la cola de mensajes.
  • Delete: Elimina el mensaje seleccionado de la cola de mensajes.
  • Show the DF GUI: Activa la interfaz del agente DF, desde la cual se puede observar los agentes que se han registrado y que servicios ofrecen.

La siguiente figura muestra la interfaz del DF:


Otra opicion es el InstrospectorAgent:

  • Start IntrospectorAgent: Inicia un agente de tipo IntrospectorAgent, mostrando su interfaz asociada. Este agente permite monitorizar y controlar el ciclo de vida de un agente y muestra las colas de entrada y salida de mensaje.

La siguiente figura muestra la interfaz del IntrospectorAgent:



Tambien se encuntr la opcion para ver las peltaformas remotas:

  • Remote Platforms: Este menú permite controlar plataformas remotas que cumplan con las especificaciones FIPA. Estas plataformas no tienen por que ser JADE.

Hasta ahora ya hemos visto de manera rápida parte de la especificación FIPA y como JADE implementa esta y las opciones de las que dispone el framework para administrar los agentes.

En el próximo post comenzaremos con la programación en JADE, veremos la estructura de un agente, como registrarse en el DF, la comunicación con ACL…...y muchas cosas mas que se encuentran en el desarrollo de agentes inteligentes y SMA.

lunes, 3 de marzo de 2008

Ya se encuentra disponible la version 1.0 de JADE-ANDROID

Android es una plataforma para desarrollar aplicaciones para dispositivos móviles que incluyan el sistema operativo realizado por el Open Handset Alliance en Noviembre del 2007(mas información en http://code.google.com/android/ y http://www.openhandsetalliance.com/ ).

El lenguaje de programación en Android es Java, el cual incluye la nueva maquina virtual Dalvik, la cual permite acceder a todas las funcionalidades propias del dispositivo móvil.

La posibilidad de combinar la expresividad de FIPA soportada por los agentes en JADE junto con el poder de la plataforma Android, permitirá el desarrollo de innovadoras aplicaciones basadas en modelos sociales y peer-to-peer.

JADE-Android es distribuido como un add-on de JADE y se encuentra disponible para descarga bajo licencia LGPL en la sitio web de JADE. Este add-on también incluye una aplicación de ejemplo llamada Dummy Agent la cual corre sobre Android SDK m5-rc14

Información mas detallada acerca de como usar JADE-Android puede ser encontrada en la guía del usuario incluida en el archivo de distribución del add-on.

Este será un gran año para la comunidad Jade, ya que junto con este add-on, también tenemos la nueva versión del add-on WSIG (Web Service Integration Getawey) pronto tendremos la nueva versión de JADE y WADE.