.. _getting_started_ros2: ROS 2 Getting Started ===================== This section serves as a comprehensive guide to assist in creating and understanding the key points of a basic Safe DDS application that successfully communicates with a ROS2 application. .. note:: It is recommended to first read the :ref:`getting_started` section to gain a better understanding of the basic concepts and terminology used in this section. .. admonition:: Download Code Try this example by downloading the code from :download:`this CMake project <../code/zip/getting_started_ros2.zip>`. .. _getting_started_ros2_create_project: Create a CMake project ---------------------- Create a CMake project with a folder structure as shown below: .. code-block:: bash ros2_example ├── CMakeLists.txt └── src └── main.cpp After the project structure folder has been created, a minimal version of the ``CMakeLists.txt`` file can be generated as follows: .. code-block:: bash mkdir ros2_example cd ros2_example touch CMakeLists.txt The ``CMakeLists.txt`` file is a crucial component, as it contains the build instructions for the project. The following example ``CMakeLists.txt`` file is provided to assist in properly configuring the project's build infrastructure: .. literalinclude:: ../code/getting_started_ros2/CMakeLists.txt :language: cmake :start-after: # GETTING_STARTED_ROS2_CMAKE_EXAMPLE :end-before: #! GETTING_STARTED_ROS2_CMAKE_EXAMPLE .. _getting_started_ros2_application: Safe DDS application -------------------- After the project folder and ``CMakeLists.txt`` file have been set up, the next step is to create a ``main.cpp`` file that will contain the application's source code: .. code-block:: bash mkdir src cd src touch main.cpp To further illustrate a successful communication between Safe DDS and ROS 2, a simple application that publishes a ROS 2 ``std_msgs/String`` message on ``HelloWorldTopicROS2`` topic is presented. To achieve this, the application requires both the **DDS headers** and a **type support**. This tutorial will provide a detailed focus on the essential considerations when establishing connections with ROS 2. For additional information, please refer to the :ref:`getting_started` section. TypeSupport ^^^^^^^^^^^ To successfully integrate with ROS 2, it is necessary to register a Type Support that aligns with a compatible message format in Safe DDS. Detailed instructions on managing Type Supports in Safe DDS can be found in the :ref:`typesupport` section. Type Name ^^^^^^^^^ To ensure compatibility between DDS types and ROS 2 types, it is necessary to adhere to a specific convention. For instance, when using a DDS type that matches the ROS 2 type ``std_msgs/String``, the corresponding DDS type name would be ``std_msgs::msg::dds_::String_``. This convention requires using the DDS type name version of the ROS 2 type. In this case, the DDS type name is derived from the ROS 2 type by appending ``::msg::dds_::`` before the actual type name. This convention is fully documented in the official `ROS 2 Desing Documents `_. .. literalinclude:: ../code/getting_started_ros2/src/main.cpp :language: c++ :start-after: // GETTING_STARTED_ROS2_TYPE_NAME :end-before: //! GETTING_STARTED_ROS2_TYPE_NAME :dedent: 4 Topic Name ^^^^^^^^^^ In ROS 2, topic names are specified using a specific convention, as detailed in the official `ROS 2 Desing Documents `_. To properly define a ROS 2 topic name, it is necessary to prepend ``rt/`` to it. .. literalinclude:: ../code/getting_started_ros2/src/main.cpp :language: c++ :start-after: // GETTING_STARTED_ROS2_TOPIC_NAME :end-before: //! GETTING_STARTED_ROS2_TOPIC_NAME :dedent: 4 Running the application ----------------------- To run the application, first navigate to the project directory, create a build folder (``GETTING_STARTED_ROS2_FOLDER`` on the example) and generate the build files with CMake. .. literalinclude:: ../code/build_documentation_code.sh :language: bash :start-after: # INSTALLATION_CMAKE_GETTING_STARTED_ROS2 :end-before: #! INSTALLATION_CMAKE_GETTING_STARTED_ROS2 :dedent: 4 This command will configure the project with the default settings, including the path to the Safe DDS library, and it will then build the application. Once the build is complete, the application can be run by executing the binary file from the build directory: .. code-block:: bash ./ros2_example If the application is successfully connected to the network and running, the console output should show messages similar to the following: .. code-block:: bash [DW: 0] Message: HelloWorld with index: 1 [DW: 0] Message: HelloWorld with index: 2 [DW: 0] Message: HelloWorld with index: 3 [DW: 0] Message: HelloWorld with index: 4 [DW: 0] Message: HelloWorld with index: 5 [DW: 0] Message: HelloWorld with index: 6 [DW: 0] Message: HelloWorld with index: 7 [DW: 0] Message: HelloWorld with index: 8 [DW: 0] Message: HelloWorld with index: 9 [DW: 0] Message: HelloWorld with index: 10 [DW: 0] Message: HelloWorld with index: 11 [DW: 0] Message: HelloWorld with index: 12 [DW: 0] Message: HelloWorld with index: 13 The program will continue publishing messages every second until it is manually stopped. At this point, it can be checked at the ROS 2 CLI if the topic is available: .. code-block:: bash root@machine:/# ros2 topic list /HelloWorldTopicROS2 /parameter_events /rosout In order to receive the publisher messages at ROS 2 CLI, the following command can be executed: .. code-block:: bash root@machine:/# ros2 topic echo /HelloWorldTopicROS2 data: HelloWorld with index: 1 --- data: HelloWorld with index: 2 --- data: HelloWorld with index: 3 --- Finally, ROS 2 side can publish messages that will be received by Safe DDS with the following command: .. code-block:: bash root@machine:/# ros2 topic pub /HelloWorldTopicROS2 std_msgs/String 'data: Hi Safe DDS, I am ROS 2' publisher: beginning loop publishing #1: std_msgs.msg.String(data='Hi Safe DDS, I am ROS 2') publishing #2: std_msgs.msg.String(data='Hi Safe DDS, I am ROS 2') publishing #3: std_msgs.msg.String(data='Hi Safe DDS, I am ROS 2') publishing #4: std_msgs.msg.String(data='Hi Safe DDS, I am ROS 2') You will be able to see incoming messages from ROS 2 in the example terminal. .. code-block:: bash [DW: 0] Message: HelloWorld with index: 22 [DW: 0] Message: HelloWorld with index: 23 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 24 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 25 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 26 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 27 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 28 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 29 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 30 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 31 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 32 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 33 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 34 [DW: 16777229] Message: Hi Safe DDS, I am ROS 2 [DW: 0] Message: HelloWorld with index: 35