.yaml参数文件的编写和使用

一、在ROS底下使用.yaml文件配置参数

在ROS底下用起来还是非常方便的,首先,写一个读参数的函数getParam(),由于参数类型不止一种,所以要使用模板。

具体语句如下:

template<typename T>
T getParam(const string& name,const T& defaultValue)  //This name must be namespace+parameter_name
{
    T v;
    if(ros::param::get(name,v))  //get parameter by name depend on ROS.
    {
        ROS_INFO_STREAM("Found parameter: "<<name<<",\tvalue: "<<v);
        return v;
    }
    else 
        ROS_WARN_STREAM("Cannot find value for parameter: "<<name<<",\tassigning default: "<<defaultValue);
    return defaultValue;  //if the parameter haven't been set,it's value will return defaultValue.
}
//How use.
int main(int argc,char** argv)
{
    ros::init(argc,argv,"readyaml");
    ros::NodeHandle nh;
    getParam<int>("readyaml/int",0);
    getParam<float>("readyaml/float",0.5);
    getParam<string>("readyaml/string","NotFound");
    getParam<bool>("readyaml/bool",false);
    return 0;
}

那么怎么设置参数?看代码。

<launch>
  <node pkg="readyaml" type="readyaml" name="readyaml" clear_params="true" output="screen">
    <!-- First way: direct set-->
    <param name="int" value="32760"/> 
    <!-- Second way: use .yaml file-->
    <rosparam file="$(find readyaml)/rosYaml.yaml"/>
  </node>
</launch>

rosYaml.yaml文件里写的什么?

#parameter_name: value
string: HaveFound
float: 3.14159
bool: true

程序运行结果:

 

二、使用Ubuntu下的yaml-cpp

 只要在CMakeLists.txt文件中添加相应声明,就可以在程序中使用Ubuntu下一个关于yaml文件的一个库,也是非常方便。

要添进去的语句如下:

FIND_LIBRARY(YAML_CPP_LIBRARIES yaml-cpp)

笔者装的是yaml的库,也可以安装package版本,CMakeLists.txt中添加的语句可以改成:

FIND_LIBRARY(YAML_CPP_LIBRARIES yaml-cpp)
if(NOT YAML_CPP_LIBRARIES)
  # If yaml-cpp not found in the system, try finding it as a user CMake-generated project
  FIND_PACKAGE(yaml-cpp REQUIRED)
  INCLUDE_DIRECTORIES(${YAML_CPP_INCLUDE_DIRS})
endif(NOT YAML_CPP_LIBRARIES)

然后,在构建可执行文件时添加相应的依赖

target_link_libraries(use_yaml ${YAML_CPP_LIBRARIES})

下面说怎么使用,

  第一步,使用YAML::LoadFile()函数加载yaml文件;

  如果参数没有“归属”(自己的理解,下面会解释),直接使用as()函数读取该参数;

  如果参数有“归属”,先找到参数的主体,再使用as()读取该参数;

说的不清楚,看程序吧。

//自己重写的读参数的函数,形参依次是,参数的主体(YAML::Node)、参数名(string)、默认值(和参数的类型一致)
template<typename T>
T getParam(const YAML::Node& node,const string& name,const T& defaultValue)
{
    T v;
    try {
        v=node[name].as<T>();  //读取参数
        std::cout<<"Found parameter: "<<name<<",\tvalue: "<<v<<std::endl;  //终端提示读取成功
    } catch (std::exception e) {
     //找不到该参数的话,将返回默认值
        v=defaultValue;
        std::cout<<"Cannot find parameter: "<<name<<",\tassigning  default: "<<v<<std::endl;
    }
    return v;
}

int main()
{
  //加载参数文件
    YAML::Node dset_config = YAML::LoadFile("/home/liban/cfiles/Learn_basic/data/test.yaml");
  //这里的title0,title1就可以看作其参数的主体
    YAML::Node title0=dset_config["title0"];
    YAML::Node title1=dset_config["title1"];

  //参数single没有“归属“,所以第一个形参为dset_config
    getParam<string>(dset_config,"single","cannot");
  //Int,Str可以看作title0的属性,Int_,Str_看作title1的属性。
    getParam<int>(title0,"Int",0);
    getParam<string>(title0,"Str","Null");
    getParam<int>(title1,"Int_",0);
    getParam<string>(title1,"Str_","Null");
    return 0;    
}

yaml文件里怎么写的?

title0:
 Int: 360
 Str: helloworld!
title1:
  Int_: 480
  Str_: success!
single: can

注意事项:

不要用Tab,用空格!用空格!用空格!

程序运行结果截图:

 

三、想不到OpenCV库里也有读取yaml参数的功能

主要是使用一个cv::FileStorage()函数用来加载参数文件

还是和前面一样,自己重写一个函数读参数 。 。 。

不再细说,直接看demo

template<typename T>
T getParam(const cv::FileStorage& file,const string& key)
{
    T v=T(file[key]); // Core sentence,read parameter.
   std::cout<<"Found parameter: "<<key<<",\tvalue: "<<v<<std::endl;
    return v;
}

int main()
{
    string filename="Path to yaml-file";
  // Load yaml-file.
    cv::FileStorage file_=cv::FileStorage(filename,cv::FileStorage::READ);
  // If cannot find yaml-file.
    if(file_.isOpened()==false)
    {
        std::cerr<<"yaml-file "<<filename<<" does not exist."<<std::endl;
        file_.release();
        return 1;
    }
    getParam<string>(file_,"#data"); // Test '#'.
    getParam<string>(file_,"Str");
    getParam<int>(file_,"Int");
    getParam<float>(file_,"Float");
  ...
    return 0;        
}

yaml-file里的数据

%YAML:1.0
#data: cannot
Int: 120
Float: 3.145926
Str: helloworld!

执行结果:

注意事项:

  (1) yaml文件开头一定要加上"%YAML:1.0";

  (2) 可以使用'#'注释文件内容,效果如上截图;

  (3) 如果数据类型为字符串,字符串不能以数字开头,否则读不出来(这个也许可以解决,只是没找着方法);  

 

posted @ 2018-03-22 22:12  scripthome  阅读(18533)  评论(0编辑  收藏  举报