JACK——PaintRobot Exercise10

来源:http://aosgrp.com/

 

Exercise 10

Synchronise the message protocol between the part and the robot.

 

Introduction

In the previous example, we found that while the robot was painting a part, it was possible for it to receive requests to perform other tasks. If there is nothing in the plans to make them wait until the robot is not busy, the robot may begin a new task and change paintColour before it has finished painting a particular part. There are various schemes you may have thought of to deal with this. Some of them may require features in JACK that we have not yet covered, such as using a beliefset to store the robot state and waiting until the robot is no longer busy before servicing the next request.

In this exercise, we illustrate the use of @reply to set up a protocol between the part and the robot. The part sends the request to the robot, then waits for a reply before continuing to the end of the SendPaintCommand plan. The SendPaintCommand plan is executed in response to the PaintRequest event that is posted using postEventAndWait() inside the submitPaintRequest() method. As it uses postEventAndWait(), the method will not return until the SendPaintCommand plan has completed. This means that the next submitPaintRequest() in the main thread will not be invoked until the part involved in the previous request has received a reply to indicate that it has been painted.

Of course, if any other Paint events are sent to the robot from elsewhere, it is still possible to have the problems we experienced in Exercise 9. In Exercise 11, we will use an alternative solution to avoid this problem.

The @reply statement takes the form:

   @reply(OriginalMessageEvent, ReplyMessageEvent)

The @reply statement is used by an agent to reply to a message that it has received from another agent. It replies to the sending agent with a message event which arrives as a data object on the reply queue of the original message. This is illustrated in the following code fragment:

   // In the part's sending plan.
 
   plan SendPaintCommand extends Plan
   {
      #sends event Paint pev;
         :
         :
 
      body()
      {
         // Need to have an instance of the MyMessage event to use
         // with replied() and getReply()
         Paint q = pev.paint(...);
 
         //Send to robot1
         @send("robot1",q);
         @waitFor(q.replied());
 
         // Finished is an event defined in your system
         Finished fev = (Finished) q.getReply();
 
         // Do something with reply
           :
           :
      }
   }
 
   // In the robot's receiving plan
   plan PaintCurrentColour extends Plan
   {
      #handles event Paint pev;
      #sends event Finished rev;
                :
                :
 
      body()
      {
                :
                :
         @reply(pev, rev.finished(...));
                :
                :
      }
   }

Note that the message event that is returned using @reply does not trigger a new task or plan.

 

Instructions

1. Remove the DisplayFinished plan from the project by removing it from the plans folder in the browser. This is achieved by right-clicking on the plan and selecting Remove "DisplayFinished" from the pop-up menu. Note that you also need to remove the #handles external event Finished declaration from the PaintRequesting capability.

2. Modify the SendPaintCommand plan so that after it sends a Paint message to the robot it waits for a reply. When it receives the reply it uses getReply() to access the reply (which will be a Finished event). It must then print a message to indicate that it (the agent name), has been painted a particular colour. The colour is available from the reply (i.e. the Finished event).

If editing the file as a JACK file, save and close the file before continuing.

3. Modify the robot's paint plans, so that when they complete painting a part they use @reply to reply with a Finished event (which conveys the colour that the part was painted). Remove the @send statements that were used to send the Finished event in the earlier exercises.

If editing the file as a JACK file, save and close the file before continuing.

4. Save the project.

5. Compile and run the program with the interaction diagram.

 

示例程序

 

运行结果:

(1) test with red

(2) Painting part the new colour requested - red

(3) Painting part the new colour requested - red 2nd coat

(4) part1@%portal has been painted red

(5) test with no specified colour

(6) No specified colour. Painting the part red

(7) part2@%portal has been painted red

(8) test with green

(9) Painting part the new colour requested - green

(10) Painting part the new colour requested - green 2nd coat

(11) part3@%portal has been painted green

(12) test with green

(13) Painting the part the current colour green

(14) part4@%portal has been painted green

 

运行结果分析:

由于Part Agent在submitPaintRequest()方法中使用同步的postEventAndWait()方法,当外部调用该方法时,若该方法未执行完成,则能很好的阻塞外部现成。同时在SendPaintCommand规划body()推理方法中,使用@waitFor,一直需要等到Robot Agent的回复@reply,才能继续执行下去,否则程序阻塞在此处。而该规划不完成则之前调用的submitPaintRequest()方法不能完成。因此,这种方法无论从内部还是外部(main)都能很好进行控制,虽然外部main方法中有4个Part Agent提交绘制请求,但能保证Robot Agent顺序执行。

你可能感兴趣的:(paint)