研究ROS参数服务器通信
目录
0.简介
参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器,可以将数据存储在该容器中,被不同的节点调用,当然不同的节点也可以往其中存储数据,关于参数服务器的典型应用场景如下:
导航实现时,会进行路径规划,比如: 全局路径规划,设计一个从出发点到目标点的大致路径。本地路径规划,会根据当前路况生成时时的行进路径
上述场景中,全局路径规划和本地路径规划时,就会使用到参数服务器:
路径规划时,需要参考小车的尺寸,我们可以将这些尺寸信息存储到参数服务器,全局路径规划节点与本地路径规划节点都可以从参数服务器中调用这些参数
参数服务器,一般适用于存在数据共享的一些应用场景。
概念:以共享的方式实现不同节点之间数据交互的通信模式。
作用:存储一些多节点共享的数据,类似于全局变量。
案例:实现参数增删改查操作。
另请参考:
http://wiki.ros.org/Parameter%20Server
http://wiki.ros.org/roscpp/Overview/Parameter%20Server
http://wiki.ros.org/rospy/Overview/Parameter%20Server
2.参数服务器理论模型
参数服务器实现是最为简单的,该模型如下图所示,该模型中涉及到三个角色: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
- 字典
注意:参数服务器不是为高性能而设计的,因此最好用于存储静态的非二进制的简单数据
3.参数服务器操作C++
需求:实现参数服务器参数的增删改查操作。
在 C++ 中实现参数服务器数据的增删改查,可以通过两套 API 实现:
- ros::NodeHandle
setParam() - ros::param
set()
参数服务器操作 | 描述 |
---|---|
参数增加 | 可以通过两套 API 实现:ros::NodeHandle::setParam()或ros::param::set() |
参数修改 | 只需要继续调用setParam()或set()函数,保证键是已经存在的,值会被覆盖 |
参数查询 | ros::NodeHandle::param(键,默认值)/getParam(键,存储结果的变量)/getParamCached键,存储结果的变量)/getParamNames(std::vector<std::string>)/hasParam(键)/searchParam(参数1,参数2 )//ros::param 方法与 NodeHandle 类似 |
下面为具体操作演示
3.1.参数服务器新增(修改)参数
/*
参数服务器操作之新增与修改(二者API一样)_C++实现:
在 roscpp 中提供了两套 API 实现参数操作
ros::NodeHandle
setParam("键",值)
ros::param
set("键","值")
示例:分别设置整形、浮点、字符串、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); //bool
nh.setParam("nh_string","hello NodeHandle"); //字符串
nh.setParam("nh_vector",stus); // vector
nh.setParam("nh_map",friends); // map
//修改演示(相同的键,不同的值)
nh.setParam("nh_int",