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:location_designators_2 [2017/07/27 08:13] – Rearrange previous tutorial cpotutorials:beginner:location_designators_2 [2022/02/25 23:20] (current) – [Using location designators with the TurtleSim] schimpf
Line 1: Line 1:
 ====== Using location designators with the TurtleSim  ====== ====== Using location designators with the TurtleSim  ======
  
-**Description:** in this tutorial you will learn about location designators, how to create and resolve them. Also, you will write another process module to make use of the location designator.+**Description:** in this tutorial you will learn about location designators, how to create and resolve them. You will expand a process module to make use of the location designator.
  
-**Previous Tutorial:** [[tutorials:beginner:assigning_actions|Automatically choosing a process module for an action]]+**Previous Tutorial:** [[tutorials:beginner:assigning_actions_2|Automatically choosing a process module for an action]]\\ 
 +**Next Tutorial:** [[tutorials:beginner:high_level_plans|Writing plans 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)
 +</code>
 ===== Location designators: an overview ===== ===== Location designators: an overview =====
  
-As mentioned previously, location designators are a way to describe a location in symbolic terms, and have actual coordinates for it generated later, when needed. The crucial difference between location and action designators comes in how they are resolved. We've seen how action designators are resolved via an inference engine (Prolog) operating on a set of rules. Instead of that, location designators make use of a pair of [types of] functions:+As mentioned previously, location designators are a way to describe a location in symbolic terms, and have actual coordinates for it generated later, when needed. The crucial difference between location and motion designators comes in how they are resolved. We've seen how motion designators are resolved via an inference engine (Prolog) operating on a set of rules. Instead of that, location designators make use of a pair of [types of] functions:
  
   * location-generator: creates a lazy list of candidate poses   * location-generator: creates a lazy list of candidate poses
Line 31: Line 46:
 ===== Location designator generators ===== ===== Location designator generators =====
  
-Let's create a new file called ''location-designators.lisp'' in our tutorial's ''src'' directory and add it to the ''*.asd'' file with ''process-modules'' depending on it. The resulting ''cram-beginner-tutorial.asd'' should now look like this:+Let's create a new file called ''location-designators.lisp'' in our tutorial's ''src'' directory and add it to the ''*.asd'' file. The resulting ''cram-my-beginner-tutorial.asd'' should now look like this:
  
 <code lisp> <code lisp>
-(defsystem cram-beginner-tutorial +(defsystem cram-my-beginner-tutorial 
-  :depends-on (cram-language roslisp turtlesim-msg geometry_msgs-msg cl-transforms +  :depends-on (roslisp cram-language turtlesim-msg turtlesim-srv cl-transforms geometry_msgs-msg cram-designators cram-prolog 
-                             cram-designators cram-prolog +                       cram-process-modules cram-language-designator-support cram-executive)
-                             actionlib actionlib_msgs-msg turtle_actionlib-msg +
-                             cram-process-modules cram-language-designator-support)+
   :components   :components
   ((:module "src"   ((:module "src"
Line 45: Line 58:
              (:file "control-turtlesim" :depends-on ("package"))              (:file "control-turtlesim" :depends-on ("package"))
              (:file "simple-plans" :depends-on ("package" "control-turtlesim"))              (:file "simple-plans" :depends-on ("package" "control-turtlesim"))
-             (:file "action-designators" :depends-on ("package")) +             (:file "motion-designators" :depends-on ("package"))
-             (:file "turtle-action-client" :depends-on ("package"))+
              (:file "location-designators" :depends-on ("package"))              (:file "location-designators" :depends-on ("package"))
              (:file "process-modules" :depends-on ("package"              (:file "process-modules" :depends-on ("package"
                                                    "control-turtlesim"                                                    "control-turtlesim"
                                                    "simple-plans"                                                    "simple-plans"
-                                                   "action-designators" +                                                   "motion-designators")) 
-                                                   "turtle-action-client"))))))+             (:file "selecting-process-modules" :depends-on ("package" 
 +                                                             "motion-designators" 
 +                                                             "process-modules"))))))
 </code> </code>
  
Line 62: Line 76:
        (make-designator :location '((:vertical-position :bottom) (:horizontal-position :left))))        (make-designator :location '((:vertical-position :bottom) (:horizontal-position :left))))
 TUT> goal-desig TUT> goal-desig
-#<LOCATION-DESIGNATOR ((:VERTICAL-POSITION :BOTTOM) +#<LOCATION 
-                       (:HORIZONTAL-POSITION :LEFT)) {1008548CD3}>+​    (VERTICAL-POSITION BOTTOM) 
 +    (HORIZONTAL-POSITION LEFT)>
 </code> </code>
  
Line 194: Line 209:
 </code> </code>
  
-Depending on the random number generator we will get some or none of the solutions rejected and, therefore, ''<='' number of valid solutions for our designator ''another-goal''.+Depending on the random number generator we will get some or none of the solutions rejected and, therefore, ''<='' number of valid solutions for our designator ''another-goal''That means, you might get a different number of solutions than what we got: we got 3 but you might be 4 or 5 or something else. 
  
  
 ===== Using a location designator ===== ===== Using a location designator =====
  
-Let's try to create a process module to make use of a location designator as well. Append the following to ''action-designators.lisp'':+Let's try to expand a process module to make use of a location designator as well. Append the following to ''motion-designators.lisp'':
  
 <code lisp> <code lisp>
-(def-fact-group goal-actions (action-desig+(def-fact-group goal-motions (motion-grounding
-  (<- (action-desig ?desig (go-to ?point)) +  (<- (motion-grounding ?desig (go-to ?point)) 
-    (desig-prop ?desig (:type :goal))+    (desig-prop ?desig (:type :going-to))
     (desig-prop ?desig (:goal ?point))))     (desig-prop ?desig (:goal ?point))))
 </code> </code>
  
-This will resolve any action designator with properties ''( (:type :goal) (:goal some-location-designator) )'' into ''(go-to some-location-designator)'' instruction.+This will resolve any motion designator with properties ''( (:type :going-to) (:goal some-location-designator) )'' into ''(go-to some-location-designator)'' instruction.
  
-Now for the process module, let's add a new process module called ''simple-navigation'' that accepts action designators with above-mentioned properties and a function ''goto-location'' that will invoke the new process module. Also, let's add ''simple-navigation'' to the running process modules in our ''with-turtle-process-modules'' macroYou ''process-modules.lisp'' should now look something like this:+Now for the process module, let's add a new case to our navigation process-module that handles motion designators with above-mentioned properties and a function ''goto-location'' that will invoke the process module with the new designatorYour ''process-modules.lisp'' should now look something like this:
  
 <code lisp> <code lisp>
 (in-package :tut) (in-package :tut)
  
-(def-process-module actionlib-navigation (action-designator)+(def-process-module turtlesim-navigation (motion-designator)
   (roslisp:ros-info (turtle-process-modules)   (roslisp:ros-info (turtle-process-modules)
-                    "Turtle shape navigation invoked with action designator `~a'." +                    "TurtleSim navigation invoked with motion designator `~a'." 
-                    action-designator) +                    motion-designator) 
-  (destructuring-bind (command action-goal) (reference action-designator) +  (destructuring-bind (command motion) (reference motion-designator)
-    (ecase command +
-      (draw-shape +
-       (call-shape-action +
-        :edges (turtle-shape-edges action-goal) +
-        :radius (turtle-shape-radius action-goal)))))) +
- +
-(def-process-module simple-navigation (action-designator) +
-  (roslisp:ros-info (turtle-process-modules) +
-                    "Turtle simple navigation invoked with action designator `~a'." +
-                    action-designator) +
-  (destructuring-bind (command action-goal) (reference action-designator)+
     (ecase command     (ecase command
 +      (drive
 +         (send-vel-cmd
 +          (turtle-motion-speed motion)
 +          (turtle-motion-angle motion)))
 +      (move
 +       (move-to motion))
       (go-to       (go-to
-       (when (typep action-goal 'location-designator) +       (when (typep motion 'location-designator) 
-         (let ((target-point (reference action-goal)))+         (let ((target-point (reference motion)))
            (roslisp:ros-info (turtle-process-modules)            (roslisp:ros-info (turtle-process-modules)
                              "Going to point ~a." target-point)                              "Going to point ~a." target-point)
            (move-to target-point)))))))            (move-to target-point)))))))
  
-(defmacro with-turtle-process-modules (&body body+(def-process-module turtlesim-pen-control (motion-designator
-  `(with-process-modules-running +  (roslisp:ros-info (turtle-process-modules
-       (actionlib-navigation +                    "TurtleSim pen control invoked with motion designator `~a'." 
-        simple-navigation+                    motion-designator) 
-     ,@body))+  (destructuring-bind (command motion) (reference motion-designator) 
 +    (ecase command 
 +      (set-pen 
 +       (call-set-pen 
 +        (pen-motion-r motion
 +        (pen-motion-g motion) 
 +        (pen-motion-b motion) 
 +        (pen-motion-width motion) 
 +        (pen-motion-off motion))))))
  
-(defun draw-hexagon (radius+(defun drive (?speed ?angle
-  (let ((turtle-name "turtle1")) +  (top-level 
-    (start-ros-node turtle-name+    (with-process-modules-running (turtlesim-navigation
-    (init-ros-turtle turtle-name+      (let ((trajectory (desig:a motion (type driving) (speed ?speed) (angle ?angle)))) 
-    (top-level +        (pm-execute 'turtlesim-navigation trajectory))))
-      (with-turtle-process-modules + 
-        (process-module-alias :navigation 'actionlib-navigation) +(defun move (?x ?y) 
-        (with-designators +  (top-level 
-            ((trajectory :action `((:type :shape) (:shape :hexagon) (:radius ,radius)))) +    (with-process-modules-running (turtlesim-navigation) 
-          (pm-execute :navigation trajectory))))))+      (let ((goal (desig:a motion (type moving) (goal (?x ?y 0))))) 
 +        (pm-execute 'turtlesim-navigation goal)))))
  
-(defun goto-location (horizontal-position vertical-position)+(defun goto-location (?horizontal-position ?vertical-position)
   (let ((turtle-name "turtle1"))   (let ((turtle-name "turtle1"))
     (start-ros-node turtle-name)     (start-ros-node turtle-name)
     (init-ros-turtle turtle-name)     (init-ros-turtle turtle-name)
     (top-level     (top-level
-      (with-turtle-process-modules +      (with-process-modules-running (turtlesim-navigation) 
-        (process-module-alias :navigation 'simple-navigation) +        (let* ((?area (desig:location 
-        (with-designators +                               (horizontal-position ?horizontal-position) 
-            ((area :location `((:horizontal-position ,horizontal-position) +                               (vertical-position ?vertical-position))) 
-                               (:vertical-position ,vertical-position))) +               (goal (desig:a motion (type going-to) (goal ?area)))) 
-             (goal :action `((:type :goal) (:goal ,area)))) +          (cram-executive:perform goal))))))
-          (pm-execute :navigation goal))))))+
 </code> </code>
  
-And let's give it a goReload the tutorial in ''roslisp_repl'' then in the command line of REPL:+In ''goto-location'' we use ''perform'', which means we have to make sure the right process module for our ''going-to'' designator can be foundFor that we add a rule to the fact-group ''available-turtle-process-modules'' from the ''selecting-process-modules.lisp'' file. The file should now look like this:
  
 <code lisp> <code lisp>
-TUT> (goto-location :center :center+(in-package :tut) 
-[(ROSLISP TOP) INFO] 1453758117.881: Node name is /turtle1 + 
-[(ROSLISP TOP) INFO] 1453758117.881: Namespace is / +(def-fact-group available-turtle-process-modules (available-process-module 
-[(ROSLISP TOP) INFO] 1453758117.885: Params are NIL +                                                  matching-process-module) 
-[(ROSLISP TOP) INFO] 1453758117.885: Remappings are: +  (<- (available-process-module turtlesim-navigation)) 
-[(ROSLISP TOP) INFO] 1453758117.885: master URI is 127.0.0.1:11311 +  (<- (available-process-module turtlesim-pen-control)) 
-[(ROSLISP TOP) INFO] 1453758119.036: Node startup complete + 
-[(TURTLE-PROCESS-MODULES) INFO] 1453758119.377Turtle simple navigation invoked with action designator +  (<- (matching-process-module ?desig turtlesim-navigation) 
-`#<ACTION-DESIGNATOR ((TYPE GOAL+    (desig-prop ?desig (:type :driving))) 
-                      (GOAL #<LOCATION-DESIGNATOR ((HORIZONTAL-POSITION CENTER+  (<- (matching-process-module ?desig turtlesim-navigation) 
-                                                   (VERTICAL-POSITION CENTER)) {10095B8283}>)) {10095B87D3}>'+    (desig-prop ?desig (:type :moving))) 
-[(TURTLE-PROCESS-MODULES) INFO] 1453758119.386: Going to point #<3D-VECTOR (6.038690567016602d0 6.027290344238281d0 0.0d0)>.+  (<- (matching-process-module ?desig turtlesim-navigation) 
 +    (desig-prop ?desig (:type :going-to))) 
 +  (<- (matching-process-module ?desig turtlesim-pen-control) 
 +    (desig-prop ?desig (:type :setting-pen)))) 
 +   
 +(defun perform-some-motion (motion-desig) 
 +  (top-level 
 +    (with-process-modules-running (turtlesim-navigation turtlesim-pen-control) 
 +      (cram-executive:perform motion-desig)))) 
 +</code> 
 + 
 +It's the same as the other ones. If the type of ''?desig'' is ''going-to'', the rule applies and ''turtlesim-navigation'' gets selected. 
 + 
 +Now let's give it a go. Reload the tutorial in ''roslisp_repl'' then in the command line of the REPL type: 
 + 
 +<code lisp> 
 +TUT> (goto-location :right :top
 +[(ROSLISP TOP) INFO] 1501153969.640: Node name is /turtle1 
 +[(ROSLISP TOP) INFO] 1501153969.640: Namespace is / 
 +[(ROSLISP TOP) INFO] 1501153969.641: Params are NIL 
 +[(ROSLISP TOP) INFO] 1501153969.641: Remappings are: 
 +[(ROSLISP TOP) INFO] 1501153969.641: master URI is 127.0.0.1:11311 
 +[(ROSLISP TOP) INFO] 1501153970.649: Node startup complete 
 +[(TURTLE-PROCESS-MODULES) INFO] 1562698457.619TurtleSim navigation invoked with motion designator `#<A MOTION 
 +    (TYPE GOING-TO
 +    (GOAL #<LOCATION 
 +    (HORIZONTAL-POSITION RIGHT
 +    (VERTICAL-POSITION TOP)>)>'
 +[(TURTLE-PROCESS-MODULES) INFO] 1501153970.691: Going to point #<3D-VECTOR (10.131428718566895d0 8.874866485595703d0 0.0d0)>.
 T T
 </code> </code>
  
-The turtle should also have moved to somewhere in the vicinity of the center of its window.+If you already had a running node in the REPL, you might get the error shown below but that is absolutely normal: ROS simply notifies you that it is going to shut down the previous node and start a new one. 
 +<code lisp> 
 +WARNING: 
 +   Before starting node, node-status equalled RUNNING instead of :shutdown.  Shutting the previous node invocation down now. 
 +</code> 
 + 
 +The turtle should also have moved to somewhere in the vicinity of the top-right corner of its window.
  
 == Next == == Next ==
  
-So far we called process modules directly. Sometimes it'better to let the system decide on its own ...+Let'put everything we made so far together to write some high-level plans.
  
-[[tutorials:beginner:assigning_actions|Automatically choosing a process module for an action]]+[[tutorials:beginner:high_level_plans|Writing high-level plans]]