Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tutorials:beginner:high_level_plans [2017/08/17 13:45] – Fix code segments cpotutorials:beginner:high_level_plans [2022/03/15 13:29] (current) – [Writing the plans] schimpf
Line 1: Line 1:
-====== Creating action designators for the TurtleSim ======+====== Writing plans for the TurtleSim ======
  
 **Description:** In this tutorial you will learn what action designators are and write high-level plans: you will learn how to define action designators and how to use them. **Description:** In this tutorial you will learn what action designators are and write high-level plans: you will learn how to define action designators and how to use them.
  
-**Previous Tutorial:** [[tutorials:beginner:simple_plans|Implementing simple plans to move a turtle]]+**Previous Tutorial:** [[tutorials:beginner:location_designators_2|Using location designators with the TurtleSim]]\\ 
 +**Next Tutorial:** [[tutorials:beginner:failure_handling|Implementing failure handling for the TurtleSim]]
  
 +To run the code in the tutuorial the roscore and the turtlesim need to be started over the terminal. Each in their own tab.
 +<code bash>
 +$ roscore
 +</code>
 +<code bash>
 +$ rosrun turtlesim turtlesim_node
 +</code>
 +
 +And in the REPL the following commands should be executed:
 +<code lisp>
 +CL-USER>(ros-load:load-system "cram_my_beginner_tutorial" :cram-my-beginner-tutorial)
 +...
 +CL-USER>(in-package :tut)
 +...
 +TUT>(start-ros-node "turtle1")
 +</code>
 ===== Designators: Actions vs Motions ===== ===== Designators: Actions vs Motions =====
  
-On a pragmatic level there is not a big difference between action and motion designators since both are a set of key-value pairs. But the difference lies in the semantics. As mentioned in an earlier tutorial about motion designators, they are meant to represent actual motions of the robot. Like Moving an arm or driving around. The action designators on the other hand should be used to describe abstract plans (e.g. tidying up a room).+On a pragmatic level there is not a big difference between action and motion designators since both are a set of key-value pairs. But the difference lies in the semantics. As mentioned in an earlier tutorial about motion designators, they are meant to represent actual motions of the robot. Like moving an arm or driving around. The action designators on the other hand should be used to describe abstract plans (e.g. tidying up a room).
  
 This difference comes to play when designators are ''performed''. The ''perfom'' function handles action designators differently than motion designators. Both are first referenced and then motion designators are executed by passing them to a matching process module. Action designators are executed by looking up a function with the same name as the resolved designator. The rest of the designator is passed as arguments to the function. Let's take a designator ''(desig:an action (type tidying-up) (what the-room))''. This could be resolved to something like ''(tidy-up the-room)''. So there has to be a function ''tidy-up'' which takes one parameter (''the-room''), for ''perform'' to be able to execute the designator. This difference comes to play when designators are ''performed''. The ''perfom'' function handles action designators differently than motion designators. Both are first referenced and then motion designators are executed by passing them to a matching process module. Action designators are executed by looking up a function with the same name as the resolved designator. The rest of the designator is passed as arguments to the function. Let's take a designator ''(desig:an action (type tidying-up) (what the-room))''. This could be resolved to something like ''(tidy-up the-room)''. So there has to be a function ''tidy-up'' which takes one parameter (''the-room''), for ''perform'' to be able to execute the designator.
Line 20: Line 37:
 ==== Defining the action designators ==== ==== Defining the action designators ====
  
-Let's create new source files for the code in this tutorial (under the ''src'' directory), call them ''action-designators.lisp'' and ''high-level-plans.lisp''. We will need to add the files to the '':components'' of the ''src'' module in your ''cram-beginner-tutorial.asd'', which should now look something like this:+Let's create new source files for the code in this tutorial (under the ''src'' directory), call them ''action-designators.lisp'' and ''high-level-plans.lisp''. We will need to add the files to the '':components'' of the ''src'' module in your ''cram-my-beginner-tutorial.asd'', which should now look something like this:
  
 <code lisp> <code lisp>
-(defsystem cram-beginner-tutorial+(defsystem cram-my-beginner-tutorial
   :depends-on (roslisp cram-language turtlesim-msg turtlesim-srv cl-transforms geometry_msgs-msg cram-designators cram-prolog   :depends-on (roslisp cram-language turtlesim-msg turtlesim-srv cl-transforms geometry_msgs-msg cram-designators cram-prolog
                        cram-process-modules cram-language-designator-support cram-executive)                        cram-process-modules cram-language-designator-support cram-executive)
Line 56: Line 73:
 TUT> (desig:an action (type drawing) (shape rectangle) (width 5) (height 4)) TUT> (desig:an action (type drawing) (shape rectangle) (width 5) (height 4))
  
-#<ACTION-DESIGNATOR ((:TYPE :DRAWING) (:SHAPE :RECTANGLE) (:WIDTH 5) +#<ACTION 
-                     (:HEIGHT 4)) {100B819903}>+    (TYPE DRAWING) 
 +    (SHAPE RECTANGLE) 
 +    (WIDTH 5) 
 +    (HEIGHT 4)>
 </code> </code>
  
Line 76: Line 96:
              (height (second parameters)))              (height (second parameters)))
          (list          (list
-          (list x y 0) 
           (list (+ x base-width) y 0)           (list (+ x base-width) y 0)
-          (list (/ (float (+ x base-width)) 2) (+ y height) 0))))+          (list (+ x (/ (float base-width) 2)) (+ y height) 0) 
 +          (list x y 0))))
       (:rectangle       (:rectangle
        (let ((width (first parameters))        (let ((width (first parameters))
              (height (second parameters)))              (height (second parameters)))
          (list          (list
-          (list x y 0) 
           (list (+ x width) y 0)           (list (+ x width) y 0)
           (list (+ x width) (+ y height) 0)           (list (+ x width) (+ y height) 0)
-          (list x (+ y height) 0)))))))+          (list x (+ y height) 0) 
 +          (list x y 0)))))))
  
-(def-fact-group turtle-action-designators (action-desig) +(def-fact-group turtle-action-designators (action-grounding)
-  (<- (desig:action-desig ?desig (draw-house)) +
-    (desig-prop ?desig (:type :drawing)) +
-    (desig-prop ?desig (:shape :house)))+
  
-  (<- (desig:action-desig ?desig (draw-simple-shape ?vertices)) +  (<- (desig:action-grounding ?action-designator (navigate ?action-designator)) 
-    (desig-prop ?desig (:type :drawing)) +     (desig-prop ?action-designator (:type :navigating)) 
-    (desig-prop ?desig (:shape :rectangle)) +     (desig-prop ?action-designator (:target ?target))) 
-    (desig-prop ?desig (:width ?width)) +  
-    (desig-prop ?desig (:height ?height)) +  (<- (desig:action-grounding ?action-designator (draw-house ?action-designator)) 
-    (lisp-fun get-shape-vertices :rectangle ?width ?height ?vertices))+    (desig-prop ?action-designator (:type :drawing)) 
 +    (desig-prop ?action-designator (:shape :house))) 
 + 
 +  (<- (desig:action-grounding ?action-designator (draw-simple-shape ?resolved-action-designator)) 
 +    (desig-prop ?action-designator (:type :drawing)) 
 +    (desig-prop ?action-designator (:shape :rectangle)) 
 +    (desig-prop ?action-designator (:width ?width)) 
 +    (desig-prop ?action-designator (:height ?height)) 
 +    (lisp-fun get-shape-vertices :rectangle ?width ?height ?vertices)    
 +    (desig:designator :action ((:type :drawing) 
 +                              (:vertices ?vertices)) 
 +                      ?resolved-action-designator)) 
 + 
 +  (<- (desig:action-grounding ?action-designator (draw-simple-shape ?resolved-action-designator)) 
 +    (desig-prop ?action-designator (:type :drawing)) 
 +    (desig-prop ?action-designator (:shape :triangle)) 
 +    (desig-prop ?action-designator (:base-width ?base-width)) 
 +    (desig-prop ?action-designator (:height ?height))     
 +    (lisp-fun get-shape-vertices :triangle ?base-width ?height ?vertices
 +    (desig:designator :action ((:type :drawing) 
 +                              (:vertices ?vertices)) 
 +                      ?resolved-action-designator)))
  
-  (<- (desig:action-desig ?desig (draw-simple-shape ?vertices)) 
-    (desig-prop ?desig (:type :drawing)) 
-    (desig-prop ?desig (:shape :triangle)) 
-    (desig-prop ?desig (:base-width ?base-width)) 
-    (desig-prop ?desig (:height ?height)) 
-    (lisp-fun get-shape-vertices :triangle ?base-width ?height ?vertices))) 
 </code> </code>
  
-Let's see what this code does. The function ''get-shape-vertices'' simply returns a list of vertices for the draw-simple-shape plan to trace. It uses the current position of the turtle to determine those points.+Let's see what this code does. The function ''get-shape-vertices'' simply returns a list of vertices for the draw-simple-shape plan to trace. It uses the current position of the turtle to calculate those points.
  
-The inference is simple again: it maps the shape value to the right call to ''get-shape-vertices'' to get the right list of vertices.+The inference is simple again: it maps the shape value to the right call to ''get-shape-vertices'' to get the right list of vertices. For the ''navigate'' plan it simply extracts the target point from the designator.
  
 Reload the tutorial package in ''roslisp_repl''. This will also load the newly defined inference rules. Reload the tutorial package in ''roslisp_repl''. This will also load the newly defined inference rules.
Line 121: Line 153:
 TUT> (reference (desig:an action (type drawing) (shape rectangle) (width 5) (height 4))) TUT> (reference (desig:an action (type drawing) (shape rectangle) (width 5) (height 4)))
 (DRAW-SIMPLE-SHAPE (DRAW-SIMPLE-SHAPE
- ((3.077953338623047d0 11.088889122009277d0 0) + #<A ACTION 
-  (8.077953338623047d0 11.088889122009277d0 0) +    (TYPE DRAWING) 
-  (8.077953338623047d0 15.088889122009277d0 0) +    (VERTICES ((9.255966663360596d0 10.373946189880371d0 0) 
-  (3.077953338623047d0 15.088889122009277d0 0)))+               (9.255966663360596d0 14.373946189880371d0 0) 
 +               (4.255966663360596d0 14.373946189880371d0 0) 
 +               (4.255966663360596d0 10.373946189880371d0 0)))>)
 TUT> (reference (desig:an action (type drawing) (shape house))) TUT> (reference (desig:an action (type drawing) (shape house)))
-(DRAW-HOUSE)+(DRAW-HOUSE 
 + #<A ACTION 
 +    (TYPE DRAWING) 
 +    (SHAPE HOUSE)>)
 </code> </code>
  
  
 ==== Writing the plans ==== ==== Writing the plans ====
 +
 +> Disclaimer: In this tutorial we omit the package (''desig:'') before the ''a'' and ''an'' macro for better readability.
  
 Append the following to your ''high-level-plans.lisp'' file: Append the following to your ''high-level-plans.lisp'' file:
Line 137: Line 176:
 (in-package :tut) (in-package :tut)
  
-(defun move-without-pen (?goal) +(defun draw-house (&key ((:shape ?shape)) 
-  (exe:perform (a motion (type setting-pen) (off 1))) +                   &allow-other-keys
-  (exe:perform (a motion (type moving) (goal ?goal))) +  (declare (type (or keyword?shape))
-  (exe:perform (a motion (type setting-pen) (off 0)))) +
- +
-(defun draw-house ()+
   (with-fields (x y)   (with-fields (x y)
       (value *turtle-pose*)       (value *turtle-pose*)
     (exe:perform (an action (type drawing) (shape rectangle) (width 5) (height 4.5)))     (exe:perform (an action (type drawing) (shape rectangle) (width 5) (height 4.5)))
-    (move-without-pen (list (+ x 3) y 0))+    (navigate-without-pen (list (+ x 3) y 0))
     (exe:perform (an action (type drawing) (shape rectangle) (width 1) (height 2.5)))     (exe:perform (an action (type drawing) (shape rectangle) (width 1) (height 2.5)))
-    (move-without-pen (list (+ x 0.5) (+ y 2) 0))+    (navigate-without-pen (list (+ x 0.5) (+ y 2) 0))
     (exe:perform (an action (type drawing) (shape rectangle) (width 1) (height 1)))     (exe:perform (an action (type drawing) (shape rectangle) (width 1) (height 1)))
-    (move-without-pen (list x (+ y 4) 0))+    (navigate-without-pen (list x (+ y 4.5) 0))
     (exe:perform (an action (type drawing) (shape triangle) (base-width 5) (height 4)))))     (exe:perform (an action (type drawing) (shape triangle) (base-width 5) (height 4)))))
  
-(defun draw-simple-shape (vertices) +(defun draw-simple-shape (&key 
-  (roslisp:ros-info (turtlesim"Drawing a simple shape (V~a)." vertices+                            ((:vertices ?vertices)) 
-  (dolist (?(append vertices (list (car vertices)))) +                          &allow-other-keys
-    (exe:perform (a motion (type moving) (goal ?v)))))+  (declare (type (or list null) ?vertices))  
 +  (mapcar 
 +   (lambda (?v) 
 +     (exe:perform (an action (type navigating) (target ?v)))) 
 +   ?vertices)) 
 + 
 + 
 +(defun navigate-without-pen (?target) 
 +  (exe:perform (motion (type setting-pen) (off 1))) 
 +  (exe:perform (an action (type navigating) (target ?target))) 
 +  (exe:perform (a motion (type setting-pen) (off 0)))) 
 + 
 +(defun navigate (&key ((:target ?target)) 
 +                 &allow-other-keys) 
 +  (declare (type (or list null) ?target)) 
 +  (exe:perform (a motion (type moving) (goal ?target))))
 </code> </code>
  
-Here we define three plans. ''move-without-pen'' is a helper-plan for moving the turtle between the pieces of the house. It just performs some motions to achieve this. In ''draw-house'' we use the turtle-pose to move the turtle to the position of the next piece by calling ''move-without-pen''. To draw the house we call ''perform'' with the action designators we defined above. These get resolved and ''draw-simple-shape'' is called. There we use the ''dolist'' macro to move the turtle by performing a moving motion for every vertex in vertices. We append the first vertex to verticesto let the turtle move back to the first position at the end.+Here we define three plans and two "helper plans". ''navigate-without-pen'' is a helper plan for moving the turtle between the pieces of the house. It calls the ''navigate'' plan to achieve this. In ''draw-house'' we use the turtle-pose to move the turtle to the position of the next piece by calling ''navigate-without-pen''. To draw the house we call ''perform'' with the action designators we defined above. These get resolved and ''draw-simple-shape'' is called. There we use the ''mapcar'' function to move the turtle by performing a navigating action for every vertex in ''vertices''For now the ''navigate'' plan is pretty barebonesbut we define it as it's own plan because it will be the one to get the failure handling in the next tutorial. Otherwise we could just perform the moving motion.
  
 Now we can test the plan. Now we can test the plan.
Line 166: Line 217:
 TUT> (top-level TUT> (top-level
     (with-process-modules-running (turtlesim-navigation turtlesim-pen-control)     (with-process-modules-running (turtlesim-navigation turtlesim-pen-control)
-      (move-without-pen '(1 1 0))+      (navigate-without-pen '(1 1 0))
       (exe:perform (an action (type drawing) (shape house)))))       (exe:perform (an action (type drawing) (shape house)))))
-[(TURTLE-PROCESS-MODULES) INFO] 1502976852.289: TurtleSim pen control invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE+[(TURTLE-PROCESS-MODULES) INFO] 1503577044.541: TurtleSim pen control invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE
                                                                             SETTING-PEN)                                                                             SETTING-PEN)
                                                                            (OFF                                                                            (OFF
-                                                                            1)) {100B1F2D13}>'+                                                                            1)) {1008B23133}>'
-[(TURTLE-PROCESS-MODULES) INFO] 1502976852.307: TurtleSim navigation invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE+[(TURTLE-PROCESS-MODULES) INFO] 1503577044.559: TurtleSim navigation invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE
                                                                            MOVING)                                                                            MOVING)
                                                                           (GOAL                                                                           (GOAL
                                                                            (1 1                                                                            (1 1
-                                                                            0))) {100CFF8DC3}>'+                                                                            0))) {1009A325A3}>'
-[(TURTLE-PROCESS-MODULES) INFO] 1502976852.598: TurtleSim pen control invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE+[(TURTLE-PROCESS-MODULES) INFO] 1503577047.556: TurtleSim pen control invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE
                                                                             SETTING-PEN)                                                                             SETTING-PEN)
                                                                            (OFF                                                                            (OFF
-                                                                            0)) {100D2AFED3}>'+                                                                            0)) {10088E73D3}>'
-[(TURTLESIM) INFO] 1502976852.610: Drawing a simple shape (V: ((1.0125720500946045d0 1.082411289215088d0 0) +[(TURTLE-PROCESS-MODULES) INFO] 1503577047.573: TurtleSim navigation invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE
-                            (6.0125720500946045d0 1.082411289215088d0 0) +
-                            (6.0125720500946045d0 5.582411289215088d0 0) +
-                            (1.0125720500946045d0 5.582411289215088d0 0)))+
-[(TURTLE-PROCESS-MODULES) INFO] 1502976852.614: TurtleSim navigation invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE+
                                                                            MOVING)                                                                            MOVING)
                                                                           (GOAL                                                                           (GOAL
-                                                                           (1.0125720500946045d0 +                                                                           (6.001096606254578d0 
-                                                                            1.082411289215088d0 +                                                                            1.0863173007965088d0 
-                                                                            0))) {100D8036B3}>'.+                                                                            0))) {1008E02D63}>'.
                                                                                                                                                          
-[ ... ]                                                                            +[ ... ]
                                                                                                                                                          
-[(TURTLESIM) INFO] 1502976879.586: Drawing a simple shape (V: ((1.059867262840271d0 5.014044284820557d0 0) +[(TURTLE-PROCESS-MODULES) INFO] 1503577079.916: TurtleSim navigation invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE
-                            (6.059867262840271d0 5.014044284820557d0 0) +
-                            (3.0299336314201355d0 9.014044284820557d0 0))). +
-[(TURTLE-PROCESS-MODULES) INFO] 1502976879.590: TurtleSim navigation invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE +
-                                                                           MOVING) +
-                                                                          (GOAL +
-                                                                           (1.059867262840271d0 +
-                                                                            5.014044284820557d0 +
-                                                                            0))) {100A8326D3}>'+
-                                                                             +
-[ ... ] +
- +
-[(TURTLE-PROCESS-MODULES) INFO] 1502976886.567: TurtleSim navigation invoked with motion designator `#<MOTION-DESIGNATOR ((TYPE+
                                                                            MOVING)                                                                            MOVING)
                                                                           (GOAL                                                                           (GOAL
-                                                                           (1.059867262840271d0 +                                                                           (1.0146702527999878d0 
-                                                                            5.014044284820557d0 +                                                                            5.501473426818848d0 
-                                                                            0))) {100B6259E3}>'+                                                                            0))) {1003C1D383}>'
-NIL+(T T T) 
 +TUT> 
 </code> </code>