This is an old revision of the document!


Writing Plans

with-policy

Policies can be used to define generic monitoring behavior that should run concurrently besides main functionality code. Such a policy might be monitoring

  • the position of an object inside a robot gripper to see whether it is moving out of the gripper (losing the object)
  • the position of an object in the real world, in order to keep the robot's head pointing towards it
  • the collision of a robot joint with objects in the real world
  • generic events that must definitely interrupt a certain piece of code, but are too specialized to be implemented directly in the monitored code itself

A policy consists of multiple parts:

  • A name (to identify it)
  • A description string (to make its purpose clear)
  • A parameter list (which can be used to specialize a generic policy for a situation at hand, without generating a new policy every time the situation changes slightly)
  • Code blocks that need to be evaluated during monitoring

Usage example

An example of how to define a policy is shown here. The policy accepts two custom parameters, one defining a maximum number and one a match number. During execution of the main `body` code (which is really just a loop with an output here), it checks a randomly generated number (ranging from `0` to `max-num`) against the match number `match-num`. If this is the case (and it will be, eventually), it interrupts (and ends) the main `body` code and executes the `:recover` code, followed by the `:clean-up` code (both just outputting something here).

(define-policy my-policy (max-num match-num)
  (:description "This is an example policy.")
  (:init (format t "Initializing policy~%")
         t)
  (:check (format t "Checking if random number from 0
                     to ~a equals ~a~%" max-num match-num)
          (let ((rnd (random max-num)))
            (format t "Got number ~a~%" rnd)
            (cond ((eql rnd match-num)
                   (format t "Match~%")
                   t)
                  (t (sleep 1)))))
  (:recover (format t "Running recovery mechanisms~%"))
  (:clean-up (format t "Running clean-up~%")))

The calling code for using the policy uses `with-named-policy` to refer to the name as specified while defining the policy. The second parameter is a list of parameter values for customizing the policy instance. The rest of the code should be pretty self explanatory.

(top-level
  (with-named-policy 'my-policy (10 5)
    (loop do (format t "Main loop cycle.~%")
             (sleep 2))))