param参数服务器

声明:本文主要内容来自: MOOC 机器人操作系统入门.仅仅是为了查阅方便,做了个小结,侵权必删!

Table of Contents

零.param介绍

0.0 param有什么用

0.1参数类型

 

 二.如何使用----三种维护方式

2.1命令行维护

2.2.launch文件

 2.2.1 yaml文件

2.3node源码

 三.命名空间对param的影响


零.param介绍

0.0 param有什么用

机器人工作时,我们有需要对机器人的参数(如传感器参数、算法的参数)进行设置。有些参数(如机器人的轮廓、传感器的高度)在机器人启动时就设定好就行了;有些参数则需要动态改变(特别是在调试的时候)。ROS提供了参数服务器来满足这一需求。我们可以将参数设置在参数服务器,在需要用到参数的时候再从参数服务器中获取。[1]
 

0.1参数类型

ROS参数服务器为参数值使用XMLRPC数据类型, 其中包括:strings, integers, floats,booleans, lists, dictionaries, iso8601 dates, and base64-encoded data

 

 二.如何使用----三种维护方式

2.1命令行维护

2.2.launch文件

       parameter是ROS系统中运行的参数,存储在参数服务器当中.在launch文件当中通过<param>元素加载parameter;launch文件执行后,parameter就加载到ROS的参数服务器上了.

      launch文件中有很多标签, 而与参数服务器相关的标签只有两个, 一个是 <param> , 另一个是 <rosparam>rosparam可操作多个参数,以及yaml文件参数,param一次性只能指定一个参数,且是标准类型的参数。

  • <param>标签可用于直接设置参数,也可以从文件中读取
  • <rosparam>标签用于从yaml文件中读取并设置参数,也可以设置多个参数
  • roslaunch发现<param>和<rosparam>标签后会调用rosparam包来实现设置
<launch>
	<!--param参数配置-->
	<param name="param1" value="1" />
	<param name="param2" value="2" />
	<!--param name="table_description" command="$(find xacro)/xacro.py $(find gazebo_worlds)/objects/table.urdf.xacro" /-->

	<!--rosparam参数配置  一次设置多个参数-->
	<rosparam>   
        param3: 3
        param4: 4
        param5: 5
        </rosparam>
	<!--以上写法将参数转成YAML文件加载,注意param前面必须为空格,不能用Tab,否则YAML解析错误-->
	<!--rosparam file="$(find robot_sim_demo)/config/xbot-u_control.yaml" command="load" /-->
	<node pkg="param_demo" type="param_demo" name="param_demo" output="screen" />

	

</launch>

 2.2.1 yaml文件

这个例子在自己创建的功能包param_meter下.

  • 如下图所示在功能包下创建新的文件夹param,再在这个文件夹下创建 yaml文件param.yaml.

  • 编写yaml文件
parammeter_test:
    param3: 56
    param4: 58
    param5: 96
  • 在launch文件中进行修改

加入

	<rosparam file="$(find param_meter)/param/param.yaml" command="load" />

 变成

<launch>
	<!--param参数配置-->

	<param name="param1" value="1" />
	<param name="param2" value="2" />
	<!--param name="table_description" command="$(find xacro)/xacro.py $(find gazebo_worlds)/objects/table.urdf.xacro" /-->

	<!--rosparam参数配置-->
	<rosparam>   
        param3: 3
        param4: 12
        param5: 9
    </rosparam>
	<!--以上写法将参数转成YAML文件加载,注意param前面必须为空格,不能用Tab,否则YAML解析错误-->
	<rosparam file="$(find param_meter)/param/param.yaml" command="load" />
    <!--rosparam file="$(find robot_sim_demo)/config/xbot-u_control.yaml" command="load" /-->
	<node pkg="param_meter" type="param_meter" name="param_meter" output="screen" />

	

</launch>
  •  运行launch文件

得到了运行结果,param的值和自己设置的相同.

2.3node源码

关于param的API, roscpp为我们提供了两套, 一套是放在 ros::param namespace下, 另一套是在 ros::NodeHandle 下, 这
两套API的操作完全一样, 用哪一个取决于你的习惯。

  •     ros::param namespace
  •     ros::NodeHandle

和param相关的操作如下:

  • get param
  • set param
  • check param
  • delete param
#include<ros/ros.h>

int main(int argc, char **argv){
	ros::init(argc, argv, "param_demo");
	ros::NodeHandle nh;
	int parameter1, parameter2, parameter3, parameter4, parameter5;
	
	//Get Param的三种方法
	//① ros::param::get()获取参数“param1”的value,写入到parameter1上
	bool ifget1 = ros::param::get("param1", parameter1);
	
	//② ros::NodeHandle::getParam()获取参数,与①作用相同
	bool ifget2 = nh.getParam("param2",parameter2);
	
	//③ ros::NodeHandle::param()类似于①和②
	//但如果get不到指定的param,它可以给param指定一个默认值(如33333)
        nh.param("param3", parameter3, 33333);
	
	if(ifget1)
		ROS_INFO("Get param1 = %d", parameter1);
	else
		ROS_WARN("Didn't retrieve param1");
	if(ifget2)
		ROS_INFO("Get param2 = %d", parameter2);
	else
		ROS_WARN("Didn't retrieve param2");
	if(nh.hasParam("param3"))
		ROS_INFO("Get param3 = %d", parameter3);
	else
		ROS_WARN("Didn't retrieve param3");


    //Set Param的两种方法
	//① ros::param::set()设置参数
	parameter4 = 4;
	ros::param::set("param4", parameter4);

	//② ros::NodeHandle::setParam()设置参数
	parameter5 = 5;
	nh.setParam("param5",parameter5);
	
	ROS_INFO("Param4 is set to be %d", parameter4);
	ROS_INFO("Param5 is set to be %d", parameter5);


	//Check Param的两种方法
	//① ros::NodeHandle::hasParam()
	bool ifparam5 = nh.hasParam("param5");

	//② ros::param::has()
	bool ifparam6 = ros::param::has("param6");

	if(ifparam5) 
		ROS_INFO("Param5 exists");
	else
		ROS_INFO("Param5 doesn't exist");
	if(ifparam6) 
		ROS_INFO("Param6 exists");
	else
		ROS_INFO("Param6 doesn't exist");


	//Delete Param的两种方法
	//① ros::NodeHandle::deleteParam()
	bool ifdeleted5 = nh.deleteParam("param5");

	//② ros::param::del()
	bool ifdeleted6 = ros::param::del("param6");
	


	
}

 三.命名空间对param的影响

在实际的项目中, 实例化句柄时, 经常会看到两种不同的写法 ros::NodeHandle n;  ros::NodeHandle nh("~");` 这两种写法有什么不同呢? launch文件夹的demo.launch定义两个参数, 一个全局serial 他的数值是5,一个是局部的serial, 他的数值是10.在launch 标签内的是全局参数值, node 标签内的是局部参数其有效域是当前节点。[2]

<launch>
  <!--全局参数serial-->
  <param name="serial" value="5" />
  <node name="name_demo" pkg="name_demo" type="name_demo"
   output="screen">
    <!--局部参数serial-->
    <param name="serial" value="10" />
  </node>
</launch>


在name_demo.cpp中, 我们分别尝试了, 利用全局命名空间句柄提取全局的param和局部的param以及在局部命名空间下的句柄提取全局的param和局部的param, 详细的代码如下 :

#include <ros/ros.h>

int main(int argc, char* argv[])
{
    int serial_number = -1;//serial_number初始化
    ros::init(argc, argv, "name_demo");//node初始化
    /*创建命名空间*/
    //n 是全局命名空间
    ros::NodeHandle n;
    //nh 是局部命名空间
    ros::NodeHandle nh("~");
    /*全局命名空间下的Param*/
    ROS_INFO("global namespace");
    //提取全局命名空间下的参数serial
    n.getParam("serial", serial_number);
    ROS_INFO("global_Serial was %d", serial_number);
    //提取局部命名空间下的参数serial
    n.getParam("name_demo/serial", serial_number);//在全局命名空间下,要提取局部命名空间下的参数,需要添加node name
    ROS_INFO("global_to_local_Serial was %d", serial_number);
    /*局部命名空间下的Param*/
    ROS_INFO("local namespace");
    //提取局部命名空间下的参数serial
    nh.getParam("serial", serial_number);
    ROS_INFO("local_Serial was %d", serial_number);
    //提取全局命名空间下的参数serial
    nh.getParam("/serial", serial_number);//在局部命名空间下,要提取全局命名空间下的参数,需要添加“/”
    ROS_INFO("local_to_global_Serial was %d", serial_number);
    ros::spin();
    return 0;
}

参考:

1.https://blog.csdn.net/u014695839/article/details/78348600

2.MOOC 机器人操作系统入门

猜你喜欢

转载自blog.csdn.net/u013528298/article/details/87937555
今日推荐