7.1.6-Gestion d'exécution de ROS

Gérer les nœuds ROS avec des fichiers launch

Les fichiers launch dans ROS sont des fichiers au format XML utilisés pour démarrer et gérer efficacement plusieurs nœuds ROS. Cette section couvre les diverses balises disponibles dans les fichiers launch, y compris leurs attributs et cas d'utilisation.

La balise <launch>

La balise <launch> est la racine de chaque fichier launch et sert de conteneur pour toutes les autres balises.

1. Attributs

  • deprecated="déclaration d'obsolescence"
    Indique à l'utilisateur que le fichier launch courant est obsolète.

2. Balises enfants

  • Toutes les autres balises d'un fichier launch sont des éléments enfants de la balise <launch>.

Exemple :

xml
<launch>
    <!-- Other tags go here -->
</launch>

La balise <node>

La balise <node> permet de spécifier un nœud ROS à lancer. C'est l'une des balises les plus utilisées dans un fichier launch. Notez que la commande roslaunch ne garantit pas que les nœuds démarrent dans l'ordre où ils sont déclarés, le démarrage des nœuds étant multi-thread.

1. Attributs

  • pkg="package_name"
    Spécifie le paquet auquel appartient le nœud.

  • type="nodeType"
    Type du nœud, qui correspond au nom du fichier exécutable.

  • name="nodeName"
    Nom du nœud dans la topologie réseau ROS.

  • args="xxx xxx xxx" (optionnel)
    Passe des arguments au nœud.

  • machine="machine_name"
    Spécifie la machine sur laquelle lancer le nœud.

  • respawn="true | false" (optionnel)
    Détermine si le nœud doit redémarrer automatiquement s'il s'arrête.

  • respawn_delay="N" (optionnel)
    Si respawn est true, définit un délai de N secondes avant le redémarrage du nœud.

  • required="true | false" (optionnel)
    Indique si ce nœud est critique. Si true, l'ensemble du processus roslaunch sera terminé si le nœud s'arrête.

  • ns="namespace" (optionnel)
    Lance le nœud dans le namespace spécifié.

  • clear_params="true | false" (optionnel)
    Efface tous les paramètres du namespace privé du nœud avant son démarrage.

  • output="log | screen" (optionnel)
    Détermine où la sortie de log est envoyée : un fichier de log ou l'écran. Par défaut, c'est log.

2. Balises enfants

  • env : Pour définir des variables d'environnement.
  • remap : Pour remapper des noms de topic ou de service.
  • rosparam : Pour définir des paramètres.
  • param : Pour définir des paramètres.

Exemple :

xml
<launch>
    <node name="node1" pkg="my_package" type="node_executable" output="screen" respawn="true" respawn_delay="5">
        <param name="param_name" value="param_value"/>
        <remap from="/old_topic" to="/new_topic"/>
    </node>
</launch>

La balise <include>

La balise <include> est utilisée pour inclure un autre fichier launch au format XML dans le fichier launch courant. Cela permet des configurations modulaires et réutilisables.

1. Attributs

  • file="$(find package_name)/path/to/file.launch"
    Spécifie le chemin vers le fichier launch à inclure.

  • ns="namespace" (optionnel)
    Inclut le fichier sous le namespace spécifié.

2. Balises enfants

  • env : Pour définir des variables d'environnement.
  • arg : Pour passer des arguments au fichier launch inclus.

Exemple :

xml
<launch>
    <include file="$(find my_package)/launch/another_launch_file.launch" ns="my_namespace"/>
</launch>

La balise <remap>

La balise <remap> est utilisée pour remapper des noms de topic ou de service ROS. Utile pour éviter les conflits de noms ou normaliser les noms entre différents nœuds.

1. Attributs

  • from="xxx"
    Le nom original du topic ou du service.

  • to="yyy"
    Le nouveau nom du topic ou du service.

2. Balises enfants

  • Aucune

Exemple :

xml
<launch>
    <node name="node1" pkg="my_package" type="node_executable">
        <remap from="/old_topic" to="/new_topic"/>
    </node>
</launch>

La balise <param>

La balise <param> permet de définir des paramètres sur le serveur de paramètres ROS. La source du paramètre peut être spécifiée directement dans la balise ou chargée depuis un fichier externe. Lorsqu'elle est utilisée à l'intérieur d'une balise <node>, le paramètre est défini dans le namespace privé du nœud.

1. Attributs

  • name="namespace/parameter_name"
    Nom du paramètre, qui peut inclure un namespace.

  • value="xxx" (optionnel)
    Définit la valeur du paramètre. Si omise, un fichier externe doit être spécifié comme source du paramètre.

  • type="str | int | double | bool | yaml" (optionnel)
    Spécifie le type du paramètre. Si non spécifié, roslaunch tentera d'inférer le type à partir de la valeur :

    • Les nombres avec un . sont analysés comme des flottants (double).
    • Les chaînes "true" et "false" sont analysées comme des booléens (insensible à la casse).
    • Tout le reste est analysé comme une chaîne.

2. Balises enfants

  • Aucune

Exemple :

xml
<launch>
    <node name="node1" pkg="my_package" type="node_executable">
        <param name="namespace/param_name" value="param_value" type="str"/>
    </node>
</launch>

La balise <rosparam>

La balise <rosparam> permet de charger des paramètres depuis un fichier YAML, de les exporter vers un fichier YAML, ou de les supprimer. Utilisée à l'intérieur d'une balise <node>, les paramètres sont considérés comme privés.

1. Attributs

  • command="load | dump | delete" (optionnel, valeur par défaut load)
    Spécifie l'opération à effectuer : charger des paramètres depuis un fichier, les exporter vers un fichier, ou les supprimer.

  • file="$(find package_name)/path/to/file.yaml"
    Spécifie le fichier YAML pour charger ou exporter les paramètres.

  • param="parameter_name"
    Nom du paramètre.

  • ns="namespace" (optionnel)
    Spécifie le namespace pour les paramètres.

2. Balises enfants

  • Aucune

Exemple :

xml
<launch>
    <rosparam file="$(find my_package)/config/params.yaml" command="load" ns="my_namespace"/>
</launch>

La balise <group>

La balise <group> est utilisée pour regrouper des nœuds et d'autres balises, et permet d'appliquer un namespace ou d'autres paramètres au groupe dans son ensemble.

1. Attributs

  • ns="namespace" (optionnel)
    Applique un namespace à tous les nœuds et paramètres du groupe.

  • clear_params="true | false" (optionnel)
    Efface tous les paramètres du namespace du groupe avant son lancement. À utiliser avec précaution car cela peut supprimer des paramètres critiques.

2. Balises enfants

  • Toute balise sauf <launch> peut être enfant de <group>.

Exemple :

xml
<launch>
    <group ns="my_namespace" clear_params="true">
        <node name="node1" pkg="my_package" type="node_executable"/>
        <node name="node2" pkg="my_package" type="node_executable"/>
    </group>
</launch>

La balise <arg>

La balise <arg> est utilisée pour définir des arguments dynamiques qui peuvent être passés au fichier launch à l'exécution, similaires à des paramètres de fonction. Cela augmente la flexibilité des fichiers launch.

1. Attributs

  • name="argument_name"
    Le nom de l'argument.

  • default="default_value" (optionnel)
    Spécifie la valeur par défaut de l'argument.

  • value="value" (optionnel)
    Spécifie la valeur de l'argument. Ne peut pas être utilisé en même temps que default.

  • doc="description"
    Fournit une description de l'argument.

2. Balises enfants

  • Aucune

3. Exemple

Fichier launch avec syntaxe d'argument, hello.launch :

xml
<launch>
    <arg name="robot_name" default="my_robot"/>
    <param name="robot_name" value="$(arg robot_name)"/>
</launch>

Invocation depuis la ligne de commande avec passage d'argument :

bash
roslaunch hello.launch robot_name:=robot_value

Superposition d'espaces de travail ROS

Imaginez que vous avez deux espaces de travail personnalisés, Workspace A et Workspace B, contenant chacun un paquet nommé turtlesim. De plus, l'espace de travail intégré du système possède aussi un paquet nommé turtlesim. Lorsque vous invoquez le paquet turtlesim, lequel sera utilisé ?

Étapes de mise en œuvre

Étape 0 : créer les espaces de travail A et B

Tout d'abord, créez deux espaces de travail séparés, A et B. Dans chaque espace de travail, créez un paquet nommé turtlesim.

Étape 1 : modifier le fichier ~/.bashrc

Ajoutez les lignes suivantes à votre fichier ~/.bashrc afin de sourcer les fichiers setup des deux espaces de travail :

bash
source /home/user/path/to/workspaceA/devel/setup.bash
source /home/user/path/to/workspaceB/devel/setup.bash

Remplacez /home/user/path/to/ par les chemins réels de vos espaces de travail.

Étape 2 : charger les variables d'environnement

Ouvrez un nouveau terminal et exécutez la commande suivante pour charger les variables d'environnement mises à jour :

bash
source ~/.bashrc

Étape 3 : vérifier les variables d'environnement ROS

Pour vérifier les chemins des paquets ROS, exécutez :

bash
echo $ROS_PACKAGE_PATH

Résultat : La sortie affichera les chemins dans l'ordre suivant : Workspace B → Workspace A → Espace de travail intégré du système.

Étape 4 : invoquer le paquet turtlesim

Maintenant, exécutez la commande suivante pour aller au paquet turtlesim :

bash
roscd turtlesim

Résultat : Vous serez dirigé vers le paquet turtlesim dans Workspace B.

Gestion des conflits de noms de nœuds ROS

Scénario

Dans ROS, chaque nœud a un nom, défini lors de l'initialisation du nœud. En C++, cela se fait avec l'API ros::init(argc, argv, "node_name");, tandis qu'en Python, cela se fait avec rospy.init_node("node_name"). Dans la topologie réseau ROS, les nœuds doivent avoir des noms uniques car, si plusieurs nœuds partagent le même nom, cela peut provoquer des confusions lors de l'invocation. Concrètement, si un nœud avec un nom en doublon est démarré, le nœud existant portant ce nom sera automatiquement arrêté. Mais que faire si vous devez exécuter plusieurs instances du même nœud ou gérer des conflits de noms ?

ROS propose deux stratégies pour gérer ce type de situation : les namespaces et le remapping de noms.

  • Les namespaces ajoutent un préfixe aux noms des nœuds.
  • Le remapping de noms attribue un alias au nom d'un nœud.

Les deux stratégies peuvent résoudre les conflits de noms de nœuds, et elles peuvent être mises en œuvre de plusieurs façons :

  1. À l'aide de la commande rosrun.
  2. Via les fichiers launch.
  3. Dans le code du nœud.

Cette section montre comment utiliser ces trois méthodes pour éviter les conflits de noms de nœuds.

Exemple de scénario

Démarrons deux nœuds turtlesim_node. Si vous ouvrez deux terminaux et démarrez les nœuds directement sans modification, le premier nœud sera arrêté lorsque vous lancerez le second. Vous verrez un message d'avertissement :

plaintext
[ WARN] [1578812836.351049332]: Shutdown request received.
[ WARN] [1578812836.351207362]: Reason given for shutdown: [new node registered with same name]

Comme les nœuds ne peuvent pas partager le même nom, nous explorerons plusieurs stratégies pour résoudre ce problème.

Utiliser rosrun pour les namespaces et le remapping

1. Définir un namespace avec rosrun

Vous pouvez définir un namespace pour un nœud avec la syntaxe suivante :

bash
rosrun package_name node_name __ns:=/new_namespace

Exemple :

bash
rosrun turtlesim turtlesim_node __ns:=/xxx
rosrun turtlesim turtlesim_node __ns:=/yyy

Avec ces commandes, les deux nœuds fonctionneront sans problème.

Résultats :

Utilisez rosnode list pour vérifier les nœuds :

plaintext
/xxx/turtlesim
/yyy/turtlesim

2. Remapper les noms de nœuds avec rosrun

Vous pouvez aussi remapper le nom d'un nœud, lui donnant ainsi un alias, avec la syntaxe suivante :

bash
rosrun package_name node_name __name:=new_name

Exemple :

bash
rosrun turtlesim turtlesim_node __name:=t1
rosrun turtlesim turtlesim_node __name:=t2

Avec ces commandes, les deux nœuds s'exécuteront avec leurs nouveaux noms.

Résultats :

Utilisez rosnode list pour vérifier les nœuds :

plaintext
/t1
/t2

3. Combiner namespace et remapping de nom avec rosrun

Vous pouvez combiner les deux techniques en définissant un namespace et en remappant le nom du nœud simultanément :

bash
rosrun package_name node_name __ns:=/new_namespace __name:=new_name

Exemple :

bash
rosrun turtlesim turtlesim_node __ns:=/xxx __name:=tn

Résultats :

Utilisez rosnode list pour vérifier le nœud :

plaintext
/xxx/tn

Vous pouvez également définir le namespace via une variable d'environnement avant de démarrer le nœud :

bash
export ROS_NAMESPACE=xxxx

Utiliser des fichiers launch pour les namespaces et le remapping

Dans les fichiers launch, la balise <node> inclut deux attributs importants : name et ns. Ils sont utilisés respectivement pour le remapping de nom et la définition de namespaces. Gérer les namespaces et le remapping de noms via un fichier launch est simple.

1. Exemple de fichier launch

Voici comment définir des namespaces et un remapping de noms dans un fichier launch :

xml
<launch>
    <node pkg="turtlesim" type="turtlesim_node" name="t1" />
    <node pkg="turtlesim" type="turtlesim_node" name="t2" />
    <node pkg="turtlesim" type="turtlesim_node" name="t1" ns="hello"/>
</launch>

Dans cet exemple, l'attribut name est obligatoire, tandis que ns est optionnel.

2. Exécuter le fichier launch

Exécutez le fichier launch puis utilisez rosnode list pour voir les résultats :

plaintext
/t1
/t2
/hello/t1

Définir des namespaces et un remapping dans le code

Si vous implémentez des nœuds personnalisés, vous avez plus de flexibilité pour définir des namespaces et un remapping de noms directement dans votre code.

1. Implémentation C++ : remapping de nom

Vous pouvez définir un alias de nom à l'aide du code suivant :

cpp
ros::init(argc, argv, "zhangsan", ros::init_options::AnonymousName);

Exécution :

Cela ajoutera un horodatage au nom du nœud, garantissant son unicité.

2. Implémentation C++ : définir un namespace

Vous pouvez définir un namespace directement dans le code comme ceci :

cpp
std::map<std::string, std::string> map;
map["__ns"] = "xxxx";
ros::init(map, "wangqiang");

Exécution :

Cela définit un namespace pour le nœud, lui permettant de s'exécuter sans conflit.

3. Implémentation Python : remapping de nom

En Python, vous pouvez obtenir une fonctionnalité similaire avec le code suivant :

python
rospy.init_node("lisi", anonymous=True)

Remapping de noms de topic dans ROS

Dans ROS, le remapping de noms de topic vous permet de changer le nom d'un topic auquel un nœud s'abonne ou publie sans modifier le code du nœud. C'est particulièrement utile lors de l'intégration de plusieurs nœuds devant communiquer sur des noms de topic différents. Il y a trois méthodes principales pour remapper les noms de topic dans ROS :

  1. À l'aide de la commande rosrun.
  2. Via les fichiers launch.
  3. En modifiant directement le code en C++ ou en Python.

Utiliser rosrun pour remapper des topics

La syntaxe pour remapper un nom de topic avec rosrun est :

bash
rosrun package_name node_name old_topic_name:=new_topic_name

Exemple : intégration de teleop_twist_keyboard avec turtlesim

Il y a deux manières de mettre en place la communication entre le nœud teleop_twist_keyboard et le nœud d'affichage turtlesim :

1. Solution 1 : remapper le topic de teleop_twist_keyboard

Dans cette approche, nous remappons le topic du nœud teleop_twist_keyboard vers /turtle1/cmd_vel.

  • Démarrer le nœud de contrôle clavier :

    bash
    rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/turtle1/cmd_vel
  • Démarrer le nœud d'affichage turtlesim :

    bash
    rosrun turtlesim turtlesim_node

Les deux nœuds communiqueront correctement via le topic /turtle1/cmd_vel.

2. Solution 2 : remapper le topic de turtlesim

Alternativement, nous pouvons remapper le topic du nœud turtlesim vers /cmd_vel.

  • Démarrer le nœud de contrôle clavier :

    bash
    rosrun teleop_twist_keyboard teleop_twist_keyboard.py
  • Démarrer le nœud d'affichage turtlesim :

    bash
    rosrun turtlesim turtlesim_node /turtle1/cmd_vel:=/cmd_vel

Les deux nœuds communiqueront correctement via le topic /cmd_vel.

Utiliser des fichiers launch pour remapper des topics

Vous pouvez aussi remapper des topics dans un fichier launch. La syntaxe pour remapper un topic dans un fichier launch est :

xml
<node pkg="package_name" type="node_type" name="node_name">
    <remap from="original_topic" to="new_topic" />
</node>

Exemple : intégration de teleop_twist_keyboard avec turtlesim à l'aide de fichiers launch

Là encore, il y a deux solutions :

1. Solution 1 : remapper le topic de teleop_twist_keyboard

Dans cette approche, nous remappons le topic du nœud teleop_twist_keyboard vers /turtle1/cmd_vel.

xml
<launch>
    <node pkg="turtlesim" type="turtlesim_node" name="t1" />
    <node pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py" name="key">
        <remap from="/cmd_vel" to="/turtle1/cmd_vel" />
    </node>
</launch>

Les deux nœuds communiqueront correctement.

2. Solution 2 : remapper le topic de turtlesim

Dans cette approche, nous remappons le topic du nœud turtlesim vers /cmd_vel.

xml
<launch>
    <node pkg="turtlesim" type="turtlesim_node" name="t1">
        <remap from="/turtle1/cmd_vel" to="/cmd_vel" />
    </node>
    <node pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py" name="key" />
</launch>

Les deux nœuds communiqueront correctement.

Remapping de topics dans le code

Le nom du topic dans ROS est influencé par le namespace du nœud, le nom du nœud et le nom du topic lui-même. Les noms de topic peuvent généralement être catégorisés en trois types :

  1. Global : Le nom du topic est absolu et commence par /, le rendant indépendant du namespace du nœud.
  2. Relatif : Le nom du topic est relatif et ne commence pas par /, ce qui signifie qu'il est interprété dans le namespace du nœud.
  3. Privé : Le nom du topic est privé et commence par ~, ce qui signifie qu'il est résolu par rapport au namespace privé du nœud.

Explorons ces concepts à travers des exemples en C++ et en Python.

1. Implémentation C++

Préparation de l'exemple :

  1. Initialisez le nœud avec un nom :

    cpp
    ros::init(argc, argv, "hello");
  2. Définissez différents types de noms de topic.

  3. Passez un argument __ns:=xxx lors du démarrage du nœud.

  4. Après le démarrage du nœud, utilisez rostopic pour vérifier les informations du topic.

Nom de topic global

Les noms de topic globaux commencent par / et sont indépendants du nom ou du namespace du nœud.

  • Exemple 1 :

    cpp
    ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter", 1000);

    Résultat : /chatter

  • Exemple 2 :

    cpp
    ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter/money", 1000);

    Résultat : /chatter/money

Nom de topic relatif

Les noms de topic relatifs ne commencent pas par / et sont résolus par rapport au namespace du nœud.

  • Exemple 1 :

    cpp
    ros::Publisher pub = nh.advertise<std_msgs::String>("chatter", 1000);

    Résultat : xxx/chatter

  • Exemple 2 :

    cpp
    ros::Publisher pub = nh.advertise<std_msgs::String>("chatter/money", 1000);

    Résultat : xxx/chatter/money

Nom de topic privé

Les noms de topic privés commencent par ~ et sont résolus par rapport au namespace privé du nœud.

  • Exemple 1 :

    cpp
    ros::NodeHandle nh("~");
    ros::Publisher pub = nh.advertise<std_msgs::String>("chatter", 1000);

    Résultat : /xxx/hello/chatter

  • Exemple 2 :

    cpp
    ros::NodeHandle nh("~");
    ros::Publisher pub = nh.advertise<std_msgs::String>("chatter/money", 1000);

    Résultat : /xxx/hello/chatter/money

  • Cas particulier : Lors de l'utilisation de ~, si le nom du topic commence par /, il est traité comme absolu.

    cpp
    ros::NodeHandle nh("~");
    ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter/money", 1000);

    Résultat : /chatter/money

Implémentation Python

Préparation de l'exemple :

  1. Initialisez le nœud avec un nom :

    python
    rospy.init_node("hello")
  2. Définissez différents types de noms de topic.

  3. Passez un argument __ns:=xxx lors du démarrage du nœud.

  4. Après le démarrage du nœud, utilisez rostopic pour vérifier les informations du topic.

Nom de topic global

Les noms de topic globaux commencent par / et sont indépendants du nom ou du namespace du nœud.

  • Exemple 1 :

    python
    pub = rospy.Publisher("/chatter", String, queue_size=1000)

    Résultat : /chatter

  • Exemple 2 :

    python
    pub = rospy.Publisher("/chatter/money", String, queue_size=1000)

    Résultat : /chatter/money

Nom de topic relatif

Les noms de topic relatifs ne commencent pas par / et sont résolus par rapport au namespace du nœud.

  • Exemple 1 :

    python
    pub = rospy.Publisher("chatter", String, queue_size=1000)

    Résultat : xxx/chatter

  • Exemple 2 :

    python
    pub = rospy.Publisher("chatter/money", String, queue_size=1000)

    Résultat : xxx/chatter/money

Nom de topic privé

Les noms de topic privés commencent par ~ et sont résolus par rapport au namespace privé du nœud.

  • Exemple 1 :

    python
    pub = rospy.Publisher("~chatter", String, queue_size=1000)

    Résultat : /xxx/hello/chatter

  • Exemple 2 :

    python
    pub = rospy.Publisher("~chatter/money", String, queue_size=1000)

    Résultat : /xxx/hello/chatter/money


Définir des paramètres dans ROS

Dans ROS, les paramètres sont utilisés pour configurer les nœuds à l'exécution. Ils peuvent être définis de différentes manières : via la commande rosrun, dans des fichiers launch, ou directement dans le code. Les paramètres peuvent être globaux, relatifs ou privés selon la façon dont ils sont définis.

Définir des paramètres avec rosrun

Vous pouvez définir des paramètres lors du lancement d'un nœud avec la commande rosrun. La syntaxe pour définir des paramètres est :

bash
rosrun package_name node_name _parameter_name:=parameter_value

Exemple : définir un paramètre pour le nœud Turtlesim

Démarrons le nœud turtlesim_node et définissons un paramètre A = 100.

bash
rosrun turtlesim turtlesim_node _A:=100

Vérifier les paramètres

Vous pouvez utiliser la commande suivante pour lister tous les paramètres et vérifier les résultats :

bash
rosparam list

Sortie :

plaintext
/turtlesim/A
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r

Explication : Le paramètre A est préfixé par le nom du nœud (/turtlesim/), indiquant que lorsque rosrun est utilisé pour définir un paramètre, il le fait en mode namespace privé.

Définir des paramètres dans des fichiers launch

Comme indiqué précédemment, les paramètres peuvent être définis dans des fichiers launch via les balises <param> ou <rosparam>. Les paramètres définis en dehors de la balise <node> sont globaux, tandis que ceux définis à l'intérieur de la balise <node> sont privés et relatifs au namespace du nœud.

Exemple : définir des paramètres avec la balise <param>

Voici un exemple où nous définissons un paramètre global et un paramètre privé :

xml
<launch>
    <param name="p1" value="100" />
    <node pkg="turtlesim" type="turtlesim_node" name="t1">
        <param name="p2" value="100" />
    </node>
</launch>

Vérifier les paramètres

Après avoir exécuté le fichier launch, vous pouvez vérifier les paramètres avec :

bash
rosparam list

Sortie :

plaintext
/p1
/t1/p2

Explication : Le paramètre p1 est global, tandis que p2 est privé au nœud t1, comme l'indique le namespace.

Définir des paramètres dans le code

Définir des paramètres dans le code offre plus de flexibilité, vous permettant de définir des paramètres globaux, relatifs et privés de manière programmatique.

1. Implémentation C++

En C++, les paramètres peuvent être définis via l'API ros::param ou via un objet ros::NodeHandle.

1.1 Utiliser ros::param pour définir des paramètres

La fonction ros::param::set est utilisée pour définir des paramètres. Le premier argument est le nom du paramètre, le second est sa valeur. Si le nom du paramètre commence par /, c'est un paramètre global. S'il commence par ~, c'est un paramètre privé. Sinon, c'est un paramètre relatif.

Exemple :

cpp
ros::param::set("/set_A", 100); // Global, independent of namespace and node name
ros::param::set("set_B", 100);  // Relative, dependent on namespace
ros::param::set("~set_C", 100); // Private, dependent on namespace and node name

En supposant que le namespace est xxx et le nom du nœud yyy, vérifier les paramètres avec rosparam list afficherait :

plaintext
/set_A
/xxx/set_B
/xxx/yyy/set_C

Utiliser ros::NodeHandle pour définir des paramètres

Pour définir des paramètres avec ros::NodeHandle, créez d'abord un objet NodeHandle, puis appelez la méthode setParam. Si le nom du paramètre commence par /, c'est global. S'il ne commence pas par /, qu'il soit relatif ou privé dépend de la manière dont l'objet NodeHandle a été créé.

Exemple :

cpp
ros::NodeHandle nh;
nh.setParam("/nh_A", 100); // Global, independent of namespace and node name

nh.setParam("nh_B", 100);  // Relative, dependent on namespace

ros::NodeHandle nh_private("~");
nh_private.setParam("nh_C", 100); // Private, dependent on namespace and node name

En supposant que le namespace est xxx et le nom du nœud yyy, vérifier les paramètres avec rosparam list afficherait :

plaintext
/nh_A
/xxx/nh_B
/xxx/yyy/nh_C

2. Implémentation Python

En Python, définir des paramètres est légèrement plus simple qu'en C++. La fonction rospy.set_param est utilisée pour définir des paramètres. Le premier argument est le nom du paramètre, le second est la valeur. Comme en C++, si le nom du paramètre commence par /, il est global. S'il commence par ~, il est privé. Sinon, il est relatif.

Exemple :

python
rospy.set_param("/py_A", 100)  # Global, independent of namespace and node name
rospy.set_param("py_B", 100)   # Relative, dependent on namespace
rospy.set_param("~py_C", 100)  # Private, dependent on namespace and node name

En supposant que le namespace est xxx et le nom du nœud yyy, vérifier les paramètres avec rosparam list afficherait :

plaintext
/py_A
/xxx/py_B
/xxx/yyy/py_C