当前位置: 首页 > news >正文

参数服务器 server and client

ROS2 参数服务器和客户端实现利用了 ROS2 内置的参数服务机制,具有以下特点:

  1. 服务器节点(param_server_node)

    • 初始化并维护参数存储
    • 定期打印当前所有参数状态
    • 支持客户端的参数查询、设置和删除操作
  2. 客户端节点(param_client_node)

    • 使用SyncParametersClient与参数服务器交互
    • 提供参数的获取、设置、更新和删除示例
    • 等待服务器可用后再执行操作
  3. 项目结构

    • 包含完整的 CMakeLists.txt 和 package.xml 配置文件
    • 符合 ROS2 的包结构规范

使用方法

  1. 创建 ROS2 工作空间并构建包:

    bash

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
# 创建包
ros2 pkg create --build-type ament_cmake parameter_server_example
# 将上述代码文件放入相应位置
cd ~/ros2_ws
colcon build
source install/setup.bash
  • 运行参数服务器:

    bash

ros2 run parameter_server_example param_server

 

  • 在另一个终端运行参数客户端:

    bash

source ~/ros2_ws/install/setup.bash
ros2 run parameter_server_example param_client

    客户端会执行一系列参数操作并输出结果,服务器则会每 10 秒打印一次当前所有参数的状态。

    这种实现充分利用了 ROS2 的参数系统,比直接使用套接字实现的参数服务器更符合 ROS2 的生态系统和设计理念。

    param_server_node.cpp

    #include "rclcpp/rclcpp.hpp"
    #include <unordered_map>
    #include <string>

    class ParamServerNode : public rclcpp::Node
    {
    public:
    ParamServerNode() : Node("param_server_node")
    {
    // 初始化一些默认参数
    declare_parameter("max_connections", 10);
    declare_parameter("timeout", 5.0);
    declare_parameter("enabled", true);
    declare_parameter("server_name", "main_server");

            RCLCPP_INFO(get_logger(), "参数服务器节点已启动");

    // 创建一个定时器用于周期性打印当前参数状态
    timer_ = this->create_wall_timer(
    std::chrono::seconds(10),
    std::bind(&ParamServerNode::print_parameters, this)
    );
    }

    private:
    void print_parameters()
    {
    RCLCPP_INFO(get_logger(), "\n当前参数列表:");

    // 获取所有参数名称
    auto param_names = get_parameter_names();

    for (const auto& name : param_names) {
    rclcpp::Parameter param;
    if (get_parameter(name, param)) {
    RCLCPP_INFO(get_logger(), "%s: %s", 
    name.c_str(), 
    param.value_to_string().c_str());
    }
    }
    }

    rclcpp::TimerBase::SharedPtr timer_;
    };

    int main(int argc, char * argv[])
    {
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<ParamServerNode>());
    rclcpp::shutdown();
    return 0;
    }
    param_client_node.cpp

    #include "rclcpp/rclcpp.hpp"
    #include <chrono>
    #include <thread>

    class ParamClientNode : public rclcpp::Node
    {
    public:
    ParamClientNode() : Node("param_client_node")
    {
    RCLCPP_INFO(get_logger(), "参数客户端节点已启动");

    // 创建参数客户端
    param_client_ = std::make_shared<rclcpp::SyncParametersClient>(this, "param_server_node");

    // 等待参数服务器可用
    while (!param_client_->wait_for_service(std::chrono::seconds(1))) {
    if (!rclcpp::ok()) {
    RCLCPP_ERROR(get_logger(), "等待参数服务器时被中断");
    return;
    }
    RCLCPP_INFO(get_logger(), "等待参数服务器...");
    }

    // 执行参数操作示例
    perform_parameter_operations();
    }

    private:
    void perform_parameter_operations()
    {
    // 获取参数
    get_parameters_example();

    // 设置新参数
    set_parameters_example();

    // 更新已有参数
    update_parameters_example();

    // 删除参数
    delete_parameters_example();

    // 再次获取参数以显示变化
    get_parameters_example();
    }

    void get_parameters_example()
    {
    RCLCPP_INFO(get_logger(), "\n--- 获取参数示例 ---");

    // 获取单个参数
    auto max_connections = param_client_->get_parameter<int>("max_connections");
    RCLCPP_INFO(get_logger(), "max_connections: %d", max_connections);

    // 批量获取参数
    std::vector<std::string> param_names = {"timeout", "enabled", "server_name"};
    auto params = param_client_->get_parameters(param_names);

    for (const auto& param : params) {
    RCLCPP_INFO(get_logger(), "%s: %s", 
    param.get_name().c_str(), 
    param.value_to_string().c_str());
    }
    }

    void set_parameters_example()
    {
    RCLCPP_INFO(get_logger(), "\n--- 设置新参数示例 ---");

    std::vector<rclcpp::Parameter> params;
    params.push_back(rclcpp::Parameter("buffer_size", 1024));
    params.push_back(rclcpp::Parameter("log_level", "info"));
    params.push_back(rclcpp::Parameter("timeout_ms", 5000));

    auto results = param_client_->set_parameters(params);

    for (size_t i = 0; i < results.size(); ++i) {
    if (results[i].successful) {
    RCLCPP_INFO(get_logger(), "成功设置参数: %s", params[i].get_name().c_str());
    } else {
    RCLCPP_ERROR(get_logger(), "设置参数失败: %s", params[i].get_name().c_str());
    }
    }
    }

    void update_parameters_example()
    {
    RCLCPP_INFO(get_logger(), "\n--- 更新参数示例 ---");

    std::vector<rclcpp::Parameter> params;
    params.push_back(rclcpp::Parameter("max_connections", 20));
    params.push_back(rclcpp::Parameter("timeout", 10.0));
    params.push_back(rclcpp::Parameter("enabled", false));

    auto results = param_client_->set_parameters(params);

    for (size_t i = 0; i < results.size(); ++i) {
    if (results[i].successful) {
    RCLCPP_INFO(get_logger(), "成功更新参数: %s", params[i].get_name().c_str());
    } else {
    RCLCPP_ERROR(get_logger(), "更新参数失败: %s", params[i].get_name().c_str());
    }
    }
    }

    void delete_parameters_example()
    {
    RCLCPP_INFO(get_logger(), "\n--- 删除参数示例 ---");

    std::vector<std::string> params_to_delete = {"server_name", "timeout_ms"};
    auto results = param_client_->delete_parameters(params_to_delete);

    for (size_t i = 0; i < results.size(); ++i) {
    if (results[i].successful) {
    RCLCPP_INFO(get_logger(), "成功删除参数: %s", params_to_delete[i].c_str());
    } else {
    RCLCPP_ERROR(get_logger(), "删除参数失败: %s", params_to_delete[i].c_str());
    }
    }
    }

    rclcpp::SyncParametersClient::SharedPtr param_client_;
    };

    int main(int argc, char * argv[])
    {
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<ParamClientNode>());
    rclcpp::shutdown();
    return 0;
    }

    CmakeList.txt  

    cmake_minimum_required(VERSION 3.5)
    project(parameter_server_example)

    if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    add_compile_options(-Wall -Wextra -Wpedantic)
    endif()

    # 查找依赖
    find_package(ament_cmake REQUIRED)
    find_package(rclcpp REQUIRED)

    # 声明服务器节点
    add_executable(param_server src/param_server_node.cpp)
    ament_target_dependencies(param_server rclcpp)

    # 声明客户端节点
    add_executable(param_client src/param_client_node.cpp)
    ament_target_dependencies(param_client rclcpp)

    # 安装目标
    install(TARGETS
    param_server
    param_client
    DESTINATION lib/${PROJECT_NAME})

    ament_package()

    packages.xml

    <?xml version="1.0"?>
    <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
    <package format="3">
    <name>parameter_server_example</name>
    <version>0.0.0</version>
    <description>ROS2参数服务器和客户端示例</description>
    <maintainer email="your@email.com">Your Name</maintainer>
    <license>Apache-2.0</license>

      <buildtool_depend>ament_cmake</buildtool_depend>
    <depend>rclcpp</depend>

      <build_depend>ament_cmake</build_depend>
    <exec_depend>rclcpp</exec_depend>

      <build_depend>ament_cmake</build_depend>
    <exec_depend>rclcpp</exec_depend>

      <export>
    <build_type>ament_cmake</build_type>
    </export>
    </package>

    http://www.dtcms.com/a/321604.html

    相关文章:

  1. 一文可视化分析2025年6月计算机视觉顶刊IJCV前沿热点
  2. 满足高性能AI服务器的企业SSD有哪些?三星PM1743与Solidigm PS1010
  3. Ⅹ—6.计算机二级综合题27---30套
  4. 研发流程管理经验分享
  5. 部署ELK8.18对日志进行收集、展示
  6. 1Panel Agent 证书绕过实现远程命令执行漏洞复现(CVE-2025-54424)
  7. 【Spring Boot 快速入门】八、登录认证
  8. Java 大视界 -- Java 大数据机器学习模型在金融风险传染路径模拟与防控策略制定中的应用(387)
  9. [Oracle] LEAST()函数
  10. CORS 跨域问题 Next.js 跨域问题放通
  11. HttpURLConnection (JDK原生)和Hutool HTTP工具的区别
  12. GStreamer:开源多媒体框架技术详解与应用实践
  13. c++初学day1(类比C语言进行举例,具体原理等到学到更深层的东西再进行解析)
  14. 从0配置yolo实例分割(ubuntu)
  15. 五种IO模型与⾮阻塞IO
  16. 无人机仿真环境搭建
  17. 二叉树实现
  18. 【科研绘图系列】R语言绘制气泡图
  19. [LLM 应用评估] 提示词四大要素 | 评估样本_单次交互快照 | 数据集 | Hugging Face集成
  20. 杰理ac791 [Info]: [LL_S]Recv - LL_CHANNEL_MAP_REQ
  21. JAVA基础-集合框架
  22. 特征值和特征向量的直觉
  23. 自适应反步控制:理论与设计
  24. 网络基础浅谈
  25. NVME M.2 SSD固态硬盘掉盘:也可能是主板出问题
  26. 【Layui】调整 Layui 整体样式大小的方法
  27. 【Lua】XLua一键构建工具
  28. 关于 Rust 异步底层实现中 waker 的猜测
  29. Xiphos 配备 GTH 计算机模块的 Q8J 低 SWaP
  30. 基于LLM的Chat应用测试方法探索:系统化评估与持续优化