What we are going to learn
- How to set up the DDS middleware for your ROS2 programs
- What are DDS and RTPS used by ROS2
- How to avoid errors when working with multiple DDS providers
List of resources used in this post
- Use the rosject: https://app.theconstructsim.com/#/l/4a5ab758/
- ROS Development Studio (ROSDS) —▸ http://rosds.online
- ROS2 Courses –▸
Opening the rosject
In order to better understand DDS/RTTPS used in ROS2, we need to have ROS2 installed in our system, and it is also useful to have some simulations. To make your life easier, we already prepared a rosject with a simulation for that: https://app.theconstructsim.com/#/l/4a5ab758/ .
You can download the rosject on your own computer if you want to work locally, but just by copying the rosject (clicking the link), you will have a setup already prepared for you.
After the rosject has been successfully copied to your own area, you should see a Run button. Just click that button to launch the rosject (below you have a rosject example).
After pressing the Run button, you should have the rosject loaded. Let’s now head to the next section to really get some real practice.
DDS stands for Data Distribution Service, it is an industry standard for distributed object management groups. More info on https://www.dds-foundation.org/what-is-dds-3/
ROS2 is built on top of DDS/RTPS Middleware implementations to handle DDS/RTPS communication. Right now, we have 4 DDS implementations available for ROS2. The different implementations implement the ROS Middleware Interface (RMW).
In this POST we will be using the ROS2 Galactic version. For ROS2 Galactic, the default DDS Implementation is Cyclone DDS.
RTPS (Real-Time Transport Protocol) is the protocol used by DDS. https://www.omg.org/spec/DDSI-RTPS/2.3/Beta1/PDF
The DDS War
Up until ROS2 Foxy, the default DDS Implementation used by ROS was eProsima’s Fast DDS (previous default RMW)
Eclipse Cyclone DDS (default one since Galactic)
For ROS2 Galactic, as we already mentioned earlier, the default DDS Implementation is Cyclone DDS. The Galactic version was released on May 23rd, 2021, and is supported until November 2022.
Running publishers and subscribers with default DDS
Assuming you have opened the rosject by clicking the Run button mentioned in earlier sections, let’s now Open a Terminal in order to launch ROS nodes.
In the first terminal that is open, let’s start a publisher by running the command below:
ros2 run demo_nodes_cpp talker
Please open a second terminal and run a subscriber there:
ros2 run demo_nodes_cpp listener
If everything went well, the publisher and subscriber should be working with no problems:
Since we did not inform the DDS Implementation that we are using, they are using the default one, which for ROS Galactic is Cyclone DDS.
You may be asking: How do I know which implementation I’m really using?
That is quite easy. After running ros2 topic list, a ROS2 Daemon will be launched and in the command line, you will see the DDS Implementation used. If you then list the process and search for rmw using grep, you will find the implementation being used.
Let’s search the DDS with the command “ps faux | grep rmw“:
ps faux | grep rmw # The output /usr/bin/python3 /opt/ros/galactic/bin/_ros2_daemon --rmw-implementation rmw_cyclonedds_cpp --ros-domain-id 0
As we can see in the output “–rmw-implementation rmw_cyclonedds_cpp“, the implementation used for ROS Galactic is Cyclone DDS.
If you want to use different DDS Implementations, you can make usage of the environment variable called RMW_IMPLEMENTATION that ROS uses.
Let’s put it into practice in the next sections.
Using eProsima’s Fast DDS
In order to use FastDDS, you have to export the following variable:
On The Construct we already have ros-galactic-rmw-fastrtps-cpp installed, but if running the nodes in your own computer, you may need to install it with:
sudo apt-get update sudo apt-get install -y ros-galactic-rmw-fastrtps-cpp
You can also set the variable when starting each node, for example. Please go to the first terminal, kill the current publisher by pressing CTRL-C, and then let’s launch the publisher with FastDDS with the command below:
RMW_IMPLEMENTATION=rmw_fastrtps_cpp ros2 run demo_nodes_cpp talker
And to run the subscriber using FastDDS, you can just set RMW_IMPLEMENTATION:
RMW_IMPLEMENTATION=rmw_fastrtps_cpp ros2 run demo_nodes_cpp listener
You can go even further and use different DDS Implementations for different ROS Nodes. To test this, please open a third terminal and do not kill the current publisher running with FastDDS. You can then run the listener in a third terminal using CyCloneDDS with:
RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 run demo_nodes_cpp listener
The listener should be working with no problems.
In order to use CycloneDDS, you just have to define RMW_IMPLEMENTATION=rmw_cyclonedds_cpp, and you will also need to have the ros-galactic-rmw-cyclonedds-cpp package installed.
On The Construct, this package is already installed, but if you are running the ROS2 nodes on your computer, you may need to install the package ros-galactic-rmw-cyclonedds-cpp with:
sudo apt-get update sudo apt-get install -y ros-galactic-rmw-cyclonedds-cpp
You can then run the talker/publisher and listener/subscriber using CycloneDDS with:
RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 run demo_nodes_cpp talker RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 run demo_nodes_cpp listener
Using GurumNetworks GurumDDS
In order to use GurumDDS, you have to export RMW_IMPLEMENTATION=rmw_gurumdds_cpp.
Let’s try to run the publisher:
RMW_IMPLEMENTATION=rmw_gurumdds_cpp ros2 run demo_nodes_cpp talker
Since we do not have that DDS implementation installed, you should have an error similar to the following:
[ERROR] [1651517328.801031797] [rcl]: Error getting RMW implementation identifier / RMW implementation not installed (expected identifier of 'rmw_gurumdds_cpp'), with error message 'failed to load shared library 'librmw_gurumdds_cpp.so' due to dlopen error: librmw_gurumdds_cpp.so: cannot open shared object file: No such file or directory, at /tmp/binarydeb/ros-galactic-rcutils-4.0.2/src/shared_library.c:99, at /tmp/binarydeb/ros-galactic-rmw-implementation-2.4.1/src/functions.cpp:75', exiting with 1., at /tmp/binarydeb/ros-galactic-rcl-3.1.2/src/rcl/rmw_implementation_identifier_check.c:139
The problem happens because we do not have the GurumDDS installed by default on The Construct. You have to install the ros-galactic-rmw-gurumdds-cpp package with:
sudo apt-get update sudo apt-get install -y ros-galactic-rmw-gurumdds-cpp
After that, running the publisher and subscriber should work with no problems:
RMW_IMPLEMENTATION=rmw_gurumdds_cpp ros2 run demo_nodes_cpp talker
Hm, now you probably have a new error similar to the following:
user:~$ RMW_IMPLEMENTATION=rmw_gurumdds_cpp ros2 run demo_nodes_cpp talker 22-05-02 18:52:44.719 2804 2804 E [License] Invalid license 22-05-02 18:52:44.719 2804 2804 E [License] Reason: No license for feature(gurumdds-x86_64-linux) 22-05-02 18:52:44.719 2804 2804 E [License] Please contact us via email below for license extension and inquiries. 22-05-02 18:52:44.719 2804 2804 E [License] email: email@example.com
Well, I think it is clear to you that this DDS implementation needs a special license. If you want to use this implementation, it would be nice to reach the creators through the email firstname.lastname@example.org.
Using Connext DDS
In order to use Connext DDS to run a ROS2 node, for example, you can just:
RMW_IMPLEMENTATION=rmw_connext_cpp ros2 run demo_nodes_cpp talker
But we will have an error also because this DDS implementation is not installed. The error is the following:
[ERROR] [1651517890.844612937] [rcl]: Error getting RMW implementation identifier / RMW implementation not installed (expected ide ntifier of 'rmw_connext_cpp'), with error message 'failed to load shared library 'librmw_connext_cpp.so' due to dlopen error: librmw_connext_cpp.so: cannot open shared object file: No such file or directory, at /tmp/binarydeb/ros-galactic-rcutils-4.0.2/src/sha red_library.c:99, at /tmp/binarydeb/ros-galactic-rmw-implementation-2.4.1/src/functions.cpp:75', exiting with 1., at /tmp/binarydeb/ros-galactic-rcl-3.1.2/src/rcl/rmw_implementation_identifier_check.c:139
If you want to install this DDS implementation, I would ask you to follow the instructions in the link below:
Limitations when mixing DDS Implementations
We saw in the Using FastDDS section that we can use different DDSs for the publisher and subscriber.
We cannot use, however, any combinations of DDS implementations because there are some limitations. The know limitations are:
Fast DDS and Connext limitations
- WString published by Fast DDS can’t be received correctly by Connext on macOS
Connext and Cyclone DDS
- Does not support pub/sub communication for WString
Connext Dynamic and Connext Dynamic
- Does not support C services
So this is the post for today. Remember that we have the live version of this post on YouTube. If you liked the content, please consider subscribing to our youtube channel. We are publishing new content ~every day.
Keep pushing your ROS Learning.
Related Courses & Training
If you want to learn more about ROS and ROS2, we recommend the following courses: