=Paper=
{{Paper
|id=Vol-1875/intro1
|storemode=property
|title=Concurrent Task Programming of Robotic Agents in TeleoR
|pdfUrl=https://ceur-ws.org/Vol-1875/intro1.pdf
|volume=Vol-1875
|authors=Keith L. Clark,Peter J. Robinson
|dblpUrl=https://dblp.org/rec/conf/ruleml/Clark017
}}
==Concurrent Task Programming of Robotic Agents in TeleoR==
Concurrent Task Programming of Robotic Agents in TeleoR Keith L. Clark1 2 and Peter J. Robinson2 1 Department of Computing, Imperial College London www.doc.ic.ac.uk/~klc klc@ic.ac.uk 2 School if ITEE, University of Queensland, Brisbane www.itee.uq.edu.au/~pjr pjr@itee.uq.edu.au Abstract. TeleoR is a major extension of Nilsson’s Teleo-Reactive (TR) rule based robotic agent programming language. Programs comprise se- quences of guarded action rules grouped into parameterised procedures. The guards are deductive queries to a set of rapidly changing percept and other dynamic facts in the agent’s Belief Store. The actions are either tuples of primitive actions for external robotic resources, to be executed in parallel, or a single call to a TeleoR procedure, which can be a re- cursive call. The guards form a sub-goal tree routed at the guard of the first rule. When partially instantiated by the arguments of some call, this guard is the goal of the call. TeleoR extends TR in being typed and higher order, with extra forms of rules that allow finer control over sub-goal achieving task behaviour. Its Belief Store inference language is a higher order logic+function rule language, QuLog. QuLog also has action rules and primitive actions for updating the Belief Store and sending messages. The action of a TeleoR rule may be a combination of the action of a TR rule and a sequence of QuLog actions. TeleoR’s most important extension of TR is the concept of task atomic procedures, some arguments of which belong to a special but application specific resource type. This allows the high level programming of multi- tasking agents using multiple robotic resources. When two or more tasks need to use overlapping resources their use is alternated between task atomic calls in each task, in such a way that there is no interference, deadlock or task starvation. This multi-task programming is illustrated by giving the essentials of a program for an agent controlling two robotic arms in multiple block tower assembly tasks. It has been used to control both a Python interac- tive graphical simulation and a Baxter robot building real block towers, in each case with help or hindrance from a human. The arms move in parallel whenever it can be done without risk of clashing. 1 Introduction TeleoR is a major extension of Nilsson’s Teleo-Reactive (TR) language [22]. Both are mid-level robotic agent programming languages. They assume basic level 2 Clark & Robinson routines written in procedural programming languages such as C. These routines will do sensor interpretation, particularly for camera images, and may implement quite complex robotic resource control actions such as moving a jointed arm to a given co-ordinate location, or to be next to a detectable object. The results of the sensor interpretation routines become available to the robotic agent as rapidly changing percept facts held in its Belief Store. An ex- ample is on table(1), reporting that a block labelled with the number 1 is ‘seen’ directly on top of the table. A primitive action routine is invoked by the agent when it chooses an action such as put on block(1). This normally, eventually puts the currently held block, say block 8, on top of block 1 providing there is no block directly on top of block 1. Why the caveat normally, eventually? It is because we assume the environ- ment may be affected not only be robotic actions but by exogenous events. Before the action of putting the held block on top of block 1 completes, another block may be placed on top of block 1 by an interfering person, meaning that a required condition for the put on block(1) arm action no longer holds. Block 1 may also be temporarily moved to be out of reach of the arm. Only when there are no interfering exogenous events, or the events do not for ever thwart the robotic action, will the action eventually succeed. TR and TeleoR are languages for deciding to invoke the C implemented arm action because doing so will achieve some logically expressed sub-goal of a current task goal, assuming the current percept beliefs accurately describe the world. This sub-goal might be to have block 8 be directly on top of block 1, on route to a task goal of building the block tower [5,3,8,1]. A simple two thread architecture for a TeleoR agent is depicted in Figure 1. Notice that the percept thread’s update of the Belief Store, and the determining of a new action response, are both atomic. The TeleoR evaluator thread will not start until the Belief Store update is completed, and no percepts update will start until a tuple of robotic actions response has been determined for the new state of the Belief Store. In the next section we describe standard TeleoR syntax, which corresponds to TR syntax, and we informally give the unusual operation semantics of TR and standard TeleoR. The semantics is formally defined in Chapter 5 of [7]. In the next two sections we describe the features of TeleoR not in TR, first for program- ming single task agents, and then for programming multi-tasking agents sharing and interleaving the use of a set of robotic resources to achieve the different but compatible goals of several tasks. We conclude by mentioning related work, and plans for further extensions of TeleoR and our agent architecture. Familiarity with logic programming [19] and robot behavioural programming [16],[20] is useful but not essential. Concurrent Task Programming of Robotic Agents in TeleoR 3 Belief Store Dynamic Percept Facts Fixed Knowledge Rules & Facts Atomic ? Updates Atomic re-evaluation of rule guards after each atomic update Percepts TeleoR Handler ? Evaluator Sensor data Action control as percept messages facts Fig. 1. Simple Two Thread TeleoR Agent Architecture 2 Standard TeleoR procedure syntax and its informal operational semantics A standard syntax TeleoR procedure comprises a parameterised sequence of committed choice guarded action rules of the form: p(X1 ,..,Xk ){ G1 ∼> A1 . . Gn ∼> An } Here the Gi are the guards, the Ai the actions, and the parameters X1 ,..,Xk can appear in any guard or action. When a procedure is called the parameter values partially instantiate the guarded rules. A rule guard is a QuLog query to the agent’s Belief Store. QuLog is a flex- ibly typed higher order logic+function+action rule programming language, see Chapter 3 of [7]. Its dynamic facts constitute the agent’s changing beliefs. Its rules and fixed facts comprise the agent’s knowledge, allowing higher level and context dependent interpretation of the Belief Store dynamic facts. A rule action is a tuple of robotic resource actions executed in parallel, e.g. move(4.5),turn(left,0.5), or a single call to a TeleoR procedure, which may be a recursive call. Example procedure calling an auxiliary procedure Here are two pro- cedures for trying to get a mobile robot close to something Th making use of 4 Clark & Robinson independent move and turn actions, and a general see percept. We use the Prolog convention that variables begin with an upper case letter or underscore. Underscope on its own is an anonymous variable. Multiple occurrences in the same rule denote different unnamed variables. get_close_to(Th){ see(Th,close,_) ∼> () see(Th,near,_) ∼> approach_until(close,Th,3.0,1.0) see(Th,far,_) ∼> approach_until(near,Th,4.5,0.5) true ∼> turn(right,0.5) } approach_until(Dist,Th,Fs,Ts){ see(Th,Dist,_) ∼> () % Th being approached is now Dist away see(Th,_,centre) ∼> move(Fs) see(Th,_,Dir) ∼> move(Fs),turn(Dir,Ts) % Dir is left or right. move forward turning Dir to bring back into centre view. } The underscores in the see conditions of the first procedure, and the first rule of the second procedure, indicate that the orientation of the seen Th is not relevant for the action of the rule. Those in the last two rules of the second procedure indicate that the distance is not relevant. move has one argument, a numerical forward speed. turn has two arguments, a direction of turn left, right or centre and a turn speed. The second call to approach_until has a higher forward speed and a lower correctional turn speed as Th is further away. So, there is more time to bring it back into centre view. see is a three argument percept that identifies the thing seen from a small set of alternative objects that a vision routine can recognise, it gives an approximate qualitive measure of its distance from the robot’s on-board camera as close, near or far. It also indicates whether the centre of the seen thing is more or less in the centre, or to the left or right of the camera image. 2.1 Guards as goals and goal regression The guards of a TeleoR procedure call should lie on a sub-goal tree routed at the guard of the first rule. When partially instantiated by the values of parameters X1 ,..,Xk of some call, this guard instance G1 0 is the goal of the call. The goal of get_close_to(bottle) is ∃Dir see(bottle,close,Dir). The goal of approach_until(near,bottle,4.5,0.5) is ∃Dir see(bottle,near,Dir). The fully instantiated action Aj is started when the guard of the j th rule is the first inferable guard. The action is continued, possible through several Belief Store updates, whilst this is the case. This action execution should normally, eventually result in progression up the sub-goal tree of guards. That is, eventually the guard of the ith rule, where i < j , should become the first inferable guard of the procedure call. Nilsson calls Gj the regression of Gi through Aj . Concurrent Task Programming of Robotic Agents in TeleoR 5 As an example, let us consider the second procedure. Suppose for the call approach_until(near,bottle,4.5,0.5) the last rule is the first rule with an infer- able guard. It must be the case that see(bottle,far,Dir), where Dir is left or right, is the latest percept. If Dir=left, the action is move(4.5),turn(left,0.5). This is move forward accompanied by a concurrent left turn. Providing the see percept in the Belief Store continues to be see(bottle,far,left), this concurrent pair of actions will continue. It should normally eventually result in either the first rule firing, because the latest received percept is see(bottle,near,Dir), for some Dir, or in the second rule firing, because see(bottle,far,centre) is the latest received percept. The reader might like to satisfy themselves that this property holds for all the rules of the two procedures. A similar program is discussed in more detail in Chapter 2 of [7]. Covering all eventualities The partially instantiated guards of a procedure call should also be such that for every Belief Store state in which the call may be active there will be at least one inferable guard. Nilsson calls this the completeness property of a procedure. This property holds for both our example procedures. For the first it trivially holds since the last rule will always be fired if no earlier rule can be fired. It holds for the second procedure given the two guard contexts from which it is called in the first procedure, both of which require a see percept to be in the Belief Store while the call is active. Universal conditional plans Nilsson calls a complete TR procedure satisfying the regression property a universal procedure for achieving its goal for any call. It may also be viewed as a universal conditional plan for achieving its call goals. These concepts also apply to TeleoR procedures. 2.2 Informal operational semantics for a standard TeleoR task A task is launched by calling some procedure such that the task goal is implied by the call’s goal. The first rule of the call with a guard instance inferable from the current Belief Store is fired, resulting in a fully determined action. If this is a procedure call, its first rule with an inferable guard is fired, and so on until a rule with robotic actions is fired. Its actions are started. After each new batch of percepts has arrived, perhaps via a ROS [24] inter- face, this process of finding and firing the first rule of each call with an inferable guard is redone, starting with the initial procedure call. This is in order to de- termine the appropriate tuple of robotic actions response to the new percepts. Actions that were in the last tuple of actions are allowed to continue, perhaps modified. Other actions of the last tuple are stopped. New actions are started. For example, if the last tuple of actions was move(4.5), turn(left,0.5) and the new tuple is just move(3), the turn action is stopped and the move action argument is modified to 3. 6 Clark & Robinson 2.3 Elasticity of complete procedure programs This reactive operational semantics means that each TeleoR procedure is not only a universal conditional plan for each of its call goals, it is also a plan that recovers from setbacks and immediately responds to opportunities. If, after a Belief Store update a higher rule of some call P Call can unexpectedly be fired, perhaps because of a helping exogenous event, that rule will be fired jumping upwards in the task’s sub-goal tree. If instead a lower rule of P Call must be fired, because of a detected unexpected result of some robotic action, or a detected result of a interfering exogenous event, the climb up the sub-goal tree of P Call’s rule guards has restarted from a different sub-goal of the call goal. Often this is a sub-goal of the guard of the rule R that was last fired, and its action is a step towards re-achieving an instance of R’s guard. For our example procedures, for a task call get_close_to(bottle), suppose that initially there is no see percept in the agent’s Belief Store. The last rule of the call will be fired. Assuming there is at least one bottle in the environment of the robot within range of its camera, before the robot has completed a 360 degree turn one of the first three rules should fire. If it is the first rule, the task goal has been achieved. Its () empty action will cause the turn action to be stopped. Now suppose that the bottle is moved away from the robot and the percept see(bottle,far,left) is received. Immediately the program tries to recover from this outside interference by firing the call’s second rule. The third rule of the auxiliary call approach until(near,bottle,4.5,0.5) will then be fired causing the robot to move forward slowly, swerving slightly to the left. As it is doing this, and before either the bottle is seen in centre view or as near, suppose the bottle is moved back to be close to the robot and in view. The robot has been helped. The first rule of get_close_to(bottle) will again be fired, with the result that both the move and the turn actions will be terminated. In fact, if it is only ever called from get_close_to(bottle), the first rule of approach until auxiliary call will never be fired as its firing will always be pre- empted by the firing of a different rule of the parent call. This is typical for an auxiliary procedure. This is because the procedure has been called to achieve the guard of a higher rule of its parent procedure call. That higher rule will be fired as soon as the goal of the auxiliary procedure call has been achieved, pre-empting the firing of the goal achieved rule of the auxiliary call. There is a scenario in which the task goal will never be achieved. This will happen if whenever the robot is about to get close, the bottle is either moved out of sight or further away. The robot will doggedly chase the bottle until its battery runs out. From deliberation to reaction Although not the case for our example pro- cedures, typically, initially called TeleoR procedures query the percept facts through several levels of defined relations. Via procedure call actions, they even- tually call a TeleoR procedure that directly queries the percept facts and mostly Concurrent Task Programming of Robotic Agents in TeleoR 7 has non-procedure call actions. So, for TeleoR and TR the interface between de- liberation about what sub-plans to invoke to achieve a task goal, to the invoking of a sensor reactive behaviour to directly control robotic resources, is a sequence of procedure calls. 3 Extra features of TeleoR for programming single task agents The TeleoR extension of TR was created in two stages. The first stage was to make the language more suited to programming single task agents controlling real robotic resources, perhaps via a ROS interface. A primary concern was to have a compile time guarantee that actions sent out to robotic resources would be fully determined and correctly typed. To this end TeleoR was made a typed language, and the untyped Prolog like Belief Store inference language of TR, as used in [22], was replaced by the typed higher order language QuLog. This has a declarative core of logic + function rules and a top layer of imperative rules. These rules can call relations and functions, but can also execute primitive actions for forking new threads, for updating an agent’s Belief Store dynamic facts, and for inter-agent message communication. 3.1 Type definitions and declarations A TeleoR procedure named p must be given a type declaration of the form: tel p(t1 ,..,tk ) % declaration of the argument types of p where each ti is a QuLog type expression. In addition, the predicate names and argument types of the percept facts must be declared, as well as the names and argument types of the robotic ac- tions. The actions are also classified as discrete or durative. A discrete action executes for a short time and cannot be prematurely terminated, for example a bleep sound. A durative action can be stopped and modified before it naturally terminates, and may not even naturally terminate. An example is move(S) which makes a mobile robot move forwards more or less in a straight line at a speed S. S can be changed causing the robot to speed up or slow down, and the action continues unless explicitly stopped. For our two example procedures we need to have: def thing ::= bottle | basket | .. % Enumerative type def. of the recognisable things def dir ::= left | centre | right def distance ::= close | near | far percept see(thing,distance,dir) % Just one percept relation durative move(num), turn(dir,num) % Two independent durative actions tel get_close_to(thing) % Type declarations for the two TeleoR procs. tel approach_until(distance,thing,num,num) 8 Clark & Robinson The relations that query the percept facts, defined by rules as well as facts, must have their argument types and modes of use declared. The modes of use specify which arguments must be given as fully determined (ground) values, and which can be underspecified, given as an unbound variable or a non-variable term containing variables (a template term) when the relation definition is ‘called’. Arguments that do not need to be ground in the relation call, but which will be given a ground value if the call succeeds, are annotated with a preceding ?. The TeleoR compiler uses the declared types of the parameters of a procedure, which must always be given ground values when it is called, the argument types for the percept relations, and the moded argument types for the program defined and built-in relations, to check that: – each rule guard only has correctly typed calls to percept, rule defined and primitive relations, – all arguments moded as needing to be ground will have ground values when a relation is called in the left to right evaluation of guard conditions, – all variables in the rule’s action will have correctly typed ground values if the guard succeeds. 3.2 Communication and Belief Store update actions We mentioned earlier that a QuLog action call sequence can be optionally added to the robotic action of a TeleoR guarded action rule. The most useful QuLog primitive actions to use are message send actions, and Belief Store update actions. Messages are communicated between agents using our Pedro [27] commu- nications server. This supports both peer-to-peer communication, in which the recipient agent is identified by an email address style agent handle of the form agent name@host name, and publish/subscribe communication. For the latter, the destination of the recipient is given as pedro and the message is forwarded to all agents that have a current subscription lodged with the Pedro server which covers the notified message. As a simple example of the use of a notification and a Belief Store update we could change the first rule of our first example procedure to be see(Th,close,_) ∼> () ++ update_count(Th,OldC); count(Th,OldC+1) to pedro using the QuLog dynamic relation declaration and update action rule dyn count_for(thing,nat) count_for(bottle,0) count_for(basket,0) count_for(....) .... act update_count(thing,?nat) update_count(Th,C) :: count_for(Th,C) ∼> forget count_for(Th,C) remember count_for(Th,C+1) % Atomic update of count for fact for Th Concurrent Task Programming of Robotic Agents in TeleoR 9 Each time the robot gets close to a thing it updates a count fact in the Belief Store of how many times this has happened. It also sends out a notification of the new count value which will be forwarded to every agent that has lodged a covering subscription with the Pedro server of the of form count(_,N) :: integer(N). With communication and Belief Store update actions a single task TeleoR agent now has the three thread architecture of Figure 2. All incoming messages Belief Store Dynamic Percept Facts Fixed Knowledge Rules & Facts ? Atomic Atomic Atomic Updates Atomic re-evaluation Updates Updates of rule guards after each atomic update Percepts Message TeleoR Handler Handler ? Evaluator Sensor data Action control as percept messages facts Messages to Messages from/to other agents/processes other agents/processes Fig. 2. Single Task Three Thread TeleoR Agent Architecture go to the message handling thread which must also lodge and maintain the agent’s Pedro subscriptions. How this is done, and how the agent’s message handling thread handles received messages is outside the scope of this paper. It is explained in Chapters 3 and 4 of [7]. 3.3 New forms of rules in TeleoR These new forms of rule have a different semantics from standard TeleoR style rules with respect to how long their action continue after the rule has been fired. until rules: Guard until UCond ∼>Action When the rule is fired with firing instance Guard0 of its guard, the corresponding fully instantiated Action0 will continue whilst Guard0 remains inferable, even if a higher rule of the procedure call could be fired, providing and the corresponding instance UCond0 of the until condition does not become inferable. As soon as Guard0 is no longer inferable, or UCond0 becomes inferable, a higher rule of the call may be fired. 10 Clark & Robinson while rules: Guard while WCond ∼>Action After the rule as been fired with inferred guard instance Guard0 , the corresponding instance WCond0 becomes an alternative to Guard0 . Providing no earlier rule becomes fireable after a Belief Store update, the corresponding action Action0 will be continued if Guard0 or WCond0 remains inferable. WCond is not an alternative firing condition. The rule is not equivalent to Guard or WCond ∼>Action. while...until rules: Guard while WCond until UCond ∼>Action This rule allows the Action0 action instance to continue even if a higher rule can be fired, providing UCond0 does not become inferable and either Guard0 or WCond0 remains inferable. We shall not need this form of rule for our example program. Communication augmenting perception The TeleoR single task extensions of TR are more fully described in [6]. The paper has an example of the use of communication between two robotic agents each controlling their own mobile robot to co-operatively collect and deliver bottles to a drop area, without the robots colliding. Communication between the agents is used so that each robot knows how many bottles they have jointly collected. Both agents stop their robot when a certain total is reached. Communication, in accordance with a protocol, is also used to compensate for poor vision perception. Each robot ‘sees’ the other robot as another ‘thing’. So another robot can be seen as near to the left of the field of view but the direction of travel of the seen robot cannot be determined. It may be approaching, moving away from, or moving across the path of the seeing robot. Cautious behaviour and communication of what each robot sees regarding the other robot allows the controlling agents to avoid collisions, with minimal divergence from each robot’s current path. 4 Multi-tasking and task atomic procedures The second phase of extension of Nilsson’s TR, and arguably the more important, were changes to the language and the way a source program is analysed and compiled. This was to allow the high level programming of multi-tasking agents dynamically sharing the use of multiple robotic resources. This second extension is the main subject of this paper. Special robotic resource type The resources that must be shared are iden- tified by declaring a special resource type. The granularity of the interleaved sharing of the resources is then specified by the declaration that certain proce- dures that have resource arguments are task atomic. A task atomic procedure call is a critical region for a task. The procedure call may be entered only if all its resource arguments are free. Whilst the task is firing rules of that task atomic call, or an offspring call, no other task can use any of its resource arguments. Concurrent Task Programming of Robotic Agents in TeleoR 11 The resources are released immediately the task atomic call is no longer active, because of a different rule firing in an ancestor call. This frees them for use by a waiting task, or for re-use by the same task if no other task is waiting to use any of the freed resources. Avoiding deadlock To avoid deadlock, only the resource arguments of the first task atomic call T aCall entered by a task T1 may be used throughout the evaluation of T aCall. This is guaranteed by a compiler check that only the re- source arguments of each task atomic procedure T aP are passed as arguments to auxiliary procedure calls that may be made directly or indirectly from T aP . So after having acquired the resource needs of its initial task atomic procedure call, task T1 will not need to wait for extra resources in order to enter an inner task atomic call. The compiler also makes sure that only the resource arguments of T aCall are used as resource arguments of the robotic action of any rule that might be fired by whilst T aCall is active. Deadlock could occur if an extra resource was needed by T1 which was being used by a concurrent task T2, and T2 also required an extra resource being used by T1. Breaking the deadlock by having one task release its resources would mean that its task atomic call was not task atomic. 4.1 Architecture of a multi-tasking agent using multiple resources An agent that can concurrently execute several tasks, using multiple resources, has an architecture as depicted in Figure 3. All the tasks threads are active and on each percepts update they re-compute their sequence of fired rules. The co-ordination of the use of resources is done by the tasks themselves using code generated by the TeleoR compiler for each task atomic procedure. This atomically queries and updates special co-ordination facts in the agent’s Belief Store. These record which tasks are currently running , i.e. inside a task atomic call, and which tasks are currently waiting for resources, and when they started waiting. Because the execution of threads is time shared the waiting start times are unique and define a wait queue order. Separate resources facts record the resource use and resource needs of each task. The running tasks respond to a Belief Store update in any order. If a running task exits its initial task atomic call it typically suspends at the firing of a rule that has a new task atomic call as its action. The compiled code for the task then updates the task’s resources fact to the resource needs of the new call, forgets the task’s running fact, and remembers a waiting fact for the task recording the current time. This puts it at the end of the queue of waiting tasks. The waiting tasks respond to a Belief Store update in wait queue order. The response to a Belief Store update by a waiting task may also result in the need to enter a different task atomic call, with a corresponding update of its resources fact, but not its waiting fact. 12 Clark & Robinson 4.2 Transition from waiting to running preventing starvation After each Belief Store update, after it has determined any change of resource needs, a waiting task will immediately transition to a running task if none of its resource needs are: being used by a running task, needed by a waiting task ahead of it on the wait queue. (As all these other waiting tasks will already have responded to the latest Belief Store update, their recorded resource needs will be up to date.) If this check succeeds, the waiting task immediately transitions to a running task by forgetting its waiting fact and remembering a running fact. Its resources fact is unchanged. Not allowing a waiting task to become a running tasks if a task ahead of it on the wait queue has overlapping resource needs prevents starvation. Task4 BeliefStore Waiting for Fixed TR procs. R1,R5 ? Facts & Rules Task3 Waiting for Dynamic R1,R3 Facts Task1 Task2 Using Using Percepts R1,R2 R3 TR Eval. Handler Threads Control actions for Sensor different data robotic resources Fig. 3. Multi-Task TeleoR Agent Architecture without Communication arm1 arm2 2 6 3 4 9 10 5 7 8 1 table1 shared table2 Fig. 4. Two Arm Multi Tower Building Stable sub-goals to prevent interference of compatible tasks We must have a way for a task to occasionally release resources, but only if the task Concurrent Task Programming of Robotic Agents in TeleoR 13 has achieved a stable sub-goal of its task goal unless the attempt to achieve that sub-goal has been aborted. The stable sub-goal concept was introduced by Benson and Nilsson in [2] for use by a TR multi-tasking scheduler that alternated evaluation of several tasks with no concurrent execution. A stable sub-goal is one that will not be undone by another task when it acquires the released resources. For tasks building towers of different blocks, an un-stable sub-goal would be holding(arm1,3). If the arm1 resource is then acquired by another task, block 3 will be put down somewhere to free the arm, undoing the sub-goal holding(arm1,3). A stable sub-goal would be on(3,1). To avoid interference between tasks, the agent programmer must ensure that only tasks with compatible goals are executed concurrently, and that every task atomic procedure has call goals that are stable. 5 Example of multi-tasking using multiple resources We exemplify TeleoR programming of a multi-tasking multi-resource using agent with a program for an agent sharing two robot arm resources between multiple concurrent configuration tasks. We use the classic block tower configuration task. Two arms are needed as blocks are distributed over three tables as in Figure 4, and each arm can only reach two tables: a home table and a shared table between the two home tables. A task to build a tower using blocks labelled [2,6,3,1] on table2, with block 1 directly on the table, can mostly just use arm2. However, when block 6 needs to be fetched to be put on top of block 3, the task must first use arm1 to move block 6 to the shared table, so arm2 can reach it to put it on top of 3 on table2. So the arms must be dynamically acquired by tower building tasks. Let us suppose the agent has a concurrent task to build tower [4,7,9,10] on table1. (All the concurrent tasks must use different blocks.) That second task can mostly use arm1. However, when 4 needs to be put on top of 7, arm2 must be used to first transfer this block to shared. Since the tasks are running concurrently we cannot allow either task to just start using the other arm when it has the need. A task must wait for the arm it wants to use to be free. Avoiding arm clashes The ability by both arms to reach over to the shared table means there is a risk that one concurrent task will try to use arm1 to fetch a block from that table, at the same time as another task uses arm2 to put down or pickup a block using the table. The arms may then clash. We can avoid this by making the shared table a resource that must be ac- quired before a task can access it, and by assuming that after putting a block down on the shared table an arm immediately and automatically swings back to its home table if not being used straight away to pick up a block from the shared table. For uniformity of programming we make all three tables resources, even though the home tables cannot be used independently of the arm for which they are the home table. 14 Clark & Robinson 5.1 A TeleoR tower builder program for multi-tasking use The percepts will be facts recording which blocks are directly on a table and which blocks are directly on top of other blocks. We also need percepts record- ing that an arm is holding a block and the table above which it is currently positioned. We need a recursive sub tower definition that holds when each block on a list of blocks is directly on top the next block on the list, except for the last block on the list which is directly on a table. A tower is then a sub tower such that the first block is clear - has no block on top of it. We will have durative pickup, put on block and put on table actions that name the arm and table resources that are to be used. For a put on table(Arm,Tab) action we assume there will always be a space on Tab to put down the held block. 5.2 The tower building ontology The key definitions we need are given below. def block ::= 1..16 % blocks are labelled 1 to 16 def arm ::= arm1 | arm2 def table ::= table1 | table2 | shared def resource == arm || table % Union def. of resource type. Must be defined when multi-tasking using multiple % robotic resources. Its values are used as arguments of actions and % task atomic procedures to indicate the resources that they use. percept on(block,block), holding(arm,block), on_table(block,table), over(arm,table) def durative ::= pickup(arm,block,table) | put_on_table(arm,table) | put_on_block(arm,block,table) rel tower(list(block),?table) tower([Block,..Blocks],Tab) <= not exists OnBlk on(OnBlk,Block) & % Block is not covered sub_tower([Block,..Blocks],Tab) rel sub_tower(list(block),?table) sub_tower([Block],Tab) <= on_table(Block,Tab) sub_tower([Block1,Block2,..Blocks],Tab) <= on(Block1,Block2) & sub_tower([Block2,..Blocks],Tab) fun other(arm) -> arm other(arm1) -> arm2 other(arm2) -> arm1 rel can_reach_block(arm,block,?table) % arm can reach block if it is somewhere on table and arm can reach table. can_reach_block(Arm,Block,Tab) <= somewhere_on(Block,Tab) & can_reach_table(Arm,Tab) rel can_reach_table(?arm,?table) can_reach_table(_Arm,shared) % Either arm can reach shared table. can_reach_table(arm1,table1) % Each arm can reach its home table. can_reach_table(arm2,table2) Concurrent Task Programming of Robotic Agents in TeleoR 15 rel somewhere_on(block,?table) % block is either directly on table or is inside a tower on table. somewhere_on(Block,Tab) <= on_table(Block,Tab) somewhere_on(Block,Tab) <= on(Block,UBlock) & somewhere_on(UBlock,Tab) The pattern [Block1,Block2,..Blocks] denotes a list with first two elements Block1 and Block2 with Blocks being the list of remaining elements. As OnBlk only appears in one condition, we can use not on( ,Block) with anonymous variable , implicitly existentially quantified inside the negation. 5.3 The makeTower procedures makeTower has three arguments. The second is the list of blocks to be configured as a tower. The first is the primary arm to be used, and the third is that arm’s home table on which the tower is to be built. task_start makeTower(arm,list(block),table) makeTower(Arm,Blocks,Tab){ tower(Blocks,Tab) ∼> () % Call goal achieved, do nothing sub_tower(Blocks,Tab) & Blocks=[Blk,..Blks] until not holding(Arm,_) ∼> makeClear(Blk,Tab) % Blk, the first block of Blocks, must be covered. Make it clear. until condition % prevents firing of rule 1 until block directly on Blk has been put down on Tab Blocks=[Blk] ∼> moveAcrossToTable(Arm,Blk,Tab) % Should eventually achieve guard of rule 1 Blocks=[Blk1,Blk2,..Blks] & tower([Blk2,..Blks],Tab) ∼> moveAcrossToBlock(Arm,Blk1,Blk2,Tab) % Move of Blk1 to be on top of Blk2 should eventually achieve % guard of rule 1. Both arms and the shared table may need to be used. Blocks=[_,..Blks] ∼> makeTower(Arm,Blks,Tab) % Recursive call action should eventually achieve guard of rule above. } tel moveAcrossToTable(arm,block,table) moveAcrossToTable(Arm,Blk,Tab){ on_table(Blk,Tab) ∼> () % Two rules below are while rules as their guards will not be inferable % after Blk is picked up, but while condition holding(Arm,Blk) will be. can_reach_block(Arm,Blk,BlkTab) & not over(other(Arm),BlkTab) while holding(Arm,Blk) ∼> oneArmMoveToTable(Arm,Blk,BlkTab,Tab) % BlkTab is Arm’s home table or shared. The move to Tab is 16 Clark & Robinson % done task atomically using resources Arm, Tab and possibly shared. OArm=other(Arm) & can_reach_block(OArm,Blk,BlkTab) & not over(Arm,shared) while holding(OArm,Blk) ∼> oneArmMoveToTable(OArm,Blk,BlkTab,shared) % BlkTab is other(Arm)’s home table. Blk must first be task % atomically moved to shared using resources other(Arm), BlkTab, shared. true ∼> () % Rule will fire if arm that will not be used to pick up Blk is seen as being % over shared. So this task waits until it has moved back to its home table. } tel moveAcrossToBlock(arm,block,table,table) % Like moveAcrossToTable using oneArmMoveToTable, oneArmMoveToBlock task_atomic oneArmMoveToTable(arm,block,table,table) % The arm and possibly two tables, the arm’s home table and shared, need % to be available resources for this task before the procedure is entered. oneArmMoveToTable(Arm,Blk,BlkTab,Tab){ on_table(Blk,Tab) ∼> () holding(Arm,Blk) ∼> put_on_table(Arm,Tab) not on(_,Blk) ∼> pickup(Arm,Blk,BlkTab) true ∼> makeClear(Arm,Blk,BlkTab) } tel makeClear(arm,block,table) % makeClear and oneArmMoveToTable are mutually recursive. makeClear(Arm,Blk,BlkTab){ not on(_,Blk) ∼> () on(OthrBlk,Blk) until not holding(Arm,OthrBlk) ∼> oneArmMoveToTable(Arm,OthrBlk,BlkTab,BlkTab) % Do not fire rule 1 until OthrBlk has been put down. } task_atomic oneArmMoveToBlock(arm,block,table,block,table) % Similar rules to the other task atomic procedure The above makeTower procedure has the same number and similar rules to Nils- son’s one arm tower builder given in [22]. Rules 3 and 4 have calls to procedures moveAcrossToTable, moveAcrossToBlock respectively, both of which may need to use both arms. If the block to be moved by a call to moveAcrossToTable is located on the other arm’s home table, it will use two task atomic oneArmMoveToTable calls. The first is to transfer Blk from wherever it is located on BlkTab to shared, using other(Arm). The second is to transfer it from shared to Tab, using Arm. Concurrent Task Programming of Robotic Agents in TeleoR 17 So, when Blk has been placed on shared, another task can acquire shared and/or other(Arm) to do some task atomic move needed for the construction of its tower. If this other task needs shared and Arm, and other(Arm) is not acquired by a task, it will automatically move back to be over its home table. Or, other(Arm) could be acquired by a task just needing to move a block on other(Arm)’s home table. The result would be parallel use of the two arms. We leave the reader to check that all the procedures are universal procedures for their goals. As with the mobile robot TeleoR procedures, these procedures will automatically recover from hindrance and take immediate advantage of help. As an example of recovery from hindrance, suppose that a tower [2,7,3,1] is being built on table1 and [7,3,1] has already been built on the table. Task makeTower(arm1,[2,7,3,1],table1) will call moveAcrossToBlock(arm1,2,7,table1) to move 2 from where ever it may be located to be on top of block 7 by fir- ing its 4th rule. Suppose block 2 is located on shared. The next call will be oneArmMoveToBlock(arm1,2,shared,7,table1), a task atomic call. The task may now have to suspend waiting for its turn to use the three resources arm1, shared, table1. Whilst it is suspended suppose that someone moves block 2 onto table2. The moveAcrossToBlock(arm1,2,7,table1) call will switch to firing its third rule and want to enter the call oneArmMoveToTable(arm2,2,shared), a different task atomic call. As this requires different resources, arm2 and shared, the task may be able to acquire them straight away to put block 2 back onto shared. Regarding taking advantage of help, suppose that while waiting to enter the call oneArmMoveToBlock(arm1,2,shared,7,table1) someone picks up block 2 and puts it on top of 7. When the next batch of percepts arrives recording the new position of block 2, the initial makeTower call will fire its rule 1, task goal achieved. TeleoR Software and Demo Programs The QuLog+TeleoR software, its doc- umentation, demo programs and Python robot simulations can be downloaded from http://staff.itee.uq.edu.au/pjr/HomePages/QulogHome.html. Videos show- ing TeleoR being used to control Python simulated robot arms building block towers, and a Baxter robot using both arms to build real block towers, are avail- able at https://www.doc.ic.ac.uk/∼klc. In each case the controlling agent is both helped and hindered. It uses the arms in parallel whenever this can be done without risk of the ams clashing. 6 Related Work Benson and Nilsson [2] describe a multi-tasking architecture in which TR proce- dures are represented as trees with the regressions represented by branches in the tree. There is a fork in the tree when there are different ways of achieving the guard sub-goal at the fork. Tasks are run one at a time until they achieve a stable sub-goal of their task goal. There is no parallel use of resources. In the TR variant described in [12] rules can have multiple robotic actions to be executed in parallel but no procedure call actions. 18 Clark & Robinson GRUE [11] is a TR architecture especially developed for programming characters in computer games. There is also the concept of a resource, although not in the sense that we use that term. A GRUE resource is not a game character, which would be a resource as we use the term, but an artefact such as money or food that can be acquired by a game character. Choi [4] presents a concurrent extension of the logic based reactive skill de- scription language Icarus [5]. It uses constraints to allocate resources to tasks. Kinny [17] describes an abstract multi-tasking agent programming language with unordered event triggered rules with logic queries as guards. There is con- current task execution but no independently useable resources. GOAL[14] is an agent programming framework that can use a variety of logical representations for the beliefs and knowledge of the agent, although Prolog is normally used. A key component of the agent state is a set of goals. There is no concurrency but the achievement of several goals can be serially interleaved. ConGolog [10] is a concurrent agent programming language based on the situ- ation calculus. Execution can interleave inference selection of actions from a non- deterministic program with additional planner generation of actions. ReadyLog [9] has program constructs for real time reactive control. Soar is a general purpose agent architecture with its roots in cognitive psy- chology. It is a very mature system with many man years of development effort. It was the first cognitive agent architecture to be used for robotic control [13]. FLUX [28], LPS [18] and 2APL [8] are logic based approaches to programming sin- gle task software agents that can be used for robotic agents. None offer compile time guarantees of type and mode safe inference, and of type correct and ground actions. Others [26], [1] acknowledge the need for type safe agent programming languages. GRL [15] and FROB [23] are typed functional robot programming lan- guages. A comprehensive survey of extensions and applications of the teleo-reactive paradigm is given in [21]. 7 Future Work Achieve goal actions and event triggered tasks The main planned fu- ture work is the incorporation of the concepts from the BDI concept language AgentSpeak(L)[25], and its implementation in Jason [3]. We will extend TeleoR rules so that they can have achieve Goal actions in addition to direct procedure calls and tuples of robotic actions. An extra non-deterministic top layer of option selection knowledge rules, perhaps of the form for Goal try ProcCall <= BSQuery can then used to find alternative TeleoR procedure calls that will normally, even- tually achieve their call goal which is or implies instance Goal0 of Goal, where the fired TeleoR rule action is achieve Goal0 . The corresponding instance BSQuery0 of the rule’s pre-condition is an extra Belief Store query that must also succeed in order for the instance ProcCall00 , determined by the match against Goal0 and a Concurrent Task Programming of Robotic Agents in TeleoR 19 successful BSQuery0 evaluation, to be tried. An extended operational semantics for TeleoR could then allow failure of such ProcCalls with backtracking to see if an alternative procedure call might be used for the achieve Goal0 action. As in Jason, these same selection rules can be used when the agent is asked to achieve a goal by another agent. They enable inter-agent task requests at the level of a common descriptive ontology for the environment, and do not require other agents or humans to know the names and argument types of an agent’s TeleoR procedures. We will also add similar rules for starting tasks whenever a significant Belief Store update occurs. These rules generalise the Jason rules for responding to the addition of removal of a single belief, and might have the form on Update do ProcCall <= BSQuery Update is a list of ++p, --q terms where p and q are names of Belief Store dynamic relations. They denote update events, ++p being the event of remembering a new fact for p, --q being the event of forgetting a fact for q. BSQuery will be repeatedly tried immediately after one or more of these update events has occurred. If it succeeds, the corresponding instance of ProcCall will be launched as a new task. Background threads and task scheduling We believe that adding back- ground activity QuLog threads that can learn about the environment, perhaps to construct and/or update a topological map, generalise or abduce beliefs, or discover and repair belief inconsistencies, will enhance the cognitive ability of our robotic agents. One such thread could also respond to goal requests and Belief Store updates that trigger tasks. We will also explore the usefulness of priority scheduling of tasks without task starvation, and the use of knowledge rules to determine when tasks should be suspended and resumed, and when they should be terminated. References 1. M. Baldoni, C. Baroglio, and F. Capuzzimati. Typing Multi-Agent Systems via Commitments. In Proc. of the 2nd Int. Workshop on Engineering Multi-Agent Systems (EMAS 2014), 2014. 2. S. Benson and N. Nilsson. Reacting planning and learning in an autonomous agent. In K. Furukawa, D. Michie, and S. Muggleton, editors, Machine Intelligence 14. Oxford University Press, 1995. 3. R. H. Bordini, J. F. Hubner, and M. Wooldridge. Programming multi-agent systems in AgentSpeak using Jason. Wiley-Interscience, 2007. 4. D. Choi. Concurrent execution in a cognitive architecture. In Proceedings of the 31st Annual Meeting of the Cognitive Science Society. Amsterdam, Netherlands: Cognitive Science Society, 2009. 5. D. Choi and P. Langley. The Icarus Cognitive Architecture. Cognitive Systems Research, 2017. 6. K. L. Clark and P. J. Robinson. Robotic Agent Programming in TeleoR. In Proceedings of International Conference of Robotics and Automation. IEEE, 2015. 20 Clark & Robinson 7. K. L. Clark and P. J. Robinson. Programming Communicating Robotic Agents: A Multi-tasking Teleo-Reactive Approach. Springer, 2018. To appear, first 5 chapters on: teleoreactiveprograms.net. 8. M. Destani. 2APL: A practical agent programming language. Autonomous Agents and Multi-agent Systems, 16:214–248, 2008. 9. A. Ferrein and G. Lakemeyer. Logic-based robot control in highly dynamic do- mains. Robotics and Autonomous Systems, 56:980–991, 2008. 10. G. Giacomo, Y. Lesperance, and H. Levesque. ConGolog, a concurrent program- ming language based on the situation calculus. Artificial Intelligence, 1–2(121):109– 169, 2000. 11. E. Gordon and B. Logan. A goal processing architecture for game agents. In Proceedings of AAMAS, 2003. 12. G. Gubisch, G. Steinbauer, M. Weiglhofer, and F. Wotawa. A teleo-reactive ar- chitecture for fast reactive and robust control of mobile robots. New Frontiers in Applied Artificial Intelligence, pages 541–550, 2008. 13. S. Hanford, O. Janrathitikarn, and L. N. Long. Control of mobile robots using the Soar cognitive architecture. Journal of Aerospace Computing, Information, and Communication, 6(2):69–91, 2009. 14. K. V. Hindriks. Programming Rational Agents in GOAL. In Multi-Agent Pro- gramming: Languages and Tools and Applications, pages 119–157. Springer, 2009. 15. I. Horswill. Functional programming of behavior-based systems. Autonomous Robots, 2000. 16. J. Jones and D. Roth. Robot programming: a practical guide to behavior-based robotics. McGraw-Hill, 2004. 17. D. Kinny. The ψ calculus: An algebraic agent language. In Intelligent Agents VII. Springer, 2002. 18. R. Kowalski and F. Sadri. Teleo-reactive abductive logic programs. In A. Artikis, R. Craven, N. Kesim, B. Sadighi, and K. Stathis, editors, Festschrift for Marek Sergot. Springer, 2012. 19. H. Levesque. Thinking as Computation. MIT Press, 2012. 20. M. J. Mataric. The Robotics Primer. MIT Press, 2007. 21. J. L. Morales, P. Sanchez, and D. Alonso. A systematic literature review of the Teleo-Reactive paradigm. Artificial Intelligence Review, 20(1), 2012. 22. N. J. Nilsson. Teleo-Reactive programs and the triple-tower architecture. Electronic Transactions on Artificial Intelligence, 5:99–110, 2001. 23. J. Peterson, G. Hager, and P. Hudak. Language for declarative robot programming. In International Conference on Robotics and Automation, 1999. 24. M. Quigley, B. Gerkey, K. Conley, J. Faust, T. Foote, J. Leibs, E. Berger, R. Wheeler, and A. Ng. ROS: an open-source Robot Operating System, 2009. At:www.robotics.stanford.edu/∼ang/papers/icraoss09-ROS.pdf. 25. A. S. Rao. AgentSpeak(L): BDI agents speak out in a logical computable lan- guage. In Seventh European Workshop on Modelling Autonomous Agents in a Multi-AgentWorld, LNAI, pages 42–55. Springer, 1996. 26. A. Ricci and A. Santi. Typing Multi-agent programs in simpAL. In Promas, volume 7837 of LNAI. Springer, 2013. 27. P. J. Robinson and K. L. Clark. Pedro: A publish/subscribe server using Prolog technology. Software Practice and Experience, 40(4):313–329, 2010. 28. M. Thielscher. Reasoning Robots: The Art and Science of Programming Robotic Agents. Springer-Verlag, 2005.