La rythmique des agents

L’un des aspects important d’un agent logiciel est son autonomie en terme de traitement. C’est en partie en cela qu’il se distingue d’un simple objet de la Programmation Orienté Objet (POO), ou d’un simple processus. En effet, un agent peut réaliser des traitements quelconques dans la limite des capacités dont il dispose. Et en particulier, il est libre d’opérer ces traitements à n’importe quel instant, à partir du moment ou son état est en cours d’exécution (quand il est à l’arrêt, ou en pause, son activité est stoppé).

Pour exprimer cette autonomie, on utilise le mot comportement pour parler des traitements que réalise un agent. Aussi, du point vu de son implémentation, les traitements réalisés par l’agent son définie dans la méthode de nom behavior (interface AgentU), qui veut dire comportement en anglais.

On pourrait s’attendre à ce que l’on doivent mettre une boucle infinie dans le code de cette méthode, dans la mesure ou l’on considère qu’un agent actif est continuellement en train de faire des traitements. Mais même si c’est tout a fait possible, en pratique on évite de faire cela. En effet, être actif ne signifie pas que l’on soit en permanence en train de réaliser des calculs. D’autant que pour faire ces calculs on à souvent besoin de ressources (un capteur sur lequel faire une lecture par exemple) dont il faut attendre la disponibilité. Et il peut aussi être utile d’attendre un laps de temps avant de refaire un calcul, car le précédent résultat peut rester valable sur une certain durée.

C’est pourquoi on parle de cycle de traitement pour traduire le fait que ces instants ou l’agent réalise réellement des calculs sont inter-coupés par des période d’attente. Et la philosophie de la méthode behavior(…) doit se comprendre comme étant l’implémentation d’une itération du cycle de traitement de l’agent. En d’autres termes : quand cette méthode est déclenchée sur un agent, cela veut dire que c’est un signal qui lui indique que c’est le moment pour lui d’analyser la situation et de réagir en conséquence. Donc de faire les calculs qui sont nécessaire pour le cycle courant.

Bien entendu, le système SKUAD ne dispose pas de lui même des informations nécessaire pour déterminer quels sont les moments opportuns sur lesquels réaliser le déclenchement de la méthode behavior(…) d’un agent. Il revient donc au concepteur du type de l’agent de spécifier ces moments dans le code source de la classe de l’agent. Cela ce fait en utilisant le descripteur de l’agent (voir l’interface AgentUDescriptor dans le tutoriel Les capacités d’un agent/Le descipteur AgentUDescriptor), et plus particulièrement les deux méthodes du groupe « Rythme du comportement » :

//...

//3) Rythme du comportement
public Pulse pulse(String label, long delay, boolean fire_uptodate); //pulse ponctuel
public Pulse loopPulse(String label, long delay, long periode, boolean reset_on_resume); //pulse périodique

//...

Ces méthodes permettent de définir ce qu’on appelle dans SKUAD un pulse. C’est un objet qui représente la configuration d’une rythmique comportementale d’un agent. C’est à dire qui spécifie le, ou les moments sur lesquels la méthode behavior(…) d’un agent doit être déclenchée.

  • La méthode pulse(String label, long delay, boolean fire_uptodate) permet de définir une rythmique ponctuelle : la méthode behavior(…) de l’agent sera déclenchée au terme du délais delay exprimé en milliseconde (ms). L’argument fire_uptodate permet d’indiquer si le décléchement doit quand même avoir lieu à la reprise de l’exécution de l’agent, si celui-ci était dans l’état pause au moment ou le déclenchement prévu devait avoir lieu.
  • La méthode loopPulse(String label, long delay, long periode, boolean reset_on_resume) permet de définir une rythmique périodique : la méthode behavior(…) de l’agent sera déclenchée une première fois au terme du délais delay ms, puis tous les period ms. l’argument reset_on_resume permet d’indiquer si les écarts de période doivent repartir de zéro dans le cas ou l’agent reprend son exécution suite à une pause (resume), ou si on doit maintenir dans la régularité de ces écarts tous les cas de figure (comme si que les mises en pause n’avaient pas lieu).

Ces méthodes retournent chacune l’objet pulse qui représente la définition de la rythmique comportementale produite. Ceux sont des objets de la classe Pulse (package: skuad.agentu), et voici les méthodes disponibles pour cette classe :

  public boolean is(String label);
  public String label();
  public boolean isLoop();    //true ssi c'est une pulsation périodique
   
  public boolean isActive();
  public int count();         //nombre de fois que ce pulse à conduit à une activation
  public boolean cancel();    //désactive ce pulse

Quand la méthode behavior(AgentUDescriptor aud, Pulse pulse) se déclenche, la valeur de son argument pulse porte l’instance de l’objet pulse qui a conduit à ce déclenchement. Cela permet, dans le code de cette méthode, de prendre connaissance du contexte dans lequel l’activation se produit. Et pour affiner cette connaissance, on utilise souvent en début de code la méthode label() de l’objet pulse afin d’obtenir l’étiquette du pulse qui a produit cette activation, afin d’orienter le traitement à réaliser en fonction des objectifs qui ont nécessité d’exprimer la rythmique comportementale correspondante à ce pulse.

Mise en pratique :

Pour mettre en pratique cette rythmique comportementale créez une nouvelle classe agent de nom AgentLogPulse. Dans cette classe vous devez faire en sorte que dès qu’un agent commence son exécution, une rythmique périodique de 3 secondes de période soit spécifiée pour animer son comportement. Vous pourrez choisir d’étiqueter cette rythmique avec le label « TimeToLog ». Et à chaque activation de son comportement sur une pulsation de cette rythmique, l’agent doit produire une action de log avec le texte « Je Pulse ! ».

Transformez ensuite cette classe en un programme qui doit : créer un agent de type AgentLogPulse; faire le nécessaire pour pouvoir tracer ses événements de changement d’état et ses logs; puis lancer l’exécution de cet agent.

A vous de jouer !

Une fois que vous avez réussi à écrire ce programme, ou si vous n’y parvenez pas, vous pouvez comparez votre code à la proposition de solution ci-dessous.

afficher la solution