参数服务器是以参数共享模式实现的,参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器,可以将数据存储在该容器中,被不同的节点调用,当然不同的节点也可以往其中存储数据。参数服务器,一般适用于存在数据共享的一些应用场景。
注意:参数服务器不是为高性能而设计的,因此最好用于存储静态的非二进制的简单数据。
一、参数服务器理论模型图
二、角色
参数服务器实现是三种通信机制中最为简单的,该模型如下图所示,该模型中涉及到三个角色:
- ROS Master (管理者)
- Talker (参数设置者)
- Listener (参数调用者)
ROS Master 作为一个公共容器保存参数,Talker 可以向容器中设置参数,Listener 可以获取参数。
三、流程
1、Talker 设置参数
setParam("foo",1)
Talker 通过 RPC 向参数服务器发送参数(包括参数名与参数值),ROS Master 将参数保存到参数列表中。
2、Listener 请求获取参数
getParam("foo")
Listener 通过 RPC 向参数服务器发送参数查找请求,请求中包含要查找的参数名。
3、ROS Master 向 Listener 发送参数值
{foo:1}
ROS Master 根据步骤2请求提供的参数名查找参数值,并将查询结果通过 RPC 发送给 Listener。
四、C++实现参数服务器参数的增删改查操作
ros在NodeHandle和param下都有一套增删改查的命令。
4.1 参数服务器增、改参数
#include "ros/ros.h"/*需要实现参数的新增和修改需求:首先设置机器人的共享参数,“名字”、“半径”再修改半径实现:1、ros::NodeHandlesetParam("键",值)2、ros::paramset("键","值")
*/int main(int argc, char *argv[])
{/* code */setlocale(LC_ALL,"");//初始化节点ros::init(argc,argv,"add_modify_param");//创建节点句柄ros::NodeHandle nh;//---------参数增-----------//方案1、nhnh.setParam("name","robot1");nh.setParam("radius",0.15);//方案2、ros::paramros::param::set("name_param","robot2");ros::param::set("radius_param",0.2);//---------参数改:其实就是用增的命令覆盖原来的数据-----------//方案1、nh// nh.setParam("radius",0.155);//方案2、ros::param// ros::param::set("radius_param",0.25);return 0;
}
4.2 参数服务器获取参数
#include "ros/ros.h"/*参数查询实现:1、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存储搜索结果的变量2、ros::param ----- 与 NodeHandle 类似*/int main(int argc, char *argv[])
{/* code */setlocale(LC_ALL,"");ros::init(argc,argv,"get_param");ros::NodeHandle nh;//ros::NodeHandle------------------//1、param(键,默认值)double radius = nh.param("radius",0.5);ROS_INFO("1/ radius = %.2f",radius);//2、getParam(键,存储结果的变量)//3、getParamCached(键,存储结果的变量)double radius2;//bool result = nh.getParam("radius",radius2);bool result = nh.getParamCached("radius",radius2);if(result){ROS_INFO("2/3/ radius = %.2f",radius);}else{ROS_INFO("查询变量不存在!");}//4、getParamNames(std::vector<std::string>)std::vector<std::string> names;nh.getParamNames(names);for(auto &&name : names){ROS_INFO("4/ 遍历到的元素:%s",name.c_str());}//5、hasParam(键)bool flag1 = nh.hasParam("radius");bool flag2 = nh.hasParam("radiuss");ROS_INFO("5/ radius 存在吗?%d",flag1);ROS_INFO("5/ radiuss 存在吗?%d",flag2);//6、searchParam(参数1,参数2)std::string key;nh.searchParam("radius",key);ROS_INFO("6/ 搜索结果:%s",key.c_str());return 0;
}
4.3 参数服务器删除参数
#include "ros/ros.h"
/*参数删除:1、ros::NodeHandledelParam()删除成功true删除失败false2、ros::paramdel()
*/int main(int argc, char *argv[])
{/* code */setlocale(LC_ALL,"");ros::init(argc,argv,"del_param");ros::NodeHandle nh;//NodeHandle-------------------------//1、delParam()bool flag1 = nh.deleteParam("radius");if(flag1){ROS_INFO("radius删除成功");}else{ROS_INFO("radius删除失败");}//parambool flag2 = ros::param::del("radius_param");if(flag2){ROS_INFO("radius_param删除成功");}else{ROS_INFO("radius_param删除失败");}return 0;
}