参数服务器实现是最为简单的,该模型如下图所示,该模型中涉及到三个角色:
- 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
-
字典
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",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::NodeHandle param(键,默认值) 存在,返回对应结果,否则返回默认值 getParam(键,存储结果的变量) 存在,返回 true,且将值赋值给参数2 若果键不存在,那么返回值为 false,且不为参数2赋值 getParamCached键,存储结果的变量)--提高变量获取效率 存在,返回 true,且将值赋值给参数2 若果键不存在,那么返回值为 false,且不为参数2赋值 getParamNames(std::vector<std::string>) 获取所有的键,并存储在参数 vector 中 hasParam(键) 是否包含某个键,存在返回 true,否则返回 false searchParam(参数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::NodeHandle deleteParam("键") 根据键删除参数,删除成功,返回 true,否则(参数不存在),返回 false ros::param del("键") 根据键删除参数,删除成功,返回 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; }
在 ROS 同提供了一些实用的命令行工具,可以用于获取不同节点的各类信息,常用的命令如下:
- rosnode : 操作节点
- rostopic : 操作话题
- rosservice : 操作服务
- rosmsg : 操作msg消息
- rossrv : 操作srv消息
- rosparam : 操作参数
rosnode 是用于获取节点信息的命令
rosnode ping 测试到节点的连接状态 rosnode list 列出活动节点 rosnode info 打印节点信息 rosnode machine 列出指定设备上节点 rosnode kill 杀死某个节点 rosnode cleanup 清除不可连接的节点
rostopic包含rostopic命令行工具,用于显示有关ROS 主题的调试信息,包括发布者,订阅者,发布频率和ROS消息。它还包含一个实验性Python库,用于动态获取有关主题的信息并与之交互。
rostopic bw 显示主题使用的带宽 rostopic delay 显示带有 header 的主题延迟 rostopic echo 打印消息到屏幕 rostopic find 根据类型查找主题 rostopic hz 显示主题的发布频率 rostopic info 显示主题相关信息 rostopic list 显示所有活动状态下的主题 rostopic pub 将数据发布到主题 rostopic type 打印主题类型
rosmsg是用于显示有关 ROS消息类型的 信息的命令行工具。
rosmsg show 显示消息描述 rosmsg info 显示消息信息 rosmsg list 列出所有消息 rosmsg md5 显示 md5 加密后的消息 rosmsg package 显示某个功能包下的所有消息 rosmsg packages 列出包含消息的功能包
rosservice包含用于列出和查询ROSServices的rosservice命令行工具。
调用部分服务时,如果对相关工作空间没有配置 path,需要进入工作空间调用 source ./devel/setup.bash
rosservice args 打印服务参数 rosservice call 使用提供的参数调用服务 rosservice find 按照服务类型查找服务 rosservice info 打印有关服务的信息 rosservice list 列出所有活动的服务 rosservice type 打印服务类型 rosservice uri 打印服务的 ROSRPC uri
rossrv是用于显示有关ROS服务类型的信息的命令行工具,与 rosmsg 使用语法高度雷同。
rossrv show 显示服务消息详情 rossrv info 显示服务消息相关信息 rossrv list 列出所有服务信息 rossrv md5 显示 md5 加密后的服务消息 rossrv package 显示某个包下所有服务消息 rossrv packages 显示包含服务消息的所有包
rosparam包含rosparam命令行工具,用于使用YAML编码文件在参数服务器上获取和设置ROS参数。
rosparam set 设置参数 rosparam get 获取参数 rosparam load 从外部文件加载参数 rosparam dump 将参数写出到外部文件 rosparam delete 删除参数 rosparam list 列出所有参数