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

【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.lryc.cn/news/598688.html

相关文章:

  • ubuntu25.04+4070+cuda+docker安装
  • prometheus监控k8s的metric详解-01-apiserver部分-05-其他
  • k8s把某个secret挂在某命名空间下
  • 【数据结构】二叉树进阶算法题
  • MongoDB常用场景
  • AI总结视频以及谷歌浏览器插件安装步骤
  • 对examples/train_lora/llama3_lora_eval.yaml模型评估配置文件的理解。
  • Vue2文件上传相关
  • 零知识证明
  • vs2019 创建MFC ActiveX的详细步骤
  • Qt WebEngine Widgets的使用
  • 爬虫基础概念
  • 在Ubuntu上使用QEMU学习RISC-V程序(1)起步第一个程序
  • linux C -glib库的基本使用
  • Windows环境下 Go项目迁移至Ubuntu(WSL) 以部署filebeat为例
  • 如何在 Ubuntu 24.04 服务器或桌面版上安装和使用 gedit
  • 深度分析Java内存回收机制
  • 跨境支付入门~国际支付结算(电商篇)
  • unordered_map和unordered_set特性以及解决哈希冲突
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-19,(知识点:PCB布局布线的设计要点)
  • DevOps 完整实现指南:从理论到实践
  • LeetCode 23:合并 K 个升序链表
  • 【已解决】YOLO11模型转wts时报错:PytorchStreamReader failed reading zip archive
  • 医疗AI轻量化部署方案的深度梳理与优化路径判研
  • 基于Qt的仿QQ聊天系统设计
  • Ethereum: 区块链浏览器,我们的“天眼”
  • 力扣 hot100 Day54
  • 【开源】WpfMap:一个基于WPF(Windows Presentation Foundation)技术构建的数据可视化大屏展示页面
  • JS对象键的秘密:数字变字符串?
  • 【Linux基础知识系列】第六十四篇 - 了解Linux的硬件架构