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

ROS-ROS通信机制-参数服务器

文章目录

  • 一、基础理论知识
  • 二、C++实现
  • 三、Python实现

一、基础理论知识

参数服务器在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。


参数可使用数据类型:

  • 32-bit integers
  • booleans
  • strings
  • doubles
  • iso8601 dates
  • lists
  • base64-encoded binary data
  • 字典

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

二、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;// param 函数int res1 = nh.param("nh_int",100); // 键存在int res2 = nh.param("nh_int2",100); // 键不存在ROS_INFO("param获取结果:%d,%d",res1,res2);// 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;
}

1.列出参数服务器中的参数及获取某个参数的值
在这里插入图片描述

三、Python实现

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

#! /usr/bin/env python
"""参数服务器操作之新增与修改(二者API一样)_Python实现:
"""import rospyif __name__ == "__main__":rospy.init_node("set_update_paramter_p")# 设置各种类型参数rospy.set_param("p_int",10)rospy.set_param("p_double",3.14)rospy.set_param("p_bool",True)rospy.set_param("p_string","hello python")rospy.set_param("p_list",["hello","haha","xixi"])rospy.set_param("p_dict",{"name":"hulu","age":8})# 修改rospy.set_param("p_int",100)

2.参数服务器获取参数

#! /usr/bin/env python"""参数服务器操作之查询_Python实现:    get_param(键,默认值)当键存在时,返回对应的值,如果不存在返回默认值get_param_cachedget_param_nameshas_paramsearch_param
"""import rospyif __name__ == "__main__":rospy.init_node("get_param_p")#获取参数int_value = rospy.get_param("p_int",10000)double_value = rospy.get_param("p_double")bool_value = rospy.get_param("p_bool")string_value = rospy.get_param("p_string")p_list = rospy.get_param("p_list")p_dict = rospy.get_param("p_dict")rospy.loginfo("获取的数据:%d,%.2f,%d,%s",int_value,double_value,bool_value,string_value)for ele in p_list:rospy.loginfo("ele = %s", ele)rospy.loginfo("name = %s, age = %d",p_dict["name"],p_dict["age"])# get_param_cachedint_cached = rospy.get_param_cached("p_int")rospy.loginfo("缓存数据:%d",int_cached)# get_param_namesnames = rospy.get_param_names()for name in names:rospy.loginfo("name = %s",name)rospy.loginfo("-"*80)# has_paramflag = rospy.has_param("p_int")rospy.loginfo("包含p_int吗?%d",flag)# search_paramkey = rospy.search_param("p_int")rospy.loginfo("搜索的键 = %s",key)

3.参数服务器删除参数

#! /usr/bin/env python
"""参数服务器操作之删除_Python实现:rospy.delete_param("键")键存在时,可以删除成功,键不存在时,会抛出异常
"""
import rospyif __name__ == "__main__":rospy.init_node("delete_param_p")try:rospy.delete_param("p_int")except Exception as e:rospy.loginfo("删除失败")

疑惑(待解决):参数服务器的发布方和调用方可以相同吗?就是A先向ROS Master设置参数,然后A之后可以调用所设置的参数吗?

参考:
[1]Autolabor-ROS机器人入门课程《ROS理论与实践》季基础教程
[2]【Autolabor初级教程】ROS机器人入门
[3]胡春旭.ROS机器人开发实践[M].机械工业出版社,2018.

http://www.lryc.cn/news/256617.html

相关文章:

  • 在github中通过action自动化部署 hugo academic theme,实现上传md文件更新博客内容
  • 深入理解asyncio:异步编程的基础用法
  • Android 消息分发机制解读
  • 【ML】LSTM应用——预测股票(基于 tensorflow2)
  • 汇编语言程序设计实验报告
  • 广域网(WAN)设备通信过程(通信流程、通信步骤、通信顺序、设备通信、主机通信)(MAC地址在本地链路中的作用)跳跃(hop)
  • ExoPlayer架构详解与源码分析(10)——H264Reader
  • 智能优化算法应用:基于粒子群算法3D无线传感器网络(WSN)覆盖优化 - 附代码
  • 微积分-序言
  • ArchLinux安装详细步骤
  • react 学习笔记 李立超老师 | (学习中~)
  • Docker镜像和容器的简单操作
  • 章鱼网络进展月报 | 2023.11.1-11.30
  • 基于Maven构建OSGI应用(Maven和OSGI结合)
  • oracle分组排序后取第一条
  • MAMBA介绍:一种新的可能超过Transformer的AI架构
  • win系统一台电脑安装两个不同版本的mysql教程
  • esp32-s3部署yolox_nano进行目标检测
  • TCP传输数据的确认机制
  • 使用Ansible Expect模块实现自动化交互式任务
  • 51单片机独立按键以及矩阵按键的使用以及其原理--独立按键 K1 控制 D1 指示灯亮灭以及数码管显示矩阵按键 S1-S16 按下后键值 0-F
  • chrome安装jsonview
  • 使用TouchSocket适配一个c++的自定义协议
  • VSC改造MD编辑器及图床方案分享
  • SpringBoot的依赖管理和自动配置
  • linux 定时任务
  • 增强现实中的真实人/机/环与虚拟人/机/环
  • Python网络爬虫环境的安装指南
  • 【MyBatis系列】MyBatis字符串问题
  • 【Java】构建表达式二叉树和表达式二叉树求值