目录
参考:赵虚左的课程+古月的ROS机器人开发实践
参数管理机制原理图

其中通信机制不涉及TCP/UDP通信,用的是RPC,导致低性能,故参数最好是存储静态的非二进制的简单数据。
实现目的:对参数服务器数据增删改查。
- #include "ros/ros.h"
-
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- ros::init(argc,argv,"set_param_c");
- ros::NodeHandle n;
- n.setParam("zhonglei","zhonglei_neirong_1");
- n.setParam("banjing",0.15);
- ros::param::set("zhonglei_1","zhonglei_neirong_2");
- ros::param::set("banjing_1",0.18);
- ROS_INFO("参数服务器参数增加成功!");
- return 0;
- }
setlocale(LC_ALL,"");
防止中文乱码。
- ros::init(argc,argv,"set_param_c");
- ros::NodeHandle n;
初始化节点,初始化句柄。
- n.setParam("zhonglei","zhonglei_neirong_1");
- n.setParam("banjing",0.15);
- ros::param::set("zhonglei_1","zhonglei_neirong_2");
- ros::param::set("banjing_1",0.18);
- ROS_INFO("参数服务器参数增加成功!");
两种增加参数方式:
- ros::NodeHandle n;
- n.setParam("zhonglei","zhonglei_neirong_1");
- n.setParam("banjing",0.15);
- ros::param::set("zhonglei_1","zhonglei_neirong_2");
- ros::param::set("banjing_1",0.18);
ROS_INFO("参数服务器参数增加成功!");
控制台输出。
- add_executable(demo01_param_set src/demo01_param_set.cpp)
- target_link_libraries(demo01_param_set
- ${catkin_LIBRARIES}
- )
rosparam list
- /banjing
- /banjing_1
- /rosdistro
- /roslaunch/uris/host_rosmelodic_virtual_machine__34955
- /rosversion
- /run_id
- /zhonglei
- /zhonglei_1
其中如下是系统自带的参数
- /rosdistro
- /roslaunch/uris/host_rosmelodic_virtual_machine__34955
- /rosversion
- /run_id
增加部分,键的查看
- /banjing
- /banjing_1
- /zhonglei
- /zhonglei_1
值的查看
rosparam get /banjing
![]()
- n.setParam("banjing",0.15);
- n.setParam("banjing",0.33);
- ros::param::set("banjing_1",0.18);
- ros::param::set("banjing_1",0.30);
键是之前存在的,利用覆盖来进行修改。键之前不存在,会增加一对键和值。
利用之前的方法
rosparam list
rosparam get /????

创建demo01_param_get.cpp
- #include "ros/ros.h"
-
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- ros::init(argc,argv,"get_param_c");
- ros::NodeHandle n;
- double jiaodu = n.param("banjing", 1.25);
- double jiaoduu = n.param("banjing_2",2.25);
- ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
- return 0;
- }
主要操作
- ros::init(argc,argv,"get_param_c");
- ros::NodeHandle n;
- double jiaodu = n.param("banjing", 1.25);
其中读取利用n.param,第一个参数为键名,第二个参数是没找到键名时给的默认值。
double jiaoduu = n.param("banjing_2",2.25);
故意找不到,看看是否输出默认值。
CMakeList.txt配置
- add_executable(demo01_param_get src/demo01_param_get.cpp)
- target_link_libraries(demo01_param_get
- ${catkin_LIBRARIES}
- )
编译+rosrun运行

其中banjing键输出了修改后的值,而banjing_2由于之前没增加,故读取默认值。
- #include "ros/ros.h"
-
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- ros::init(argc,argv,"get_param_c");
- ros::NodeHandle n;
-
- double jiaodu = n.param("banjing", 1.25);
- double jiaoduu = n.param("banjing_2",2.25);
- ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
-
- double jiaodu_1 = 0.0;
- bool result = n.getParam("banjing",jiaodu_1);
- if (result)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_1);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
-
- double jiaodu_2 = 0.0;
- bool result1 = n.getParam("banjingg",jiaodu_2);
- if (result1)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_2);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
- return 0;
- }
关键部分
- double jiaodu_1 = 0.0;
- bool result = n.getParam("banjing",jiaodu_1);
- if (result)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_1);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
getParam函数,参数为要查询的键名和值的赋值对象。返回值是布尔类型,判断是否查询成功。
同时也测试了没找到键名的情况。
编译+rosrun运行

和getParamCached用法一样,但是性能提升了。
- #include "ros/ros.h"
-
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- ros::init(argc,argv,"get_param_c");
- ros::NodeHandle n;
-
- double jiaodu = n.param("banjing", 1.25);
- double jiaoduu = n.param("banjing_2",2.25);
- ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
-
- double jiaodu_1 = 0.0;
- bool result = n.getParamCached("banjing",jiaodu_1);
- if (result)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_1);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
-
- double jiaodu_2 = 0.0;
- bool result1 = n.getParamCached("banjingg",jiaodu_2);
- if (result1)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_2);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
- return 0;
- }
编译+rosrun运行

- #include "ros/ros.h"
-
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- ros::init(argc,argv,"get_param_c");
- ros::NodeHandle n;
-
- double jiaodu = n.param("banjing", 1.25);
- double jiaoduu = n.param("banjing_2",2.25);
- ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
-
- double jiaodu_1 = 0.0;
- bool result = n.getParamCached("banjing",jiaodu_1);
- if (result)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_1);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
-
- double jiaodu_2 = 0.0;
- bool result1 = n.getParamCached("banjingg",jiaodu_2);
- if (result1)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_2);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
-
- std::vector
names; - n.getParamNames(names);
- for (auto &&name : names)
- {
- ROS_INFO("遍历到的元素:%s",name.c_str());
- }
- return 0;
- }
关键部分
- std::vector
names; - n.getParamNames(names);
- for (auto &&name : names)
- {
- ROS_INFO("遍历到的元素:%s",name.c_str());
- }
通过gatParamNames读取所有的键名,并保存在names中。
编译+rosrun运行

- #include "ros/ros.h"
-
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- ros::init(argc,argv,"get_param_c");
- ros::NodeHandle n;
-
- double jiaodu = n.param("banjing", 1.25);
- double jiaoduu = n.param("banjing_2",2.25);
- ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
-
- double jiaodu_1 = 0.0;
- bool result = n.getParamCached("banjing",jiaodu_1);
- if (result)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_1);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
-
- double jiaodu_2 = 0.0;
- bool result1 = n.getParamCached("banjingg",jiaodu_2);
- if (result1)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_2);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
-
- std::vector
names; - n.getParamNames(names);
- for (auto &&name : names)
- {
- ROS_INFO("遍历到的元素:%s",name.c_str());
- }
-
- bool cunzai1 = n.hasParam("banjing");
- bool cunzai2 = n.hasParam("banjingg");
- ROS_INFO("banjing存在?%d,banjingg存在?%d",cunzai1,cunzai2);
- return 0;
- }
关键部分
- bool cunzai1 = n.hasParam("banjing");
- bool cunzai2 = n.hasParam("banjingg");
- ROS_INFO("banjing存在?%d,banjingg存在?%d",cunzai1,cunzai2);
- return 0;
查找键名,并返回布尔值,判断键的存在。
编译+rosrun运行

- #include "ros/ros.h"
-
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- ros::init(argc,argv,"get_param_c");
- ros::NodeHandle n;
-
- double jiaodu = n.param("banjing", 1.25);
- double jiaoduu = n.param("banjing_2",2.25);
- ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
-
- double jiaodu_1 = 0.0;
- bool result = n.getParamCached("banjing",jiaodu_1);
- if (result)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_1);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
-
- double jiaodu_2 = 0.0;
- bool result1 = n.getParamCached("banjingg",jiaodu_2);
- if (result1)
- {
- ROS_INFO("获取的参数为:%.2f",jiaodu_2);
- }
- else
- {
- ROS_INFO("被查询的变量不存在。");
- }
-
- std::vector
names; - n.getParamNames(names);
- for (auto &&name : names)
- {
- ROS_INFO("遍历到的元素:%s",name.c_str());
- }
-
- bool cunzai1 = n.hasParam("banjing");
- bool cunzai2 = n.hasParam("banjingg");
- ROS_INFO("banjing存在?%d,banjingg存在?%d",cunzai1,cunzai2);
-
- std::string key;
- n.searchParam("banjing",key);
- ROS_INFO("搜索结果:%s",key.c_str());
- return 0;
- }
关键部分
- std::string key;
- n.searchParam("banjing",key);
- ROS_INFO("搜索结果:%s",key.c_str());
- return 0;
编译+rosrun运行

7.第7种方式 ros::param::xxxxx

根据代码提示与句柄的方式一一对应,而且这种方式与句柄的方式使用方法相同。
把刚刚创建的没意义的键与值删除掉
rosparam list

用两种方式删除掉
- /banjing
- /banjing_1
- /zhonglei
- /zhonglei_1
- #include "ros/ros.h"
-
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- ros::init(argc,argv,"del_param_c");
- ros::NodeHandle n;
-
- bool flag1 = n.deleteParam("banjing");
- if(flag1)
- {
- ROS_INFO("删除成功");
- }
- else
- {
- ROS_INFO("删除失败");
- }
-
- return 0;
- }
关键部分
- ros::NodeHandle n;
-
- bool flag1 = n.deleteParam("banjing");
句柄的方式,调用deleteParam函数,其中参数为键名,返回值为是否删除成功的布尔值。
CMakeList.txt配置
- add_executable(demo01_param_del src/demo01_param_del.cpp)
- target_link_libraries(demo01_param_del
- ${catkin_LIBRARIES}
- )
编译+rosrun运行
![]()
看看是否删除成功
rosparam list

- #include "ros/ros.h"
-
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- ros::init(argc,argv,"del_param_c");
- ros::NodeHandle n;
-
- bool flag1 = n.deleteParam("banjing");
- if(flag1)
- {
- ROS_INFO("删除成功");
- }
- else
- {
- ROS_INFO("删除失败");
- }
- bool flag2 = ros::param::del("banjing_1");
- if(flag2)
- {
- ROS_INFO("第二种方法删除成功");
- }
- else
- {
- ROS_INFO("第二种方法删除失败");
- }
- return 0;
- }
此程序在上一个程序上修改,而且在上一个程序运行后运行,由上一个程序结果可知banjing节点已经删除了,故再次删除就会由于找不到键,而导致删除失败。
关键部分
bool flag2 = ros::param::del("banjing_1");
参数为键名,返回值为是否删除成功的布尔值。
编译+rosrun运行

结果符合预期。
下一步把剩下两个键也给删掉,使ros的参数服务器参数回到初始状态。
- #include "ros/ros.h"
-
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- ros::init(argc,argv,"del_param_c");
- ros::NodeHandle n;
-
- bool flag1 = n.deleteParam("zhonglei");
- if(flag1)
- {
- ROS_INFO("删除成功");
- }
- else
- {
- ROS_INFO("删除失败");
- }
- bool flag2 = ros::param::del("zhonglei_1");
- if(flag2)
- {
- ROS_INFO("第二种方法删除成功");
- }
- else
- {
- ROS_INFO("第二种方法删除失败");
- }
- return 0;
- }
