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
doc:beginner:controlling_turtlesim [2013/12/12 14:30] gkazhoyadoc:beginner:controlling_turtlesim [2014/01/19 12:51] (current) gkazhoya
Line 5: Line 5:
 **Next Tutorial:** [[doc:beginner:simple_plans|Implementing simple plans to move a turtle]] **Next Tutorial:** [[doc:beginner:simple_plans|Implementing simple plans to move a turtle]]
  
-In this tutorial we will re-use the package ''cram_tutorial'' that you have created in the previous tutorial. For controlling the turtle, we need to depend on the ''turtlesim'' package, since it contains the message definitions we will use. Further, we will want to use the communication functionality of ROS to talk to the ''turtlesim'' from inside Lisp, so we depend on ''roslisp''. Finally, we will have to deal with poses. For that, we want to use the package ''cl_transforms'' and ''geometry_msgs'', the latter one is only needed if you're working with Hydro or a newer ROS version. +In this tutorial we will re-use the package ''cram_beginner_tutorial'' that you have created in the previous tutorial. For controlling the turtle, we need to depend on the ''turtlesim'' package, since it contains the message definitions we will use. Further, we will want to use the communication functionality of ROS to talk to the ''turtlesim'' from inside Lisp, so we depend on ''roslisp''. Finally, we will have to deal with poses. For that, we want to use the package ''cl_transforms'' and ''geometry_msgs'', the latter one is only needed if you're working with Hydro or a newer ROS version. 
  
  
Line 14: Line 14:
 ==== catkin ==== ==== catkin ====
  
-Open ''package.xml'' from the root directory of your ''cram_tutorial'' package and add the lines +Open ''package.xml'' from the root directory of your ''cram_beginner_tutorial'' package and add the lines 
-<code>+<code xml>
   <build_depend>roslisp</build_depend>   <build_depend>roslisp</build_depend>
   <build_depend>turtlesim</build_depend>   <build_depend>turtlesim</build_depend>
Line 22: Line 22:
 </code> </code>
 under ''<build_depend>cram_language</build_depend>'' and under ''<build_depend>cram_language</build_depend>'' and
-<code>+<code xml>
   <run_depend>roslisp</run_depend>   <run_depend>roslisp</run_depend>
   <run_depend>turtlesim</run_depend>   <run_depend>turtlesim</run_depend>
Line 32: Line 32:
 ==== rosbuild ==== ==== rosbuild ====
 Open ''manifest.xml'' and add the lines Open ''manifest.xml'' and add the lines
-<code>+<code xml>
   <depend package="roslisp"/>   <depend package="roslisp"/>
   <depend package="turtlesim"/>   <depend package="turtlesim"/>
Line 42: Line 42:
 ==== Updating cram dependecies ==== ==== Updating cram dependecies ====
  
-Now open ''cram-tutorial.asd'' and update the system dependencies to include the system  ''roslisp'', ''turtlesim-msg'', ''geometry_msgs-msg'' and ''cl-transforms''. The systems that correspond to the messages of a package are always named like the package name with a ''-msg'' suffix. Your system should now look like this:+Now open ''cram-beginner-tutorial.asd'' and update the system dependencies to include the system  ''roslisp'', ''turtlesim-msg'', ''geometry_msgs-msg'' and ''cl-transforms''. The systems that correspond to the messages of a package are always named like the package name with a ''-msg'' suffix. Your system should now look like this:
  
-<code> +<code lisp
-(defsystem cram-tutorial+(defsystem cram-beginner-tutorial
   :depends-on (roslisp cram-language turtlesim-msg cl-transforms geometry_msgs-msg)   :depends-on (roslisp cram-language turtlesim-msg cl-transforms geometry_msgs-msg)
   :components   :components
Line 54: Line 54:
 </code> </code>
  
-===== Updating the the Lisp Package =====+===== Updating the Lisp Package =====
  
 We also want to add ''roslisp'' and ''cl-transforms'' to our namespace in the file ''package.lisp'' so that we don't have to specify the namespace each time we use a function from that package in our code. We also want to add ''roslisp'' and ''cl-transforms'' to our namespace in the file ''package.lisp'' so that we don't have to specify the namespace each time we use a function from that package in our code.
-<code> +<code lisp
-(defpackage cram-tutorial+(defpackage cram-beginner-tutorial
   (:nicknames :tut)   (:nicknames :tut)
   (:use #:cpl #:roslisp #:cl-transforms))   (:use #:cpl #:roslisp #:cl-transforms))
Line 65: Line 65:
 ===== Writing the communication glue code ===== ===== Writing the communication glue code =====
  
-Now it's time to use roslisp to connect to turtlesim. Turtlesim creates one ROS topic namespace per turtle. For each turtle name (turtle1, turtle2, etc.) it publishes the pose of the turtle on a ''~/pose topic'', publishes the color value under the turtle (the background color) on a ''~/color_sensor'' topic. For each turtle turtlesim subscribes to a ''~/cmd_vel'' topic (or ''~/command_velocity'' before hydro) waiting for commands to move the turtle. This is the topic through which we will be controlling our turtles from Lisp.+Now it's time to use roslisp to connect to turtlesim. Turtlesim creates one ROS topic namespace per turtle. For each turtle name (turtle1, turtle2, etc.) it publishes the pose of the turtle on a ''~/pose'' topic, publishes the color value under the turtle (the background color) on a ''~/color_sensor'' topic. For each turtle turtlesim subscribes to a ''~/cmd_vel'' topic (or ''~/command_velocity'' before hydro) waiting for commands to move the turtle. This is the topic through which we will be controlling our turtles from Lisp.
  
 ==== The code ==== ==== The code ====
Line 73: Line 73:
 === hydro === === hydro ===
  
-<code>+<code lisp>
 (in-package :tut) (in-package :tut)
  
-(defvar *color-value* (make-fluent :name :color-value) "current color of turtle")+(defvar *color-value* (make-fluent :name :color-value) "current color under the turtle")
 (defvar *turtle-pose* (make-fluent :name :turtle-pose) "current pose of turtle") (defvar *turtle-pose* (make-fluent :name :turtle-pose) "current pose of turtle")
  
Line 113: Line 113:
 === groovy and older === === groovy and older ===
  
-<code>+<code lisp>
 (in-package :tut) (in-package :tut)
  
Line 159: Line 159:
 ===== Experimenting in the REPL ===== ===== Experimenting in the REPL =====
  
-Now let's try it out. Open your Lisp REPL and make sure that you loaded the system ''cram-tutorial'' and switched to the package ''tut'', hint:+Now let's try it out. Open your Lisp REPL and make sure that you loaded the system ''cram-beginner-tutorial'' and switched to the package ''tut'', hint:
  
-<code> +<code lisp
-CL-USER> (ros-load:load-system "cram_tutorial" :cram-tutorial)+CL-USER> (ros-load:load-system "cram_beginner_tutorial" :cram-beginner-tutorial)
 ... ...
 CL-USER> (in-package :tut) CL-USER> (in-package :tut)
Line 173: Line 173:
 Enter the following commands: Enter the following commands:
  
-<code>+<code lisp>
 TUT> (start-ros-node "cram_tutorial_client") TUT> (start-ros-node "cram_tutorial_client")
 [(ROSLISP TOP) INFO] 1292688669.674: Node name is cram_tutorial_client [(ROSLISP TOP) INFO] 1292688669.674: Node name is cram_tutorial_client
Line 185: Line 185:
 The name of the node is arbitrary. We need to call ''start-ros-node'' before we can use the functions subscribe and advertise. The name of the node is arbitrary. We need to call ''start-ros-node'' before we can use the functions subscribe and advertise.
  
-<code>+<code lisp>
 TUT> (init-ros-turtle "/turtle1") TUT> (init-ros-turtle "/turtle1")
 </code> </code>
Line 193: Line 193:
 Now we should start up turtlesim in a new terminal: Now we should start up turtlesim in a new terminal:
  
-<code>+<code bash>
 $ rosrun turtlesim turtlesim_node $ rosrun turtlesim turtlesim_node
 </code> </code>
Line 207: Line 207:
 We are ready for experiments now. Let's see if the fluents are containing the right values: We are ready for experiments now. Let's see if the fluents are containing the right values:
  
-<code>+<code lisp>
 TUT>  (value *turtle-pose*) TUT>  (value *turtle-pose*)
 [TURTLESIM-MSG:<POSE> [TURTLESIM-MSG:<POSE>
Line 234: Line 234:
 Let's see if the pose changes if we move the turtle. Start up ''turtle_teleop_key'' and move the turtle a little bit using the arrows on your keyboard: Let's see if the pose changes if we move the turtle. Start up ''turtle_teleop_key'' and move the turtle a little bit using the arrows on your keyboard:
  
-<code>$ rosrun turtlesim turtle_teleop_key</code>+<code bash>$ rosrun turtlesim turtle_teleop_key</code>
  
 Try evaluating ''*turtle-pose*'' in the REPL again: Try evaluating ''*turtle-pose*'' in the REPL again:
-<code>+<code lisp>
 TUT>  (value *turtle-pose*) TUT>  (value *turtle-pose*)
 [TURTLESIM-MSG:<POSE> [TURTLESIM-MSG:<POSE>
Line 261: Line 261:
  
 Fluents allow us to wait for specific events. For instance, we can wait for the ''x'' coordinate of the turtle being smaller than ''5'': Fluents allow us to wait for specific events. For instance, we can wait for the ''x'' coordinate of the turtle being smaller than ''5'':
-<code>+<code lisp>
 TUT> (wait-for (< (fl-funcall #'turtlesim-msg:x *turtle-pose*) TUT> (wait-for (< (fl-funcall #'turtlesim-msg:x *turtle-pose*)
                   5.0))                   5.0))
 </code> </code>
 The code above constructs a fluent network. The expression The code above constructs a fluent network. The expression
-<code>+<code lisp>
 (fl-funcall #'turtlesim-msg:x *turtle-pose*) (fl-funcall #'turtlesim-msg:x *turtle-pose*)
 </code> </code>
 returns a new fluent that contains the ''x''-value of the turtle pose. So from a proxy that wrapped the whole pose of a turtle, we got a new proxy that wraps just the ''x'' coordinate. The expression returns a new fluent that contains the ''x''-value of the turtle pose. So from a proxy that wrapped the whole pose of a turtle, we got a new proxy that wraps just the ''x'' coordinate. The expression
-<code>+<code lisp>
 (< (fl-funcall #'turtlesim-msg:x *turtle-pose*) (< (fl-funcall #'turtlesim-msg:x *turtle-pose*)
    5.0)    5.0)
Line 282: Line 282:
  
 Let's see if we can also move the turtle from LISP. Try the following: Let's see if we can also move the turtle from LISP. Try the following:
-<code>+<code lisp>
 TUT> (dotimes (i 10) (send-vel-cmd 1 1) (sleep 1)) TUT> (dotimes (i 10) (send-vel-cmd 1 1) (sleep 1))
 </code> </code>
Line 290: Line 290:
  
  
-Now that we have functions and fluents to connect to the turtlesim, let'implementing some simple plans.+Now that we have functions and fluents to connect to the turtlesim, let'implement some simple plans.
  
 [[doc:beginner:simple_plans|Implementing simple plans to move a turtle]] [[doc:beginner:simple_plans|Implementing simple plans to move a turtle]]