javaagents-jade

problems with ACLMessages in JADE


I have written a program and everything looks fine.. but at runtime agents confuse messages. for example I have this code:

ACLMessage msg = new ACLMessages (ACLMessage.INFORM);
msg.setContent = ("G" + groupID);
for(int i =0 ; i<50 ; i++){
    msg.addReceiver(new AID("MyClass" + i, AID.ISLOCALNAME));
}
send (msg);

and assume i receive it like this:

ACLMessage rcv = myAgent.receive();

and assume I define another ACLMessage in another part of the program for example named msg2.. in another block.. with content = "T" + temp.

when I receive the next message I realized that the messages are confused ... they are not received properly. I mean running the code below has 2 different results:

System.out.println("rcv Content is: " + rcv.getContent());

and the result will be: G1 and some times it is: T34

this mistaken messages make my program not to run correctly... I changed message formats like: "T" + groupID + "T" or other forms... but it didn't work..

/////////////////////////////////////////////////// After I learned to use message templates:

 case 17:{// in this case deligates send the avg to the supervisor
                if(!deligateFlag){
                    state++;
                    break;
                }

                ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
                msg.setConversationId("A");
                msg.setContent("V" + avg);
                //System.err.println("Content of rcv is: " + msg.getContent());
                msg.addReceiver(mySupervisor);
                send(msg);
                System.out.println(myAgent.getLocalName() 
                        + " Says: I am deligate of group " 
                        + group 
                        + " And I sent the average temp of my followers "
                        + "to the supervisor which is: " 
                        + mySupervisor.getLocalName());
                state++;
                break;
            }
            case 18:{/* in this case supervisor receives the avg temp of 
                each group and calculates the avg of averages and then 
                decides what to do*/
                if(!supervisorFlag){
                    n=1;
                    state++;
                    break;
                }
                //System.err.println("This is Beginning of case 18");
                if(supervisorFlag){
                    MessageTemplate mt = MessageTemplate.MatchConversationId("A");
                    ACLMessage msg = myAgent.receive(mt);
                    if (msg != null) { System.err.println("TContent is: " + msg.getContent());
                        dAvg += Character.getNumericValue(msg.getContent().charAt(1));

                        if(msg.getContent().charAt(0) == 'V'){
                            n++;
                            System.err.println("N is: " + n);
                        }
                    }
                    if(n > 4){

                                dAvg /= 4;
                                totalAvg = dAvg;
                                System.out.println("Supervisor " 
                                        + myAgent.getLocalName() 
                                        + "Says: The total average of whole system is: " 
                                        + totalAvg);
                        }
                        state++;
                        break;

The problem is, in the best case program runs until if (n>4) .. and everything stops .. no errors, no warnings .. it just stops.. even n goes to 5 but nothing happens ... I do not know what could be the exact problem.. whether ACL messages or I don't know ... generally I don't know why in 90% program doesn't print TContent . what will happen to the messages..


Solution

  • If you want to receive specific aclMessages you can use myAgent.receive(MessageTemplate t).

    For example, you want to send message

    Agent1:

    ACLMessage request = new ACLMessage(ACLMessage.REQUEST);
    ...     
    request.setConversationId("G");
    myAgent.send(request)
    

    And you want your Agent2 to receive only messages with ConversationId = "G"

    Agent2:

    MessageTemplate mt = MessageTemplate.MatchConversationId("G");;
    ACLMessage msg = myAgent.receive(mt);
    if (msg != null) {
      // Process it
      ...
    } else {
       block();
    }