|
| 1 | +The Ros2Supervisor Node |
| 2 | +======================= |
| 3 | + |
| 4 | +**Goal:** Extend the interface with a default Supervisor robot, named ``Ros2Supervisor``. |
| 5 | + |
| 6 | +**Tutorial level:** Advanced |
| 7 | + |
| 8 | +**Time:** 10 minutes |
| 9 | + |
| 10 | +.. contents:: Contents |
| 11 | + :depth: 2 |
| 12 | + :local: |
| 13 | + |
| 14 | +Background |
| 15 | +---------- |
| 16 | + |
| 17 | +In this tutorial, you will learn how to enable the ``Ros2Supervisor`` node which enhances the interface by creating additional services and topics to interact with the simulation. |
| 18 | +You can, for example, record animations or spawn Webots nodes directly from the ROS 2 interface while the simulation is running. |
| 19 | +These instructions list in details the current implemented features and how to use them. |
| 20 | + |
| 21 | +Prerequisites |
| 22 | +------------- |
| 23 | + |
| 24 | +Before proceeding with this tutorial, make sure you have completed the following: |
| 25 | + |
| 26 | +- Understanding of ROS 2 nodes and topics covered in the beginner :doc:`../../../../Tutorials`. |
| 27 | +- Knowledge of Webots and ROS 2 and its interface package. |
| 28 | +- Familiarity with :doc:`./Setting-Up-Simulation-Webots-Basic`. |
| 29 | + |
| 30 | +The ``Ros2Supervisor`` |
| 31 | +---------------------- |
| 32 | + |
| 33 | +The ``Ros2Supervisor`` is made of two main parts: |
| 34 | + |
| 35 | +* A Webots Robot node added to the simulation world. Its ``supervisor`` field is set to TRUE. |
| 36 | +* A ROS 2 node that connects to the Webots Robot as an extern controller (in a similar way to your own robot plugin). |
| 37 | + |
| 38 | +The ROS 2 node acts as a controller that calls Supervisor API functions to control or interact with the simulation world. |
| 39 | +User interactions with the ROS 2 node are mainly performed through services and topics. |
| 40 | + |
| 41 | +These nodes can be automatically created at the Webots launch using the ``ros2_supervisor`` parameter in the ``WebotsLauncher``. |
| 42 | + |
| 43 | +.. code-block:: python |
| 44 | +
|
| 45 | + webots = WebotsLauncher( |
| 46 | + world=PathJoinSubstitution([package_dir, 'worlds', world]), |
| 47 | + mode=mode, |
| 48 | + ros2_supervisor=True |
| 49 | + ) |
| 50 | +
|
| 51 | +The ``webots._supervisor`` object must also be included in the ``LaunchDescription`` returned by the launch file. |
| 52 | + |
| 53 | +.. code-block:: python |
| 54 | +
|
| 55 | + return LaunchDescription([ |
| 56 | + webots, |
| 57 | + webots._supervisor, |
| 58 | +
|
| 59 | + # This action will kill all nodes once the Webots simulation has exited |
| 60 | + launch.actions.RegisterEventHandler( |
| 61 | + event_handler=launch.event_handlers.OnProcessExit( |
| 62 | + target_action=webots, |
| 63 | + on_exit=[ |
| 64 | + launch.actions.EmitEvent(event=launch.events.Shutdown()) |
| 65 | + ], |
| 66 | + ) |
| 67 | + ) |
| 68 | + ]) |
| 69 | +
|
| 70 | +More information about launch files for ``webots_ros2`` projects can be found in :doc:`./Setting-Up-Simulation-Webots-Basic`. |
| 71 | + |
| 72 | +Clock topic |
| 73 | +----------- |
| 74 | + |
| 75 | +The ``Ros2Supervisor`` node is responsible to get the time of the Webots simulation and publish it to the ``/clock`` topic. |
| 76 | +This means that it is mandatory to spawn the ``Ros2Supervisor`` if some other nodes have their ``use_sim_time`` parameter set to ``true``. |
| 77 | +More information about the ``/clock`` topic can be found in the `ROS wiki <http://wiki.ros.org/Clock>`_. |
| 78 | + |
| 79 | +Import a Webots node |
| 80 | +-------------------- |
| 81 | + |
| 82 | +The ``Ros2Supervisor`` node also allows you to spawn Webots nodes from strings through a service. |
| 83 | + |
| 84 | +The service is named ``/Ros2Supervisor/spawn_node_from_string`` and is of type ``webots_ros2_msgs/srv/SpawnNodeFromString``. |
| 85 | +The ``SpawnNodeFromString`` type expects a ``data`` string as input and returns a ``success`` boolean. |
| 86 | + |
| 87 | +From the given string, the Supervisor node is getting the name of the imported node and adding it to an intern list for potential later removal (see :ref:`Remove a Webots imported node`). |
| 88 | + |
| 89 | +The node is imported using the ``importMFNodeFromString(nodeString)`` `API function <https://cyberbotics.com/doc/reference/supervisor?tab-language=python#wb_supervisor_field_import_mf_node_from_string>`_. |
| 90 | + |
| 91 | +Here is an example to import a simple Robot named ``imported_robot``: |
| 92 | + |
| 93 | +.. code-block:: bash |
| 94 | +
|
| 95 | + ros2 service call /Ros2Supervisor/spawn_node_from_string webots_ros2_msgs/srv/SpawnNodeFromString "data: Robot { name \"imported_robot\" }" |
| 96 | +
|
| 97 | +.. note:: |
| 98 | + If you try to import some PROTOs in the node string, their respective URLs must be declared in the .wbt world file as EXTERNPROTO or as IMPORTABLE EXTERNPROTO. |
| 99 | + |
| 100 | +.. _Remove a Webots imported node: |
| 101 | + |
| 102 | +Remove a Webots imported node |
| 103 | +----------------------------- |
| 104 | + |
| 105 | +Once a node has been imported with the ``/Ros2Supervisor/spawn_node_from_string`` service, it can also be removed. |
| 106 | + |
| 107 | +This can be achieved by sending the name of the node to the topic named ``/Ros2Supervisor/remove_node`` of type ``std_msgs/msg/String``. |
| 108 | + |
| 109 | +If the node is indeed in the imported list, it is removed with the ``remove()`` `API method <https://cyberbotics.com/doc/reference/supervisor?tab-language=python#wb_supervisor_node_remove>`_. |
| 110 | + |
| 111 | +Here is an example on how to remove the ``imported_robot`` Robot: |
| 112 | + |
| 113 | +.. code-block:: bash |
| 114 | +
|
| 115 | + ros2 topic pub --once /Ros2Supervisor/remove_node std_msgs/msg/String "{data: imported_robot}" |
| 116 | +
|
| 117 | +Record animations |
| 118 | +----------------- |
| 119 | + |
| 120 | +The ``Ros2Supervisor`` node also creates two additional services to record HTML5 animations. |
| 121 | + |
| 122 | +The ``/Ros2Supervisor/animation_start_recording`` service is of type ``webots_ros2_msgs/srv/SetString`` and allows to start the animation. |
| 123 | +The ``SetString`` type expects a ``value`` string as input and returns a ``success`` boolean. |
| 124 | +The input ``value`` represents the absolute path to the directory where the animations files should be saved. |
| 125 | + |
| 126 | +Here is an example on how to start an animation: |
| 127 | + |
| 128 | +.. code-block:: bash |
| 129 | +
|
| 130 | + ros2 service call /Ros2Supervisor/animation_start_recording webots_ros2_msgs/srv/SetString "{value: "<ABSOLUTE_PATH>/index.html"}" |
| 131 | +
|
| 132 | +
|
| 133 | +The ``/Ros2Supervisor/animation_stop_recording`` service is of type ``webots_ros2_msgs/srv/GetBool`` and allows to stop the animation. |
| 134 | + |
| 135 | +.. code-block:: bash |
| 136 | +
|
| 137 | + ros2 service call /Ros2Supervisor/animation_stop_recording webots_ros2_msgs/srv/GetBool "{ask: True}" |
| 138 | +
|
| 139 | +
|
| 140 | +Summary |
| 141 | +------- |
| 142 | + |
| 143 | +In this tutorial, you learned how to enable the ``Ros2Supervisor`` and how to extend the interface with the Webots simulation. |
| 144 | +The node creates multiple services and topics to interact with and modify the simulation. |
0 commit comments