【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.pswp.cn/diannao/93108.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/93108.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#.NET dapper 详解

简介 Dapper 是由 Stack Overflow 团队开发的一个简单、高性能的微型 ORM&#xff08;Object‑Relational Mapper&#xff09;&#xff0c;仅几千行代码&#xff0c;依赖于 ADO.NET 的 IDbConnection&#xff0c;通过动态生成 IL 来映射结果到实体对象。 与 EF、NHibernate 这类…

【LeetCode 热题 100】35. 搜索插入位置——二分查找(左闭右开)

Problem: 35. 搜索插入位置 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 文章目录整体思路完整代码时空复杂度时间…

Python-初学openCV——图像预处理(四)——滤波器

目录 一、图像噪点消除噪声&#xff1a; 1、概念 2、均值滤波 3、方框滤波 4 、高斯滤波 5、中值滤波 6、双边滤波 7、总结 一、图像噪点消除噪声&#xff1a; 1、概念 指图像中的一些干扰因素&#xff0c;通常是由图像采集设备、传输信道等因素造成的&#xff0c;表现…

嵌入式系统可靠性设计

嵌入式系统可靠性设计硬件件可靠性设计1. 硬件设计原则2. 硬件设计注意问题2.1 引脚布局和走线2.2 元器件选择和布局2.3 电源和地线分离2.4 EMI/EMC设计2.5 系统可靠性2.6 资源利用和扩展性软件可靠性设计1. 设计原则1.1 模块化设计1.2 冗余设计1.3 容错设计1.4 实时性保障1.5 …

cJSON在STM32单片机上使用遇到解析数据失败问题

我们在单片机上解析JSON格式时&#xff08;比如在用云平台物联网开发时&#xff09;&#xff0c;可以直接使用cJson库来完成自己的操作&#xff0c;而不需要单独实现&#xff0c;具体使用方法可以搜一下。 cJson&#xff1a;一个基于 C 语言的 Json 库&#xff0c;它是一个开源…

python3基础语法梳理(三)

接上一篇博客 &#x1f3ae; 猜数字小游戏 - Python版 &#x1f9e0; 游戏规则&#xff1a; 系统随机生成一个 1 到 10 的整数玩家输入猜测的数字使用 if 语句判断玩家猜得是否正确提示“猜对了”或“太大/太小了” import randomsecret_number random.randint(1, 10) att…

【docker】将已有mysql脚本导入镜像内使用

准备SQL脚本将SQL脚本&#xff08;如init.sql&#xff09;放在宿主机目录下&#xff0c;例如&#xff1a;/path/to/sql-scripts/init.sql启动MySQL容器并挂载脚本使用 -v 参数将SQL脚本挂载到容器的初始化目录&#xff1a;docker run --name mysql-container \-e MYSQL_ROOT_PA…

【机器学习深度学习】LLamaFactory微调效果与vllm部署效果不一致如何解决

目录 前言 一、问题本质 1.1 问题说明 1.2 问题本质示意 二、常见原因 LLaMAFactory对话模板规则定义 模型对话模板定义规则 三、解决方法 提取代码myset.py 创建jinja文件 安装VLLM 运行VLLM 安装运行open webui流程 四、流程梳理 前言 本文主要讲述的主要内容…

Python入门构建网页

用纯 Python 构建 Web 应用 本教程将带你从零开始&#xff0c;构建一个交互式的待办事项清单。 fasthtml 的核心哲学是“回归初心&#xff0c;大道至简”。在当今复杂的前后端分离技术栈中 &#xff0c;它提供了一条返璞归真的路径&#xff0c;旨在让你能用纯粹的 Python 构建从…

开源 Arkts 鸿蒙应用 开发(九)通讯--tcp客户端

文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发&#xff0c;公司安排开发app&#xff0c;临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 Arkts …

Go的defer和recover

在 Go 语言中&#xff0c;defer 和 recover 是两个紧密相关的关键字&#xff0c;主要用于错误处理和资源清理。它们通常一起使用&#xff0c;特别是在处理panic&#xff08;运行时崩溃&#xff09;时&#xff0c;确保程序不会直接崩溃&#xff0c;而是能够优雅地恢复并继续执行…

Spring Boot 配置文件常用配置属性详解(application.properties / application.yml)

前言 Spring Boot 的一大优势就是通过简单的配置文件即可快速定制应用行为&#xff0c;而无需编写大量 XML 配置或 Java 代码。Spring Boot 使用 application.properties 或 application.yml 作为核心配置文件&#xff0c;支持丰富的配置属性。 本文将详细介绍 Spring Boot 常用…

uni-appDay02

1.首页-通用轮播组件 轮播图组件需要再首页和分类页使用&#xff0c;封装成通用组件 准备组件自动导入组件 <script setup lang"ts"> import XtxSwiper from /components/XtxSwiper.vue import CustomNavbar from ./components/CustomNavbar.vue </scrip…

FastAPI入门:请求体、查询参数和字符串校验、路径参数和数值校验

请求体 FastAPI 使用请求体从客户端&#xff08;例如浏览器&#xff09;向 API 发送数据。请求体是客户端发送给 API 的数据。响应体是 API 发送给客户端的数据。 使用 Pydantic 模型声明请求体&#xff0c;能充分利用它的功能和优点 from fastapi import FastAPI from pydanti…

Docker的docker-compose类比Spring的ApplicationContext

总一句话是&#xff1a;Docker Compose&#xff1a;集中化管理多个容器及其依赖的资源环境&#xff1b;ApplicationContext&#xff1a;集中化管理 多个Bean 及其运行所需的资源和依赖关系。 1. 整体概念 Docker Compose&#xff1a;用于定义和运行多容器 Docker 应用程序&…

Reason-before-Retrieve(CVPR 2025)

研究方向&#xff1a;Image Captioning论文全名&#xff1a;《Reason-before-Retrieve: One-Stage Reflective Chain-of-Thoughts for Training-Free Zero-Shot Composed Image Retrieval》1. 论文介绍组合图像检索&#xff08;CIR&#xff09;旨在检索与参考图像密切相似的目标…

Idefics2:构建视觉-语言模型时,什么是重要的

温馨提示&#xff1a; 本篇文章已同步至"AI专题精讲" Idefics2&#xff1a;构建视觉-语言模型时&#xff0c;什么是重要的 摘要 随着large language models和vision transformers的进步&#xff0c;视觉-语言模型&#xff08;VLMs&#xff09;受到了越来越多的关注…

再谈fpga开发(fpga调试方法)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】我们之前在学校学习c、c的时候&#xff0c;其实学校漏掉了很重要的一个教学环节&#xff0c;那就是调试、测试。很多时候我们代码写出来了&#xff…

C语言中的数据结构--栈和队列(1)

前言本届开始我们将对数据结构中栈的内容进行讲解,那么废话不多说,我们正式进入今天的学习栈栈是一种很特殊的线性表&#xff0c;它只能在固定的一端进行插入和删除操作&#xff0c;进行数据的插入和删除的一端叫做栈顶&#xff0c;另外一端叫做栈底&#xff0c;栈中的元素遵守…

字符串是数据结构还是数据类型?

比较纠结的一个问题&#xff0c;以下是在网上查到后总结的&#xff0c;不知道对不对&#xff0c;欢迎讨论。这是个触及计算机科学核心概念的精妙问题&#xff01;字符串既可以被视为一种数据类型&#xff0c;也可以被视为一种数据结构&#xff0c;这取决于你观察的视角和讨论的…