Differences

This shows you the differences between two versions of the page.

Link to this comparison view

tutorials:advanced [2015/05/11 17:04] – created gkazhoyatutorials:advanced [2015/05/11 17:06] (current) – removed gkazhoya
Line 1: Line 1:
-====== Writing Plans ====== 
  
-==== with-policy ==== 
-{{ :doc:with-policy.png?nolink&300|}} 
- 
-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). 
- 
-<code lisp> 
-(define-policy my-policy (max-num match-num) 
-  "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~%"))) 
-</code> 
- 
-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. 
-<code lisp> 
-(top-level 
-  (with-named-policy 'my-policy (10 5) 
-    (loop do (format t "Main loop cycle.~%") 
-             (sleep 2)))) 
-</code> 
- 
-=== Exception handling === 
-When policies are used, multiple failures can be signalled. The most meaningful of those are 
-  * ''policy-not-found'': Signalled when a named policy is used that was not defined before. 
-  * ''policy-init-failed'': Signalled when initialization of a policy went wrong (i.e. '':init'' returned ''nil''). 
-  * ''policy-check-condition-met'': The '':check'' condition of the policy returned a non-''nil'' value, '':recover'' was executed and the ''body'' code was interrupted before it could complete execution. 
- 
-If one wants to monitor the triggering of a policy's '':check'' condition, this can be achieved like this: 
-<code lisp> 
-(top-level 
-  (with-failure-handling 
-      ((policy-check-condition-met (f) 
-         (declare (ignore f))is available that the given 
-         (do-custom-handling-here) 
-         (retry))) ;; Or whatever seems appropriate in your use-case e.g. (return) 
-    (with-named-policy 'my-policy (10 5) 
-      (loop do (format t "Main loop cycle.~%") 
-               (sleep 2))))) 
-</code> 
- 
-=== Using multiple policies at once === 
-When multiple policies are to be used (either a mix of different policies, or the same policy multiple times, each with different parameters), two helpful macros can be used: ''with-policies'' and ''with-named-policies''. Both of these take lists of policies, together with their respective instantiation parameters, as arguments. 
- 
-When policy instances by the names ''my-policy-object'' and ''my-other-policy-object'' should be used, the following code snippet reflects this behaviour. The policy ''my-policy-object'' takes two ''int''s as parameters, while ''is available that the givenmy-other-policy-object'' takes a string as an argument. 
-<code lisp> 
-(with-policies 
-    ((my-policy-object (3 1)) 
-     (my-policy-object (100 4)) 
-     (my-other-policy-object ("Test"))) 
-  (body-code)) 
-</code> 
-In this example, the resulting code will be equivalent to the following: 
-<code lisp> 
-(with-policy my-policy-object (3 1) 
-  (with-policy my-policy-object (100 4) 
-    (with-policy my-other-policy-object ("Test") 
-      (body-code)))) 
-</code> 
- 
-The same princple applies to ''with-named-policies'', with the only difference being that it does not take policy instances, but policy name symbols as parameters: 
-<code lisp> 
-(with-named-policies 
-    (('my-policy (3 1)) 
-     ('my-policy (100 4)) 
-     ('my-other-policy ("Test"))) 
-  (body-code)) 
-</code> 
-This results in the same behavior as: 
-<code lisp> 
-(with-named-policy 'my-policy (3 1) 
-  (with-named-policy 'my-policy (100 4) 
-    (with-named-policy 'my-other-policy ("Test") 
-      (body-code)))) 
-</code> 
- 
-=== Built-in Policies === 
-== timeout-policy == 
-When a piece of code only has a limited maximum amount of time for execution (and must be aborted after that duration), the ''timeout-policy'' comes in handy. 
- 
-Use it like this: 
-<code lisp> 
-(with-policy cpl:timeout-policy (5.0) ; Timeout after 5.0 seconds (fractions may be used) 
-  (body-code-goes-here)) 
-</code> 
-And for catching the check condition when the timeout actually happens: 
-<code lisp> 
-(with-failure-handling 
-    ((policy-check-condition-met (f) 
-      (declare (ignore f)) 
-      (handle-error-here-and-maybe-retry))) 
-  (with-policy cpl:timeout-policy (5.0) 
-    (body-code-goes-here))) 
-</code> 
-The ''timeout-policy'' stops the given ''body'' code after a given amount of time (in seconds) if it hasn't finished by then. This helps to add a ''timeout'' functionality to functions that do not inherently support a timeout mechanism (blocking function calls).