ROS2 + DDS: A Field Guide to Interoperability
Written by Neil Puthuff
September 27, 2018
Although ROS2 is designed to use DDS as its connectivity framework (see my previous blog post - ROS2 + DDS: When Ecosystems Merge for more information), the integration process has a few quirks that must be accommodated in order for a pure DDS system to seamlessly interoperate with a ROS2 system. This blog serves as a practical field guide to interoperability and covers some of the known issues as of the “Bouncy Bolson” (July 2018) release of ROS2 and how to mitigate them.
ROS2 is an evolving project. There may be changes in future ROS2 releases that further affect interoperability. That being said, always remember that when using the
rmw_connext_cpp layer under ROS2 – it’s still Connext DDS. The power and flexibility inherent to the Connext libraries are still available, using the same methods as a non-ROS implementation. You have control over your system.
Here’s a run-down of settings that can affect interoperability between pure DDS and ROS2 systems (ROS2 “Bouncy Bolson” unless otherwise specified):
Topic Names and Partitions
ROS2 identifies the namespace of the topic data by encoding it in the name or DDS partition of the topic. User data topics will be in the “rt” (ROS Topic) namespace, encoded in DDS as:
Topic Data Types
When using the Connext RMW layer under ROS2, you may have noticed that all of the ROS2 “rt/*” topics are reported during discovery to have the same data type:
This type definition is inserted by the ROS2 rmw_connext_cpp layer to represent a serialization of the topic data, even though the topic data is unchanged. When a connection is attempted with a DDS topic using the original data type -- a QoS mismatch will occur, preventing a connection.
The easiest solution is to suppress this typecode announcement from the ROS2 participants. This can be done by adding a USER_QOS_PROFILES.xml file to the directory used to launch the ROS2 participants. This file contains QoS settings to suppress type code and type object sharing, such as:
Note that this file also sets reliability to “Best Effort” – this is only an example starting point.
Note also that this QoS file only affects the ROS2 participants that were launched for the same directory as the QoS file. If needed, every ROS2 participant could have its own custom QoS file in a separate directory.
Connecting a DDS system to a ROS2 system may result in warnings about non-addressable locators/transports not installed. This is the result of participants having different lists of available transports, such as participant A(udpv4) discovering participant B(udpv4, udpv6); A warning would be issued that participant A will not be able to connect using udpv6.
Transport selection with Connext RMW under ROS2 uses the same methods as in a Connext-only system:
- Set the allowed transports in the USER_QOS_PROFILES.xml file by adding to the <participant_qos> section, as in:
- Set the initial peers (and enable / disable multicast) by adding an “NDDS_DISCOVERY_PEERS” file to the directory used to launch the application. The plain-text file should contain a comma-separated list of the desired peers for discovery, such as:
localhost,192.168.1.12,shmem://(this example disables multicast discovery)
RMW Selection in ROS2
Be sure to set the environment variable to select Connext as the RMW layer under ROS2:
This can also be passed on the command line when launching ROS2 applications, as in:
RMW_IMPLEMENTATION=rmw_connext_cpp ros2 run demo_nodes_cpp talker
Some ROS2 topics use unbounded sequences and strings. DDS applications that seek to interoperate using these topics will need to enable ‘Unbounded Support’ in the DDS code generator.
Stay tuned for the next article in this series, which covers a crucial (albeit temporary) gap in the ROS2 lineup: record and replay of topic data.