前言
参数服务器可以简单理解为全局变量,实现数据在各个节点间共享。参数服务器的数据采用key-value的方式进行存入和取出。
本案例使用参数服务器在多个节点间实现增删改查。
一、代码编写
1、在功能包下的src目录中分别创建param_set.cpp、param_get.cpp、param_del.cpp
2、编写CmakeLists.txt
add_executable(param_set src/param_set.cpp)
add_executable(param_get src/param_get.cpp)
add_executable(param_del src/param_del.cpp)
target_link_libraries(param_set
${catkin_LIBRARIES}
)
target_link_libraries(param_get
${catkin_LIBRARIES}
)
target_link_libraries(param_del
${catkin_LIBRARIES}
)
3、向参数服务器中设置参数和修改参数(编写param_set.cpp)
设置参数有2种方式:
1、调用NodeHandle下的setParam()函数
2、调用ros命名空间下的ros::param::set()函数
修改参数与设置参数调用方式一样,键一样时,值会覆盖
#include "ros/ros.h"
int main(int argc, char *argv[])
{
//初始化ros节点
ros::init(argc,argv,"param_set");
//创建节点句柄
ros::NodeHandle nh;
//------------第一种方式:nh.param设置--------------
nh.setParam("name","sun");
nh.setParam("age",24);
//------------第二种方式:ros::param::set设置--------------
//ros::param::set("name","sun");
//ros::param::set("age",24);
//修改参数(与设置参数一样,键一样时,值会覆盖)
nh.setParam("age",25);
//或
// ros::param::set("age",25);
return 0;
}
4、从参数服务器中获取参数(编写param_get.cpp)
根据key获取对应的value调用param()的2种方式:
1、调用NodeHandle下的param()函数
2、调用ros命名空间下的ros::param::param()函数
#include "ros/ros.h"
int main(int argc, char *argv[])
{
//初始化ros节点
ros::init(argc,argv,"param_get");
//创建节点句柄对象
ros::NodeHandle nh;
//------------第一种方式:nh.param获取--------------
//查找键为age的值,如果存在则返回,如果不存在则返回20
int age1 = nh.param("age",20);//参数服务器中存在age,返回age为25
//查找键为height的值,如果存在则返回,如果不存在则返回180
int height1 = nh.param("height",180);//参数服务器中并不存在height,所以返回180
ROS_INFO("param_get:age:%d,height:%d",age1,height1);
//------------第二种方式:ros::param::param获取--------------
//int age2 = ros::param::param("age",20);
//int height2 = ros::param::param("height",180);
//ROS_INFO("param_get:age:%d,height:%d",age2,height2);
return 0;
}
根据key获取对应的value并返回结果的2种方式:
1、调用NodeHandle下的getParam()函数
2、调用ros命名空间下的ros::param::get()函数
#include "ros/ros.h"
int main(int argc, char *argv[])
{
//初始化ros节点
ros::init(argc,argv,"param_get");
//创建节点句柄对象
ros::NodeHandle nh;
//------------第一种方式:nh.getParam获取--------------
int age1 = 0;
//存在返回true,并将结果存在age中,否则返回false,结果为空
bool ret1 = nh.getParam("age",age1);
if(ret1 == true)
{
//存在
ROS_INFO("param_get:age:%d",age1);
}
else
{
//不存在该键
ROS_INFO("The key does not exist!");
}
//------------第二种方式:ros::param::get获取--------------
//int age2 = 0;
//存在返回true,并将结果存在age中,否则返回false,结果为空
//bool ret2 = ros::param::get("age",age2);
//if(ret2 == true)
//{
//存在
// ROS_INFO("param_get:age:%d",age2);
//}
//else
//{
//不存在该键
// ROS_INFO("The key does not exist!");
//}
return 0;
}
根据key获取对应的value并返回结果的2种方式:
1、调用NodeHandle下的getParamCached()函数
2、调用ros命名空间下的ros::param::getCached()函数
相比上一种getParam()和os::param::get()来说,此函数效率更高
#include "ros/ros.h"
int main(int argc, char *argv[])
{
//初始化ros节点
ros::init(argc,argv,"param_get");
//创建节点句柄对象
ros::NodeHandle nh;
//------------第一种方式:nh.getParamCached获取--------------
int age1 = 0;
//存在返回true,并将结果存在age中,否则返回false,结果为空
bool ret1 = nh.getParamCached("age",age1);
if(ret1 == true)
{
//存在
ROS_INFO("param_get:age:%d",age1);
}
else
{
//不存在该键
ROS_INFO("The key does not exist!");
}
//------------第二种方式:ros::param::getCached获取--------------
//int age2 = 0;
//存在返回true,并将结果存在age中,否则返回false,结果为空
//bool ret2 = ros::param::getCached("age",age2);
//if(ret2 == true)
//{
//存在
// ROS_INFO("param_get:age:%d",age2);
//}
//else
//{
//不存在该键
// ROS_INFO("The key does not exist!");
//}
return 0;
}
获取所有key的2种方式:
1、调用NodeHandle下的getParamNames()函数
2、调用ros命名空间下的ros::param::getParamNames()函数
#include "ros/ros.h"
int main(int argc, char *argv[])
{
//初始化ros节点
ros::init(argc,argv,"param_get");
//创建节点句柄对象
ros::NodeHandle nh;
//------------第一种方式:nh.getParamNames获取所有的键--------------
//首先定义一个vector来存所有的key
std::vector<std::string> names;
//获取所有的key
nh.getParamNames(names);
for(auto &&name : names)
{
ROS_INFO("name = %s",name.c_str());
}
//------------第二种方式:ros::param::getParamNames获取所有的键--------------
//首先定义一个vector来存所有的key
//std::vector<std::string> names;
//获取所有的key
//ros::param::getParamNames(names);
//for(auto &&name : names)
//{
// ROS_INFO("name = %s",name.c_str());
//}
return 0;
}
查询key是否存在的2种方式存在返回true,否则返回false:
1、调用NodeHandle下的hasParam()函数
2、调用ros命名空间下的ros::param::has()函数
#include "ros/ros.h"
int main(int argc, char *argv[])
{
//初始化ros节点
ros::init(argc,argv,"param_get");
//创建节点句柄对象
ros::NodeHandle nh;
//------------第一种方式:nh.hasParam查找键是否存在--------------
//如果键存在返回true
bool ret = nh.hasParam("age");
//------------第二种方式:ros::param::has查找键是否存在--------------
//如果键存在返回true
//bool ret = ros::param::has("age");
return 0;
}
根据key查找key是否存在,并输出key的名称的2种方式:
1、调用NodeHandle下的searchParam()函数
2、调用ros命名空间下的ros::param::search()函数
#include "ros/ros.h"
int main(int argc, char *argv[])
{
//初始化ros节点
ros::init(argc,argv,"param_get");
//创建节点句柄对象
ros::NodeHandle nh;
//------------第一种方式:nh.searchParam 查找键并输出键的名称--------------
std::string key;
nh.searchParam("age",key);
ROS_INFO("search key:%s",key.c_str());
//------------第二种方式:ros::param::search查找键并输出键的名称--------------
//std::string key;
//ros::param::search("age",key);
//ROS_INFO("search key:%s",key.c_str());
return 0;
}
5、从参数服务器中删除参数(编写param_del.cpp)
删除key的2种方式:
1、调用NodeHandle下的deleteParam()函数
2、调用ros命名空间下的ros::param::del()函数
#include "ros/ros.h"
int main(int argc, char *argv[])
{
//初始化ros节点
ros::init(argc,argv,"param_del");
//创建节点句柄
ros::NodeHandle nh;
//--------------方式一 使用NodeHandle的deleteParam函数--------------
bool r1 = nh.deleteParam("name");
//--------------方式二 使用ros命名空间下的ros::param::del函数----------------
//bool r2 = ros::param::del("name");
return 0;
}
二、编译运行
1、vscode中 ctrl + shift + b编译
2、在工作空间目录下打开终端,依次运行以下四个程序:
- roscore
- rosrun param_server param_set //设置参数
- rosrun param_server param_get //获取参数
- rosrun param_server param_del //删除参数
注意:这里有可能运行时报错 “package xxxx not found”的错误。只需要在每个终端窗口中都运行一遍source ./devel/setup.bash ,再次运行时就没有报错了。
3、查看终端(左上为roscore,左下为param_set,右上为param_get ,右下为param_del。