参数服务器(parameter server)是节点管理器(Master)的一部分,并且允许系统将数据或配置信息保存在关键位置,所有的节点可以获取这些数据来配置、改变自己的状态。
参数可以认为是节点中使用的全局变量,用途与Windows程序中的*.ini配置文件非常类似。默认情况下,这些设置值是指定的,有需要时可以从外部读取或写入参数。特别是,由于可以通过使用来自外部的写入功能来实时地改变设置值,因此它是非常有用的,因为它可以灵活地应对多变的情况。例如,可以指定与外部设备连接的PC的USB端口、相机校准值、电机速度或命令的最大值和最小值等设置值。
命令 | 详细说明 |
---|---|
rosparam list | 查看参数列表 |
rosparam get [参数名称] | 获取参数值 |
rosparam set [参数名称] | 设置参数值 |
rosparam dump [文件名称] | 将参数保存到指定文件 |
rosparam load [文件名称] | 获取保存在指定文件中的参数 |
rosparam delete [参数名称] | 删除参数通信模型 |
ROS Master(管理者)
Talker (参数设置者)
Listener (参数调用者)
参考:ROS Wiki
有两套API可以实现参数的操作,两者的使用基本完全一样:
下面仅使用ros::NodeHandle来记录两种主要的操作方法:
使用set和get函数可以向参数服务器写入和读取参数,setParam和getParam有多个函数的重载,主要区别在于参数2的类型,这里只选取了两个来做说明
参数是以键值对的方式存储的,参数1为写入的参数名称(字符串类型),参数2为写入参数的值(对应上面的参数类型)
参数1为参数服务器中的键,参数2为查询到的参数值,可以赋值给本地变量来使用
这里使用了类模板,函数主要功能是:通过参数1到参数服务器查找该字段对应的值,找到的话则赋值给参数2,未找到则使用参数3(默认值)。和方式一相比,这里多了一个默认值
参考:ROS Wiki、ROS API
在launch文件中,可以通过标签来设置参数名称、类型、值等,launch文件执行后,parameter就加载到ROS的参数服务器上了,可以通过
来从yaml
文件中加载参数。在实际项目中,通常会在launch文件中设置参数,在程序代码中获取参数
<launch>
<!-- 直接设置参数 -->
<param name="name" value="张三" type="string"/>
<param name="age" value="10" type="int"/>
<!-- 从yaml文件加载参数 -->
<rosparam command="load" file="$(find param_test)/cfg/test.yaml"/>
</launch>
需求描述:简单的API调用,向参数服务器写入参数,从参数服务器读取参数。
首先,这里创建了一个param_test的包,然后分别创建talker.cpp和listener.cpp两个文件。
#include "ros/ros.h"
int main(int argc, char **argv)
{
// 设置编码
setlocale(LC_ALL, "");
// 初始化ROS节点
ros::init(argc, argv, "param_set_node");
// 实例化ROS句柄
ros::NodeHandle nh;
std::vector<std::string> course;
course.push_back("语文");
course.push_back("数学");
course.push_back("英语");
// 参数1为写入的参数名称,参数2为写入参数的值
nh.setParam("name", "张三");
nh.setParam("age", 10);
nh.setParam("course", course);
// 功能与上面相同
// ros::param::set("name", "张三");
// ros::param::set("age", 10);
// ros::param::set("course", course);
return 0;
}
#include "ros/ros.h"
int main(int argc, char **argv)
{
// 设置编码
setlocale(LC_ALL, "");
// 初始化ROS节点
ros::init(argc, argv, "param_get_node");
// 实例化ROS句柄
ros::NodeHandle nh;
std::string name;
int age;
std::vector<std::string> course_list;
std::string course;
// 方式一:参数1为参数服务器中的键,参数2为查询到的参数值
nh.getParam("name", name);
nh.getParam("age", age);
nh.getParam("course", course_list);
// 功能与上面相同
// ros::param::get("name", name);
// ros::param::get("age", age);
// ros::param::get("course", course_list);
for (auto c : course_list)
{
course = course + c + ";";
}
ROS_INFO("获取到的名字为:%s", name.c_str());
ROS_INFO("获取到的年龄为:%d", age);
ROS_INFO("获取到的课程为:%s", course.c_str());
// 方式二:默认值版本。参数1为到参数服务器查找该字段的值,找到的话则赋值给参数2,未找到则使用参数3(默认值)
int ageA;
nh.param("ageA", ageA, 15);
ROS_INFO("获取到的年龄(A)为:%d", ageA);
return 0;
}
# 节点构建选项,配置可执行文件
add_executable(param_set_node src/talker.cpp)
add_executable(param_get_node src/listener.cpp)
# 节点构建选项,配置目标链接库
target_link_libraries(param_set_node
${catkin_LIBRARIES}
)
target_link_libraries(param_get_node
${catkin_LIBRARIES}
)
使用Ctrl+Shift+B进行编译,然后使用roscore命令启动主节点,然后source下环境变量,分别运行参数写入和参数读取节点即可看到打印输出。
☝ ★★★ — 返回 《ROS机器人开发笔记汇总》总目录 — ★★★ ☝