.yaml引數檔案的編寫和使用

詩筱涵發表於2020-12-15

 

 

摘自:https://www.cnblogs.com/scripthome/p/8583783.html

.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) 如果資料型別為字串,字串不能以數字開頭,否則讀不出來(這個也許可以解決,只是沒找著方法); 

相關文章