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

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

目录

一、参数服务器概念

二、参数操作

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;// 参数增加// 方式1nh.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. paramdouble radius = nh.param("radius", 0.5);  //查询参数名为“radius”对应的值,如果“radius”不存在返回0.5ROS_INFO("radius = %.2f", radius);// 2. getParamdouble radius2 = 0.0;bool result = nh.getParam("radius", radius2);if (result){ROS_INFO("radius = %.2f", radius2);}// 3.getparamCached// 4.getParamNamesstd::vector<std::string> names;nh.getParamNames(names);for (auto &&name : names){ROS_INFO("遍历的元素:%s", name.c_str());}// 5.hasParambool flag = nh.hasParam("radius");// 6.searchParamstd::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 rospyif __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 rospyif __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")
http://www.xdnf.cn/news/16316.html

相关文章:

  • 接口多态之我的误解
  • 高可用架构模式——异地多活设计步骤
  • k8s之ingress定义https访问方式
  • 精通Python PDF裁剪:从入门到专业的三重境界
  • Vue工程化 ElementPlus
  • 分布式推客系统开发全解:微服务拆分、佣金结算与风控设计
  • 强制缓存与协商缓存
  • 如何衡量测试的有效性?(如缺陷发现率、逃逸率等)
  • Transformer 位置编码对比
  • pytorch-geometric包(torch_scatter、torch_sparse、torch_cluster)
  • 【性能测试】Jmeter+Grafana+InfluxDB+Prometheus Windows安装部署教程
  • 保障工业核心命脉:深度解读工业交换机QoS的“智能流量治理”之道
  • LeetCode 刷题【12. 整数转罗马数字】
  • Spring Bean生命周期七步曲:定义、实例化、初始化、使用、销毁
  • Android Studio历史版本快速下载(二次修改记录)
  • 面试150 搜索二维矩阵
  • Android集成Google Map
  • 黑马头条项目详解
  • springboot项目如何写出优雅的service?
  • AI时代,我的编程工作搭子
  • TreeMap一致性哈希环设计与实现 —— 高可用的数据分布引擎
  • The Missing Semester of Your CS Education 学习笔记以及一些拓展知识(六)
  • 解决http的web服务中与https服务交互的问题
  • RuoYi-Vue 项目 Docker 全流程部署实战教程
  • PS一键图片智能添加噪点脚本 GrainLab for Photoshop安装与使用介绍
  • 5种最佳方法将iPhone语音备忘录传输到Mac
  • esp32 挂载mpu6050实现加速度计
  • Apache POI 实战应用:企业级文档处理解决方案
  • 编写程序,打印图案,要求该图案的行数由用户输入
  • Hadoop磁盘I/O瓶颈的监控与优化:从iostat指标到JBOD vs RAID的深度解析