5.8. Services and Actions#
Services and actions provide alternative methods of communication for nodes in the ROS graph for situations where the publisher-subscriber model of topics are not well-suited.
services are the name given to short, synchronous robot behaviors that can be done quickly, like turning on lights and switching components on or off. Services are based on a request-reply model versus the publisher-subscriber model of topics. While topics allow nodes to subscribe to data streams and get continual updates, services only provide data when they are specifically called by a client.


actions are longer term, asynchronous, tasks that may have intermediate steps. Actions are built on topics and services, and consist of three parts: a goal, feedback, and a result. 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 thus correspond to a client-server model. 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.

Actions are intended for long running tasks. A classic example of an action is navigation: a robot is provided a goal position and asked to navigate to that goal. Try as the robot might, since it cannot move infinitely fast, it takes time to move to a goal and sometimes its path may become blocked.
These two primitives are the backbone of most robotic systems using ROS and learning how to use them via the command line will allow you quickly and easily command a robot to complete a task for you.
5.8.1. Finding all actions and services of all nodes#
We can use the CLI to list all available services and actions provided by all currently running ROS nodes and even to call a node’s service or an action using a single command. While typically such services and actions are called by other nodes as part of the automated workflow of the robot, having the ability to make such calls from the command line is convenient for debugging and testing.
The command line interface for services and actions are very similar, in fact they both have only four sub commands.
Let’s run the action
and service
commands and compare them:
$ ros2 action --help
usage: ros2 action [-h]
Call `ros2 action <command> -h` for more detailed usage.
...
Various action related sub-commands
options:
-h, --help show this help message and exit
Commands:
info Print information about an action
list Output a list of action names
send_goal Send an action goal
$ ros2 service --help
usage: ros2 service [-h] [--include-hidden-services]
Call `ros2 service <command> -h` for more detailed usage.
...
Various service related sub-commands
options:
-h, --help show this help message and exit
--include-hidden-services
Consider hidden services as well
Commands:
call Call a service
find Output a list of available services of a given type
list Output a list of available services
type Output a service's type
Call `ros2 service <command> -h` for more detailed usage.
We can see that both commands have a list
command that gives a list of
available services or actions from all nodes in the grouph.
Tip
If you just want to know the services and actions from one particular running node,
remember you can also just use the ros2 node info <node-name>
command, e.g.
$ ros2 node info /turtlesim
/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:
We already saw this command and its output in the Nodes and the Graph section, but now this information should appear more familiar. We can see all the topics that the node subscribes to, as well as all topics the nodes it publishes to.
We can also see a number of “Service Servers” and “Service Clients”. It is worth noting the client and server relationship here. Since ROS may have multiple nodes running some nodes may offer services (these are servers), and other ROS nodes may call those servers (these are the clients).
5.8.2. Using ROS 2 Services#
Let’s begin digging into inspecting and controlling services using the CLI.
Running the ros2 service list
command in a new terminal will return a list of all the services currently active in the system:
/clear
/kill
/reset
/spawn
/teleop_turtle/describe_parameters
/teleop_turtle/get_parameter_types
/teleop_turtle/get_parameters
/teleop_turtle/list_parameters
/teleop_turtle/set_parameters
/teleop_turtle/set_parameters_atomically
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/describe_parameters
/turtlesim/get_parameter_types
/turtlesim/get_parameters
/turtlesim/list_parameters
/turtlesim/set_parameters
/turtlesim/set_parameters_atomically
Note
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 a later section.
In this section, the parameter services will be omitted from the 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
.
Using ros2 service list
, there seem to be quite a few services listed.
5.8.2.1. Understanding service types#
Services have types that describe how the request and response data of a service is structured. ROS services and actions use messages similar to those used in topics to communicate. In fact, actions and services are built on top of messages. Service types are defined similarly to topic types, except service types have two parts: one message for the request and another for the response.
We can use the service type
sub command to determine the message type
used by a particular service.
To find out the type of a service, use the command ros2 service type <service_name>
.
For example, let’s take a look at the /spawn
service, which will create more turtles.
$ ros2 service type /spawn
turtlesim/srv/Spawn
5.8.2.2. Inspecting a Service message type#
Just as with regular topic message types, we can find specifics of the message by using the interface show
command.
$ ros2 interface show turtlesim/srv/Spawn
float32 x
float32 y
float32 theta
string name # Optional. A unique name will be created and returned if this is empty
---
string name
The output above shows that the spawn message takes three float32
values for its position and orientation as well a string
for its name. The
---
indicate the return value of the services. Unlike topics, services have
a return value, which enables them to do things like perform computations and
calculations.
Note
Sometimes a service does not really need to provide a return value.
In those cases, services can use the Empty
type as return value.
Empty
means the service call sends no data when making a request and receives no data when receiving a response.
To see an example, 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
5.8.2.3. Other basic ros2 service
sub commands#
The ros2 service --help
also showed the sub command find
,
which is relatively straightforward.
Try it out yourself!
If you want to find all the services in your ROS graph of a specific type,
you can use ros2 service find <type_name>
.
For example, you can find that there are two services with the Empty
like this:
$ ros2 service find std_srvs/srv/Empty
/clear
/reset
5.8.2.4. Calling a service from the CLI#
Let’s examine the help for calling a service by running ros2 service call --help
:
$ ros2 service call --help
usage: ros2 service call [-h] [-r N] service_name service_type [values]
Call a service
positional arguments:
service_name Name of the ROS service to call to (e.g. '/add_two_ints')
service_type Type of the ROS service (e.g. 'std_srvs/srv/Empty')
values Values to fill the service request with in YAML format (e.g.
"{a: 1, b: 2}"), otherwise the service request will be
published with default values
optional arguments:
-h, --help show this help message and exit
-r N, --rate N Repeat the call at a specific rate in Hz
The syntax here is very similar to publishing to a topic, but instead of using a
a topic name we use a service name. The service type is just like the topic type
that we used in the past, but instead of using a message type we need a service
type. Finally we give it a value in YAML format. Note that a YAML string must be encased
in single quotes. Let’s try calling a service by creating a turtle
named Larry
at a position where all values are zero (use TAB-complete).
$ ros2 service call /spawn turtlesim/srv/Spawn "{x: 0, y: 0, theta: 0.0, name: 'Larry'}"
requester: making request: turtlesim.srv.Spawn_Request(x=0.0, y=0.0, theta=0.0, name='Larry')
response:
turtlesim.srv.Spawn_Response(name='Larry')
If everything is working correctly you should now have a turtle named “Larry” in the lower left hand corner of the screen:
Tip
Try exploring the other services offered, or
creating more turtles at different locations and moving them around.
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.

5.8.3. Using ROS 2 Actions#
New let’s move on to actions. As mentioned previously, actions differ from services in a few ways and offer a number of advantages. Actions have the following advantages:
Actions have a
goal
. That is to say you send them a goal, and they attempt to complete it.Actions can reject goal requests. This prevents them from becoming too busy.
Actions are asynchronous and can perform tasks “while you wait.”
Actions will provide you with “updates” with information about their progress while you wait.
Actions are preemptable, meaning you can cancel them if you change your mind.
Just like with services, we’ll first figure out how to call the sole action in
our ROS system by using the action list
and action info
commands. Recall, that when we called ros2 action list
we got a single
service. Now that we have Larry things have changed. Let’s take a look:
$ ros2 action list
/Larry/rotate_absolute
/turtle1/rotate_absolute
Now there are two actions available, one for Larry and one for turtle1
.
Let’s rotate turtle1 to face Larry. First we’ll call action info
using /turtle1/rotate_absolute
as the input and see what we get:
$ ros2 action info /turtle1/rotate_absolute
Action: /turtle1/rotate_absolute
Action clients: 0
Action servers: 1
/turtlesim
Well, that tells us about the client and servers, but it really isn’t
helpful for our goal of moving Larry. Why don’t we look at the action send_goal
help and see if we can
figure out how to use it:
$ ros2 action send_goal --help
usage: ros2 action send_goal [-h] [-f] action_name action_type goal
Send an action goal
positional arguments:
action_name Name of the ROS action (e.g. '/fibonacci')
action_type Type of the ROS action (e.g.
'example_interfaces/action/Fibonacci')
goal Goal request values in YAML format (e.g. '{order: 10}')
optional arguments:
-h, --help show this help message and exit
-f, --feedback Echo feedback messages for the goal
This command needs an action name, an action type, and a goal in YAML. We know the action name, and we know how to write YAML, so all we need is to determine the action type. The best way to get the action type is the same way we published a message.
We see each of our turtles have one service called rotate_absolute
.
Let’s dig into this action using the info
sub command. This command has a -t
flag to list the types of messages.
$ ros2 action info /turtle1/rotate_absolute -t
Action: /turtle1/rotate_absolute
Action clients: 0
Action servers: 1
/turtlesim [turtlesim/action/RotateAbsolute]
The first line lists the action
name. The second line gives the current number of clients for the
action. The Action servers
line gives the total number of action
servers for this action. The last line gives the package and message
type for the action.
We can see here that we need to know the action name, the type, and the values. Now the only problem is figuring out the format of the action type.
Let’s understand the RotateAbsolute
action message
The ros2 interface show
command can be used to find the type of action
message. Let’s take a look:
$ ros2 interface show turtlesim/action/RotateAbsolute
# The desired heading in radians
float32 theta #< --- This section is the GOAL
---
# The angular displacement in radians to the starting position
float32 delta #< --- This section is the final result, different from the goal.
---
# The remaining rotation in radians
float32 remaining # < --- This is the current state.
What does this say about rotate absolute?
There is a float input,
theta
, the desired heading. This first section is the actual goal.delta
is the angle from the initial heading. This is the value returned when the action completes.remaining
is the remaining radians to move. This is the value posted by the action while the action is being done.
With this information we can create our call to the action server. We’ll
use the -f
flag to make this a bit clearer. Keep an eye on your turtle! It should move, slowly.
$ ros2 action send_goal -f /turtle1/rotate_absolute turtlesim/action/RotateAbsolute {'theta: 1.70'}
Waiting for an action server to become available...
Sending goal:
theta: 1.7
Feedback:
remaining: 0.11599969863891602
Goal accepted with ID: 35c40e91590047099ae5bcc3c5151121
Feedback:
remaining: 0.09999966621398926
Feedback:
remaining: 0.06799960136413574
Feedback:
remaining: 0.03599953651428223
Result:
delta: -0.09600019454956055
Goal finished with status: SUCCEEDED
If everything worked correctly we should see our turtle has rotated.
5.8.4. Summary#
Nodes can communicate using services in ROS 2. Unlike a topic - a one way 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 section you used command line tools to identify, introspect, and call services.
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.