The co-operating bottle collector main procedure

The top-level TeleoR procedure contains several new constructs.

tel communicating_collect_bottles(nat,agent_handle)
communicating_collect_bottles(Total,OthrAg){
>>>
near(robot, _) commit_while min_time 6 ~>
avoid_robot(OthrAg)
% Rules between the chrevron >>> and <<< brackets
% are exception reaction rules for handling
% exceptional events
<<<
% The normal goal directed regression rules start here
$collected + $other_collected >= Total ~> ()
delivered() or_while min_time 5 ~>
[turn(right,0.5):3,move(1.5)] ++
update_and_communicate_count(OthrAg)
holding() & next_to_centre(drop) ~> open_gripper()
holding() ~> get_next_to(drop)
next_to_centre(bottle) & gripper_open() ~> close_gripper()
next_to(bottle,Dir) & gripper_open() ~> turn(Dir,0.3)
gripper_open() ~> get_next_to(bottle)
true ~> open_gripper()
}
As discussed in the previous section, the top-level goal of this agent procedure is the guard of the second rule, not the first rule as is normally the case. The guard of the first rule, near(robot,_), is an exception condition, a condition that if all goes well will not occur. But if it does occur, we must temporarily jump out of the sub-goal regression behaviour of the rules below the <<<, to bring about a situation in which the percept near(robot,_) is no longer received by either robotic agent executing separate calls to communicating_collect_bottles.

Notice that the exception handling rule has a min_time component. This rule is a shorthand for

near(robot, _) commit_while min_time 4 ~> avoid_robot(OthrAg)

and instead of commiting to the rule while a test is true we commit to the rule for 4 seconds. This gives the agent 4 seconds to avoid the conflict.

The third rule uses a or_while. As with commit_while, the test is an alternative to the rule guard after the rule has been fired. The action of the rule will continue while the guard or the test remain inferable, providing no earlier rule in the procedure has an inferable guard. It normally takes a test and in that case it takes over this rule (only) while the test is true. In this case it means that the action sequence [turn(right,0.5):3,move(1.5)] will continue for 5 seconds providing neither of the two earlier rules can fire, that is providing the other robot is not seen as near and the sum of the counts of the delivered bottles does not equal or exceed the target total. Recall that messages are concurrently being received in the agent's message handling thread so a count update message from the agent controlling the other robot may cause the second rule to fire. The first rule will fire if the other robot is seen as close.

This rule also contains the ++ operator. This is a QuLog action that is attached to the rule action and when this rule is fired or refired this action is executed. In this case this action updates it's local count and communicates that to the other agent.

Attached actions are also used in the TeleoR procedure below but in a shorthand form.

tel avoid_robot(agent_handle)
avoid_robot(OthrAg) {

stopped_dir_sent(OtherRobotDir) &
stopped_dir_received(MyRobotDir)
~> avoid_move(MyRobotDir,OtherRobotDir)

other_robot_is_stopped() & near(robot,OtherRobotDir)
~+> send_stopped_dir_remember_sent(OtherRobotDir,OthrAg)

true
~+> send_stopped(OtherAg)
}
The rule operator+> may be used when the TeleoR action is the null action to emphasise that there is no robot action. The last rule of avoid_robot is shorthand for:
true ~> () ++ send_stopped(OtherAg)
The robots avoid one another using the same set of avoidance rules:
tel avoid_move(dir,dir)
avoid_move(MyRobDir,OtherRobDir){

centre_dir(MyRobDir) & centre_dir(OtherRobDir) ~>
[turn(left,0.5):2, move(1.0)]
% Robots see each other head on, both turn left then move forward

MyRobDir=OtherRobDir ~> [turn(MyRobDir,-0.2):2, move(1.0)]
% Each robot sees the other on its left or right. Each turns slightly in opp
% direction to increase divergence of their paths then move forward.

centre_dir(MyRobDir) ~>
[turn(OtherRobDir,-0.4):2, move(1.0)]
% Only this robot sees the other in centre view. Other robot will do
% nothing, as per rule below, until it can no longer see this robot. This
% robot turns to point behind the other robot then moves forward.

centre_dir(OtherRobDir) ~> ()
% Other agent will be doing an avoid move using rule above.
% This robot waits until other robot no longer seen.

true ~> [turn(MyRobDir,-0.4):2, move(1.0)]
% One sees other on its left, the other sees it on its right. Each
% turns slightly away from the other robot. They then pass each other
% slowly. Both are using this rule.
}