-
Notifications
You must be signed in to change notification settings - Fork 0
Week 1.5
You should be able to complete the exercises on this page within a two-hour lab session.
- Exercise 1: Making a ROS robot move
- Exercise 2: Exploring a ROS Package
- Exercise 3: Visualising the ROS Network
- Exercise 4: Exploring ROS Topics and Messages
- Exercise 5: Creating your own ROS Package
- Exercise 6: Creating a publisher node
- Exercise 7: Creating a subscriber node
- Exercise 8: Creating a launch file
In this first week you will learn the basics of ROS and become familiar with some of the key tools and principles of this framework, which will allow you to program robots and work with ROS applications effectively. For the most part, you will interact with ROS using the Linux command line and so you will also become familiar with some key Linux command line tools that will help you. Finally, you will learn how to create some basic ROS Nodes using Python.
By the end of this session you will be able to:
- Control a TurtleBot3 Robot, in simulation, using ROS.
- Launch ROS applications using
roslaunch
androsrun
. - Interrogate running ROS applications using key ROS command line tools.
- Create a ROS package comprised of multiple nodes and program these nodes (in Python) to communicate with one another using ROS Communication Methods.
- Navigate a Linux filesystem and learn how to do various filesystem operations from within a Linux Terminal.
ROS applications are organised into packages. ROS packages are collections of scripts, parameters and configurations relating to some common robot functionality, and ROS uses packages as a way to organise all the programs running on a robot. The package system is a fundamental concept in ROS and all ROS programs are organised in this way.
-
If you haven't done so already, launch your WSL-ROS environment by running the WSL-ROS shortcut in the Windows Start Menu. This should open up a terminal application and an Ubuntu terminal instance. We'll refer to this terminal instance as TERMINAL 1.
-
In the terminal enter the following command to launch a simulation of a TurtleBot3 Waffle in an empty world:
[TERMINAL 1] $ roslaunch turtlebot3_gazebo turtlebot3_empty_world.launch
Note: A
$
symbol indicates a command that should be entered directly into a Linux Terminal. Enter (or copy and paste) all the text after the$
into the terminal excluding the$
! -
A Gazebo simulation window should open and within this you should see a TurtleBot3 Waffle (similar to the real robots that you will be working with later in this course):
-
With your Gazebo Simulation up and running, return to the terminal application and open up a new Ubuntu terminal instance (TERMINAL 2) by pressing the New Tab button:
(or, alternatively, press the
Ctrl+Shift+T
keyboard shortcut). -
In the new terminal instance enter the following command:
[TERMINAL 2] $ roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
-
Follow the instructions provided in the terminal to drive the robot around in its simulated environment.
Summary:
You have so far launched two separate ROS applications using the roslaunch
command. roslaunch
is one way to launch ROS programs. As you should have observed from the above examples, we use this command in the following way:
roslaunch {package name} {launch file}
The command takes two parameters as inputs: {package name}
is the name of the ROS package that contains the functionality that we want to execute and {launch file}
is a file within that package that tells ROS exactly what functionality within the package we want to launch.
roscd
is a ROS command that allows us to navigate to the directory of any ROS package installed on our system, without us needing to know the path to the package beforehand.
-
Open up a new terminal instance (TERMINAL 3) and use the
roscd
command to navigate to theturtlebot3_teleop
package directory on our Linux filesystem:[TERMINAL 3] $ roscd turtlebot3_teleop
The terminal prompt should have changed to illustrate where on the filesystem the
roscd
command has just taken you: -
pwd
is a Linux command which tells us where the terminal is currently located in the filesystem (i.e. Print Working Directory). Use this to confirm what the terminal prompt is telling you:[TERMINAL 3] $ pwd
We now know where the
turtlebot3_teleop
package is located on our machine, and we can then use more Linux commands to explore this further: -
ls
is a Linux command which lists the contents of the current directory. Use this to list the contents of theturtlebot3_teleop
package directory.[TERMINAL 3] $ ls
This will simply list the items in the current directory, but we can use the
-F
option to find out a little more:[TERMINAL 3] $ ls -F
You will notice that the output has now changed slightly: items followed by a
/
are folders (aka "directories") and items without the/
are files (files will often have a file extension too). How many items are there in theturtlebot3_teleop
package directory? How many of these are directories and how many are files?Launch files for a package are typically located in a launch folder within the package directory. You should have noticed a
launch
folder in the output of thels
command above. -
cd
is a Linux command that allows us to Change the Directory that the terminal is currently located in. Use this to navigate to theturtlebot3_teleop
packagelaunch
folder and then usels
again to see what's in there. In this folder you should see theturtlebot3_teleop_key.launch
file that we executed with theroslaunch
command in Exercise 1. We will now have a look at the contents of this file... -
cat
is a Linux command that we can use to display the contents of a file in the terminal. Use this to display the contents of theturtlebot3_teleop_key.launch
file.[TERMINAL 3] $ cat turtlebot3_teleop_key.launch
Summary:
From the output of cat
in the step above you should have noticed that the contents of a launch file are contained within a <launch>
tag:
<launch>
...
</launch>
Within that, we also have (amongst other things) a <node>
tag which tells ROS exactly what scripts or executables to launch and how to launch them:
<node pkg="turtlebot3_teleop" type="turtlebot3_teleop_key" name="turtlebot3_teleop_keyboard" output="screen">
</node>
The attributes here have the following meaning:
-
pkg
: The name of the ROS package containing the functionality that we want to launch. -
type
: The full name of the script (i.e. ROS Node) that we want to execute within that package (including the file extension, if it has one). -
name
: A descriptive name that we want to give to the ROS node, which will be used to register it on the ROS Network. -
output
: The place where any output from the node will be printed (either screen where the output will be printed to our terminal window, or log where the output will be printed to a log file).
ROS Nodes are executable programs that perform specific robot tasks and operations, such as remote (or "teleoperational") control, as we have seen in the above example.
The packages that we will create throughout this course will contain nodes, launch files and other things too. The turtlebot3_teleop
package that we have just interrogated here however is fairly minimal and only contains launch files... the nodes are actually located elsewhere, in a directory called /opt/ros/noetic/lib/turtlebot3_teleop/
. This is just the way things are organised for pre-installed packages. What is the name of the node that is launched by the turtlebot3_teleop_key.launch
file? Use the Linux/ROS command line tools that you have learnt about so far to interrogate this file.
A ROS Robot might have hundreds of individual nodes running simultaneously to carry out all its necessary operations and actions. Each node runs independently, but uses ROS communication methods to communicate and share data with the other nodes on the ROS Network.
You can use the ROS command rosnode
to view all the nodes that are currently active on a ROS Network.
You should currently have three terminal windows active: the first in which you launched the Gazebo simulation (TERMINAL 1), the second with your turtlebot3_teleop_key
node active (TERMINAL 2), and the third where you explored the contents of the turtlebot3_teleop
package directory (TERMINAL 3). TERMINAL 3 should now be idle.
-
In TERMINAL 3 enter
$ cd ~
to go back to your home directory (remember that~
is an alias for your home directory). -
Use the following command to have a look at what nodes are currently active:
[TERMINAL 3] $ rosnode list
Only a handful of nodes should be listed:
/gazebo /gazebo_gui /rosout /turtlebot3_teleop_keyboard
-
We can visualise the connections between the active nodes by using the
rqt_graph
node within therqt_graph
package. We can userosrun
to launch this node directly (you might get some error messages, but don't worry about them):[TERMINAL 3] $ rosrun rqt_graph rqt_graph
A new window should then open, displaying something similar to the following (hover over the diagram to enable colour highlighting):
This tool shows us that the
/turtlebot3_teleop_keyboard
and/gazebo
nodes are communicating with one another. The direction of the arrow tells us that the/turtlebot3_teleop_keyboard
node is a Publisher and the/gazebo
node is a Subscriber. The two nodes communicate via a ROS Topic, in this case the/cmd_vel
topic, and on this topic the/turtlebot3_teleop_keyboard
node publishes messages.
We can find out more about the /cmd_vel
topic by using the rostopic
ROS command.
-
In a new terminal instance (TERMINAL 4) type the following:
[TERMINAL 4] $ rostopic info /cmd_vel
This should provide an output similar to the following:
Type: geometry_msgs/Twist Publishers: * /turtlebot3_teleop_keyboard (http://localhost:#####/) Subscribers: * /gazebo (http://localhost:#####/)
This confirms what we discovered earlier about the publisher(s) and subscriber(s) to the
/cmd_vel
topic. In addition, this also tells us the topic type, or the type of message that is being published on this topic. -
We can use the
rosmsg
ROS command to provide further information about this message, or any other message that we may be interested in:[TERMINAL 4] $ rosmsg info geometry_msgs/Twist
From this, we should obtain the following:
geometry_msgs/Vector3 linear float64 x float64 y float64 z geometry_msgs/Vector3 angular float64 x float64 y float64 z
We'll learn more about what this means next week.
-
To finish, shut down any active terminal processes by entering
Ctrl+C
in any that still have processes running (Terminals 1, 2 and 3). The associated Gazebo and rqt_graph windows should close as a result of this too.
In a minute or two you will create some simple publisher and subscriber nodes in Python and send messages between them. As we learnt earlier though, ROS applications should be contained within packages and so we need to create a package in order to start creating our own ROS nodes.
ROS provides a tool to create a new ROS package and ensure that all the essential elements are present: catkin_create_pkg
.
It is important to work in a specific filesystem location when we create and work on our own ROS packages, so that ROS can access and build everything appropriately. These spaces are called "Catkin Workspaces" and one has already been created in the WSL-ROS environment: called catkin_ws
.
-
Navigate to the
catkin_ws
folder by using the Linuxcd
command. In TERMINAL 1 enter the following:[TERMINAL 1] $ cd ~/catkin_ws/
-
Inside the catkin workspace there is a directory called
src
(use thels
command to confirm this). All new packages need to be located in thesrc
folder, so we need to be here when we use thecatkin_create_pkg
tool to create a new package. So, use thecd
command again to navigate to thecatkin_ws/src
folder:[TERMINAL 1] $ cd src
-
Now, use the
catkin_create_pkg
script to create a new package calledweek1_pubsub
which will havestd_msgs
androspy
as dependencies:[TERMINAL 1] $ catkin_create_pkg week1_pubsub std_msgs rospy
What did the
catkin_create_pkg
tool just do? (Hint: there are four things and it will have told you about them!) -
Navigate into this new package directory and use
ls
to list the content that has been created by thecatkin_create_pkg
tool.Catkin packages are typically organised in the following way, and have a few essential features that must be present in order for the package to be valid. These items are highlighted with [*]:
package_folder/ -- All packages must be self-contained within their own root folder [*] |-launch/ -- A folder for launch files (optional) |-src/ -- A folder for source files (python scripts etc) |-CMakeLists.txt -- Rules for compiling the package [*] `-package.xml -- Information about the package [*]
You will have noticed that the
catkin_create_pkg
tool made sure that the essential features of a Catkin Package were created when we asked it to build theweek1_pubsub
package above. -
Before we do anything else, it's good practice to now run
CMake
on the package (usingcatkin build
) to register it on our ROS system and make sure there are no errors with its definition so far:[TERMINAL 1] $ catkin build week1_pubsub
Finally, "re-source" your environment using the following alias:
[TERMINAL 1] $ src
... and we're good to go.
-
Within the
week1_pubsub
package directory, navigate to thesrc
folder using thecd
command. -
touch
is a Linux command that we can use to create an empty file. Use this to create an empty file calledpublisher.py
, which we will add content to shortly:[TERMINAL 1] $ touch publisher.py
-
Because we want to be able to run (or execute) this script, we will need to set the correct file permissions to allow us to do so. To do this, we can use the Linux
chmod
command in the following way:chmod +x {name of the python script}
. First though have a look at the file as it is usingls
again, but this time with an additional option:[TERMINAL 1] $ ls -lF
Which should provide the following output:
-rw-r--r-- 1 student student 0 Jan 01 12:00 publisher.py
The first bit of the output here tells us the file permissions:
-rw-r--r--
. This tells us who has permission to do what with this file and - currently - the first bit:-rw-
, tells us that we have permission to Read or Write to it.Now run the
chmod
command:[TERMINAL 1] $ chmod +x publisher.py
And then run the
ls -lF
command again to see what has changed:[TERMINAL 1] $ ls -lF -rwxr-xr-x 1 student student 0 Jan 01 12:00 publisher.py*
We have now granted permission for the file to be eXecuted too. Job done!
-
We now need to open this file to edit it. As discussed on the Getting Started page, we will be using Visual Studio Code as our IDE for this work. It's important to launch this in a very specific way in order for it to work properly with the WSL-ROS environment, so follow the instructions here to get this up and running now!
-
Make sure that the "Remote - WSL" VS Code extension is enabled within the WSL-ROS environment!!
-
Using the VS Code File Explorer, navigate to your
week1_pubsub
package directory (~/catkin_ws/src/week1_pubsub/
), locate thepublisher.py
file that you have just created in the/week1_pubsub/src/
folder and click on the file to open it. -
Once opened, copy the code provided here into the empty file and save it.
Note: It is important that you understand how this code works, so make sure that you read the explainer!
-
We can now run this node using the ROS command
rosrun
. However, because we closed everything down earlier on, the ROS Master is no longer active. First then, we need to re-launch it manually usingroscore
:[TERMINAL 1] $ roscore
-
Then, in TERMINAL 2, use
rosrun
to execute thepublisher.py
script that you have just created by providing the relevant information to therosrun
command as follows:rosrun {package name} {script name}
If you see a message in the terminal similar to the following then the node has been launched successfully:
[INFO] [#####]: The 'simple_publisher' node is active...
We can further verify that our publisher node is running using a number of different tools. Try the following in TERMINAL 3:
-
$ rosnode list
: This will provide a list of all the nodes that are currently active on the system. Verify that the name of our publisher node is visible in this list. -
$ rostopic list
: This will provide a list of the topics that are currently being used by nodes on the system. Verify that the name of the topic that our publisher is publishing messages to is present within this list.
So far we have used the rostopic
ROS command with two additional arguments:
-
list
to provide us with a list of all the topics that are active on our ROS system, and -
info
to provide us with information on a particular topic of interest.
We can use the autocomplete functionality of the Linux terminal to provide us with a list of all the available options that we can use with the rostopic
command. To do this you can type rostopic
followed by a space and then press the Tab
key twice:
rostopic[SPACE][TAB][TAB]
You should then be presented with a list of the available arguments for the rostopic
command:
-
rostopic hz {topic name}
provides information on the frequency (in Hz) at which messages are being published to a topic:[TERMINAL 3] $ rostopic hz /chatter
This should tell us that our publisher node is publishing messages to the
/chatter
topic at (or close to) 10 Hz, which is exactly what we ask for in thepublisher.py
file (in the__init__
part of ourPublisher
class). PressCtrl+C
to stop this command. -
rostopic echo {topic name}
shows the messages being published to a topic:[TERMINAL 3] $ rostopic echo /chatter
This will provide a live stream of the messages that our
publisher.py
node is publishing to the/chatter
topic. PressCtrl+C
to stop this. -
We can see some additional options for this command by viewing the help documentation:
[TERMINAL 3] $ rostopic echo -h
From here, for instance, we can learn that if we just wanted the echo command to display a set number of messages from the
/chatter
topic we could use the-n
option. To display the most recent two message only for example:[TERMINAL 3] $ rostopic echo /chatter -n2
You will now create another node to subscribe to the topic that our publisher node is broadcasting messages to, to access the information within the topic messages.
-
In TERMINAL 3 use the filesystem commands that were introduced earlier (
cd
,ls
androscd
) to navigate to thesrc
folder of theweek1_pubsub
package that we created earlier. -
Use the same procedure as before to create a new empty Python file called
subscriber.py
and make it executable. -
Then, open the newly created
subscriber.py
file in VS Code, paste in the code provided here and save it. Once again, it's important that you understand how this code works, so make sure you read the explainer. -
Use
rosrun
(remember:rosrun {package name} {script name}
) to run your newly createdsubscriber.py
node. If your publisher and subscriber nodes are working correctly you should see an output like this: -
As before, we can find out what nodes are running on our system by using the
$ rosnode list
command. Open a new terminal window (TERMINAL 4), run this and see if you can identify the nodes that you have just launched. -
Finally, close down your publisher and subscriber nodes and the ROS Master by entering
Ctrl+C
in Terminals 1, 2 and 3.
At the beginning of this lab session we launched our Gazebo Simulation and the turtlebot3_teleop_keyboard
node using launch files and the roslaunch
command. This provides a means to launch multiple ROS nodes simultaneously, and we will demonstrate this by building a launch file for the publisher and subscriber nodes that we have just created.
-
In TERMINAL 1, use
roscd
to navigate to the root of yourweek1_pubsub
package directory. -
Use the Linux
mkdir
command to make a new directory in the package root folder calledlaunch
:[TERMINAL 1] $ mkdir launch
-
Use the
cd
command to enter the launch folder that you have just created, then use thetouch
command (in the same way as before) to create a new, empty file calledpubsub.launch
. -
Open this launch file in VS Code and enter the following text:
<launch> <node pkg={BLANK} type={BLANK} name="pub_node" output="screen"> </node> </launch>
FILL IN THE {BLANK}(s)! Referring to what we learned about the format of launch files earlier, replace each
{BLANK}
above with the correct text to launch the publisher node that you created in Exercise 6. -
Use
roslaunch
to launch this file and test it out as it is (remember:roslaunch {package name} {launch file}
). If everything looks OK then carry on to the next step. -
The launch file that you have just created should launch the
publisher.py
node, but not thesubscriber.py
node. Add another<node>
tag to launch the subscriber node as well. -
The publisher and subscriber nodes and the ROS Master can now all be launched with the
roslaunch
command and thepubsub.launch
file that you have now created. -
Launch this in TERMINAL 1 and then use
$ rosnode list
in TERMINAL 2 to check that it all works correctly.
Summary:
-
roslaunch
can be used to launch multiple nodes on a robot from one single command. - It will also automatically launch the ROS Master (equivalent to running the
roscore
command manually) if it isn't already running. Did you notice that we didn't have to do this manually in Task 4, but we did when we launched our nodes individually usingrosrun
? - In the
rospy.init(...)
functions of ourpublisher.py
andsubscriber.py
Python scripts, we defined a node name and setanonymous=True
. As a result, when we launched our nodes manually usingrosrun
, the names we defined were honoured, but were appended with a unique combination of numbers. - When we launched our nodes using
roslaunch
however, the node names were set according to what we had defined in thename
field of the<node>
tag within the launch file, and anything specified within therospy.init(...)
function within our Python scripts was overwritten as a result.
In this session we've learnt about some key concepts in ROS, such as Packages; Launch files; Nodes and the Publisher-Subscriber Communication Method using Topics and Messages.
We have learnt how to use some key ROS commands:
-
roslaunch
: to launch multiple ROS Nodes via launch files. -
roscd
: to navigate to installed ROS packages using a package name alone. -
rosnode
: to display information about active ROS Nodes. -
rosrun
: to run executables within a ROS package. -
rostopic
: to display information about active ROS topics. -
rosmsg
: to display information about all ROS messages that are available to use in a ROS application. -
roscore
: to launch the ROS Master: The baseline nodes and programs that are required for ROS to function.
In addition to this we also learnt how to use catkin_create_pkg
, which is a helper script for creating ROS package templates.
We have also learnt how to work in the Linux Terminal and navigate a Linux filesystem using key commands such as:
-
pwd
: prints the path of the current working directory to show you which directory you're currently located in. -
ls
: lists the files in the current directory. -
cd
: change directory to move around the file system. -
mkdir
: make a new directory (mkdir {new_folder}
). -
cat
: show the contents of a file. -
chmod
: modify file permissions (i.e. to add execute permissions to a file for all users:chmod +x {file}
). -
touch
: create a file without any content.
Finally, we have learnt how to create basic ROS nodes in Python to both publish and subscribe to ROS topics using standard ROS messages.
Remember, the work you have done in the WSL-ROS environment during this session will not be preserved for future sessions or across different University machines automatically! To save the work you have done here today you should now run the following script in any idle WSL-ROS Terminal Instance:
$ wsl_ros backup
This will export your home directory to your University U: Drive, allowing you to restore it at the start of the next session.
Navigating This Wiki:
← Getting Started [Previous] |
[Next] Week 2: Odometry and Basic Navigation →
COM2009/3009 Robotics Lab Course
Updated for the 2021-22 Academic Year
Dr Tom Howard | Multidisciplinary Engineering Education (MEE) | The University of Sheffield
The documentation within this Wiki is licensed under Creative Commons License CC BY-NC:
You are free to distribute, remix, adapt, and build upon this work (for non-commercial purposes only) as long as credit is given to the original author.