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

【ROS】参数服务器--理论模型与参数操作(C++)

一、概念介绍

参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器,可以将数据存储在该容器中,被不同的节点调用,当然不同的节点也可以往其中存储数据。

作用:存储一些多节点共享的数据,类似于全局变量。




二、理论模型[Autolabor-ROS]

参数服务器实现是最为简单的,该模型如下图所示,该模型中涉及到三个角色:

ROS Master (管理者)
Talker (参数设置者)
Listener (参数调用者)

ROS Master 作为一个公共容器保存参数,Talker 可以向容器中设置参数,Listener 可以获取参数。


在这里插入图片描述


整个流程由以下步骤实现:

1.Talker 设置参数
Talker 通过 RPC 向参数服务器发送参数(包括参数名与参数值),ROS Master 将参数保存到参数列表中。

2.Listener 获取参数
Listener 通过 RPC 向参数服务器发送参数查找请求,请求中包含要查找的参数名。

3.ROS Master 向 Listener 发送参数值
ROS Master 根据步骤2请求提供的参数名查找参数值,并将查询结果通过 RPC 发送给 Listener。


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




三、参数操作(C++)

在 C++ 中实现参数服务器数据的增删改查,均可以通过两套 API 实现:

ros::NodeHandle
ros::param

下面为具体操作演示:


1.参数服务器新增(修改)参数 【增、改】

/*参数服务器操作之新增与修改(二者API一样)_C++实现:在 roscpp 中提供了两套 API 实现参数操作ros::NodeHandlesetParam("键",值)ros::paramset("键","值")示例:分别设置整形、浮点、字符串、bool、列表、字典等类型参数修改(相同的键,不同的值)*/
#include "ros/ros.h"int main(int argc, char *argv[])
{ros::init(argc,argv,"set_update_param");std::vector<std::string> stus;stus.push_back("zhangsan");stus.push_back("李四");stus.push_back("王五");stus.push_back("孙大脑袋");std::map<std::string,std::string> friends;friends["guo"] = "huang";friends["yuang"] = "xiao";//NodeHandle--------------------------------------------------------ros::NodeHandle nh;nh.setParam("nh_int",10); //整型nh.setParam("nh_double",3.14); //浮点型nh.setParam("nh_bool",true); //boolnh.setParam("nh_string","hello NodeHandle"); //字符串nh.setParam("nh_vector",stus); // vectornh.setParam("nh_map",friends); // map//修改演示(相同的键,不同的值)nh.setParam("nh_int",10000);//param--------------------------------------------------------ros::param::set("param_int",20);ros::param::set("param_double",3.14);ros::param::set("param_string","Hello Param");ros::param::set("param_bool",false);ros::param::set("param_vector",stus);ros::param::set("param_map",friends);//修改演示(相同的键,不同的值)ros::param::set("param_int",20000);return 0;
}

2.参数服务器获取参数 【查】

/*参数服务器操作之查询_C++实现:在 roscpp 中提供了两套 API 实现参数操作ros::NodeHandleparam(键,默认值)存在,返回对应结果,否则返回默认值getParam(键,存储结果的变量)存在,返回 true,且将值赋值给参数2若果键不存在,那么返回值为 false,且不为参数2赋值getParamCached(键,存储结果的变量)--提高变量获取效率存在,返回 true,且将值赋值给参数2若果键不存在,那么返回值为 false,且不为参数2赋值getParamNames(std::vector<std::string>)获取所有的键,并存储在参数 vector 中hasParam(键)是否包含某个键,存在返回 true,否则返回 falsesearchParam(参数1,参数2)搜索键,参数1是被搜索的键,参数2存储搜索结果的变量ros::param ----- 与 NodeHandle 类似
*/#include "ros/ros.h"int main(int argc, char *argv[])
{setlocale(LC_ALL,"");ros::init(argc,argv,"get_param");//NodeHandle实现--------------------------------------------------------/*ros::NodeHandle nh;// 1.param 函数int res1 = nh.param("nh_int",100); // 键存在int res2 = nh.param("nh_int2",100); // 键不存在ROS_INFO("param获取结果:%d,%d",res1,res2);// 2.getParam 函数int nh_int_value;double nh_double_value;bool nh_bool_value;std::string nh_string_value;std::vector<std::string> stus;std::map<std::string, std::string> friends;nh.getParam("nh_int",nh_int_value);nh.getParam("nh_double",nh_double_value);nh.getParam("nh_bool",nh_bool_value);nh.getParam("nh_string",nh_string_value);nh.getParam("nh_vector",stus);nh.getParam("nh_map",friends);ROS_INFO("getParam获取的结果:%d,%.2f,%s,%d",nh_int_value,nh_double_value,nh_string_value.c_str(),nh_bool_value);for (auto &&stu : stus){ROS_INFO("stus 元素:%s",stu.c_str());        }for (auto &&f : friends){ROS_INFO("map 元素:%s = %s",f.first.c_str(), f.second.c_str());}// getParamCached()nh.getParamCached("nh_int",nh_int_value);ROS_INFO("通过缓存获取数据:%d",nh_int_value);//getParamNames()std::vector<std::string> param_names1;nh.getParamNames(param_names1);for (auto &&name : param_names1){ROS_INFO("名称解析name = %s",name.c_str());        }ROS_INFO("----------------------------");ROS_INFO("存在 nh_int 吗? %d",nh.hasParam("nh_int"));ROS_INFO("存在 nh_intttt 吗? %d",nh.hasParam("nh_intttt"));std::string key;nh.searchParam("nh_int",key);ROS_INFO("搜索键:%s",key.c_str());*///param实现--------------------------------------------------------ROS_INFO("++++++++++++++++++++++++++++++++++++++++");int res3 = ros::param::param("param_int",20); //存在int res4 = ros::param::param("param_int2",20); // 不存在返回默认ROS_INFO("param获取结果:%d,%d",res3,res4);// getParam 函数int param_int_value;double param_double_value;bool param_bool_value;std::string param_string_value;std::vector<std::string> param_stus;std::map<std::string, std::string> param_friends;ros::param::get("param_int",param_int_value);ros::param::get("param_double",param_double_value);ros::param::get("param_bool",param_bool_value);ros::param::get("param_string",param_string_value);ros::param::get("param_vector",param_stus);ros::param::get("param_map",param_friends);ROS_INFO("getParam获取的结果:%d,%.2f,%s,%d",param_int_value,param_double_value,param_string_value.c_str(),param_bool_value);for (auto &&stu : param_stus) // &&右值引用{ROS_INFO("stus 元素:%s",stu.c_str());        }for (auto &&f : param_friends){ROS_INFO("map 元素:%s = %s",f.first.c_str(), f.second.c_str());}// getParamCached()ros::param::getCached("param_int",param_int_value);ROS_INFO("通过缓存获取数据:%d",param_int_value);//getParamNames()std::vector<std::string> param_names2;ros::param::getParamNames(param_names2);for (auto &&name : param_names2){ROS_INFO("名称解析name = %s",name.c_str());        }ROS_INFO("----------------------------");ROS_INFO("存在 param_int 吗? %d",ros::param::has("param_int"));ROS_INFO("存在 param_intttt 吗? %d",ros::param::has("param_intttt"));std::string key;ros::param::search("param_int",key);ROS_INFO("搜索键:%s",key.c_str());return 0;
}

3.参数服务器删除参数 【删】

/* 参数服务器操作之删除_C++实现:ros::NodeHandledeleteParam("键")根据键删除参数,删除成功,返回 true,否则(参数不存在),返回 falseros::paramdel("键")根据键删除参数,删除成功,返回 true,否则(参数不存在),返回 false*/
#include "ros/ros.h"int main(int argc, char *argv[])
{   setlocale(LC_ALL,"");ros::init(argc,argv,"delete_param");ros::NodeHandle nh;bool r1 = nh.deleteParam("nh_int");ROS_INFO("nh 删除结果:%d",r1);bool r2 = ros::param::del("param_int");ROS_INFO("param 删除结果:%d",r2);return 0;
}

4.配置CMakeList.txt

add_executable(demo01_param_set src/demo01_param_set.cpp)
add_executable(demo02_param_get src/demo02_param_get.cpp)
add_executable(demo03_param_del src/demo03_param_del.cpp)target_link_libraries(demo01_param_set${catkin_LIBRARIES}
)
target_link_libraries(demo02_param_get${catkin_LIBRARIES}
)
target_link_libraries(demo03_param_del${catkin_LIBRARIES}
)

在这里插入图片描述




之后编译运行即可,参数服务器相较于之前两个通信机制还是比较简洁的。。。

相关文章:

【ROS】参数服务器--理论模型与参数操作(C++)

一、概念介绍 参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据。 作用&#xff1a;存储一些多节点…...

[oneAPI] 基于BERT预训练模型的英文文本蕴含任务

[oneAPI] 基于BERT预训练模型的英文文本蕴含任务 Intel DevCloud for oneAPI 和 Intel Optimization for PyTorch基于BERT预训练模型的英文文本蕴含任务语料介绍数据集构建 模型训练 结果参考资料 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0…...

【洛谷】P1163 银行贷款

原题链接&#xff1a;https://www.luogu.com.cn/problem/P1163 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 这题需要注意的是利率按月累计这句话&#xff0c;也就是相当于“利滚利”。 我们定义sum变量表示贷款原值&#xff0c;money表示每月支付…...

Java版工程行业管理系统源码-专业的工程管理软件-提供一站式服务 em

​ 鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工…...

kafka--技术文档--基本docker中安装<单机>-linux

安装zookeeper 阿丹小科普&#xff1a; Kafka在0.11.0.0版本之后不再依赖Zookeeper&#xff0c;而是使用基于Raft协议的Kafka自身的仲裁机制来替代Zookeeper。具体来说&#xff0c;Kafka 2.8.0版本是第一个不需要Zookeeper就可以运行Kafka的版本&#xff0c;这被称为Kafka Raf…...

回归预测 | MATLAB实现WOA-RF鲸鱼优化算法优化随机森林算法多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现WOA-RF鲸鱼优化算法优化随机森林算法多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现WOA-RF鲸鱼优化算法优化随机森林算法多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览…...

Linux系统安全——NAT(SNAT、DNAT)

目录 NAT SNAT SNAT实际操作 DNAT DNAT实际操作 NAT NAT: network address translation&#xff0c;支持PREROUTING&#xff0c;INPUT&#xff0c;OUTPUT&#xff0c;POSTROUTING四个链 请求报文&#xff1a;修改源/目标IP&#xff0c; 响应报文&#xff1a;修改源/目标…...

uniapp项目添加人脸识别功能,可用作登录,付款,流程审批前的安全校验

本案例使用了hbuilder插件商城中的活体检验插件&#xff0c;可自行前往作者处下载查看&#xff0c; 效果图如下 此插件需要在manifest.json中勾选 实现流程 1&#xff1a;前往hbuilder插件市场下载插件 2&#xff1a;在页面中导入import face from "/uni_modules/mcc-…...

SpringBoot面试题

Spring Boot的启动流程主要分为以下几个步骤&#xff1a; 加载Spring Boot配置文件&#xff0c;初始化Spring Boot环境和核心组件&#xff0c;如ApplicationContext上下文环境、自动装配机制等。 执行SpringApplication.run()方法&#xff0c;执行所有Spring Boot自动配置的Be…...

Git相关命令

SSH密钥文件 Github里面S设置SH公钥有两者选择方式 账号下的每个仓库都设置一个公钥&#xff0c;因为GitHub官方要求每个仓库的公钥都不能相同&#xff0c;所以每个账号都要搞一个密钥&#xff08;很麻烦&#xff09;给账号分配一个公钥&#xff0c;然后这个公钥就可以在这个…...

《HeadFirst设计模式(第二版)》第八章代码——模板方法模式

代码文件目录&#xff1a; CaffeineBeverage package Chapter8_TemplateMethodPattern;/*** Author 竹心* Date 2023/8/17**/public abstract class CaffeineBeverage {final void prepareRecipe(){boilWater();brew();pourInCup();//这里使用钩子customerWantsCondiments()来…...

RESTful API,以及如何使用它构建 web 应用程序

RESTful API是一种基于HTTP协议的API设计风格&#xff0c;它的核心思想是将资源作为 API 的核心&#xff0c;使用 HTTP 的 GET、POST、PUT、DELETE 等方法对这些资源进行操作&#xff0c;并通过 URL 来定位资源。 RESTful API的特点包括&#xff1a; 资源是 API 的核心使用 H…...

Git+Gitee使用分享

GitGitee快速入门 创建仓库 ​ ​ ​ 初始化本地仓库 验证本地git是否安装好 打开cmd窗口&#xff0c;输入git ​ 这样就OK。 Git 全局设置:(只需要设置一次) 这台电脑如果是第一次使用git&#xff0c;就需要这样初始化一下&#xff0c;这样才知道是谁提交到仓库了。 git confi…...

【3D激光SLAM】LOAM源代码解析--transformMaintenance.cpp

系列文章目录 【3D激光SLAM】LOAM源代码解析–scanRegistration.cpp 【3D激光SLAM】LOAM源代码解析–laserOdometry.cpp 【3D激光SLAM】LOAM源代码解析–laserMapping.cpp 【3D激光SLAM】LOAM源代码解析–transformMaintenance.cpp 写在前面 本系列文章将对LOAM源代码进行讲解…...

DiscuzQ 二开教程(7)——二次开发版本部署文档

DiscuzQ 二开教程&#xff08;7&#xff09;——二次开发版本部署文档 源码&#xff1a;Discuz-Q-V3: 本仓库为Discuz-Q V3.0.211111 版本的二次开发版本&#xff0c;是将DiscuzQ官方仓库进行合并代码&#xff08;All in One&#xff09;整理后的仓库&#xff0c;使用更方便。…...

u盘数据丢失但占内存如何恢复?不要着急,这里有拯救方案

U盘数据丢失但占内存如何恢复&#xff1f;数据丢失是一种让人非常头疼的问题&#xff0c;尤其是当我们的U盘数据丢失了&#xff0c;但内存仍然被占用时&#xff0c;更令人困惑和焦虑。然而&#xff0c;不要慌张&#xff01;在本文中&#xff0c;将为大家介绍一些有效的方法来恢…...

springboot日志文件名称为什么叫logback-spring.xml

如题&#xff0c;为什么springboot日志配置文件叫logback-spring.xml&#xff1f; 在整个项目中搜索 logback-spring.xml 并没有搜索到。 先看一下 org.springframework.boot.context.logging.LoggingApplicationListener#initialize protected void initialize(ConfigurableEn…...

Mysql 开窗函数(窗口函数)

文章目录 全部数据示例1&#xff08;说明&#xff09;开窗函数可以比groupby多查出条件列外的字段&#xff0c;开窗函数主要是为了跟聚合函数一起使用&#xff0c;达到分组统计效果&#xff0c;并且开窗函数的结果集基本都是跟总行数一样示例2示例3示例4错误示例1错误示例2错误…...

计算机视觉之图像特征提取

图像特征提取是计算机视觉中的重要任务&#xff0c;它有助于识别、分类、检测和跟踪对象。以下是一些常用的图像特征提取算法及其简介&#xff1a; 颜色直方图&#xff08;Color Histogram&#xff09;&#xff1a; 简介&#xff1a;颜色直方图表示图像中各种颜色的分布情况。通…...

【面试经典150题】移除元素·JavaScript版

题目来源 大致思路&#xff1a;遍历数组&#xff0c;如果遇到值为val的元素&#xff0c;使用数组最后一个元素替换它。详细过程&#xff1a; /*** param {number[]} nums* param {number} val* return {number}*/ var removeElement function(nums, val) {let i0,nnums.leng…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...