.. _tutorials_tools_monitor_with_backend: Monitoring ROS 2 with Fast DDS Statistics Backend ================================================= .. contents:: :depth: 2 :local: :backlinks: none Background ---------- Vulcanexus integrates :ref:`fastdds_statistics_backend`, which is a useful tool for monitoring and studying a ROS 2 network since ROS 2 relies on the `DDS specification `_ to communicate the different nodes. This tool will be used to create a monitoring application tailored to the user's needs. Therefore, this tutorial provides a step by step tutorial on how to create your first application as a ROS 2 package to monitor your ROS 2 deployment. .. figure:: /rst/figures/tutorials/tools/monitor_backend/monitor_talker_listener_summary.png This tutorial will use the ``demo_nodes_cpp`` package, available in the Vulcanexus Desktop distribution. First, a ROS 2 ``talker`` is launched and then a ``listener`` node is started in the same machine. At this point, the monitor application created using the *Fast DDS Statistics Backend* library will be deployed to record and present the overall communication performance. Prerequisites ------------- It is required to have previously installed Vulcanexus using one of the following installation methods: * :ref:`linux_binary_installation` * :ref:`linux_source_installation` * :ref:`docker_installation` Ensure that the Vulcanexus installation includes Vulcanexus Tools (either ``vulcanexus-iron-desktop``, ``vulcanexus-iron-tools``, or ``vulcanexus-iron-base``). Creating the monitor package and application -------------------------------------------- In this section the monitoring application is created from scratch, covering the creation of the working environment and the development of the source code. Creating the application workspace ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The application workspace will have the following structure at the end of the project. .. code-block:: shell-session ros2_ws └── src └── monitor_tutorial ├── src └── monitor.cpp ├── CMakeLists.txt └── package.xml Let's create the ROS 2 workspace and package by running the following commands: .. code-block:: bash mkdir -p ros2_ws/src cd ros2_ws/src ros2 pkg create --build-type ament_cmake monitor_tutorial --dependencies fastcdr fastrtps fastdds_statistics_backend You will now have a new folder within your workspace `src` directory called `monitor_tutorial`. Writing the monitor application ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From the `ros_ws/src/monitor_tutorial/src` directory in the workspace, run the following command to download the `monitor.cpp` file. .. code-block:: bash wget -O monitor.cpp \ https://raw.githubusercontent.com/eProsima/vulcanexus/main/code/monitor_tutorial/src/monitor.cpp This is the C++ source code for the application. This source code can also be found `here `_. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ Examining the code ^^^^^^^^^^^^^^^^^^ At the beginning of the file, the Doxygen style comment block with the ``@file`` field states the name of the file. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 15-18 Below are the includes of the C++ headers that allow the use of *Fast DDS* and *Fast DDS Statistics Backend* API. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 28-31 Next, we define the namespace that contains the *Fast DDS Statistics Backend* classes and functions that we are going to use in our application. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 33 The next line creates the :class:`Monitor` class that implements the monitor. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 35 The public constructor and destructor of the :class:`Monitor` class are defined below. The constructor initializes the protected data members of the class to the values passed as arguments. The class destructor stops the monitor. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 39-54 Continuing with the public member functions of the :class:`Monitor` class, the next snippet of code defines the public initialization member function. This function performs several actions: #. Initialize the monitor. #. Check the monitor has a valid id in the Statistics Backend database. #. Assign the physical listener to the Statistics Backend. This listener will capture any update in the discovery of DDS entities. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 56-68 To run the monitor, the public member function ``run()`` is implemented. This function search for the ``rt/chatter`` topic in the Statistics Backend database by calling the ``get_topic_id()`` function. If this is found, the we can proceed to compute the actual statistics data. In order to do so, it calls ``get_fastdds_latency_mean()`` and ``get_publication_throughput_mean()`` public member functions explained below. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 70-86 As introduced before, the ``get_topic_id()`` public member function get the id of the topic searching by topic name and data type name. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 88-108 The public member function ``get_fastdds_latency_mean()`` gets the Fast DDS latency mean of the last ``t_interval`` seconds between the ``talker`` and the ``listener``. To achieve this the function performs several actions: #. Get the Publishers and Subscriptions in a Topic. #. Get the current time. #. Get the mean of the ``FASTDDS_LATENCY`` of the last time interval between the Publishers and Subscriptions publishing under and subscribed to the given topic, ``rt/chatter`` in this case. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 109-155 Finally, the public member function ``get_publication_throughput_mean()`` gets the publication throughput mean of the last ``t_interval`` seconds of the ``talker``. The function has a similar execution procedure than the previous one but in this case it query the mean of the ``PUBLICATION_THROUGHPUT`` instead of the ``FASTDDS_LATENCY``. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 156-197 Then, the protected :class:`Listener` class is defined by inheriting from the `PhysicalListener `_ class. This class overrides the default PhysicalListener callbacks, which allows the execution of routines in case of an event. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 214-226 Within the PhysicalListener class, we can override several callback to adapt how the monitor application reacts to some events. These overridden callbacks are: * ``on_host_discovery()`` allows the definition of a series of actions when a new host is detected. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 226-241 * ``on_user_discovery()`` detects when a new user is discovered. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 242-257 * ``on_process_discovery()`` involves when a new process is discovered. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 258-273 * ``on_topic_discovery()`` is called when a new Topic is discovered. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 274-295 * ``on_participant_discovery()`` is called when a new participant is discovered. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 296-313 * ``on_datareader_discovery()`` and ``on_datawriter_discovery()`` involves when a new DataReader or DataWriter respectively are discovered. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 314-349 Finally, the monitor application is initialized and run in ``main`` function. .. literalinclude:: /../code/monitor_tutorial/src/monitor.cpp :language: C++ :lines: 360-375 CMakeLists.txt ^^^^^^^^^^^^^^ Include at the end of the `CMakeList.txt` file you created earlier the following code snippet. This adds all the source files needed to build the executable, and links the executable and the library together. .. literalinclude:: /../code/monitor_tutorial/CMakeLists.txt :language: cmake :lines: 40-49 This file can also be downloaded with this command in `ros_ws/src/monitor_tutorial` directory: .. code-block:: bash wget -O CMakeList.txt \ https://raw.githubusercontent.com/eProsima/vulcanexus/main/code/monitor_tutorial/CMakeLists.txt Running the application ----------------------- At this point the project is ready for building, compiling and running the application. From the base workspace directory (`ros_ws`), run the following commands. .. code-block:: bash colcon build source install/setup.bash ros2 run monitor_tutorial monitor_tutorial Then open two more terminals and load the Vulcanexus environment. Then, in one of them run a ``talker`` and in the other one a ``listener`` of the ``demo_nodes_cpp`` ROS 2 package, available in the Vulcanexus Desktop distribution. * Terminal 1: .. code-block:: bash source /opt/vulcanexus/iron/setup.bash export FASTDDS_STATISTICS="HISTORY_LATENCY_TOPIC;PUBLICATION_THROUGHPUT_TOPIC;PHYSICAL_DATA_TOPIC" ros2 run demo_nodes_cpp talker * Terminal 2: .. code-block:: bash source /opt/vulcanexus/iron/setup.bash export FASTDDS_STATISTICS="HISTORY_LATENCY_TOPIC;PUBLICATION_THROUGHPUT_TOPIC;PHYSICAL_DATA_TOPIC" ros2 run demo_nodes_cpp listener .. note:: In order to monitor other *statistics topics*, add them to environment variable :code:`FASTDDS_STATISTICS`. Check the *statistics topics* available in the `Fast DDS Documentation `_. You should be able to see something similar to the following image. .. figure:: /rst/figures/tutorials/tools/monitor_backend/monitor_talker_listener_terminal.png Next steps ---------- Now you can develop more functionalities in your application, such as collecting more performance data or monitoring other topics. You can check also :ref:`this tutorial ` explaining how to connect an application developed with the *Fast DDS Statistics Backend* to a visualization tool like *Grafana*. For more information about *Fast DDS Statistics Backend* features please refer to the `project's documentation `_.