4.3 A Robot Control Architecture
4.3.4 The Example Revisited
This leads us, finally, to the specification of our initial example in cc-Golog. Again, we assume a fluent wheels, which is initially True, set False by grabWheels, and reset by the action releaseWheels.
Πintro= withPol(whenever(battLevel. ≤ 46,
[grabWheels, chargeBatteries, releaseWheels]), withPol(whenever(nearDoor(r6213),
[say(“hello”), waitFor(¬nearDoor(r6213))]),
withCtrl(wheels, deliverMail)))
In this program, nearDoor(r6213) is a macro which is true if the robot’s position is near Door 6213. The outermost policy is waiting until the battery level drops to 46. At this point, a grabWheels is immediately executed, which blocks the execution of the program deliverMail.
4.3. A ROBOT CONTROL ARCHITECTURE 77 It is only after the complete execution of chargeBatteries that wheels gets released so that deliverMail may resume execution (if, while driving to the battery docking station, the robot passes by Room 6213, it would still say “hello”). Note that the cc-Golog program is in a form very close to the original RPL-program we started out with. Hence we feel that cc-Golog is a step in the right direction towards modeling more realistic domains which so far could only be dealt with in non-logic-based approaches. Moreover, with their rigorous logical foundation, it is now possible to make provable predictions about how the world evolves when executing cc-Golog programs.
In order to complete the example, we only need to specify the procedures chargeBatteries and deliverMail. In this example, new subtleties arise due to the fact that the high-priority policy might interrupt a low-level process during execution. In particular, deliverMail might be interrupted by chargeBatteries due to low voltage level while travelling to a room r. If this happens, chargeBatteries will block the further execution of deliverMail and will immediately tell the navigation process to abort its actual task and instead travel to the docking station. It is only after completition of chargeBatteries that deliverMail will become unblocked. By that time, however, the low-level navigation process will have completed execution – the robot is already near the docking station. That is, the navigation process will not cause the robot
to move towards r. So if deliverMail would simply wait for reg(arrivedAt ) = r like Πsimple
(cf. page 73), it would get blocked forever.
In order to avoid this deadlock, deliverMail has to realize that the navigation process is idle, and has to reactivate it. The following cc-Golog procedure represents a possible solution to an interruptible high-level navigation routine leading the robot to room r. It makes use of the fact that the condition reg(arrivedAt ) = reg(destRoom) can be used to determine whether the low-level process has finished execution. If after completion of the navigation process currentRoom is different from r, then the navigation process is activated once again. Thus, gotoRoom(r) only ends if the robot has actually reached room r.
proc(gotoRoom(r),
while(currentRoom6= r,
[send(destRoom, r), reg(arrivedAt ) = reg(destRoom)?]))
The following code sketches a possible realization of deliverMail, which makes use of gotoRoom to assure that the delivery is interruptible. It is defined in terms of the functional fluent letterQueue, which intuitively represents a queue whose elements are the letters that are to be delivered. We assume a predicate empty(letterQueue), which is true if and only if no letter is queued in letterQueue, and two functions top(letterQueue) and destination(l), whose values correspond to the first element of letterQueue respectively to the name of the destination of letter l. Furthermore, we assume appropriate successor state axioms which ensure that the effect of push(l, letterQueue) and pop(letterQueue) is to enqueue a letter, respectively to remove the first element of letterQueue.
proc(deliverMail,
while(¬empty(letterQueue),
[gotoRoom(destination(top(letterQueue))), say(“hello, i got mail for you”),
... /* wait for the user to get her letter */ pop(letterQueue)]))
Finally, the following procedure replaces the earlier definition on page 65, which did not account for the fact that the high-level plans do not directly operate the robot’s physical sensors and effectors.
proc(chargeBatteries,
[gotoRoom(dockingStation), plugIn, waitFor(battLevel≥ 49), plugOut])
Figure 4.5 illustrates a possible projection trace of the example plan Πintro, where the robot
is to deliver two letters to Room 6205 respectively to Room 6214. The robot first delivers a letter to Room 6205 (“1”), and then heads towards Room 6214. During this route, the battery level drops below 46 V, and the mail delivery is interrupted by chargeBatteries (“2”). After recharging its batteries (“3”), deliverMail is reactivated. The routine gotoRoom realizes that the journey towards Room 6214 has been aborted, and issues another send(destRoom, 6214), which causes the robot to move to Room 6214 and complete its journey (“4”).
4 2 1 3
BattStation
Batteries ! low !Rm 6214
Rm 6205
Rm 6213
Figure 4.5: Projection of the mail delivery plan
4.4
Discussion
In this chapter, we have presented an extension of the situation calculus which includes a model of continuous change and a novel approach to modeling the passage of time. The pre- sentation in the sections 4.1.1, 4.1.2 and 4.1.3 essentially follows Pinto [Pin97], in a somewhat simplified form. We then considered cc-Golog, a deterministic variant of ConGolog which is based on the extended situation calculus. A key feature of the new language is the ability to have part of a program wait for an event like the battery voltage dropping dangerously low while other parts of the program run in parallel. For that purpose, we have introduced the special action waitFor, motivated by the fact that a similar instruction is present in many special robot programming languages, in particular in RPL, RAP, PRS-Lite and Colbert. Such mechanisms allow very natural formulations of robot controllers, in particular, because there is no need to state explicitly in the program when actions should occur. On the downside, cc-Golog does not provide nondeterministic instructions.
4.4. DISCUSSION 79 We remark that waitFor cannot be simulated by means of the instructions already present in ConGolog. Although it may seem suggestive to make use of tests (φ?) to react to con- ditions like low voltage level, this does not result in the intended behavior. The problem is that continuously changing conditions are neither true nor false in a given situation, but instead become true at a certain time point. For example, imagine we would run the test nearDoor(6204)? concurrently to deliverMail. Even though deliverMail will cause the robot to come near this door, the nearDoor condition might never be true at the beginning of a situation during the execution trace.
Of course, one could make use of an explicit “clock” which causes time to advance by means of a sequence of discrete “clock tick” actions. However, one objection against the use of a clock is that it is not clear what granularity to choose – the right granularity may depend on the application as well as on the high-level plan considered. Furthermore, the resulting execution traces would be glutted with irrelevant “clock tick” actions. This is particularly undesirable because a large number of clock tick actions may significantly decrease the performance of an implementation. Note that after every clock tick action the interpreter would have to check whether that action unblocks any of the concurrently running sub-plans.
We end this section with some remarks on Reiter’s proposal for a temporal version of GOLOG [Rei98], which makes use of a different temporal extension of the situation calcu- lus [Rei96]. Roughly, the idea is that every primitive action has as an extra argument its execution time. For example, we would write endGo(20) to indicate that endGo is executed at time 20. It turns out that this explicit mention of time is problematic when it comes to formulating programs such as the one from Section 4.3.4. Consider the part about saying “hello” whenever the robot is near Room 6213. In Reiter’s approach, the programmer would have to supply a temporal expression as an argument of the say-action. However, it is far from obvious what this expression would look like since it involves analyzing the mail delivery sub-program as well as considering the odd chance of a battery recharge. In a nutshell, while Reiter’s approach forces the user to figure out when to act, we let cc-Golog do the work. — As a final aside, we remark that waitFor-actions allow us to easily emulate Reiter’s approach within our framework by using a continuous fluent time with value linear(0, 1, 0) and replacing
Chapter 5
On-Line Execution of cc-Golog Plans
Using the high-level language cc-Golog introduced in the last chapter, it is possible to provide quite natural formulations of robot controllers, in particular to specify event-driven actions which react to conditions on the value of continuously changing properties like the robot’s position. So far, however, we have only shown how to project event-driven cc-Golog plans, making use of an extended situation calculus capable of representing continuous change. Up to now, it remains unclear how to actually execute a cc-Golog plan.5 1 2 3 4
Rm 6213
Rm 6205
‘‘In Hallway’’
Figure 5.1: Piece-wise Linear Approximation and Actual Trajectory
To get a sense of the problem, consider a cc-Golog plan telling the robot to move from Room 6213 to Room 6205, and concurrently to react to the continuous condition inHall- way by announcing that it has just reached the hallway (see Figure 5.1). In the previous chapter, we have shown how, based on a model of the robot control architecture and the low-level processes, it is possible to generate projections of such cc-Golog plans. In particular, the projected execution traces include waitFor actions for every node on the approximating trajectory. While the resulting execution traces can be understood as a way of assessing whether a program is executable in principle, they are not suitable as input to the execution mechanism of the robot for several reasons.
For one, many of the actions in the projected execution trace only serve to model the 81
navigation process and are not meant to be executed by the high-level controller at all. For example, the waitFor actions corresponding to the nodes on the approximating trajectory result from the simulation of a cc-Golog program which models the effects of the level-low navigation process. During actual execution, the controller should only issue a message to the low-level navigation process telling it the new destination (i.e. node 5 in Figure 5.1), and the navigation process would then move the robot to its desired location. For another, the time point of actions that do belong to the high-level controller like waitFor(inHallway)
or waitFor(battLevel≤ 46) must be interpreted differently during on-line execution. This is
because during projection, the time point of a waitFor-condition like inHallway or battLevel≤
46 is computed based on an idealized model of the world (like piece-wise linear trajectories and constant energy consumption). However, the robot has no control over the passage of time, and the actual trajectory often follows a function quite different from the idealized approximation (see the curved vs. the straight (dotted) line in Figure 5.1). During actual execution, of course, the robot should react at the actual time where a condition becomes true.
What is needed, it seems, are frequent sensor readings telling the robot about the current time and location, which should be used instead of the models of how time passes or how the robot moves. For example, the robot should react to the actual battery level by periodically reading its voltage meter. A waitFor action would then simply reduce to a test, where a condition like being at a certain location is matched against sensor readings reflecting the actual state of affairs. That is, we opt for an on-line style of execution (cf. Section 2.2) where we distinguish between projection-time and execution-time effects. Thereby, we take advantage from the fact that in our robot control architecture from Section 4.3 there is a clear separation of the actions of the high-level controller from those of low-level processes like the navigation process, and completely ignore the model of the low-level processes during execution.
Apart from this, while projection in cc-Golog so far is limited to a complete program starting in the initial state, one would often like to project on the fly during execution, similar to the search operator of de Giacomo and Levesque [dGL99b]. However, for reasons of limited resources, we would like to go beyond that and allow for a restricted projection of a program, which only searches up to a (temporally) limited horizon. For instance, if the robot is in the middle of a delivery but near the docking station, we want to enable it to find out whether the coming activities would allow it to operate for at least another 5 minutes and, if not, decide to charge the batteries first.
In this chapter, we show how all this can be done in cc-Golog. The chapter is organized as follows: in the next section, we discuss the changes necessary to use the same cc-Golog program both for on-line execution and projection. Thereafter, we show how on-line execution and projection can be interleaved, and introduce a time-bounded projection mechanism that can be used to appeal to on-the-fly projection in cc-Golog programs.
5.1
On-Line Execution of cc-Golog Plans
As mentioned above, during on-line execution of a cc-Golog plan it seems appropriate to make use of frequent sensor readings telling the robot about the current time and location, instead of using the models of how time passes or how the robot moves. In order to see how such sensor
5.1. ON-LINE EXECUTION OF CC-GOLOG PLANS 83
or MINERVA [TBB+99] deal with it. There, we find a tight update loop between the low-level
system and the high-level controller. This update loop periodically provides the high-level controller with an update of the low-level processes’ estimates of continuous properties like the batteries’ voltage level or the robot’s position (typically several times a second). The period of time between two subsequent updates is so small that for practical purposes the latest update can be regarded as providing not only the correct current time but also accurate values of the continuous fluents at the current time.