7.1.4-ROS-communicatiemechanisme:

Tutorial Topic-communicatie

Inleiding tot topic-communicatie

In ROS is topic-communicatie een van de fundamentele manieren waarop nodes informatie uitwisselen. Deze tutorial begeleidt u door het opzetten van basis topic-communicatie met zowel C++ als Python. We implementeren een eenvoudig publisher-subscriber-model waarbij de publisher tekstberichten verzendt met een frequentie van 10Hz, en de subscriber deze berichten ontvangt en afdrukt.

J3010

1. Theoretisch model

Topic-communicatie omvat drie hoofdcomponenten:

  • ROS Master: Beheert de registratie en verbinding van nodes.
  • Talker (Publisher): Verzendt berichten.
  • Listener (Subscriber): Ontvangt berichten.

De ROS Master helpt verbindingen tot stand te brengen tussen Talkers en Listeners. Hieronder een stapsgewijze uitleg van hoe de communicatie verloopt:

  • Talker-registratie: De Talker registreert zichzelf bij de ROS Master, inclusief de topicnaam van zijn berichten.
  • Listener-registratie: De Listener registreert zichzelf bij de ROS Master en geeft het topic op waarop hij wil abonneren.
  • Matching: De ROS Master koppelt Talker en Listener op basis van de topicnaam en stuurt de benodigde verbindingsinformatie.
  • Verbindingsopbouw: De Listener vraagt een verbinding aan met de Talker, en de Talker bevestigt deze.
  • Berichtuitwisseling: Zodra de verbinding tot stand is gebracht, begint de Talker berichten naar de Listener te sturen.

Belangrijke punten:

  • De ROS Master is alleen nodig voor het tot stand brengen van de verbinding.
  • De communicatie gaat door, ook als de ROS Master wordt afgesloten nadat de verbinding tot stand is gebracht.
  • Er kunnen meerdere Talkers en Listeners bestaan, en ze kunnen in elke volgorde starten.

2. Basis topic-communicatie operaties (C++)

Doel: Een publisher-node maken die tekstberichten verzendt op 10Hz en een subscriber-node die de ontvangen berichten afdrukt.

Stappen:

  1. Pakket aanmaken

    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. Publisher-implementatie:

    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. Subscriber-implementatie:

    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. CMakeLists.txt-configuratie:

    Voeg de volgende code toe aan het einde van de CMakeLists.txt van uw pakket:

    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. Code uitvoeren:

  • Open een terminal en start roscore:

    bash
    roscore
  • Navigeer in een nieuwe terminal naar uw werkruimte en voer de publisher-node uit:

    bash
    rosrun listener_and_talker listener
  • Voer in een andere terminal de subscriber-node uit:

    bash
    rosrun listener_and_talker talker

    J3010

    J3010

U zou berichten moeten zien die in de terminal worden gepubliceerd en ontvangen.

3. Basis topic-communicatie operaties (Python)

Doel: Een publisher-node maken die tekstberichten verzendt op 10Hz en een subscriber-node die de ontvangen berichten afdrukt.

Stappen:

  1. Pakket aanmaken

    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. Publisher-implementatie:

    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. Subscriber-implementatie:

    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. Uitvoeringsrechten toevoegen:

    bash
     sudo chmod +x *.py
  5. CMakeLists.txt-configuratie:

    Voeg de volgende code toe aan het einde van de CMakeLists.txt van uw pakket:

    cmake
    catkin_install_python(PROGRAMS
      scripts/talker.py
      scripts/listener.py
      DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    )
  6. Code uitvoeren:

    • Open een terminal en start roscore:
      bash
      roscore
    • Navigeer in een nieuwe terminal naar uw werkruimte en voer de publisher-node uit:
      bash
      rosrun listener_and_talker talker.py
    • Voer in een andere terminal de subscriber-node uit:
      bash
      rosrun listener_and_talker listener.py

U zou berichten moeten zien die in de terminal worden gepubliceerd en ontvangen.

Veelgebruikte ROS Topic-commando's

  • rostopic bw: Toon het bandbreedtegebruik van een topic
  • rostopic delay: Toon de vertraging van een topic met header
  • rostopic echo: Druk berichten af op het scherm
  • rostopic find: Zoek topics op type
  • rostopic hz: Toon de publicatiefrequentie van een topic
  • rostopic info: Toon informatie over een topic
  • rostopic list: Geef alle actieve topics weer
  • rostopic pub: Publiceer gegevens naar een topic
  • rostopic type: Druk het type van een topic af

Inleiding tot servicecommunicatie

Servicecommunicatie in ROS verschilt van topic-communicatie doordat ze bidirectioneel is. Ze maakt niet alleen het verzenden van berichten mogelijk, maar ook het ontvangen van feedback. Dit model bestaat uit twee hoofdonderdelen:

  1. Client: De entiteit die een verzoek verstuurt.
  2. Server: De entiteit die het verzoek verwerkt en een respons terugstuurt.

Wanneer een client een verzoek naar een server stuurt, wacht hij tot de server het verzoek heeft verwerkt en een respons retourneert. Dit mechanisme volgt een "verzoek-antwoord"-structuur, waarmee de communicatie wordt voltooid.

Hoe werkt het?

  • Node B (de server) biedt een service-interface, gewoonlijk met een naam als /service_name.
  • Node A (de client) stuurt een verzoek naar Node B.
  • Node B verwerkt het verzoek en stuurt een respons terug.

Het communicatieproces kan als volgt worden geïllustreerd:

  1. Talker-node adverteert een service via ROS Master:

    • De Talker-node adverteert een service (bijv. advertiseService("bar", foo:1234)) via de ROS Master, wat de beschikbaarheid aangeeft.
  2. Listener-node zoekt de service op via ROS Master:

    • De Listener-node verstuurt een verzoek naar de ROS Master om de service te vinden (bijv. lookupService("bar")).
  3. ROS Master geeft het serviceadres terug:

    • De ROS Master antwoordt met het serviceadres (bijv. foo:3456) zodat de Listener-node verbinding kan maken.
  4. Listener-node vraagt gegevens op bij Talker-node:

    • De Listener-node verstuurt een serviceverzoek naar de Talker-node, waarbij XML/RPC voor communicatie wordt gebruikt.
  5. Talker-node antwoordt met de gevraagde gegevens:

    • De Talker-node verwerkt het verzoek en stuurt de antwoordgegevens terug via TCP.

    J3010

Belangrijke punten:

  • De client wordt geblokkeerd totdat hij een respons van de server ontvangt.
  • Servicecommunicatie is efficiënt, omdat ze alleen middelen verbruikt wanneer dat nodig is (d.w.z. wanneer een verzoek wordt gedaan).

Theoretisch model

Het servicecommunicatiemodel omvat drie belangrijke componenten:

  1. ROS Master: Beheert de registratie van zowel servers als clients en helpt verbindingen tot stand te brengen op basis van overeenkomende servicenamen.
  2. Server: Biedt de service.
  3. Client: Vraagt de service op.

Procesoverzicht:

  1. Serverregistratie:

    • De server registreert zichzelf bij de ROS Master, inclusief de naam van de service die hij biedt.
  2. Clientregistratie:

    • De client registreert zichzelf bij de ROS Master en geeft op welke service hij wil gebruiken.
  3. Matching en verbinding:

    • De ROS Master koppelt client en server op basis van de servicenaam en faciliteert de verbinding.
  4. Verzoek-antwoordcyclus:

    • De client stuurt een verzoek naar de server, die het verwerkt en een respons retourneert.

Topic- vs. servicecommunicatie

Laten we deze twee meest voorkomende ROS-communicatiemethoden vergelijken om ons begrip te vergroten:

AspectTopic-communicatieServicecommunicatie
Type communicatieAsynchroonSynchroon
ProtocolTCP/IPTCP/IP
CommunicatiemodelPublish-SubscribeVerzoek-Antwoord
RelatieVeel-op-veelEen-op-veel
KenmerkenOp callback gebaseerdRemote Procedure Call (RPC)
ToepassingenContinue, hoogfrequente gegevensLaagfrequente, specifieke taken
VoorbeeldPubliceren van LiDAR-gegevensTriggeren van een sensor of een foto maken

Opmerking: Remote Procedure Call (RPC) verwijst naar het uitvoeren van een functie in een ander proces alsof deze lokaal is.

5. Een aangepaste service (srv) in ROS maken

Laten we een praktisch voorbeeld doornemen waarin we een aangepaste service maken die twee gehele getallen die door de client worden verzonden optelt. De server verwerkt dit verzoek en retourneert de som aan de client.

Implementatiestappen:

  1. Een nieuw pakket maken

    bash
    cd ~/seeed_ws/src
    catkin_create_pkg service_communication roscpp rospy std_msgs
    cd ~/seeed_ws
    catkin_make
  2. Het srv-bestand definiëren: Het srv-bestand definieert de structuur van het verzoek en het antwoord. In dit geval bevat het verzoek twee gehele getallen en het antwoord hun som. Maak een nieuwe map met de naam srv aan in uw pakket en voeg een bestand met de naam AddInts.srv toe:

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

    Kopieer het volgende naar AddInts.srv:

    srv
    int32 num1
    int32 num2
    ---
    int32 sum

    J3010

  3. package.xml bijwerken: Voeg de benodigde afhankelijkheden voor het genereren van berichtbestanden toe aan de package.xml van het pakket:

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

    J3010

  4. CMakeLists.txt bijwerken:

    • Voeg de benodigde configuraties toe om de servicebestanden te genereren in de CMakeLists.txt van het pakket:
      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. Uw pakket compileren:

    • Compileer uw pakket om de service-berichtheaders te genereren:
      bash
      cd ~/seeed_ws
      catkin_make
      source devel/setup.bash

Servicecommunicatie implementeren (C++)

Dit voorbeeld laat zien hoe servicecommunicatie in ROS te implementeren met C++. We maken een eenvoudige service waarbij de server twee door de client opgegeven gehele getallen optelt en de som retourneert.

1. Server-implementatie:

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. Client-implementatie:

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;
}

CMakeLists.txt-configuratie:

Zorg ervoor dat u de volgende regels aan het einde van CMakeLists.txt toevoegt om zowel de server als de client te compileren:

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})

De demo compileren en uitvoeren

Open één terminal:

bash
cd ~/seeed_ws
catkin_make
roscore

Open een andere terminal:

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

Open nog een terminal:

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

J3010

Servicecommunicatie implementeren (Python)

Dit Python-voorbeeld bereikt dezelfde functionaliteit als het C++-voorbeeld, waarbij een service wordt gebruikt om twee gehele getallen op te tellen.

Maak een scripts-map onder het pakket aan en maak daarin de bestanden add_two_ints_server.py en add_two_ints_client.py.

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

1. Server-implementatie:

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. Client-implementatie:

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)

CMakeLists.txt-configuratie:

Voeg de volgende regels toe aan uw CMakeLists.txt voor de Python-scripts:

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

De demo compileren en uitvoeren

Open één terminal:

bash
cd ~/seeed_ws
catkin_make
roscore

Open een andere terminal:

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

Open nog een terminal:

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

Commando's voor servicecommunicatie

Om met services in ROS te werken, gebruikt u het commando rosservice. Hier volgt een lijst van veelgebruikte rosservice-commando's en hun functies:

  • rosservice args: Druk de argumenten af die voor een service vereist zijn
  • rosservice call: Roep een service aan met de opgegeven argumenten
  • rosservice find: Zoek services op type
  • rosservice info: Druk informatie over een service af
  • rosservice list: Geef alle actieve services weer
  • rosservice type: Druk het type van een service af
  • rosservice uri: Druk de ROSRPC-URI van een service af

Inleiding tot de ROS Parameter Server

De ROS Parameter Server is een gedeelde, multi-user, via het netwerk toegankelijke opslagruimte voor parameters. Hij biedt een manier om parameters tijdens runtime op te slaan en op te halen, die kunnen worden gebruikt om nodes te configureren of om gegevens tussen nodes te delen. Parameters op de server kunnen verschillende datatypes hebben, waaronder gehele getallen, booleans, strings, doubles, lijsten en woordenboeken. De Parameter Server wordt beheerd door de ROS Master, en nodes communiceren ermee door parameters in te stellen, op te halen of te verwijderen.

Theoretisch model van de Parameter Server

De Parameter Server omvat drie hoofdrollen:

  1. ROS Master: Beheert de Parameter Server en fungeert als centrale opslag voor parameters.
  2. Talker: Een node die parameters op de server instelt.
  3. Listener: Een node die parameters van de server ophaalt.

Het proces van interactie met de Parameter Server omvat doorgaans de volgende stappen:

  1. Parameters instellen (Talker):

    • De Talker-node verstuurt een parameter naar de Parameter Server via RPC (Remote Procedure Call), inclusief de naam en waarde van de parameter. De ROS Master slaat deze parameter op in zijn lijst.
  2. Parameters ophalen (Listener):

    • De Listener-node vraagt een parameter aan bij de Parameter Server door een query met de parameternaam te versturen.
  3. Parameters retourneren (ROS Master):

    • De ROS Master zoekt de gevraagde parameter in zijn opslag en retourneert de bijbehorende waarde aan de Listener.

    J3010

Ondersteunde datatypes:

  • 32-bit gehele getallen
  • Booleans
  • Strings
  • Doubles
  • ISO8601-datums
  • Lijsten
  • Base64-gecodeerde binaire gegevens
  • Woordenboeken

C++-implementatie

Parameters instellen (C++):

We beginnen met het instellen van verschillende soorten parameters op de Parameter Server met twee verschillende API's: ros::NodeHandle en 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;
}

Voeg de volgende code toe aan het einde van de CMakeLists.txt van uw pakket:

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

In dit voorbeeld:

  • We stellen verschillende soorten parameters in op de Parameter Server, waaronder gehele getallen, doubles, booleans, strings, vectors en maps.
  • We hebben zowel de API's ros::NodeHandle als ros::param gebruikt om de parameters in te stellen.

Parameters ophalen (C++):

Vervolgens halen we de parameters op die we eerder hebben ingesteld op de Parameter Server.

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;
}

Voeg de volgende code toe aan het einde van de CMakeLists.txt van uw pakket:

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

In dit voorbeeld:

  • We halen de op de server ingestelde parameters op met de API ros::NodeHandle.
  • De opgehaalde parameters worden vervolgens ter verificatie afgedrukt naar het ROS-logboek.

Parameters verwijderen (C++):

Tot slot kijken we hoe parameters van de Parameter Server kunnen worden verwijderd.

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;
}

Voeg de volgende code toe aan het einde van de CMakeLists.txt van uw pakket:

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

In dit voorbeeld:

  • We gebruiken zowel de API's ros::NodeHandle als ros::param om parameters van de server te verwijderen.
  • Het al dan niet slagen van de verwijdering wordt gelogd.

2.2 Python-implementatie

Parameters instellen (Python):

Laten we nu parameters instellen met Python. Het proces is zeer vergelijkbaar met de C++-versie.

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)

Voeg de volgende code toe aan het einde van de CMakeLists.txt van uw pakket:

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

In dit voorbeeld:

  • We stellen verschillende soorten parameters in, waaronder gehele getallen, doubles, booleans, strings, lijsten en woordenboeken.
  • We laten ook zien hoe een bestaande parameter te wijzigen.

Parameters ophalen (Python):

Vervolgens halen we de parameters op die we hebben ingesteld.

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)

Voeg de volgende code toe aan het einde van de CMakeLists.txt van uw pakket:

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

In dit voorbeeld:

  • We gebruiken rospy.get_param om op de server ingestelde parameters op te halen.
  • De opgehaalde waarden worden gelogd met rospy.loginfo.

Parameters verwijderen (Python):

Tot slot verwijderen we parameters van de Parameter Server met 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.")

Voeg de volgende code toe aan het einde van de CMakeLists.txt van uw pakket:

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}
)

In dit voorbeeld:

  • We proberen een parameter te verwijderen en behandelen het geval waarin de parameter niet bestaat met behulp van uitzonderingsafhandeling (KeyError).

Veelgebruikte commando's voor de ROS Parameter Server

rosparam bevat command-line-tools voor het ophalen en instellen van ROS-parameters op de Parameter Server, met behulp van YAML-gecodeerde bestanden.

  • rosparam set: Een parameter instellen
  • rosparam get: Een parameter ophalen
  • rosparam load: Parameters laden vanuit een extern bestand
  • rosparam dump: Parameters exporteren naar een extern bestand
  • rosparam delete: Een parameter verwijderen
  • rosparam list: Alle parameters weergeven

Voorbeelden:

  • rosparam list: Geef alle parameters op de Parameter Server weer.
  • rosparam set <param_name> <value>: Stel een parameter met een specifieke waarde in.
  • rosparam get <param_name>: Haal de waarde van een specifieke parameter op.
  • rosparam delete <param_name>: Verwijder een specifieke parameter.
  • rosparam load <file_name.yaml>: Laad parameters vanuit een YAML-bestand.
  • rosparam dump <file_name.yaml>: Exporteer de huidige parameters naar een YAML-bestand.