【ROS1】09-ROS通信机制——参数服务器

发布于:2025-07-26 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

一、参数服务器概念

二、参数操作

2.1 C++实现

2.1.1 新增参数

2.1.2 修改参数

2.1.3 查询参数

2.1.4 删除参数

2.2 python实现

2.2.1 新增参数

2.2.2 修改参数

2.2.3 查询参数

2.2.4 删除参数


一、参数服务器概念

假设正在开发一个复杂的机器人应用,里面有很多需要配置的数值,比如:

  • 机器人的物理尺寸(轮子直径、轮距)

  • PID 控制器的增益参数(Kp, Ki, Kd)

  • 传感器的配置(相机分辨率、激光雷达扫描频率)

  • 导航算法的参数(避障距离、目标容忍度)

你当然可以把这些数值硬编码(hard-code)在你的 C++ 或 Python 代码里。但这样做有几个巨大的缺点:

  • 修改困难:每次想调整一个参数,都必须重新修改代码、重新编译、重新部署。

  • 复用性差:同一个算法用在不同机器人上,参数不同,就需要维护多个版本的代码。

  • 管理混乱:参数散落在各个节点的代码中,难以集中查看和管理。

参数服务器就是为了解决这些问题而生的。它是一个全局的、集中式的、运行在 ROS Master 内部的字典(dictionary),能够存储一些多节点共享的数据,类似于全局变量。

这个“字典”可以存储各种基本数据类型的键值对(Key-Value pairs),任何 ROS 节点都可以在运行时存入 (set)查询 (get) 和 删除 (delete) 这些参数。

核心特点:

  • 集中存储: 所有参数都存储在一个地方(ROS Master),方便管理和调试。

  • 全局可访问: 任何连接到同一个 ROS Master 的节点都可以访问这些参数。

  • 动态配置: 可以在节点运行时动态地修改参数,而无需重启节点(需要节点代码支持动态重配置)。

  • 与代码解耦: 将配置参数从业务逻辑代码中分离出来,提高了代码的通用性和可维护性。

  • 支持多种数据类型: 支持字符串、整数、浮点数、布尔值、列表(数组)和字典(结构体)。

注意:参数服务器不是为高性能而设计的,因此最好用于存储静态的非二进制的简单数据。

二、参数操作

2.1 C++实现

2.1.1 新增参数

进入到工作空间的src目录下,输入如下指令来创建一个名为“plumbing_param_server”的功能包

在功能包的src目录下新建一个cpp文件,这里命名为“demo01_param_set.cpp”

在“demo01_param_set.cpp”中添加如下代码来实现参数的新增

#include "ros/ros.h"

/*
需求:
    实现参数的新增
实现:
    ros::NodeHandle.setParam()
    ros::param.set()
*/

int main(int argc, char *argv[])
{
    // 初始化ROS节点
    ros::init(argc, argv, "set_param_c");

    // 创建ROS节点句柄
    ros::NodeHandle nh;

    // 参数增加
    // 方式1
    nh.setParam("type", "type1");
    nh.setParam("radius", 0.15);

    // // 方式2
    // ros::param::set("type", "type1");
    // ros::param::set("radius", 0.15);

    return 0;
}

打开功能包下的“CMakeLists.txt”,添加如下部分

Ctrl+Shift+B编译一下,然后开启3个终端窗口分别用于启动ROS核心、启动ROS节点、查看参数

roscore  // 启动ROS核心

source ./devel/setup.bash
rosrun plumbing_param_server demo01_param_set  //启动ROS节点


rosparam list  //列出参数

如果想查询参数的值,可以使用如下命令

rosparam get 参数名

2.1.2 修改参数

如果再次设置相同参数名,就会覆盖之前参数名对应的参数值

2.1.3 查询参数

在功能包的src目录中新创建一个cpp文件,这里命名为“demo02_param_get.cpp” 

在“demo02_param_get.cpp” 添加如下代码,用于展示如何执行参数的相关查询操作

#include "ros/ros.h"

/*
需求:实现参数的查询
实现:
    ros::NodeHandle
        .param(键,默认值)  存在这个键方法返回存储的值,否则返回默认值
        .getParam(键,变量) 存在这个键方法返回true并将存储的值赋值给变量,否则返回false,且不为变量赋值
        .getparamCached(键,变量)  和.getParam基本一样
        .getParamNames(td::vector<std::string>)  获取所有的键并存储在vector中
        .hasParam(键) 判断是否存在某个键,存在返回true,否则返回false
        .searchParam(键,变量)   能够搜索到就将“/”+键名赋值给变量,否则将空字符串赋给变量
    ros::param
*/

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");

    // 初始化ROS节点
    ros::init(argc, argv, "get_param_c");

    // 创建ROS节点句柄
    ros::NodeHandle nh;

    // ros::NodeHandle
    // 1. param
    double radius = nh.param("radius", 0.5);  //查询参数名为“radius”对应的值,如果“radius”不存在返回0.5
    ROS_INFO("radius = %.2f", radius);

    // 2. getParam
    double radius2 = 0.0;
    bool result = nh.getParam("radius", radius2);
    if (result){
        ROS_INFO("radius = %.2f", radius2);
    }

    // 3.getparamCached

    // 4.getParamNames
    std::vector<std::string> names;
    nh.getParamNames(names);
    for (auto &&name : names)
    {
        ROS_INFO("遍历的元素:%s", name.c_str());
    }

    // 5.hasParam
    bool flag = nh.hasParam("radius");

    // 6.searchParam
    std::string key;
    nh.searchParam("radius", key);
    ROS_INFO("搜索结果:%s", key.c_str());

    return 0;
}

打开功能包中的“CMakeLists.txt”,添加如下部分

编译一下,该节点执行效果如下:

2.1.4 删除参数

 删除参数主要通过如下两种方式实现

#include "ros/ros.h"

/*
删除参数:
    实现:
    ros::NodeHandle.delParam()
    ros::param.del()

*/

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

    ros::NodeHandle nh;
    bool flag = nh.deleteParam("radius");
    if (flag){
        ROS_INFO("删除成功!");
    }else{
        ROS_INFO("删除失败!");
    }

    // ros::param::del("radius");

    return 0;
}

运行效果如下,可以看到成功删除了“radius”参数

2.2 python实现

2.2.1 新增参数

在功能包中添加一个“scripts”目录 

在“scripts”目录添加一个python文件,用于新增参数

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import rospy

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

    rospy.set_param("name", "czc")
    rospy.set_param("age", 18)

在“CMakeLists.txt”中添加如下部分

为python文件添加可执行权限

chmod +x *.py

可以看到成功添加了两个参数

2.2.2 修改参数

只需重新设置一下相同键名的参数,那么参数值就会被重新覆盖 

2.2.3 查询参数

参数查询可通过如下方法实现

1. get_param

2. get_param_cached

3. get_param names

4. has_param

5. search param

示例:

import rospy

if __name__ == "__main__":
    rospy.init_node('param_example_node')
    
    # 1. get_param - 获取参数值,支持默认值
    name1 = rospy.get_param('name', 'default_name')
    print(f"Name1: {name1}")
    
    # 2. get_param_cached - 缓存参数值,减少RPC调用
    name2 = rospy.get_param_cached('name', 'default_name')
    print(f"Name2: {name2}")
    
    # 3. get_param_names - 获取所有参数名称
    all_params = rospy.get_param_names()
    for param in all_params:
        print(f"param: - {param}")
    
    # 4. has_param - 检查参数是否存在
    has_name = rospy.has_param('name')
    print(f"Has Param: {has_name}")
    
    # 5. search_param 
    key = rospy.search_param('name')
    rospy.loginfo("key = %s", key)
    
    rospy.spin()

执行效果如下:

2.2.4 删除参数

rospy.delete_param("Key")

网站公告

今日签到

点亮在社区的每一天
去签到