Composer plusieurs nœuds en un seul processus

Objectif : Composez plusieurs nœuds en un seul processus.

Niveau du didacticiel : Intermédiaire

Durée : 20 minutes

Exécutez les démos

Les démos utilisent des exécutables de rclcpp_components, ros2component <https://github.com/ros2/ros2cli/tree/rolling/ros2component> `__ et `composition packages, et peuvent être exécutés avec les commandes suivantes.

Découvrez les composants disponibles

Pour voir quels composants sont enregistrés et disponibles dans l’espace de travail, exécutez ce qui suit dans un shell :

ros2 component types

Le terminal renverra la liste de tous les composants disponibles :

(... components of other packages here)
composition
  composition::Talker
  composition::Listener
  composition::NodeLikeListener
  composition::Server
  composition::Client
(... components of other packages here)

Composition d’exécution à l’aide des services ROS avec un éditeur et un abonné

Dans le premier shell, démarrez le conteneur de composants :

ros2 run rclcpp_components component_container

Ouvrez le deuxième shell et vérifiez que le conteneur s’exécute via les outils de ligne de commande ros2 :

ros2 component list

Vous devriez voir un nom du composant :

/ComponentManager

Dans le second shell, chargez le composant talker (voir talker code source) :

ros2 component load /ComponentManager composition composition::Talker

La commande renverra l’ID unique du composant chargé ainsi que le nom du nœud :

Loaded component 1 into '/ComponentManager' container node as '/talker'

Maintenant, le premier shell doit afficher un message indiquant que le composant a été chargé ainsi qu’un message répété pour la publication d’un message.

Exécutez une autre commande dans le deuxième shell pour charger le composant d’écouteur (voir listener code source) :

ros2 component load /ComponentManager composition composition::Listener

Le terminal renverra :

Loaded component 2 into '/ComponentManager' container node as '/listener'

L’utilitaire de ligne de commande ros2 peut maintenant être utilisé pour inspecter l’état du conteneur :

ros2 component list

Vous verrez le résultat suivant :

/ComponentManager
   1  /talker
   2  /listener

Maintenant, le premier shell doit afficher une sortie répétée pour chaque message reçu.

Composition d’exécution à l’aide des services ROS avec un serveur et un client

L’exemple avec un serveur et un client est très similaire.

Dans la première coque :

ros2 run rclcpp_components component_container

Dans le second shell (voir server et client code source) :

ros2 component load /ComponentManager composition composition::Server
ros2 component load /ComponentManager composition composition::Client

Dans ce cas, le client envoie une demande au serveur, le serveur traite la demande et répond avec une réponse, et le client imprime la réponse reçue.

Composition au moment de la compilation à l’aide des services ROS

Cette démo montre que les mêmes bibliothèques partagées peuvent être réutilisées pour compiler un seul exécutable exécutant plusieurs composants. L’exécutable contient les quatre composants ci-dessus : locuteur et écouteur ainsi que serveur et client.

Dans l’appel du shell (voir code source) :

ros2 run composition manual_composition

Cela devrait montrer des messages répétés des deux paires, le locuteur et l’auditeur ainsi que le serveur et le client.

Note

Les composants composés manuellement ne seront pas reflétés dans la sortie de l’outil de ligne de commande ros2 component list.

Composition d’exécution à l’aide de dlopen

Cette démo présente une alternative à la composition d’exécution en créant un processus de conteneur générique et en passant explicitement les bibliothèques à charger sans utiliser les interfaces ROS. Le processus ouvrira chaque bibliothèque et créera une instance de chaque classe « rclcpp :: Node » dans le code source de la bibliothèque <https://github.com/ros2/demos/blob/rolling/composition/src/dlopen_composition.cpp> `__).

ros2 run composition dlopen_composition `ros2 pkg prefix composition`/lib/libtalker_component.so `ros2 pkg prefix composition`/lib/liblistener_component.so

Maintenant, le shell doit afficher une sortie répétée pour chaque message envoyé et reçu.

Note

Les composants composés par dlopen ne seront pas reflétés dans la sortie de l’outil de ligne de commande ros2 component list.

Composition à l’aide d’actions de lancement

Bien que les outils de ligne de commande soient utiles pour le débogage et le diagnostic des configurations de composants, il est souvent plus pratique de démarrer un ensemble de composants en même temps. Pour automatiser cette action, nous pouvons utiliser la fonctionnalité de ros2 launch.

ros2 launch composition composition_demo.launch.py

Sujets avancés

Maintenant que nous avons vu le fonctionnement de base des composants, nous pouvons aborder quelques sujets plus avancés.

Déchargement des composants

Dans le premier shell, démarrez le conteneur de composants :

ros2 run rclcpp_components component_container

Vérifiez que le conteneur s’exécute via les outils de ligne de commande ros2 :

ros2 component list

Vous devriez voir un nom du composant :

/ComponentManager

Dans le deuxième shell, chargez à la fois le locuteur et l’auditeur comme nous l’avons fait auparavant :

ros2 component load /ComponentManager composition composition::Talker
ros2 component load /ComponentManager composition composition::Listener

Utilisez l’ID unique pour décharger le nœud du conteneur de composants.

ros2 component unload /ComponentManager 1 2

Le terminal doit renvoyer :

Unloaded component 1 from '/ComponentManager' container
Unloaded component 2 from '/ComponentManager' container

Dans le premier shell, vérifiez que les messages répétés du locuteur et de l’auditeur se sont arrêtés.

Remappage du nom du conteneur et de l’espace de noms

Le nom et l’espace de noms du gestionnaire de composants peuvent être remappés via des arguments de ligne de commande standard :

ros2 run rclcpp_components component_container --ros-args -r __node:=MyContainer -r __ns:=/ns

Dans un deuxième shell, les composants peuvent être chargés en utilisant le nom de conteneur mis à jour :

ros2 component load /ns/MyContainer composition composition::Listener

Note

Les remappages d’espace de noms du conteneur n’affectent pas les composants chargés.

Remapper les noms de composants et les espaces de noms

Les noms de composants et les espaces de noms peuvent être ajustés via des arguments à la commande load.

Dans le premier shell, démarrez le conteneur de composants :

ros2 run rclcpp_components component_container

Quelques exemples de remappage de noms et d’espaces de noms.

Remapper le nom du nœud :

ros2 component load /ComponentManager composition composition::Talker --node-name talker2

Remapper l’espace de noms :

ros2 component load /ComponentManager composition composition::Talker --node-namespace /ns

Remappez les deux :

ros2 component load /ComponentManager composition composition::Talker --node-name talker3 --node-namespace /ns2

Utilisez maintenant l’utilitaire de ligne de commande ros2 :

ros2 component list

Dans la console, vous devriez voir les entrées correspondantes :

/ComponentManager
   1  /talker2
   2  /ns/talker
   3  /ns2/talker3

Note

Les remappages d’espace de noms du conteneur n’affectent pas les composants chargés.

Passer des valeurs de paramètres dans des composants

La ligne de commande ros2 component load prend en charge la transmission de paramètres arbitraires au nœud lors de sa construction. Cette fonctionnalité peut être utilisée comme suit :

ros2 component load /ComponentManager image_tools image_tools::Cam2Image -p burger_mode:=true

Passer des arguments supplémentaires dans les composants

La ligne de commande ros2 component load prend en charge la transmission d’options particulières au gestionnaire de composants à utiliser lors de la construction du nœud. À l’heure actuelle, la seule option de ligne de commande prise en charge consiste à instancier un nœud à l’aide de la communication intra-processus. Cette fonctionnalité peut être utilisée comme suit :

ros2 component load /ComponentManager composition composition::Talker -e use_intra_process_comms:=true

Nœuds composables en tant que bibliothèques partagées

Si vous souhaitez exporter un nœud composable en tant que bibliothèque partagée à partir d’un package et utiliser ce nœud dans un autre package qui effectue la composition au moment de la liaison, ajoutez du code au fichier CMake qui importe les cibles réelles dans les packages en aval.

Installez ensuite le fichier généré et exportez le fichier généré.

Un exemple pratique peut être vu ici : ROS Discourse - Ament best practice for sharing library