ROS 2 Generic Server and Client

Learning Objectives

In this example, we will explain how to use Isaac Sim to

  • Receive a ROS2 message of any type and respond via generic server nodes

  • Send a ROS2 message of any type and receive the response via generic client nodes

Getting Started

Important

Make sure to source your ROS 2 installation from the terminal before running Isaac Sim. If sourcing ROS 2 is a part of your .bashrc then Isaac Sim can be run directly.

Prerequisite

  • Complete ROS and ROS 2 Installation.

  • Set the FASTRTPS_DEFAULT_PROFILES_FILE environment variable per instructions in ROS and ROS 2 Installation before launching Isaac Sim, as well as any terminal where ROS messages will be sent or received, and ROS 2 Extension is enabled.

ROS 2 Messages Types

See ROS 2 Generic Publisher and Subscriber for background information about ROS2 topics and message types. Generic services (server and client) build on top of the similar communication style. Generic server and client nodes allow sending/receiving any ROS messages when the underlying message type and ROS package are defined. To check out all existing services in your environment use the follow.

ros2 interface list --only-srvs

Furthermore, you can check out the actual service configuration in your ROS distro under share/packageName/srv/serviceName subdirectory (e.g. share/std_srvs/srv/SetBool for std_srvs/srv/SetBool service). The service configuration file is comprised of two sections; the first section defines the request message sent by a client and received by the server. The second section of the configuration file defines the response message that is sent by the server and received by the client.

Generic Server

Basic Methodology:

  1. Go to Create > Visual Scripting > Action Graph to create an Action Graph.

  2. Add (and connect) the following OmniGraph nodes into the Action Graph:

  • On Playback Tick node to execute other graph nodes every simulation frame.

  • ROS2 Context node to create a context using either the given Domain ID or the ROS_DOMAIN_ID environment variable.

  • ROS2 Service Server Request node to receive a ROS2 service request message of any type.

  • ROS2 Service Server Response node to respond a ROS2 service request message of any type.

  1. Make the following connections:

  • Connecting the Server Handle output property of the ROS2 Service Server Request to Server Handle input property of ROS2 Service Server Response ensures that the two nodes share the same server.

  • Connecting the On received output execution property of the ROS2 Service Server Request to On received input property of ROS2 Service Server Response ensures that the server sends responses only when a request is received.

  1. After connecting playback tick node to the request node and the context node to both request and response nodes, the graph should look like the following:

    ROS2 Server
  2. In the node Property panel define the message type following this pattern: messagePackage / messageSubfolder / messageName.

    When a valid (existing) message type is defined, the node will reconfigure its input/out attributes in order to set the values to be received/sent.

    Note

    • You should enter the same message fields for both ROS2 Service Server Request and ROS2 Service Server Response nodes that are connected through their server handle. For example, for a service such as std_srvs/srv/SetBool messagePackage will be std_srvs, messageSubfolder will be srv and messageName should be SetBool.

    • The outputs of the ROS2 Service Server Request will include the service request fields whereas the inputs of the ROS2 Service Server Response will include the service response fields.

    Hint

    It is not necessary to play the simulation to (re)configure the node’s input attributes for different message types.

    Example of how the ROS2 Service Server Request node outputs will reconfigure to include the Request fields.

    Example of node reconfiguration for `Service Server Request`

    Example of how the ROS2 Service Server Response node inputs will reconfigure to include the Response fields.

    Example of node reconfiguration for `Service Server Response`
  3. You can also modify the default Service Name property of ROS2 Service Server Request node in the Property panel of the node. Note that the client should use the same name to communicate with this server.

Example:

After following the above step the Final configuration of our example server is the following

Example of node reconfiguration for `Service Server Response`
  1. Play the simulation. The server should be ready to receive requests.

  2. Fill out the input fields of the ROS2 Service Server Response as you wish with a sample message to be sent back to the client as well as a status bool data.

  3. In a separate terminal source ROS and issue the following command. This will send a request of type example_interfaces/srv/SetBool from a ROS client with a True bool data field to the server with the service name of /service_name.

    ros2 service call /service_name std_srvs/srv/SetBool "{data: true}"
    

    which should return the server response you provided in the server node, e.g.

    requester: making request: std_srvs.srv.SetBool_Request(data=True)
    
    response:
    std_srvs.srv.SetBool_Response(success=True, message='Sample response message')
    

    where Sample response message is the sample message we entered in the Response Message of the ROS2 Service Server Response node.

Generic Client

Basic Methodology:

To add a generic client

  1. Go to Create > Visual Scripting > Action Graph to create an Action Graph.

  2. Add (and connect) the following OmniGraph nodes into the Action Graph:

  • On Playback Tick node to execute other graph nodes every simulation frame.

  • ROS2 Context node to create a context using either the given Domain ID or the ROS_DOMAIN_ID environment variable.

  • ROS2 Service Client node to send a ROS2 request message of any type and receive a response message of any type.

  1. In the node Property panel define the message type following this pattern: messagePackage / messageSubfolder / messageName.

    ROS2 Service Client node inputs/outputs will reconfigure according to the service configuration selected by the user. The inputs will include the service request fields. The outputs will include the response field. For instance, for a service such as std_srvs/srv/SetBool messagePackage will be std_srvs, messageSubfolder will be srv and messageName should be SetBool. When a valid (existing) message type is defined, the node will reconfigure its input/outputs attributes. Below is an example of how the ROS2 Service Client node inputs/outputs reconfigure to include the Request/Response fields.

    Example of node reconfiguration for `Service Client`
  2. Once you play the simulation the client will start making requests according to its input data/fields. The server response is accessible from the node’s outputs.

Example:

Let’s reconfigure the previous OmniGraph example to include the client node in the same graph. This will enable us to send requests from within the OmniGraph via the client node instead of the terminal.

  1. Create a graph as follows:

    Example of an |omnigraph_short| that involves both ROS2 server and client nodes.
  2. Play the simulation. The client and server nodes are both sending/receiving request/response messages.

  3. Select the ROS2 Service Server Response and modify the response message of the server in the Response Message field of the input as you wish.

  4. Select the ROS2 Service Client node and checkout to see that the client node is receiving the response you provided in the server node.

Summary

In this tutorial we learned how to reconfigure the generic server and client nodes to send and receive any ROS2 messages in Isaac Sim.