7.1.4-Mécanisme de communication ROS :

Tutoriel sur la communication par topics

Introduction à la communication par topics

Dans ROS, la communication par topics est l'une des manières fondamentales pour les nœuds d'échanger des informations. Ce tutoriel vous guidera dans la mise en place d'une communication par topics de base en utilisant à la fois C++ et Python. Nous mettrons en œuvre un modèle simple de publisher-subscriber où le publisher envoie des messages texte à une fréquence de 10Hz, et le subscriber reçoit et imprime ces messages.

J3010

1. Modèle théorique

La communication par topics implique trois composants principaux :

  • ROS Master : Gère l'enregistrement et la connexion des nœuds.
  • Talker (Publisher) : Envoie les messages.
  • Listener (Subscriber) : Reçoit les messages.

Le ROS Master aide à établir les connexions entre les Talkers et les Listeners. Voici une description étape par étape de la communication :

  • Enregistrement du Talker : Le Talker s'enregistre auprès du ROS Master, en incluant le nom du topic de ses messages.
  • Enregistrement du Listener : Le Listener s'enregistre auprès du ROS Master, en spécifiant le topic auquel il souhaite s'abonner.
  • Mise en correspondance : Le ROS Master met en correspondance le Talker et le Listener selon le nom du topic et envoie les informations de connexion nécessaires.
  • Établissement de la connexion : Le Listener demande une connexion au Talker, et le Talker la confirme.
  • Échange de messages : Une fois connectés, le Talker commence à envoyer des messages au Listener.

Points clés :

  • Le ROS Master n'est nécessaire que pour établir la connexion.
  • La communication continue même si le ROS Master est arrêté après l'établissement de la connexion.
  • Plusieurs Talkers et Listeners peuvent exister, et ils peuvent démarrer dans n'importe quel ordre.

2. Opérations de base de communication par topics (C++)

Objectif : Créer un nœud publisher qui envoie des messages texte à 10Hz et un nœud subscriber qui imprime les messages reçus.

Étapes :

  1. Créer le paquet

    bash
    cd ~/seeed_ws/src/
    catkin_create_pkg listener_and_talker roscpp rospy std_msgs
    cd ~/seeed_ws/src/listener_and_talker/src
    touch listener.cpp talker.cpp
  2. Implémentation du Publisher :

    talker.cpp

    cpp
    #include "ros/ros.h"
    #include "std_msgs/String.h"
    #include <sstream>
    
    int main(int argc, char *argv[]) {
        // Set locale for printing messages in the local language
        setlocale(LC_ALL, "");
        // Initialize the ROS node with a unique name
        ros::init(argc, argv, "talker");
        // Create a ROS node handle
        ros::NodeHandle nh;
        // Create a publisher object
        ros::Publisher pub = nh.advertise<std_msgs::String>("chatter", 10);
    
        std_msgs::String msg;
        std::string msg_front = "Hello Seeed";
        int count = 0;
        ros::Rate r(10); // 10Hz
    
        while (ros::ok()) {
            std::stringstream ss;
            ss << msg_front << count;
            msg.data = ss.str();
            pub.publish(msg);
            ROS_INFO("Sent message: %s", msg.data.c_str());
            r.sleep();
            count++;
        }
        return 0;
    }
  3. Implémentation du Subscriber :

    listener.cpp

    cpp
    #include "ros/ros.h"
    #include "std_msgs/String.h"
    
    void doMsg(const std_msgs::String::ConstPtr& msg_p) {
        ROS_INFO("Heard: %s", msg_p->data.c_str());
    }
    
    int main(int argc, char *argv[]) {
        setlocale(LC_ALL, "");
        ros::init(argc, argv, "listener");
        ros::NodeHandle nh;
        ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter", 10, doMsg);
        ros::spin();
        return 0;
    }
  4. Configuration de CMakeLists.txt :

    Ajoutez le code suivant à la fin du CMakeLists.txt de votre paquet :

    cmake
    add_executable(listener src/listener.cpp)
    add_executable(talker src/talker.cpp)
    
    target_link_libraries(listener ${catkin_LIBRARIES})
    target_link_libraries(talker ${catkin_LIBRARIES})

    J3010

  5. Exécution du code :

  • Ouvrez un terminal et démarrez roscore :

    bash
    roscore
  • Dans un nouveau terminal, allez dans votre espace de travail et exécutez le nœud publisher :

    bash
    rosrun listener_and_talker listener
  • Dans un autre terminal, exécutez le nœud subscriber :

    bash
    rosrun listener_and_talker talker

    J3010

    J3010

Vous devriez voir des messages publiés et reçus, affichés dans le terminal.

3. Opérations de base de communication par topics (Python)

Objectif : Créer un nœud publisher qui envoie des messages texte à 10Hz et un nœud subscriber qui imprime les messages reçus.

Étapes :

  1. Créer le paquet

    bash
    cd ~/seeed_ws/src/
    catkin_create_pkg listener_and_talker roscpp rospy std_msgs
    mkdir ~/seeed_ws/src/listener_and_talker/script
    cd ~/seeed_ws/src/listener_and_talker/script
    touch listener.py talker.py
  2. Implémentation du Publisher :

    talker.py

    python
    #!/usr/bin/env python
    import rospy
    from std_msgs.msg import String
    
    if __name__ == "__main__":
        rospy.init_node("talker_p")
        pub = rospy.Publisher("chatter", String, queue_size=10)
        msg = String()
        msg_front = "hello 你好"
        count = 0
        rate = rospy.Rate(10)  # 10Hz
    
        while not rospy.is_shutdown():
            msg.data = msg_front + str(count)
            pub.publish(msg)
            rospy.loginfo("Sent message: %s", msg.data)
            rate.sleep()
            count += 1
  3. Implémentation du Subscriber :

    listener.py

    python
    #!/usr/bin/env python
    import rospy
    from std_msgs.msg import String
    
    def doMsg(msg):
        rospy.loginfo("Heard: %s", msg.data)
    
    if __name__ == "__main__":
        rospy.init_node("listener_p")
        sub = rospy.Subscriber("chatter", String, doMsg, queue_size=10)
        rospy.spin()
  4. Ajouter les permissions d'exécution :

    bash
     sudo chmod +x *.py
  5. Configuration de CMakeLists.txt :

    Ajoutez le code suivant à la fin du CMakeLists.txt de votre paquet :

    cmake
    catkin_install_python(PROGRAMS
      scripts/talker.py
      scripts/listener.py
      DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    )
  6. Exécution du code :

    • Ouvrez un terminal et démarrez roscore :
      bash
      roscore
    • Dans un nouveau terminal, allez dans votre espace de travail et exécutez le nœud publisher :
      bash
      rosrun listener_and_talker talker.py
    • Dans un autre terminal, exécutez le nœud subscriber :
      bash
      rosrun listener_and_talker listener.py

Vous devriez voir des messages publiés et reçus, affichés dans le terminal.

Commandes courantes pour les topics ROS

  • rostopic bw : Affiche l'utilisation de la bande passante d'un topic
  • rostopic delay : Affiche le délai d'un topic avec en-tête
  • rostopic echo : Imprime les messages à l'écran
  • rostopic find : Recherche les topics par type
  • rostopic hz : Affiche la fréquence de publication d'un topic
  • rostopic info : Affiche des informations sur un topic
  • rostopic list : Liste tous les topics actifs
  • rostopic pub : Publie des données sur un topic
  • rostopic type : Affiche le type d'un topic

Introduction à la communication par services

La communication par services dans ROS diffère de la communication par topics par sa nature bidirectionnelle. Elle permet non seulement l'envoi de messages mais aussi la réception d'une réponse. Ce modèle se compose de deux parties principales :

  1. Client : L'entité qui envoie une requête.
  2. Serveur : L'entité qui traite la requête et renvoie une réponse.

Lorsqu'un client envoie une requête à un serveur, il attend que celui-ci traite la requête et retourne une réponse. Ce mécanisme suit une structure « requête-réponse » qui complète la communication.

Comment cela fonctionne ?

  • Le nœud B (le serveur) fournit une interface de service, généralement nommée comme /service_name.
  • Le nœud A (le client) envoie une requête au nœud B.
  • Le nœud B traite la requête et renvoie une réponse.

Le processus de communication peut être illustré comme suit :

  1. Le nœud Talker annonce un service via le ROS Master :

    • Le nœud Talker annonce un service (par ex. advertiseService("bar", foo:1234)) via le ROS Master, indiquant sa disponibilité.
  2. Le nœud Listener cherche le service via le ROS Master :

    • Le nœud Listener envoie une requête au ROS Master pour trouver le service (par ex. lookupService("bar")).
  3. Le ROS Master renvoie l'adresse du service :

    • Le ROS Master répond avec l'adresse du service (par ex. foo:3456) pour que le nœud Listener s'y connecte.
  4. Le nœud Listener demande des données au nœud Talker :

    • Le nœud Listener envoie une requête de service au nœud Talker, en utilisant XML/RPC pour la communication.
  5. Le nœud Talker répond avec les données demandées :

    • Le nœud Talker traite la requête et renvoie les données de réponse via TCP.

    J3010

Points clés :

  • Le client est bloqué jusqu'à ce qu'il reçoive une réponse du serveur.
  • La communication par services est efficace, car elle ne consomme des ressources qu'au moment nécessaire (c'est-à-dire lors d'une requête).

Modèle théorique

Le modèle de communication par services implique trois composants clés :

  1. ROS Master : Gère l'enregistrement des serveurs et des clients, aidant à établir les connexions sur la base de la correspondance des noms de service.
  2. Serveur : Fournit le service.
  3. Client : Demande le service.

Vue d'ensemble du processus :

  1. Enregistrement du serveur :

    • Le serveur s'enregistre auprès du ROS Master, en incluant le nom du service qu'il fournit.
  2. Enregistrement du client :

    • Le client s'enregistre auprès du ROS Master, en spécifiant le service qu'il souhaite utiliser.
  3. Mise en correspondance et connexion :

    • Le ROS Master met en correspondance le client et le serveur en fonction du nom du service et facilite la connexion.
  4. Cycle requête-réponse :

    • Le client envoie une requête au serveur, qui la traite et renvoie une réponse.

Communication par topics vs. par services

Comparons ces deux méthodes de communication ROS les plus courantes pour approfondir notre compréhension :

AspectCommunication par topicsCommunication par services
Type de communicationAsynchroneSynchrone
ProtocoleTCP/IPTCP/IP
Modèle de communicationPublish-SubscribeRequête-Réponse
RelationPlusieurs à plusieursUn à plusieurs
CaractéristiquesBasé sur des callbacksAppel de procédure distante (RPC)
Cas d'utilisationDonnées continues à haute fréquenceTâches spécifiques à basse fréquence
ExemplePublication de données LiDARDéclenchement d'un capteur ou prise d'une photo

Remarque : L'appel de procédure distante (RPC) consiste à exécuter une fonction sur un processus différent comme s'il s'agissait d'une fonction locale.

5. Création d'un service personnalisé (srv) dans ROS

Plongeons-nous dans un exemple pratique où nous créons un service personnalisé qui additionne deux entiers envoyés par le client. Le serveur traitera cette requête et renverra la somme au client.

Étapes pour la mise en œuvre :

  1. Créer un nouveau paquet

    bash
    cd ~/seeed_ws/src
    catkin_create_pkg service_communication roscpp rospy std_msgs
    cd ~/seeed_ws
    catkin_make
  2. Définir le fichier srv : Le fichier srv définit la structure de la requête et de la réponse. Dans ce cas, la requête contiendra deux entiers, et la réponse contiendra leur somme. Créez un nouveau répertoire appelé srv dans votre paquet et ajoutez un fichier nommé AddInts.srv :

    bash
     mkdir ~/seeed_ws/src/service_communication/srv
     cd ~/seeed_ws/src/service_communication/srv
     touch AddInts.srv

    Copiez ce qui suit dans AddInts.srv :

    srv
    int32 num1
    int32 num2
    ---
    int32 sum

    J3010

  3. Mettre à jour package.xml : Ajoutez les dépendances nécessaires à la génération des fichiers de message dans le package.xml du paquet :

    xml
    <build_depend>message_generation</build_depend>
    <exec_depend>message_runtime</exec_depend>

    J3010

  4. Mettre à jour CMakeLists.txt :

    • Incluez les configurations nécessaires à la génération des fichiers de service dans le CMakeLists.txt du paquet :
      cmake
      find_package(catkin REQUIRED COMPONENTS
        roscpp
        rospy
        std_msgs
        message_generation
      )
      
      add_service_files(
        FILES
        AddInts.srv
      )
      
      generate_messages(
        DEPENDENCIES
        std_msgs
      )

      J3010

  5. Compiler votre paquet :

    • Compilez votre paquet pour générer les en-têtes des messages de service :
      bash
      cd ~/seeed_ws
      catkin_make
      source devel/setup.bash

Implémentation de la communication par services (C++)

Cet exemple montre comment implémenter la communication par services dans ROS en utilisant C++. Nous créerons un service simple où le serveur additionne deux entiers fournis par le client et renvoie la somme.

1. Implémentation du serveur :

add_two_ints_server.cpp

cpp
#include "ros/ros.h"
#include "service_communication/AddInts.h"

// Callback function to handle the client's request
bool add(service_communication::AddInts::Request &req,
         service_communication::AddInts::Response &res) {
    res.sum = req.num1 + req.num2;  // Compute the sum
    ROS_INFO("Request: a=%ld, b=%ld", (long int)req.num1, (long int)req.num2);
    ROS_INFO("Sending back response: [%ld]", (long int)res.sum);
    return true;
}

int main(int argc, char **argv) {
    ros::init(argc, argv, "add_two_ints_server");
    ros::NodeHandle nh;

    // Advertise the service to the ROS master
    ros::ServiceServer service = nh.advertiseService("add_two_ints", add);
    ROS_INFO("Ready to add two integers.");
    ros::spin();

    return 0;
}

2. Implémentation du client :

add_two_ints_client.cpp

cpp
#include "ros/ros.h"
#include "service_communication/AddInts.h"
#include <cstdlib>

int main(int argc, char **argv) {
    ros::init(argc, argv, "add_two_ints_client");
    if (argc != 3) {
        ROS_INFO("Usage: add_two_ints_client X Y");
        return 1;
    }

    ros::NodeHandle nh;
    ros::ServiceClient client = nh.serviceClient<service_communication::AddInts>("add_two_ints");

    // Prepare the service request
    service_communication::AddInts srv;
    srv.request.num1 = atoll(argv[1]);
    srv.request.num2 = atoll(argv[2]);

    // Call the service and check if it was successful
    if (client.call(srv)) {
        ROS_INFO("Sum: %ld", (long int)srv.response.sum);
    } else {
        ROS_ERROR("Failed to call service add_two_ints");
        return 1;
    }

    return 0;
}

Configuration de CMakeLists.txt :

Veillez à ajouter les lignes suivantes à la fin de CMakeLists.txt pour compiler à la fois le serveur et le client :

cmake
add_executable(add_two_ints_server src/add_two_ints_server.cpp)
add_executable(add_two_ints_client src/add_two_ints_client.cpp)

add_dependencies(add_two_ints_server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(add_two_ints_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})

Compiler et exécuter la démo

Ouvrez un terminal :

bash
cd ~/seeed_ws
catkin_make
roscore

Ouvrez un autre terminal :

bash
cd ~/seeed_ws
source devel/setup.bash
 rosrun service_communication server

Ouvrez un autre terminal :

bash
cd ~/seeed_ws
source devel/setup.bash
rosrun service_communication client 1 5

J3010

Implémentation de la communication par services (Python)

Cet exemple Python obtient la même fonctionnalité que l'exemple C++, où un service est utilisé pour additionner deux entiers.

Créez un dossier scripts sous le paquet et créez les fichiers add_two_ints_server.py et add_two_ints_client.py à l'intérieur.

bash
cd ~/seeed/src/service_communication/
mkdir scripts
cd scripts
touch add_two_ints_server.py add_two_ints_client.py

1. Implémentation du serveur :

add_two_ints_server.py

python
#!/usr/bin/env python
import rospy
from service_communication.srv import AddInts,AddIntsRequest, AddIntsResponse
def doReq(req):
    sum = req.num1 + req.num2
    rospy.loginfo("data:num1 = %d, num2 = %d, sum = %d",req.num1, req.num2, sum)
    resp = AddIntsResponse(sum)
    return resp
if __name__ == "__main__":
    rospy.init_node("addints_server_p")
    server = rospy.Service("AddInts",AddInts,doReq)
    rospy.spin()

2. Implémentation du client :

add_two_ints_client.py

python
#!/usr/bin/env python

import sys
import rospy
from service_communication.srv import *

if __name__ == "__main__":
    if len(sys.argv) != 3:
        rospy.logerr("error")
        sys.exit(1)
    rospy.init_node("AddInts_Client_p")
    client = rospy.ServiceProxy("AddInts",AddInts)
    client.wait_for_service()
    req = AddIntsRequest()
    req.num1 = int(sys.argv[1])
    req.num2 = int(sys.argv[2]) 
    resp = client.call(req)
    rospy.loginfo("result:%d",resp.sum)

Configuration de CMakeLists.txt :

Ajoutez les lignes suivantes dans votre CMakeLists.txt pour les scripts Python :

cmake
catkin_install_python(PROGRAMS
  scripts/add_two_ints_server.py 
  scripts/add_two_ints_client.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

Compiler et exécuter la démo

Ouvrez un terminal :

bash
cd ~/seeed_ws
catkin_make
roscore

Ouvrez un autre terminal :

bash
cd ~/seeed_ws
source devel/setup.bash
rosrun service_communication add_two_ints_server.py

Ouvrez un autre terminal :

bash
cd ~/seeed_ws
source devel/setup.bash
rosrun service_communication add_two_ints_client.py 1 5

Commandes de communication par services

Pour travailler avec les services dans ROS, vous utiliserez la commande rosservice. Voici une liste des commandes rosservice courantes et de leurs fonctions :

  • rosservice args : Affiche les arguments requis par un service
  • rosservice call : Appelle un service avec les arguments fournis
  • rosservice find : Recherche les services par type
  • rosservice info : Affiche des informations sur un service
  • rosservice list : Liste tous les services actifs
  • rosservice type : Affiche le type d'un service
  • rosservice uri : Affiche l'URI ROSRPC d'un service

Introduction au serveur de paramètres ROS

Le serveur de paramètres ROS est un espace de stockage pour paramètres partagé, multi-utilisateur et accessible via le réseau. Il permet de stocker et de récupérer des paramètres au moment de l'exécution, ce qui peut servir à configurer des nœuds ou à partager des données entre eux. Les paramètres sur le serveur peuvent être de divers types de données, notamment des entiers, booléens, chaînes, doubles, listes et dictionnaires. Le serveur de paramètres est géré par le ROS Master, et les nœuds interagissent avec lui en définissant, récupérant ou supprimant des paramètres.

Modèle théorique du serveur de paramètres

Le serveur de paramètres implique trois rôles principaux :

  1. ROS Master : Gère le serveur de paramètres, agissant comme un stockage central pour les paramètres.
  2. Talker : Un nœud qui définit des paramètres sur le serveur.
  3. Listener : Un nœud qui récupère des paramètres depuis le serveur.

Le processus d'interaction avec le serveur de paramètres comprend généralement les étapes suivantes :

  1. Définition des paramètres (Talker) :

    • Le nœud Talker envoie un paramètre au serveur de paramètres via RPC (Remote Procedure Call), incluant le nom et la valeur du paramètre. Le ROS Master stocke ce paramètre dans sa liste.
  2. Récupération des paramètres (Listener) :

    • Le nœud Listener demande un paramètre au serveur de paramètres en envoyant une requête avec le nom du paramètre.
  3. Retour des paramètres (ROS Master) :

    • Le ROS Master cherche le paramètre demandé dans son stockage et renvoie la valeur correspondante au Listener.

    J3010

Types de données pris en charge :

  • Entiers 32 bits
  • Booléens
  • Chaînes
  • Doubles
  • Dates ISO8601
  • Listes
  • Données binaires encodées en Base64
  • Dictionnaires

Implémentation en C++

Définir des paramètres (C++) :

Commençons par définir divers types de paramètres sur le serveur de paramètres en utilisant deux APIs différentes : ros::NodeHandle et ros::param.

set_parameters.cpp

cpp
#include "ros/ros.h"

int main(int argc, char *argv[]) {
    ros::init(argc, argv, "set_parameters");

    std::vector<std::string> students = {"Alice", "Bob", "Charlie", "David"};
    std::map<std::string, std::string> friends = {{"John", "Doe"}, {"Jane", "Smith"}};

    // Using ros::NodeHandle to set parameters
    ros::NodeHandle nh;
    nh.setParam("int_param", 42);
    nh.setParam("double_param", 3.14159);
    nh.setParam("bool_param", true);
    nh.setParam("string_param", "Hello ROS");
    nh.setParam("vector_param", students);
    nh.setParam("map_param", friends);

    // Using ros::param to set parameters
    ros::param::set("int_param_param", 84);
    ros::param::set("double_param_param", 6.28318);
    ros::param::set("bool_param_param", false);
    ros::param::set("string_param_param", "Goodbye ROS");
    ros::param::set("vector_param_param", students);
    ros::param::set("map_param_param", friends);

    return 0;
}

Ajoutez le code suivant à la fin du CMakeLists.txt de votre paquet :

cmake
add_executable(set_parameters src/set_parameters.cpp)
target_link_libraries(set_parameters ${catkin_LIBRARIES})

Dans cet exemple :

  • Nous définissons divers types de paramètres sur le serveur de paramètres, notamment des entiers, doubles, booléens, chaînes, vecteurs et mappes.
  • Nous avons utilisé les deux APIs ros::NodeHandle et ros::param pour définir les paramètres.

Récupérer les paramètres (C++) :

Ensuite, nous récupérerons les paramètres que nous avions précédemment définis sur le serveur de paramètres.

get_parameters.cpp

cpp
#include "ros/ros.h"

int main(int argc, char *argv[]) {
    ros::init(argc, argv, "get_parameters");

    // Using ros::NodeHandle to retrieve parameters
    ros::NodeHandle nh;
    int int_value;
    double double_value;
    bool bool_value;
    std::string string_value;
    std::vector<std::string> students;
    std::map<std::string, std::string> friends;

    nh.getParam("int_param", int_value);
    nh.getParam("double_param", double_value);
    nh.getParam("bool_param", bool_value);
    nh.getParam("string_param", string_value);
    nh.getParam("vector_param", students);
    nh.getParam("map_param", friends);

    ROS_INFO("Retrieved values:");
    ROS_INFO("int_param: %d", int_value);
    ROS_INFO("double_param: %.5f", double_value);
    ROS_INFO("bool_param: %d", bool_value);
    ROS_INFO("string_param: %s", string_value.c_str());

    for (const auto &student : students) {
        ROS_INFO("Student: %s", student.c_str());
    }

    for (const auto &friend_pair : friends) {
        ROS_INFO("Friend: %s = %s", friend_pair.first.c_str(), friend_pair.second.c_str());
    }

    return 0;
}

Ajoutez le code suivant à la fin du CMakeLists.txt de votre paquet :

cmake
add_executable(get_parameters src/get_parameters.cpp)
target_link_libraries(get_parameters ${catkin_LIBRARIES})

Dans cet exemple :

  • Nous récupérons les paramètres définis sur le serveur en utilisant l'API ros::NodeHandle.
  • Les paramètres récupérés sont ensuite imprimés dans le journal ROS pour vérification.

Supprimer les paramètres (C++) :

Enfin, voyons comment supprimer des paramètres du serveur de paramètres.

delete_parameters.cpp

cpp
#include "ros/ros.h"

int main(int argc, char *argv[]) {
    ros::init(argc, argv, "delete_parameters");

    ros::NodeHandle nh;
    bool success;

    // Using ros::NodeHandle to delete parameters
    success = nh.deleteParam("int_param");
    ROS_INFO("Delete int_param: %s", success ? "Success" : "Failure");

    // Using ros::param to delete parameters
    success = ros::param::del("int_param_param");
    ROS_INFO("Delete int_param_param: %s", success ? "Success" : "Failure");

    return 0;
}

Ajoutez le code suivant à la fin du CMakeLists.txt de votre paquet :

cmake
add_executable(delete_parameters src/delete_parameters.cpp)
target_link_libraries(delete_parameters ${catkin_LIBRARIES})

Dans cet exemple :

  • Nous utilisons les deux APIs ros::NodeHandle et ros::param pour supprimer des paramètres du serveur.
  • Le succès de la suppression est consigné dans le journal.

2.2 Implémentation en Python

Définir des paramètres (Python) :

Définissons maintenant des paramètres en Python. Le processus est très similaire à la version C++.

python
#!/usr/bin/env python

import rospy

if __name__ == "__main__":
    rospy.init_node("set_parameters_py")

    # Setting various types of parameters
    rospy.set_param("int_param", 42)
    rospy.set_param("double_param", 3.14159)
    rospy.set_param("bool_param", True)
    rospy.set_param("string_param", "Hello ROS")
    rospy.set_param("list_param", ["apple", "banana", "cherry"])
    rospy.set_param("dict_param", {"first_name": "John", "last_name": "Doe"})

    # Modifying a parameter
    rospy.set_param("int_param", 84)

Ajoutez le code suivant à la fin du CMakeLists.txt de votre paquet :

cmake
catkin_install_python(PROGRAMS
  scripts/set_parameters_py.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

Dans cet exemple :

  • Nous définissons divers types de paramètres, notamment des entiers, doubles, booléens, chaînes, listes et dictionnaires.
  • Nous montrons aussi comment modifier un paramètre existant.

Récupérer les paramètres (Python) :

Ensuite, nous récupérerons les paramètres que nous avons définis.

python
#!/usr/bin/env python

import rospy

if __name__ == "__main__":
    rospy.init_node("get_parameters_py")

    # Retrieving parameters
    int_value = rospy.get_param("int_param", 0)
    double_value = rospy.get_param("double_param", 0.0)
    bool_value = rospy.get_param("bool_param", False)
    string_value = rospy.get_param("string_param", "")
    list_value = rospy.get_param("list_param", [])
    dict_value = rospy.get_param("dict_param", {})

    rospy.loginfo("Retrieved values:")
    rospy.loginfo("int_param: %d", int_value)
    rospy.loginfo("double_param: %.5f", double_value)
    rospy.loginfo("bool_param: %s", bool_value)
    rospy.loginfo("string_param: %s", string_value)
    rospy.loginfo("list_param: %s", list_value)
    rospy.loginfo("dict_param: %s", dict_value)

Ajoutez le code suivant à la fin du CMakeLists.txt de votre paquet :

cmake
catkin_install_python(PROGRAMS
  scripts/set_parameters_py.py
  scripts/get_parameters_py.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

Dans cet exemple :

  • Nous utilisons rospy.get_param pour récupérer les paramètres définis sur le serveur.
  • Les valeurs récupérées sont consignées via rospy.loginfo.

Supprimer des paramètres (Python) :

Enfin, supprimons des paramètres du serveur de paramètres en Python.

python
#!/usr/bin/env python

import rospy

if __name__ == "__main__":
    rospy.init_node("delete_parameters_py")

    try:
        rospy.delete_param("int_param")
        rospy.loginfo("int_param deleted successfully.")
    except KeyError:
        rospy.logwarn("int_param does not exist.")

    try:
        rospy.delete_param("non_existent_param")
        rospy.loginfo("non_existent_param deleted successfully.")
    except KeyError:
        rospy.logwarn("non_existent_param does not exist.")

Ajoutez le code suivant à la fin du CMakeLists.txt de votre paquet :

cmake
catkin_install_python(PROGRAMS
  scripts/set_parameters_py.py
  scripts/get_parameters_py.py
  scripts/delete_parameters_py.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

Dans cet exemple :

  • Nous tentons de supprimer un paramètre et gérons le cas où il n'existe pas avec une gestion d'exception (KeyError).

Commandes courantes du serveur de paramètres ROS

rosparam inclut des outils en ligne de commande pour obtenir et définir des paramètres ROS sur le serveur de paramètres, en utilisant des fichiers encodés en YAML.

  • rosparam set : Définit un paramètre
  • rosparam get : Obtient un paramètre
  • rosparam load : Charge des paramètres depuis un fichier externe
  • rosparam dump : Exporte des paramètres vers un fichier externe
  • rosparam delete : Supprime un paramètre
  • rosparam list : Liste tous les paramètres

Exemples :

  • rosparam list : Liste tous les paramètres du serveur de paramètres.
  • rosparam set <param_name> <value> : Définit un paramètre avec une valeur spécifique.
  • rosparam get <param_name> : Obtient la valeur d'un paramètre spécifique.
  • rosparam delete <param_name> : Supprime un paramètre spécifique.
  • rosparam load <file_name.yaml> : Charge des paramètres depuis un fichier YAML.
  • rosparam dump <file_name.yaml> : Exporte les paramètres actuels dans un fichier YAML.