【ROS】ros学习笔记(6)——参数服务器
2026/7/17 4:03:44 网站建设 项目流程

ros学习笔记(6)——参数服务器

  • 一、参数服务器理论模型
  • 二、参数服务器操作
    • 2.1参数服务器新增(修改)参数
      • 2.1.1 写cpp文件
      • 2.1.2 修改CMake
      • 2.1.3 实验效果
    • 2.2 参数服务器获取参数
      • 2.2.1 写cpp文件
        • 2.2.1.1 问题排查
      • 2.2.2 修改CMake
      • 2.2.3 实验效果
    • 2.3 参数服务器删除参数
      • 2.3.1 写cpp文件
      • 2.3.2 修改CMake
      • 2.3.3 实验效果

一、参数服务器理论模型

参数服务器实现是最为简单的,该模型如下图所示,该模型中涉及到三个角色:

  • 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

  • 字典

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

二、参数服务器操作

需求:实现参数服务器参数的增删改查操作。

在 C++ 中实现参数服务器数据的增删改查,可以通过两套 API 实现:

ros::NodeHandle

ros::param

下面为具体操作演示

2.1参数服务器新增(修改)参数

2.1.1 写cpp文件

在功能包下面的src添加cpp文件

#include"ros/ros.h"/* 需要实现参数的新增和修改 需求:首先设置机器人共享参数,类型,半径(0.15m) 再修改半径(0.2m) 实现: ros::NodeHandle setParam() ros::param set() 修改,只需要继续调用函数,保证键是已经存在的,那么值会覆盖 */intmain(intargc,char*argv[]){//初始化ros节点ros::init(argc,argv,"demo01_param_set");//创建ros节点句柄ros::NodeHandle nh;//参数增---------------//方案一:nhnh.setParam("car_type","xaiomisu7");nh.setParam("car_radius",0.15);//方案二:ros::paramros::param::set("type_param","xiaomisu8");ros::param::set("radius_param",0.15);//参数改---------------//方案一:nhnh.setParam("car_radius",0.2);//其实是参数的覆盖//方案二:ros::paramros::param::set("car_radius",0.25);return0;}

2.1.2 修改CMake

添加add_executabletarget_link_libraries函数。分别在136行和149-151行

add_executable(demo01_param_set src/demo01_param_set.cpp)
target_link_libraries(demo01_param_set ${catkin_LIBRARIES} )

2.1.3 实验效果

编译

启动ros

source一下然后rosrun

source./devel/setup.bash rosrun plumbing_permit_sever demo01_param_set


开一个新终端source一下,然后用rosparam list可以列出现在的参数列表rosparam get 参数名可以看到具体参数

source./devel/setup.bash rosparam list rosparam get car_radius

2.2 参数服务器获取参数

2.2.1 写cpp文件

在功能包下的src目录下添加cpp文件
内容如下:

#include"ros/ros.h"/* 演示参数查询 实现: 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 类似 */intmain(intargc,char*argv[]){//设置编码setlocale(LC_ALL,"");//初始化ros节点ros::init(argc,argv,"param_get");//创建节点句柄ros::NodeHandle nh;//ros::NodeHandle------------------------------//1.paramdoubleradius=nh.param("radius",10);ROS_INFO("半径是 = %.2f",radius);//2.getParamdoubleradius2=0.0;boolresult=nh.getParam("radius_param",radius2);if(result){ROS_INFO("getParam获取的半径是 = %.2f",radius2);}else{ROS_INFO("getParam获取失败");}//3.getParamCached//getParamCached 和 getParam一样,只是在性能上有提升,一般的测试性能提升肉眼不可见// double radius2 = 0.0;// bool result = nh.getParamCached("radius_param",radius2);if(result){ROS_INFO("getParamCached获取的半径是 = %.2f",radius2);}else{ROS_INFO("getParamCached获取失败");}//4.getParamNamesstd::vector<std::string>names;nh.getParamNames(names);for(auto&&name:names){ROS_INFO("遍历的元素:%s",name.c_str());}//5.hasParamboolflag1=nh.hasParam("radius_param");boolflag2=nh.hasParam("radius");ROS_INFO("radius_param是否存在:%d",flag1);ROS_INFO("radius是否存:%d",flag2);//6.searchParamstd::string key1;std::string key2;nh.searchParam("radius_param",key1);nh.searchParam("radius",key2);ROS_INFO("搜索的结果 = %s",key1.c_str());ROS_INFO("搜索的结果 = %s",key2.c_str());return0;}
2.2.1.1 问题排查

在看着老师的视频跟练第二个的时候

//ros::NodeHandle------------------------------//1.paramdoubleradius=nh.param("radius",10);ROS_INFO("半径是 = %.2f",radius);//2.getParamdoubleradius2=0.0;boolresult=nh.getParam("radius",radius2);if(result){ROS_INFO("getParam获取的半径是 = %.2f",radius2);}else{ROS_INFO("getParam获取失败");}

运行结果是

这是因为:
代码查找的是/radius,但参数服务器里实际存在的是/radius_param,它们不是同一个参数。

看一下参数列表

rosparam list


参数应该是:

/radius_param

而代码是:

doubleradius2=0.0;boolresult=nh.getParam("radius",radius2);

普通节点句柄:

ros::NodeHandle nh;

会把"radius"解析成全局参数:

/radius

由于参数服务器没有/radius,所以:

result==false

于是程序输出:

获取失败

为什么上一行还能显示 10?

doubleradius=nh.param("radius",10);

param()getParam()的行为不同:

nh.param("radius",10);

意思是:

尝试获取/radius,获取不到就使用默认值10

所以输出10.00并不代表成功读取到了参数,而是使用了默认值。

而:

nh.getParam("radius",radius2);

没有提供默认值,找不到就返回false

2.2.2 修改CMake

添加add_executabletarget_link_libraries函数。分别在136行和149-151行

add_executable(demo01_param_get src/demo01_param_get.cpp)
target_link_libraries(demo01_param_get ${catkin_LIBRARIES} )

2.2.3 实验效果

编译

启动ros

source一下然后rosrun

source./devel/setup.bash rosrun plumbing_permit_sever demo01_param_get

2.3 参数服务器删除参数

2.3.1 写cpp文件

在功能包下的src目录下添加cpp文件
内容如下:

#include"ros/ros.h"/* 演示参数的删除: 实现: ros::NodeHandle deleteParam() ros::param del() */intmain(intargc,char*argv[]){setlocale(LC_ALL,"");ros::init(argc,argv,"param_del");ros::NodeHandle nh;//删除:ros::NodeHandle-----------------boolflag1=nh.deleteParam("radius_param");if(flag1){ROS_INFO("deleteParam删除radius_param成功");}else{ROS_INFO("deleteParam删除radius_param失败");}boolflag2=nh.deleteParam("radius");if(flag2){ROS_INFO("deleteParam删除radius成功");}else{ROS_INFO("deleteParam删除radius失败");}//删除:ros::param----------------------boolflag3=ros::param::del("car_type");if(flag3){ROS_INFO("ros::param::del删除car_type成功");}else{ROS_INFO("ros::param::del删除car_type失败");}boolflag4=ros::param::del("type");if(flag4){ROS_INFO("ros::param::del删除type成功");}else{ROS_INFO("ros::param::del删除type失败");}return0;}

2.3.2 修改CMake

添加add_executabletarget_link_libraries函数。分别在136行和149-151行

add_executable(demo01_param_del src/demo01_param_del.cpp)
target_link_libraries(demo01_param_del ${catkin_LIBRARIES} )

2.3.3 实验效果

编译

启动ros

source一下然后rosrun

source./devel/setup.bash rosrun plumbing_permit_sever demo01_param_del

开一个新终端source一下,

rosparam list一下,看到去试试被删除了

学习的为赵虚左老师的教程 1.老师的文档 2.老师的视频
在笔记上理论部分大量参考了老师的文档

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询