一.通过独立 demo 吃透所有核心 API,再迁移到项目中
1.目录结构
2.param_test.cpp
#include"ros/ros.h"intmain(intargc,char**argv){ros::init(argc,argv,"param_test_node");ros::NodeHandle nh;// 1. 向参数服务器写入参数 setParamnh.setParam("robot_name","patrol_bot_01");nh.setParam("max_speed",0.5);nh.setParam("patrol_mode",true);ROS_INFO("参数写入完成");// 2. 读取参数 getParam(读取失败返回false,不改变变量值)std::string name;doublespeed;boolmode;if(nh.getParam("robot_name",name))ROS_INFO("读取机器人名称:%s",name.c_str());elseROS_WARN("未找到参数 robot_name");if(nh.getParam("max_speed",speed))ROS_INFO("读取最大速度:%.2f m/s",speed);// 3. param() 读取参数,读取失败直接用默认值赋值(最常用)intpoint_num=nh.param("patrol_point_num",3);ROS_INFO("巡逻点数量:%d",point_num);// 4. 检查参数是否存在 hasParamif(nh.hasParam("battery_level"))ROS_INFO("电池电量参数存在");elseROS_WARN("电池电量参数不存在,使用默认值");// 5. 删除参数 deleteParamnh.deleteParam("patrol_mode");ROS_INFO("已删除参数 patrol_mode");ros::spinOnce();return0;}3.注意点
1.ros::init(argc,argv,“param_test_node”)
初始化节点 向roscore注册param_test_node节点
2.setParam()写入参数
// 1. 向参数服务器写入参数 setParamnh.setParam("robot_name","patrol_bot_01");nh.setParam("max_speed",0.5);nh.setParam("patrol_mode",true);ROS_INFO("参数写入完成");nh.setParam(“参数名”,值 )
作用:往参数服务器存一对【键值对】
参数可以是:字符串、小数、整数、布尔
如果这个参数本来不存在:直接新建;如果已经存在:直接覆盖旧值。
终端执行 rosparam list 就能看到这三个参数。
3.getParam () 读取参数,有返回值判断(读取失败不会修改变量)
bool getParam(“参数名”, 接收变量)
// 2. 读取参数 getParam(读取失败返回false,不改变变量值)std::string name;doublespeed;boolmode;if(nh.getParam("robot_name",name))ROS_INFO("读取机器人名称:%s",name.c_str());elseROS_WARN("未找到参数 robot_name");返回值:读到参数返回 true;找不到参数返回 false
重点:读取失败的时候,name变量里面的值不会被修改,保留原来垃圾值。
适合场景:必须要读到这个参数,读不到节点要告警。
4.param () 带默认值读取 有这个参数就直接读取 没有直接赋值默认值
nh.param(“参数名”, 默认值)
// 3. param() 读取参数,读取失败直接用默认值赋值(最常用)intpoint_num=nh.param("patrol_point_num",3);ROS_INFO("巡逻点数量:%d",point_num);逻辑:
如果参数服务器存在patrol_point_num → 读出真实值给point_num
如果参数不存在 → 直接把 3 赋值给 point_num,不会报错
本代码里我们没有 set 这个参数,所以这里输出一定是 3。
实际项目大量用这个:参数 hasParam () 判断参数是否存在可以 launch 文件配置,不配置就安全走默认,程序不会崩。
5. hasParam () 判断参数是否存在
// 4. 检查参数是否存在 hasParamif(nh.hasParam("battery_level"))ROS_INFO("电池电量参数存在");elseROS_WARN("电池电量参数不存在,使用默认值");bool hasParam(“参数名”)
返回 true:参数服务器里面有这个参数
返回 false:没有这个参数
这里代码没有设置battery_level,所以会打印警告。
一般搭配getParam使用,先判断有没有,再读取。
6.deleteParam () 删除参数
// 5. 删除参数 deleteParamnh.deleteParam("patrol_mode");ROS_INFO("已删除参数 patrol_mode");直接把参数服务器上patrol_mode删掉。
执行完之后 rosparam get /patrol_mode 就找不到该参数。
7.5 个 API 记忆口诀
setParam:写参数,没有就新建,有就覆盖
getParam:读参数,返回真假,失败变量不变
param:读参数,读不到就给默认值(项目首选)
hasParam:单纯判断参数有没有
deleteParam:删掉参数服务器的参数
重要坑点
参数服务器在 roscore,roscore 一关,全部参数灰飞烟灭,不会保存到磁盘
节点退出,自己 setParam 写进去的参数还在,只要 roscore 不关闭
变量类型必须匹配:存 double,不能读到 int,会出错。