ROS2 - Backend Contribution

ROS2 is the preferred way of communication in the robot backend. It is recommended to use ROS2 in URCap backend contributions for communicating with other backend contributions, the controller and external hardware. The robot platform also provides an easy way of communicating with the frontend using a ROS2 Web API. See Working with ROS2 in a frontend contribution.

For a general ROS2 overview, guides and documentation visit ROS2 Humble

All backend contributions must be containerized, this includes ROS2 nodes. For instruction on how to set up a containerized ROS2 node in manifest.yaml see How to configure, package and install a contribution.

Creating a ROS2 Backend Contribution

Utilizing the URCap Contribution Generator you will be prompted to include ROS2 Docker support. If you choose to include this, a template ROS package will be generated in your backend including the Dockerfile. For more information about ROS packages, please visit the official ROS2 Documentation: Creating your first ROS 2 package.

Samples and templates used in the SDK follows the examples of ROS closely.

The package generated by the URCap Contribution Generator extends the official ROS template package with the following changes to the package manifest (package.xml) that specifies execution dependencies (<exec_depend>) on:

  • ROS Client Library for Python (rclpy)

  • Standard ROS Messages (std_msgs)

  • Custom UR message definitions (for controller ROS topics and services (urinterfaces))

Subscribing to Topics and Calling Services

ROS offers simple guides to creating subscribers to topics and clients to call services. Please refer to the official ROS2 documentation for Creating a Simple Subscriber and Creating a Simple Client.

Communicating with the Robot through Topics and Services

The controller offers a set of ROS topics and services accessible from contributed ROS nodes. See ROS2 Topics and Services for the comprehensive list of topics and services. For each topic or service, the message column shows what message type is supported by that topic or service and the quality of service (QoS) settings required to successfully obtain communication.

For details on messages types used in the urinterfaces package see URInterfaces API reference.

ROS Namespace for the UR Controller

All controller topics and services are prefixed with a controller specific namespace. The ROS message bus permits multiple robots, and other ROS nodes on the same network. Multiple nodes can publish to the same topic - in some cases this behavior is desirable, but in general namespaces are used to prevent collisions.

A contributed ROS node will be able to read the namespace of the local controller (the controller running on the robot that the URCap is installed on) using the environment variable “ROS2_NAMESPACE”.

Example:

namespace = os.getenv('ROS2_NAMESPACE')

If the contributed ROS node will primarily communicate with the local controller, the node can be created within that namespace using either the inline create_node method or passing the namespace variable to the initializer of the Node class:

# Option 1: Inline creation of ROS node
namespace = os.getenv('ROS2_NAMESPACE')
node = rclpy.create_node('simple_ros2_node', namespace=namespace)

# Option 2: Inheritance based creation of a ROS node
class SimpleROS2Node(Node):
    """Creates a ROS Node"""

    def __init__(self):
        self.namespace = os.getenv('ROS2_NAMESPACE')
        super().__init__('simple_ros2_node', namespace=self.namespace)

If you prefer your node to be created in the root namespace, simply leave out the namespace. Subscribing to topics and calling services must then prepend the namespace of the controller which can easily be done by:

namespace = os.getenv('ROS2_NAMESPACE')
example_topic = '/' + namespace + '/standard_analog_output_0'
example_service = '/' + namespace + '/set_standard_analog_output'