01 Ros2 Cli
01 Ros2 Cli
01 Ros2 Cli
Goal: This tutorial will show you how to prepare your ROS 2 environment.
Tutorial level: Beginner
Time: 5 minutes
Contents
Background
Prerequisites
Tasks
1 Source the setup files
2 Add sourcing to your shell startup script
3 Check environment variables
o Summary
o Next steps
Background
ROS 2 relies on the notion of combining workspaces using the shell environment. “Workspace” is
a ROS term for the location on your system where you’re developing with ROS 2. The core ROS 2
workspace is called the underlay. Subsequent local workspaces are called overlays. When
developing with ROS 2, you will typically have several workspaces active concurrently.
Combining workspaces makes developing against different versions of ROS 2, or against different
sets of packages, easier. It also allows the installation of several ROS 2 distributions (or “distros”,
e.g. Dashing and Eloquent) on the same computer and switching between them.
This is accomplished by sourcing setup files every time you open a new shell, or by adding the
source command to your shell startup script once. Without sourcing the setup files, you won’t be
able to access ROS 2 commands, or find or use ROS 2 packages. In other words, you won’t be
able to use ROS 2.
Prerequisites
Before starting these tutorials, install ROS 2 by following the instructions on the ROS
2 Installation page.
The commands used in this tutorial assume you followed the binary packages installation guide for
your operating system (Debian packages for Linux). You can still follow along if you built from
source, but the path to your setup files will likely be different. You also won’t be able to use
the sudo apt install ros-<distro>-<package> command (used frequently in the beginner level
tutorials) if you install from source.
If you are using Linux or macOS, but are not already familiar with the shell, this tutorial will help.
Tasks
1 Source the setup files
You will need to run this command on every new shell you open to have access to the ROS 2
commands, like so:
LinuxmacOSWindows
source /opt/ros/galactic/setup.bash
Note
The exact command depends on where you installed ROS 2. If you’re having problems, ensure
the file path leads to your installation.
2 Add sourcing to your shell startup script
If you don’t want to have to source the setup file every time you open a new shell (skipping task 1),
then you can add the command to your shell startup script:
LinuxmacOSWindows
echo "source /opt/ros/galactic/setup.bash" >> ~/.bashrc
To undo this, locate your system’s shell startup script and remove the appended source
command.
3 Check environment variables
Sourcing ROS 2 setup files will set several environment variables necessary for operating ROS 2.
If you ever have problems finding or using your ROS 2 packages, make sure that your
environment is properly setup using the following command:
LinuxmacOSWindows
printenv | grep -i ROS
If the environment variables are not set correctly, return to the ROS 2 package installation section
of the installation guide you followed. If you need more specific help (because environment setup
files can come from different places), you can get answers from the community.
3.1 The ROS_DOMAIN_ID variable
See the domain ID article for details on ROS domain IDs.
Once you have determined a unique integer for your group of ROS 2 agents, you can set the
environment variable with the following command:
LinuxmacOSWindows
export ROS_DOMAIN_ID=<your_domain_id>
To maintain this setting between shell sessions, you can add the command to your shell startup
script:
echo "export ROS_DOMAIN_ID=<your_domain_id>" >> ~/.bashrc
Summary
The ROS 2 development environment needs to be correctly configured before use. This can be
done in two ways: either sourcing the setup files in every new shell you open, or adding the source
command to your startup script.
If you ever face any problems locating or using packages with ROS 2, the first thing you should do
is check your environment variables and ensure they are set to the version and distro you
intended.
Next steps
Now that you have a working ROS 2 installation and you know how to source its setup files, you
can start learning the ins and outs of ROS 2 with the turtlesim tool.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 Start turtlesim
To start turtlesim, enter the following command in your terminal:
ros2 run turtlesim turtlesim_node
The simulator window should appear, with a random turtle in the center.
In the terminal under the command, you will see messages from the node:
[INFO] [turtlesim]: Starting turtlesim with node name /turtlesim
Here you can see your default turtle’s name is turtle1 , and the default coordinates where it
spawns.
3 Use turtlesim
Open a new terminal and source ROS 2 again.
Now you will run a new node to control the turtle in the first node:
ros2 run turtlesim turtle_teleop_key
At this point you should have three windows open: a terminal running turtlesim_node , a terminal
running turtle_teleop_key and the turtlesim window. Arrange these windows so that you can see
the turtlesim window, but also have the terminal running turtle_teleop_key active so that you can
control the turtle in turtlesim.
Use the arrow keys on your keyboard to control the turtle. It will move around the screen, using its
attached “pen” to draw the path it followed so far.
Note
Pressing an arrow key will only cause the turtle to move a short distance and then stop. This is
because, realistically, you wouldn’t want a robot to continue carrying on an instruction if, for
example, the operator lost the connection to the robot.
You can see the nodes and their associated services, topics, and actions using
the list command:
ros2 node list
ros2 topic list
ros2 service list
ros2 action list
You will learn more about these concepts in the coming tutorials. Since the goal of this tutorial is
only to get a general overview of turtlesim, we will use rqt (a graphical user interface for ROS 2) to
look at services a little closer.
4 Install rqt
Open a new terminal to install rqt and its plugins:
Linux (apt 2.0/Ubuntu 20.04 and newer)Linux (apt 1.x/Ubuntu 18.04 and older)macOSWindows
sudo apt update
To run rqt:
rqt
5 Use rqt
After running rqt the first time, the window will be blank. No worries; just
select Plugins > Services > Service Caller from the menu bar at the top.
Note
It may take some time for rqt to locate all the plugins itself. If you click on Plugins, but don’t
see Services or any other options, you should close rqt, enter the command rqt --force-
discover in your terminal.
Use the refresh button to the left of the Service dropdown list to ensure all the services of your
turtlesim node are available.
Click on the Service dropdown list to see turtlesim’s services, and select the /spawn service.
5.1 Try the spawn service
Let’s use rqt to call the /spawn service. You can guess from its name that /spawn will create
another turtle in the turtlesim window.
Give the new turtle a unique name, like turtle2 by double-clicking between the empty single
quotes in the Expression column. You can see that this expression corresponds to
the name value, and is of type string.
Enter new coordinates for the turtle to spawn at, like x = 1.0 and y = 1.0 .
Note
If you try to spawn a new turtle with the same name as an existing turtle, like your default turtle1 ,
you will get an error message in the terminal running turtlesim_node :
[ERROR] [turtlesim]: A turtle named [turtle1] already exists
To spawn turtle2, you have to call the service by clicking the Call button on the upper right side of
the rqt window.
You will see a new turtle (again with a random design) spawn at the coordinates you input
for x and y.
If you refresh the service list in rqt, you will also see that now there are services related to the new
turtle, /turtle2/… , in addition to /turtle1/… .
5.2 Try the set_pen service
Now let’s give turtle1 a unique pen using the /set_pen service:
The values for r, g and b, between 0 and 255, will set the color of the pen turtle1 draws with,
and width sets the thickness of the line.
To have turtle1 draw with a distinct red line, change the value of r to 255, and the value
of width to 5. Don’t forget to call the service after updating the values.
If you return to the terminal where turtle_teleop_node is running and press the arrow keys, you will
see turtle1’s pen has changed.
You’ve probably noticed that there’s no way to move turtle2. You can accomplish this by
remapping turtle1’s cmd_vel topic onto turtle2.
6 Remapping
In a new terminal, source ROS 2, and run:
ros2 run turtlesim turtle_teleop_key --ros-args --remap turtle1/cmd_vel:=turtle2/cmd_vel
Now you can move turtle2 when this terminal is active, and turtle1 when the other terminal running
the turtle_teleop_key is active.
7 Close turtlesim
To stop the simulation, you can enter Ctrl + C in the turtlesim_node terminal, and q in the teleop
terminal.
Summary
Using turtlesim and rqt is a great way to learn the core concepts of ROS 2.
Next steps
Now that you have turtlesim and rqt up and running, and an idea of how they work, let’s dive in to
the first core ROS 2 concept with the next tutorial, Understanding ROS 2 nodes.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A full robotic system is comprised of many nodes working in concert. In ROS 2, a single
executable (C++ program, Python program, etc.) can contain one or more nodes.
Prerequisites
The previous tutorial shows you how to install the turtlesim package used here.
As always, don’t forget to source ROS 2 in every new terminal you open.
Tasks
1 ros2 run
The command ros2 run launches an executable from a package.
ros2 run <package_name> <executable_name>
To run turtlesim, open a new terminal, and enter the following command:
ros2 run turtlesim turtlesim_node
Open another new terminal and start the teleop node with the command:
ros2 run turtlesim turtle_teleop_key
Here, we are searching the turtlesim package again, this time for the executable
named turtle_teleop_key .
Return to the terminal where you ran ros2 node list and run it again. You will now see the names
of two active nodes:
/turtlesim
/teleop_turtle
2.1 Remapping
Remapping allows you to reassign default node properties, like node name, topic names, service
names, etc., to custom values. In the last tutorial, you used remapping on turtle_teleop_key to
change the default turtle being controlled.
Now, lets reassign the name of our /turtlesim node. In a new terminal, run the following
command:
ros2 run turtlesim turtlesim_node --ros-args --remap __node:=my_turtle
Since you’re calling ros2 run on turtlesim again, another turtlesim window will open. However, now
if you return to the terminal where you ran ros2 node list , and run it again, you will see three node
names:
/my_turtle
/turtlesim
/teleop_turtle
ros2 node info returns a list of subscribers, publishers, services, and actions (the ROS graph
connections) that interact with that node. The output should look like this:
/my_turtle
Subscribers:
/parameter_events: rcl_interfaces/msg/ParameterEvent
/turtle1/cmd_vel: geometry_msgs/msg/Twist
Publishers:
/parameter_events: rcl_interfaces/msg/ParameterEvent
/rosout: rcl_interfaces/msg/Log
/turtle1/color_sensor: turtlesim/msg/Color
/turtle1/pose: turtlesim/msg/Pose
Service Servers:
/clear: std_srvs/srv/Empty
/kill: turtlesim/srv/Kill
/my_turtle/describe_parameters: rcl_interfaces/srv/DescribeParameters
/my_turtle/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
/my_turtle/get_parameters: rcl_interfaces/srv/GetParameters
/my_turtle/list_parameters: rcl_interfaces/srv/ListParameters
/my_turtle/set_parameters: rcl_interfaces/srv/SetParameters
/my_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
/reset: std_srvs/srv/Empty
/spawn: turtlesim/srv/Spawn
/turtle1/set_pen: turtlesim/srv/SetPen
/turtle1/teleport_absolute: turtlesim/srv/TeleportAbsolute
/turtle1/teleport_relative: turtlesim/srv/TeleportRelative
Service Clients:
Action Servers:
/turtle1/rotate_absolute: turtlesim/action/RotateAbsolute
Action Clients:
Now try running the same command on the /teleop_turtle node, and see how its connections
differ from my_turtle .
You will learn more about the ROS graph connection concepts including the message types in the
upcoming tutorials.
Summary
A node is a fundamental ROS 2 element that serves a single, modular purpose in a robotics
system.
In this tutorial, you utilized nodes created from the turtlesim package by running the
executables turtlesim_node and turtle_teleop_key .
You learned how to use ros2 node list to discover active node names and ros2 node info to
introspect on a single node. These tools are vital to understanding the flow of data in a complex,
real-world robot system.
Next steps
Now that you understand nodes in ROS 2, you can move on to the topics tutorial. Topics are one
of the communication types that connects nodes.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Understanding ROS 2 topics
Goal: Use rqt_graph and command line tools to introspect ROS 2 topics.
Tutorial level: Beginner
Time: 20 minutes
Contents
Background
Prerequisites
Tasks
1 Setup
2 rqt_graph
3 ros2 topic list
4 ros2 topic echo
5 ros2 topic info
6 ros2 interface show
7 ros2 topic pub
8 ros2 topic hz
9 Clean up
o Summary
o Next steps
Background
ROS 2 breaks complex systems down into many modular nodes. Topics are a vital element of the
ROS graph that act as a bus for nodes to exchange messages.
A node may publish data to any number of topics and simultaneously have subscriptions to any
number of topics.
Topics are one of the main ways in which data is moved between nodes and therefore between
different parts of the system.
Prerequisites
The previous tutorial provides some useful background information on nodes that is built upon
here.
As always, don’t forget to source ROS 2 in every new terminal you open.
Tasks
1 Setup
By now you should be comfortable starting up turtlesim.
Open a new terminal and run:
ros2 run turtlesim turtlesim_node
You should see the above nodes and topic, as well as two actions around the periphery of the
graph (let’s ignore those for now). If you hover your mouse over the topic in the center, you’ll see
the color highlighting like in the image above.
The graph is depicting how the /turtlesim node and the /teleop_turtle node are communicating
with each other over a topic. The /teleop_turtle node is publishing data (the keystrokes you enter
to move the turtle around) to the /turtle1/cmd_vel topic, and the /turtlesim node is subscribed to
that topic to receive the data.
The highlighting feature of rqt_graph is very helpful when examining more complex systems with
many nodes and topics connected in many different ways.
rqt_graph is a graphical introspection tool. Now we’ll look at some command line tools for
introspecting topics.
3 ros2 topic list
Running the ros2 topic list command in a new terminal will return a list of all the topics currently
active in the system:
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
ros2 topic list -t will return the same list of topics, this time with the topic type appended in
brackets:
/parameter_events [rcl_interfaces/msg/ParameterEvent]
/rosout [rcl_interfaces/msg/Log]
/turtle1/cmd_vel [geometry_msgs/msg/Twist]
/turtle1/color_sensor [turtlesim/msg/Color]
/turtle1/pose [turtlesim/msg/Pose]
These attributes, particularly the type, are how nodes know they’re talking about the same
information as it moves over topics.
If you’re wondering where all these topics are in rqt_graph, you can uncheck all the boxes
under Hide:
For now, though, leave those options checked to avoid confusion.
4 ros2 topic echo
To see the data being published on a topic, use:
ros2 topic echo <topic_name>
Since we know that /teleop_turtle publishes data to /turtlesim over the /turtle1/cmd_vel topic,
let’s use echo to introspect on that topic:
ros2 topic echo /turtle1/cmd_vel
At first, this command won’t return any data. That’s because it’s waiting for /teleop_turtle to
publish something.
Return to the terminal where turtle_teleop_key is running and use the arrows to move the turtle
around. Watch the terminal where your echo is running at the same time, and you’ll see position
data being published for every movement you make:
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
is the node created by the echo we just ran (the number might be different). Now
/_ros2cli_26646
you can see that the publisher is publishing data over the cmd_vel topic, and two subscribers are
subscribed.
5 ros2 topic info
Topics don’t have to only be point-to-point communication; it can be one-to-many, many-to-one, or
many-to-many.
Another way to look at this is running:
ros2 topic info /turtle1/cmd_vel
This means that in the package geometry_msgs there is a msg called Twist .
Now we can run ros2 interface show <msg type> on this type to learn its details, specifically, what
structure of data the message expects.
ros2 interface show geometry_msgs/msg/Twist
Vector3 linear
float64 x
float64 y
float64 z
Vector3 angular
float64 x
float64 y
float64 z
This tells you that the /turtlesim node is expecting a message with two
vectors, linear and angular , of three elements each. If you recall the data we
saw /teleop_turtle passing to /turtlesim with the echo command, it’s in the same structure:
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
The '<args>' argument is the actual data you’ll pass to the topic, in the structure you just
discovered in the previous section.
It’s important to note that this argument needs to be input in YAML syntax. Input the full command
like so:
ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0},
angular: {x: 0.0, y: 0.0, z: 1.8}}"
--once is an optional argument meaning “publish one message then exit”.
You will receive the following message in the terminal:
publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0),
angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))
The turtle (and commonly the real robots which it is meant to emulate) require a steady stream of
commands to operate continuously. So, to get the turtle to keep moving, you can run:
ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0},
angular: {x: 0.0, y: 0.0, z: 1.8}}"
The difference here is the removal of the --once option and the addition of the --rate 1 option,
which tells ros2 topic pub to publish the command in a steady stream at 1 Hz.
You can refresh rqt_graph to see what’s happening graphically. You will see
the ros 2 topic pub ... node ( /_ros2cli_30358 ) is publishing over the /turtle1/cmd_vel topic, and is
being received by both the ros2 topic echo ... node ( /_ros2cli_26646 ) and the /turtlesim node
now.
Finally, you can run echo on the pose topic and recheck rqt_graph:
ros2 topic echo /turtle1/pose
You can see that the /turtlesim node is also publishing to the pose topic, which the
new echo node is subscribed to.
8 ros2 topic hz
For one last introspection on this process, you can view the rate at which data is published using:
ros2 topic hz /turtle1/pose
It will return data on the rate at which the /turtlesim node is publishing data to the pose topic.
average rate: 59.354
min: 0.005s max: 0.027s std dev: 0.00284s window: 58
Recall that you set the rate of turtle1/cmd_vel to publish at a steady 1 Hz using ros2 topic pub --
rate 1 . If you run the above command with turtle1/cmd_vel instead of turtle1/pose , you will see an
You will see that both nodes have the same six services with parameters in their names. Nearly
every node in ROS 2 has these infrastructure services that parameters are built off of. There will
be more about parameters in the next tutorial. In this tutorial, the parameter services will be
omitted from discussion.
For now, let’s focus on the turtlesim-specific
services, /clear , /kill , /reset , /spawn , /turtle1/set_pen , /turtle1/teleport_absolute ,
and /turtle1/teleport_relative . You may recall interacting with some of these services using rqt in
the “Introducing turtlesim and rqt” tutorial.
3 ros2 service type
Services have types that describe how the request and response data of a service is structured.
Service types are defined similarly to topic types, except service types have two parts: one
message for the request and another for the response.
To find out the type of a service, use the command:
ros2 service type <service_name>
Let’s take a look at turtlesim’s /clear service. In a new terminal, enter the command:
ros2 service type /clear
Which should return:
std_srvs/srv/Empty
The Empty type means the service call sends no data when making a request and receives no
data when receiving a response.
3.1 ros2 service list -t
To see the types of all the active services at the same time, you can append the --show-
types option, abbreviated as -t , to the list command:
ros2 service list -t
For example, you can find all the Empty typed services like this:
ros2 service find std_srvs/srv/Empty
The information above the --- line tells us the arguments needed to
call /spawn . x , y and theta determine the location of the spawned turtle, and name is clearly
optional.
The information below the line isn’t something you need to know in this case, but it can help you
understand the data type of the response you get from the call.
6 ros2 service call
Now that you know what a service type is, how to find a service’s type, and how to find the
structure of that type’s arguments, you can call a service using:
ros2 service call <service_name> <service_type> <arguments>
The <arguments> part is optional. For example, you know that Empty typed services don’t have any
arguments:
ros2 service call /clear std_srvs/srv/Empty
This command will clear the turtlesim window of any lines your turtle has drawn.
Now let’s spawn a new turtle by calling /spawn and inputting arguments. Input <arguments> in a
service call from the command-line need to be in YAML syntax.
Enter the command:
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: ''}"
You will get this method-style view of what’s happening, and then the service response:
requester: making request: turtlesim.srv.Spawn_Request(x=2.0, y=2.0, theta=0.2, name='')
response:
turtlesim.srv.Spawn_Response(name='turtle2')
Your turtlesim window will update with the newly spawned turtle right away:
Summary
Nodes can communicate using services in ROS 2. Unlike a topic - a oneway communication
pattern where a node publishes information that can be consumed by one or more subscribers - a
service is a request/response pattern where a client makes a request to a node providing the
service and the service processes the request and generates a response.
You generally don’t want to use a service for continuous calls; topics or even actions would be
better suited.
In this tutorial you used command line tools to identify, elaborate on, and call services.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Understanding ROS 2 parameters
Goal: Learn how to get, set, save and reload parameters in ROS 2.
Tutorial level: Beginner
Time: 5 minutes
Contents
Background
Prerequisites
Tasks
1 Setup
2 ros2 param list
3 ros2 param get
4 ros2 param set
5 ros2 param dump
6 ros2 param load
7 Load parameter file on node startup
o Summary
o Next steps
Background
A parameter is a configuration value of a node. You can think of parameters as node settings. A
node can store parameters as integers, floats, booleans, strings and lists. In ROS 2, each node
maintains its own parameters. All parameters are dynamically reconfigurable, and built off of ROS
2 services.
Prerequisites
This tutorial uses the turtlesim package.
As always, don’t forget to source ROS 2 in every new terminal you open.
Tasks
1 Setup
Start up the two turtlesim nodes, /turtlesim and /teleop_turtle .
Open a new terminal and run:
ros2 run turtlesim turtlesim_node
You will see the node namespaces, /teleop_turtle and /turtlesim , followed by each node’s
parameters:
/teleop_turtle:
qos_overrides./parameter_events.publisher.depth
qos_overrides./parameter_events.publisher.durability
qos_overrides./parameter_events.publisher.history
qos_overrides./parameter_events.publisher.reliability
scale_angular
scale_linear
use_sim_time
/turtlesim:
background_b
background_g
background_r
qos_overrides./parameter_events.publisher.depth
qos_overrides./parameter_events.publisher.durability
qos_overrides./parameter_events.publisher.history
qos_overrides./parameter_events.publisher.reliability
use_sim_time
Every node has the parameter use_sim_time ; it’s not unique to turtlesim.
Based on their names, it looks like /turtlesim ’s parameters determine the background color of the
turtlesim window using RGB color values.
To determine a parameter’s type, you can use ros2 param get .
3 ros2 param get
To display the type and current value of a parameter, use the command:
ros2 param get <node_name> <parameter_name>
Let’s find out the current value of /turtlesim ’s parameter background_g :
ros2 param get /turtlesim background_g
To save your current configuration of /turtlesim ’s parameters, enter the command:
ros2 param dump /turtlesim
You will find a new file in the directory your workspace is running in. If you open this file, you’ll see
the following contents:
/turtlesim:
ros__parameters:
background_b: 255
background_g: 86
background_r: 150
qos_overrides:
/parameter_events:
publisher:
depth: 1000
durability: volatile
history: keep_last
reliability: reliable
use_sim_time: false
Dumping parameters comes in handy if you want to reload the node with the same parameters in
the future.
6 ros2 param load
You can load parameters from a file to a currently running node using the command:
ros2 param load <node_name> <parameter_file>
To load the ./turtlesim.yaml file generated with ros2 param dump into /turtlesim node’s parameters,
enter the command:
ros2 param load /turtlesim ./turtlesim.yaml
Note
Read-only parameters can only be modified at startup and not afterwards, that is why there are
some warnings for the “qos_overrides” parameters.
7 Load parameter file on node startup
To start the same node using your saved parameter values, use:
ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>
This is the same command you always use to start turtlesim, with the added flags --ros-
args and --params-file , followed by the file you want to load.
Stop your running turtlesim node so you can try reloading it with your saved parameters, using:
ros2 run turtlesim turtlesim_node --ros-args --params-file ./turtlesim.yaml
The turtlesim window should appear as usual, but with the purple background you set earlier.
Note
In this case, parameters are being modified at startup so the specified read-only parameters will
also take effect.
Summary
Nodes have parameters to define their default configuration values. You
can get and set parameter values from the command line. You can also save the parameter
settings to a file to reload them in a future session.
Next steps
Jumping back to ROS 2 communication methods, in the next tutorial you’ll learn about actions.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Understanding ROS 2 actions
Goal: Introspect actions in ROS 2.
Tutorial level: Beginner
Time: 15 minutes
Contents
Background
Prerequisites
Tasks
1 Setup
2 Use actions
3 ros2 node info
4 ros2 action list
5 ros2 action info
6 ros2 interface show
7 ros2 action send_goal
o Summary
o Next steps
o Related content
Background
Actions are one of the communication types in ROS 2 and are intended for long running tasks.
They consist of three parts: a goal, feedback, and a result.
Actions are built on topics and services. Their functionality is similar to services, except actions
can be canceled. They also provide steady feedback, as opposed to services which return a single
response.
Actions use a client-server model, similar to the publisher-subscriber model (described in
the topics tutorial). An “action client” node sends a goal to an “action server” node that
acknowledges the goal and returns a stream of feedback and a result.
Prerequisites
This tutorial builds off concepts, like nodes and topics, covered in previous tutorials.
This tutorial uses the turtlesim package.
As always, don’t forget to source ROS 2 in every new terminal you open.
Tasks
1 Setup
Start up the two turtlesim nodes, /turtlesim and /teleop_turtle .
Open a new terminal and run:
ros2 run turtlesim turtlesim_node
2 Use actions
When you launch the /teleop_turtle node, you will see the following message in your terminal:
Use arrow keys to move the turtle.
Use G|B|V|C|D|E|R|T keys to rotate to absolute orientations. 'F' to cancel a rotation.
Let’s focus on the second line, which corresponds to an action. (The first instruction corresponds
to the “cmd_vel” topic, discussed previously in the topics tutorial.)
Notice that the letter keys G|B|V|C|D|E|R|T form a “box” around the F key on a US QWERTY
keyboard (if you are not using a QWERTY keyboard, see this link to follow along). Each key’s
position around F corresponds to that orientation in turtlesim. For example, the E will rotate the
turtle’s orientation to the upper left corner.
Pay attention to the terminal where the /turtlesim node is running. Each time you press one of
these keys, you are sending a goal to an action server that is part of the /turtlesim node. The goal
is to rotate the turtle to face a particular direction. A message relaying the result of the goal should
display once the turtle completes its rotation:
[INFO] [turtlesim]: Rotation goal completed successfully
Not only can the client-side (your input in the teleop) stop a goal, but the server-side
(the /turtlesim node) can as well. When the server-side chooses to stop processing a goal, it is
said to “abort” the goal.
Try hitting the D key, then the G key before the first rotation can complete. In the terminal where
the /turtlesim node is running, you will see the message:
[WARN] [turtlesim]: Rotation goal received before a previous goal finished. Aborting previous goal
This action server chose to abort the first goal because it got a new one. It could have chosen
something else, like reject the new goal or execute the second goal after the first one finished.
Don’t assume every action server will choose to abort the current goal when it gets a new one.
3 ros2 node info
To see the /turtlesim node’s actions, open a new terminal and run the command:
ros2 node info /turtlesim
Which will return a list of /turtlesim ’s subscribers, publishers, services, action servers and action
clients:
/turtlesim
Subscribers:
/parameter_events: rcl_interfaces/msg/ParameterEvent
/turtle1/cmd_vel: geometry_msgs/msg/Twist
Publishers:
/parameter_events: rcl_interfaces/msg/ParameterEvent
/rosout: rcl_interfaces/msg/Log
/turtle1/color_sensor: turtlesim/msg/Color
/turtle1/pose: turtlesim/msg/Pose
Service Servers:
/clear: std_srvs/srv/Empty
/kill: turtlesim/srv/Kill
/reset: std_srvs/srv/Empty
/spawn: turtlesim/srv/Spawn
/turtle1/set_pen: turtlesim/srv/SetPen
/turtle1/teleport_absolute: turtlesim/srv/TeleportAbsolute
/turtle1/teleport_relative: turtlesim/srv/TeleportRelative
/turtlesim/describe_parameters: rcl_interfaces/srv/DescribeParameters
/turtlesim/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
/turtlesim/get_parameters: rcl_interfaces/srv/GetParameters
/turtlesim/list_parameters: rcl_interfaces/srv/ListParameters
/turtlesim/set_parameters: rcl_interfaces/srv/SetParameters
/turtlesim/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
Service Clients:
Action Servers:
/turtle1/rotate_absolute: turtlesim/action/RotateAbsolute
Action Clients:
Notice that the /turtle1/rotate_absolute action for /turtlesim is under Action Servers . This
means /turtlesim responds to and provides feedback for the /turtle1/rotate_absolute action.
The /teleop_turtle node has the name /turtle1/rotate_absolute under Action Clients meaning that
it sends goals for that action name.
ros2 node info /teleop_turtle
Which will return:
/teleop_turtle
Subscribers:
/parameter_events: rcl_interfaces/msg/ParameterEvent
Publishers:
/parameter_events: rcl_interfaces/msg/ParameterEvent
/rosout: rcl_interfaces/msg/Log
/turtle1/cmd_vel: geometry_msgs/msg/Twist
Service Servers:
/teleop_turtle/describe_parameters: rcl_interfaces/srv/DescribeParameters
/teleop_turtle/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
/teleop_turtle/get_parameters: rcl_interfaces/srv/GetParameters
/teleop_turtle/list_parameters: rcl_interfaces/srv/ListParameters
/teleop_turtle/set_parameters: rcl_interfaces/srv/SetParameters
/teleop_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
Service Clients:
Action Servers:
Action Clients:
/turtle1/rotate_absolute: turtlesim/action/RotateAbsolute
This is the only action in the ROS graph right now. It controls the turtle’s rotation, as you saw
earlier. You also already know that there is one action client (part of /teleop_turtle ) and one action
server (part of /turtlesim ) for this action from using the ros2 node info <node_name> command.
4.1 ros2 action list -t
Actions have types, similar to topics and services. To find /turtle1/rotate_absolute ’s type, run the
command:
ros2 action list -t
In brackets to the right of each action name (in this case only /turtle1/rotate_absolute ) is the action
type, turtlesim/action/RotateAbsolute . You will need this when you want to execute an action from
the command line or from code.
5 ros2 action info
You can further introspect the /turtle1/rotate_absolute action with the command:
ros2 action info /turtle1/rotate_absolute
This tells us what we learned earlier from running ros2 node info on each node:
The /teleop_turtle node has an action client and the /turtlesim node has an action server for
the /turtle1/rotate_absolute action.
6 ros2 interface show
One more piece of information you will need before sending or executing an action goal yourself is
the structure of the action type.
Recall that you identified /turtle1/rotate_absolute ’s type when running the
command ros2 action list -t . Enter the following command with the action type in your terminal:
ros2 interface show turtlesim/action/RotateAbsolute
The first section of this message, above the --- , is the structure (data type and name) of the goal
request. The next section is the structure of the result. The last section is the structure of the
feedback.
7 ros2 action send_goal
Now let’s send an action goal from the command line with the following syntax:
ros2 action send_goal <action_name> <action_type> <values>
You should see the turtle rotating, as well as the following message in your terminal:
Waiting for an action server to become available...
Sending goal:
theta: 1.57
Result:
delta: -1.568000316619873
All goals have a unique ID, shown in the return message. You can also see the result, a field with
the name delta , which is the displacement to the starting position.
To see the feedback of this goal, add --feedback to the ros2 action send_goal command:
ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}"
--feedback
Feedback:
remaining: -3.1268222332000732
Feedback:
remaining: -3.1108222007751465
Result:
delta: 3.1200008392333984
You will continue to receive feedback, the remaining radians, until the goal is complete.
Summary
Actions are like services that allow you to execute long running tasks, provide regular feedback,
and are cancelable.
A robot system would likely use actions for navigation. An action goal could tell a robot to travel to
a position. While the robot navigates to the position, it can send updates along the way (i.e.
feedback), and then a final result message once it’s reached its destination.
Turtlesim has an action server that action clients can send goals to for rotating turtles. In this
tutorial, you introspected that action, /turtle1/rotate_absolute , to get a better idea of what actions
are and how they work.
Next steps
Now you’ve covered all of the core ROS 2 concepts. The last few tutorials in the “Users” set will
introduce you to some tools and techniques that will make using ROS 2 easier, starting with Using
rqt_console.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Using rqt_console
Goal: Get to know rqt_console , a tool for introspecting log messages.
Tutorial level: Beginner
Time: 5 minutes
Contents
Background
Prerequisites
Tasks
1 Setup
2 Messages on rqt_console
3 Logger levels
o Summary
o Next steps
Background
rqt_console is a GUI tool used to introspect log messages in ROS 2. Typically, log messages show
up in your terminal. With rqt_console , you can collect those messages over time, view them closely
and in a more organized manner, filter them, save them and even reload the saved files to
introspect at a different time.
Nodes use logs to output messages concerning events and status in a variety of ways. Their
content is usually informational, for the sake of the user.
Prerequisites
You will need rqt_console and turtlesim installed.
As always, don’t forget to source ROS 2 in every new terminal you open.
Tasks
1 Setup
Start rqt_console in a new terminal with the following command:
ros2 run rqt_console rqt_console
2 Messages on rqt_console
To produce log messages for rqt_console to display, let’s have the turtle run into the wall. In a new
terminal, enter the ros2 topic pub command (discussed in detail in the topics tutorial) below:
ros2 topic pub -r 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular:
{x: 0.0,y: 0.0,z: 0.0}}"
Since the above command is publishing the topic at a steady rate, the turtle is continuously
running into the wall. In rqt_console you will see the same message with the Warn severity level
displayed over and over, like so:
Press Ctrl+C in the terminal where you ran the ros2 topic pub command to stop your turtle from
running into the wall.
3 Logger levels
ROS 2’s logger levels are ordered by severity:
Fatal
Error
Warn
Info
Debug
There is no exact standard for what each level indicates, but it’s safe to assume that:
Fatal messages indicate the system is going to terminate to try to protect itself from
detriment.
Error messages indicate significant issues that won’t necessarily damage the system, but
Now you won’t see the initial Info level warnings that came up in the console last time you
started turtlesim . That’s because Info messages are lower priority than the new default
severity, Warn .
Summary
rqt_console can be very helpful if you need to closely examine the log messages from your
system. You might want to examine log messages for any number of reasons, usually to find out
where something went wrong and the series of events leading up to that.
Next steps
The next tutorial will teach you how to create launch files.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Creating a launch file
Goal: Create a launch file to run a complex ROS 2 system.
Tutorial level: Beginner
Time: 10 minutes
Contents
Background
Prerequisites
Tasks
1 Setup
2 Write the launch file
3 ros2 launch
4 Introspect the system with rqt_graph
o Summary
o Next steps
Background
In the tutorials up until now, you have been opening new terminals for every new node you run. As
you create more complex systems with more and more nodes running simultaneously, opening
terminals and reentering configuration details becomes tedious.
Launch files allow you to start up and configure a number of executables containing ROS 2 nodes
simultaneously.
Running a single launch file with the ros2 launch command will start up your entire system - all
nodes and their configurations - at once.
Prerequisites
This tutorial uses the rqt_graph and turtlesim packages.
You will also need to use a text editor of your preference.
As always, don’t forget to source ROS 2 in every new terminal you open.
Tasks
1 Setup
Create a new directory to store your launch file:
mkdir launch
Create a launch file named turtlesim_mimic_launch.py by entering the following command in the
terminal:
LinuxmacOSWindows
touch launch/turtlesim_mimic_launch.py
You can also go into your system’s file directory using the GUI and create a new file that way.
Open the new file in your preferred text editor.
2 Write the launch file
Let’s put together a ROS 2 launch file using the turtlesim package and its executables.
Copy and paste the complete code into the turtlesim_mimic_launch.py file:
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim'
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim'
),
Node(
package='turtlesim',
executable='mimic',
name='mimic',
remappings=[
('/input/pose', '/turtlesim1/turtle1/pose'),
('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
]
)
])
])
Within the LaunchDescription is a system of three nodes, all from the turtlesim package. The goal
of the system is to launch two turtlesim windows, and have one turtle mimic the movements of the
other.
The first two actions in the launch description launch two turtlesim windows:
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim'
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim'
),
Note the only difference between the two nodes is their namespace values. Unique namespaces
allow the system to start two simulators without node name nor topic name conflicts.
Both turtles in this system receive commands over the same topic and publish their pose over the
same topic. Without unique namespaces, there would be no way to distinguish between messages
meant for one turtle or the other.
The final node is also from the turtlesim package, but a different executable: mimic .
Node(
package='turtlesim',
executable='mimic',
name='mimic',
remappings=[
('/input/pose', '/turtlesim1/turtle1/pose'),
('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
]
)
to /turtlesim2/turtle1/cmd_vel . This means mimic will subscribe to /turtlesim1/sim ’s pose topic and
republish it for /turtlesim2/sim ’s velocity command topic to subscribe to. In other
words, turtlesim2 will mimic turtlesim1 ’s movements.
3 ros2 launch
To launch turtlesim_mimic_launch.py , enter into the directory you created earlier and run the
following command:
cd launch
ros2 launch turtlesim_mimic_launch.py
Note
It is possible to launch a launch file directly (as we do above), or provided by a package. When it is
provided by a package, the syntax is:
ros2 launch <package_name> <launch_file_name>
This helps make sure that the ros2 launch command is available after building your package. It
also ensures that all launch file formats are recognized.
Two turtlesim windows will open, and you will see the following [INFO] messages telling you which
nodes your launch file has started:
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [turtlesim_node-1]: process started with pid [11714]
[INFO] [turtlesim_node-2]: process started with pid [11715]
[INFO] [mimic-3]: process started with pid [11716]
To see the system in action, open a new terminal and run the ros2 topic pub command on
the /turtlesim1/turtle1/cmd_vel topic to get the first turtle moving:
ros2 topic pub -r 1 /turtlesim1/turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z:
0.0}, angular: {x: 0.0, y: 0.0, z: -1.8}}"
This tutorial talks about concepts covered in previous tutorials, like nodes and topics. It also uses
the turtlesim package.
As always, don’t forget to source ROS 2 in every new terminal you open.
Tasks
1 Setup
You’ll be recording your keyboard input in the turtlesim system to save and replay later on, so
begin by starting up the /turtlesim and /teleop_turtle nodes.
Open a new terminal and run:
ros2 run turtlesim turtlesim_node
Let’s also make a new directory to store our saved recordings, just as good practice:
mkdir bag_files
cd bag_files
2 Choose a topic
ros2 bag can only record data from topics that are published on. To see a list of your system’s
topics, open a new terminal and run the command:
ros2 topic list
In the topics tutorial, you learned that the /turtle_teleop node publishes commands on
the /turtle1/cmd_vel topic to make the turtle move in turtlesim.
To see the data that /turtle1/cmd_vel is publishing, run the command:
ros2 topic echo /turtle1/cmd_vel
Nothing will show up at first because no data is being published by the teleop. Return to the
terminal where you ran the teleop and select it so it’s active. Use the arrow keys to move the turtle
around, and you will see data being published on the terminal running ros2 topic echo .
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
You will see the following messages in the terminal (the date and time will be different):
[INFO] [rosbag2_storage]: Opened database 'rosbag2_2019_10_11-05_18_45'.
[INFO] [rosbag2_transport]: Listening for topics...
[INFO] [rosbag2_transport]: Subscribed to topic '/turtle1/cmd_vel'
[INFO] [rosbag2_transport]: All requested topics are subscribed. Stopping discovery...
Now ros2 bag is recording the data published on the /turtle1/cmd_vel topic. Return to the teleop
terminal and move the turtle around again. The movements don’t matter, but try to make a
recognizable pattern to see when you replay the data later.
You can move the turtle around and press Ctrl+C when you’re finished.
Note
There is another option you can add to the command, -a , which records all the topics on your
system.
4 ros2 bag info
You can see details about your recording by running:
ros2 bag info <bag_file_name>
Running this command on the subset bag file will return a list of information on the file:
ros2 bag info subset
Files: subset.db3
Bag size: 228.5 KiB
Storage id: sqlite3
Duration: 48.47s
Start: Oct 11 2019 06:09:09.12 (1570799349.12)
End Oct 11 2019 06:09:57.60 (1570799397.60)
Messages: 3013
Topic information: Topic: /turtle1/cmd_vel | Type: geometry_msgs/msg/Twist | Count: 9 | Serialization
Format: cdr
Topic: /turtle1/pose | Type: turtlesim/msg/Pose | Count: 3004 | Serialization Format:
cdr
To view the individual messages, you would have to open up the database, in this case sqlite3, to
examine it, which is beyond the scope of ROS 2.
5 ros2 bag play
Before replaying the bag file, enter Ctrl+C in the terminal where the teleop is running. Then make
sure your turtlesim window is visible so you can see the bag file in action.
Enter the command:
ros2 bag play subset
Your turtle will follow the same path you entered while recording (though not 100% exactly;
turtlesim is sensitive to small changes in the system’s timing).
Because the subset file recorded the /turtle1/pose topic, the ros2 bag play command won’t quit for
as long as you had turtlesim running, even if you weren’t moving.
This is because as long as the /turtlesim node is active, it publishes data on
the /turtle1/pose topic at regular intervals. You may have noticed in the ros2 bag info example
result above that the /turtle1/cmd_vel topic’s Count information was only 9; that’s how many times
we pressed the arrow keys while recording.
Notice that /turtle1/pose has a Count value of over 3000; while we were recording, data was
published on that topic 3000 times.
To get an idea of how often position data is published, you can run the command:
ros2 topic hz /turtle1/pose
Summary
You can record data passed on topics in your ROS 2 system using the ros2 bag command.
Whether you’re sharing your work with others or introspecting on your own experiments, it’s a
great tool to know about.
Next steps
You’ve completed the “Beginner: CLI Tools” tutorials! The next step is tackling the “Beginner:
Client Libraries” tutorials, starting with Creating a workspace.
Related content
A more thorough explanation of ros2 bag can be found in the README here. For more information
on QoS compatibility and ros2 bag , see rosbag2: Overriding QoS Policies.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%