This repository contains an example of having a "raw" DDS node communicate with a ROS 2 network. In this case "raw" means that it is a program that does not use any of the ROS 2 libraries, but instead uses a DDS implementation directly. This repository has examples using Fast-DDS and CycloneDDS.
Follow the instructions at https://docs.ros.org/en/rolling/Installation.html.
$ git clone https://github.com/eProsima/Fast-CDR -b v1.0.19
$ mkdir -p Fast-CDR/build
$ pushd Fast-CDR/build
$ cmake -DCMAKE_INSTALL_PREFIX=../../install ..
$ make -j10 install
$ popd
$ git clone https://github.com/eProsima/foonathan_memory_vendor
$ mkdir -p foonathan_memory_vendor/build
$ pushd foonathan_memory_vendor/build
$ cmake -DCMAKE_INSTALL_PREFIX=../../install ..
$ make -j10 install
$ popd
$ git clone https://github.com/eProsima/Fast-DDS -b 2.1.x
$ mkdir -p Fast-DDS/build
$ pushd Fast-DDS/build
$ cmake -DCOMPILE_TOOLS=OFF -DCMAKE_INSTALL_PREFIX=../../install ..
$ make -j10 install
$ popd
$ git clone https://github.com/eclipse-cyclonedds/cyclonedds
$ mkdir -p cyclonedds/build
$ pushd cyclonedds/build
$ cmake -DCMAKE_INSTALL_PREFIX=../../install ..
$ make -j10 install
$ popd
$ mkdir -p build
$ pushd build
$ cmake .. -DCMAKE_INSTALL_PREFIX=../install ..
$ make -j10
$ popd
This repository builds 4 binaries: ros2_fastdds_send
, ros2_fastdds_recv
, ros2_cyclonedds_send
, and ros2_cyclonedds_recv
.
ros2_fastdds_send
uses Fast-DDS to publish a ROS 2 UUID message on the /uuid_topic
once a second, incrementing the first number of the UUID every publication.
ros2_cyclonedds_send
uses CycloneDDS to do the same.
ros2_fastdds_recv
uses Fast-DDS to listen to the /uuid_topic
, and print every time it gets a new UUID message.
ros2_cyclonedds_recv
uses CycloneDDS to do the same.
This demo requires 3 terminals.
$ ./ros2_fastdds_send
$ ./ros2_fastdds_recv
$ . /opt/ros/rolling/setup.bash
$ RMW_IMPLEMENTATION=rmw_fastrtps_cpp ros2 topic list -t
$ RMW_IMPLEMENTATION=rmw_fastrtps_cpp ros2 topic echo /uuid_topic unique_identifier_msgs/msg/UUID
You should see the data being published from Terminal 1 into both Terminal 2 and Terminal 3.
This demo requires 2 terminals.
$ . /opt/ros/rolling/setup.bash
$ RMW_IMPLEMENTATION=rmw_fastrtps_cpp ros2 topic pub /uuid_topic unique_identifier_msgs/msg/UUID "uuid:
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0"
$ ./ros2_fastdds_recv
You should see the data being published from Terminal 1 into Terminal 2.
This demo requires 3 terminals.
$ ./ros2_cyclonedds_send
$ ./ros2_cyclonedds_recv
$ . /opt/ros/rolling/setup.bash
$ RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 topic list -t
$ RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 topic echo /uuid_topic unique_identifier_msgs/msg/UUID
You should see the data being published from Terminal 1 into both Terminal 2 and Terminal 3.
This demo requires 2 terminals.
$ . /opt/ros/rolling/setup.bash
$ RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 topic pub /uuid_topic unique_identifier_msgs/msg/UUID "uuid:
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0"
$ ./ros2_cyclonedds_recv
You should see the data being published from Terminal 1 into Terminal 2.
This particular example uses the unique_identifer_msgs/msg/UUID
, but the idea can be extended to any ROS 2 message.
To understand how, we need to briefly discuss how ROS 2 generates code from .msg
files.
At a very high-level, ROS 2 takes the data from .msg
files and produces .idl
files from those messages.
It then takes the .idl
files and generates code specific to that particular message for that particular DDS implementation.
When ROS 2 is installed, it installs both the .msg
and the generated .idl
files into the installation directory.
With the knowledge from the previous section we can look at generating Fast-DDS code for any ROS 2 message.
Because we are trying to not use any ROS 2 in this example directly, we need one more tool that will generate the code for us.
That tool is called Fast-DDS-Gen, and will convert our .idl
files into code that we can use.
$ git clone https://github.com/eProsima/Fast-DDS-Gen
$ pushd Fast-DDS-Gen
$ ./gradlew assemble
$ popd
Now that we have Fast-DDS-Gen installed, we can use it to recreate the UUID code we have checked in to this repository.
We can run the following:
$ mkdir output ; ./Fast-DDS-Gen/scripts/fastddsgen -example CMake -d output -typeros2 /opt/ros/rolling/share/unique_identifier_msgs/msg/UUID.idl
Fast-DDS-Gen generated a bunch of files in the output
subdirectory.
We'll go through each one, describe what it is used for, and describe the changes needed to make it ROS 2 compliant.
CMakeLists.txt
- Not used, ignore this file.UUID.cxx
- The class implementation of the message in the IDL file. No changes needed to make it ROS 2 compliant.UUID.h
- The class definition of the message in the IDL file. No changes needed to make it ROS 2 compliant.UUIDPublisher.cxx
- The class implementation of a publisher for the message in the IDL file. To make it ROS 2 compliant, the topic name for thecreate_topic
call must be prefixed with the stringrt/
(for ROS Topic).UUIDPublisher.h
- The class definition of a publisher for the message in the IDL file. No changes needed to make it ROS 2 compliant.UUIDPubSubMain.cxx
- Not used, ignore this file.UUIDPubSubTypes.cxx
- The class implementation of the serialization/deserialization code for the message in the IDL file. To make it ROS 2 compliant, the type name as set bysetName
must be set to<namespace>::msg::dds_::<Type>_
. For instance, for the UUID IDL file, the typename must be set tounique_identifier_msgs::msg::dds_::UUID_
.UUIDPubSubTypes.h
- The class definition of the serialization/deserialization code for the message in the IDL file. No changes needed to make it ROS 2 compliant.UUIDSubscriber.cxx
- The class implementation of a subscriber for the message in the IDL file. To make it ROS 2 compliant, the topic name for thecreate_topic
call must be prefixed with the stringrt/
(for ROS Topic).UUIDSubscriber.h
- The class definition of a subscriber for the mssage in the IDL file. No changes need to make it ROS 2 compliant.
With all of the above explanation in mind, the following are what is needed to allow a raw Fast-DDS participant to communicate with a ROS 2 network:
- The QoS of the publisher and subscriber have to match. This is true for all participants in the network that wish to communicate.
- The topic that the raw DDS participant uses must begin with
rt/
. - The type that the raw DDS participant uses must be of the form
<namespace>::msg::dds_::<Type>_
.