À propos de la composition

ROS 1 - Nœuds vs. Nodelets

Dans ROS 1, vous pouvez écrire votre code soit en tant que nœud ROS soit en tant que nodelet ROS . Les nœuds ROS 1 sont compilés en exécutables. Les nodelets ROS 1, quant à eux, sont compilés dans une bibliothèque partagée qui est ensuite chargée au moment de l’exécution par un processus de conteneur.

ROS 2 - API unifiée

Dans ROS 2, la manière recommandée d’écrire votre code est similaire à un nodelet - nous l’appelons un Component. Cela facilite l’ajout de concepts communs au code existant, comme un cycle de vie. Le plus gros inconvénient des différentes API est évité dans ROS 2 puisque les deux approches utilisent la même API dans ROS 2.

Note

Il est toujours possible d’utiliser le style de type nœud de « écrire votre propre main », mais pour le cas courant, il n’est pas recommandé.

En faisant de la disposition du processus une décision au moment du déploiement, l’utilisateur peut choisir entre :

  • exécuter plusieurs nœuds dans des processus séparés avec les avantages de l’isolation des processus/défauts ainsi qu’un débogage plus facile des nœuds individuels et

  • exécutant plusieurs nœuds dans un seul processus avec une surcharge moindre et éventuellement une communication plus efficace (voir Intra Process Communication).

De plus, ros2 launch peut être utilisé pour automatiser ces actions grâce à des actions de lancement spécialisées.

Ecrire un composant

Puisqu’un composant n’est intégré qu’à une bibliothèque partagée, il n’a pas de fonction main (voir Talker source code). Un composant est généralement une sous-classe de rclcpp::Node. Puisqu’il ne contrôle pas le thread, il ne devrait pas effectuer de tâches longues ou bloquantes dans son constructeur. Au lieu de cela, il peut utiliser des minuteries pour obtenir une notification périodique. De plus, il peut créer des éditeurs, des abonnés, des serveurs et des clients.

Un aspect important de la transformation d’une telle classe en composant est que la classe s’enregistre elle-même à l’aide des macros du package rclcpp_components (voir la dernière ligne du code source). Cela rend le composant détectable lorsque sa bibliothèque est chargée dans un processus en cours d’exécution - il agit comme une sorte de point d’entrée.

De plus, une fois qu’un composant est créé, il doit être enregistré auprès de l’index pour pouvoir être découvert par les outils.

add_library(talker_component SHARED
   src/talker_component.cpp)
rclcpp_components_register_nodes(talker_component "composition::Talker")
# To register multiple components in the same shared library, use multiple calls
# rclcpp_components_register_nodes(talker_component "composition::Talker2")

Note

Pour que le component_container puisse trouver les composants souhaités, il doit être exécuté ou lancé à partir d’un shell qui a sourcé l’espace de travail correspondant.

Utiliser des composants

Le package composition contient plusieurs approches différentes sur la façon d’utiliser les composants. Les trois plus courants sont :

  1. Démarrez un (processus de conteneur générique) et appelez le service ROS load_node offert par le conteneur. Le service ROS chargera alors le composant spécifié par le nom de package et le nom de bibliothèque passés et commencera à l’exécuter dans le processus en cours d’exécution. Au lieu d’appeler le service ROS par programmation, vous pouvez également utiliser un outil de ligne de commande pour appeler le service ROS avec les arguments de ligne de commande passés

  2. Créez un exécutable personnalisé contenant plusieurs nœuds connus au moment de la compilation. Cette approche nécessite que chaque composant ait un fichier d’en-tête (ce qui n’est pas strictement nécessaire pour le premier cas).

  3. Créez un fichier de lancement et utilisez ros2 launch pour créer un processus de conteneur avec plusieurs composants chargés.