zoukankan      html  css  js  c++  java
  • YAML-CPP

    yaml作为一种便捷的文件格式,通过c++进行操作时,可以利用yaml-cpp进行。

    一,yaml-cpp的安装

    下载源码

    git clone https://github.com/jbeder/yaml-cpp.git

    编译安装

    mkdir build
    cd build
    cmake -DBUILD_SHARED_LIBS=ON ..    # ON 设置生成共享库
    sudo make install

    验证

    pkg-config --modversion yaml-cpp

    使用

    YAML::Node node1 = YAML::LoadFile("config.yaml");    // 加载文件
    YAML::Node node2 = YAML::Load("[1,2,3]");        // 加载数组
    cout << node1[0].as<string>() << endl;
    cout << node2[0].as<int>() << endl;        // 输出元素

    更多API参考yaml-cpp docs

    示例:

    a、CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)
    project(yaml_test)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    link_directories(/home/jonty/Softwares/yaml-cpp/build)
    include_directories(/home/jonty/Softwares/yaml-cpp/include/yaml-cpp)
    add_executable(test main.cpp)
    target_link_libraries(test yaml-cpp)

    b、main.cpp

    #include <iostream>
    #include "yaml.h"
    using namespace std;
    int main()
    {
        YAML::Node node = YAML::Load("[22,3,4,4]");
        cout << node[0] << endl;
        YAML::Node node2 = YAML::LoadFile("../config.yaml");
        cout << node2["ttt"] << endl;
        return 0;
    }

    编译运行

    mkdir build
    cd build
    cmake ..
    make 
    ./test

    参考教程https://github.com/jbeder/yaml-cpp/wiki/Tutorial

    编译也可以采用g++ test.cpp /usr/local/lib/libyaml-cpp.a -std=c++11

    源码编译yaml-cpp

    git clone https://github.com/jbeder/yaml-cpp.git
    cd yaml-cpp # 进入克隆的文件夹
    mkdir build
    cd build
    cmake ..
    make
    make install

    可参考https://blog.csdn.net/Fourier_Legend/article/details/82798297

    记得在CMakeLists.txt中加入

    link_directories(/usr/local/lib)
    include_directories(/usr/local/include/yaml-cpp)

    以及在链接库target_link_libraries时,加上yaml-cpp。

    void write_robot_status_to_yaml(string path, const string &filename,
                                    double x, double y, double th)
    {
        //dir_file_exists(path, true);
        dir_file_exists(path, false, true, filename.c_str());
        std::ofstream yaml_file(path + filename, std::ios::out | std::ios::binary);
        {
            YAML::Emitter out(yaml_file);
            out << YAML::BeginMap;
            // TODO(whess): Use basename only?
            out << YAML::Key << "x";
            out << YAML::Value << x;
            out << YAML::Key << "y";
            out << YAML::Value << y;
            out << YAML::Key << "th";
            out << YAML::Value << th;
            out << YAML::EndMap;
        }
    
        yaml_file.close();
    }
    bool read_robot_status_from_yaml(string file_path, const string &file_name,  double &x,
                                     double &y, double &th)
    {
        if (!dir_file_exists(file_path, false, true, file_name.c_str()))
            return false;
        std::ifstream yaml_file(file_path + file_name, std::ios::out | std::ios::binary);
        {
            YAML::Node doc = YAML::Load(yaml_file);
    
            doc["x"] >> x;
            doc["y"] >> y;
            doc["th"] >> th;
        }
        yaml_file.close();
    
        return true;
    }
    /*
     * @brief 创建文件夹
     */
    bool dir_file_exists(string dir, bool mkdir_flag, bool touchfile_flag, string filename)
    {
        char des_dir[255];
        str_2_char(dir, des_dir);
        int state = access(des_dir, R_OK | W_OK);//#include<unistd.h>
        if(state == 0)
        {
            ROS_INFO("state == 0");
            return true;
        }
        else if(mkdir_flag)
        {
            dir = "mkdir " + dir;
            str_2_char(dir, des_dir);
            if(system(des_dir))
            {
                printf("generate dir %s successfully.",dir.c_str());
                ROS_INFO("generate dir %s successfully.",dir.c_str());
                //Basic_Info("generate dir {} successfully.",dir.c_str());
            }
            else
            {
                printf("generate dir %s fail.",dir.c_str());
                ROS_INFO("generate dir %s fail.",dir.c_str());
                //Basic_Info("generate dir {} fail.",dir.c_str());
            }
            return true;
        }
        else if(touchfile_flag)
        {
            dir = "touch " + dir + "/" + filename;
            ROS_INFO("dir is %s", dir.c_str());
            str_2_char(dir, des_dir);
            if(system(des_dir))
            {
                printf("generate filename %s successfully.",dir.c_str());
                ROS_INFO("generate filename %s successfully.",dir.c_str());
                //Basic_Info("generate filename {} successfully.",dir.c_str());
            }
            else
            {
                printf("generate filename %s fail.",dir.c_str());
                ROS_INFO("generate filename %s fail.",dir.c_str());
                //Basic_Info("generate filename {} fail.",dir.c_str());
            }
            return true;
        }
            return false;
    }
    View Code
    template <typename T>
    void operator>>(const YAML::Node& node, T& i);
    
    template <typename T>
    void operator>>(const YAML::Node& node, T& i) {
        i = node.as<T>();
    };

    写个模板类加载参数

    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<<",	value: "<<v);
            return v;
        }
        else 
            ROS_WARN_STREAM("Cannot find value for parameter: "<<name<<",	assigning default: "<<defaultValue);
        return defaultValue;  //if the parameter haven't been set,it's value will return defaultValue.
    }
    View Code

    在ROS系统中,参数读写一般通过xml或者yaml格式的文件,其中yaml用得比较多。这是一种可读性高,轻量级的标记语言,简单好用。
    对于yaml文件,ros中用的较早版本的yaml-cpp库,最新的可在github上下载,并按照readme中所述的方法编译安装。

    特别留意的是,如果需要生成共享库,cmake的时候后面一定要加上 -DBUILD_SHARED_LIBS=ON 这句话。

     

    有了yaml库,在CMakeLists.txt中加入,

    link_directories(/usr/local/lib)
    include_directories(/usr/local/include/yaml-cpp)

    最后别忘了在链接库target_link_libraries时,加上yaml-cpp。
    关于库的使用,github上有一些简单的tutorial教程
     

    以下是简单的yaml文件读写操作示例。

    #include <ros/ros.h>
    #include <yaml-cpp/yaml.h>
    #include <iostream>
    #include <fstream>
     
    int main(int argc, char **argv)
    {
        std::string fin = "/home/user/param/param.yaml";       //yaml文件所在的路径
        YAML::Node yamlConfig = YAML::LoadFile(fin);
        int int_param = yamlConfig["int_param"].as<int>();
        std::cout << "  node size: " << yamlConfig.size() << std::endl;
        std::cout << yamlConfig["bool_param"].as<bool>() << "
    ";
        yamlConfig["bool_param"] = !yamlConfig["bool_param"].as<bool>();
        yamlConfig["str_param"] = "test";
        std::ofstream file;
        file.open(fin);
        file.flush();
        file << yamlConfig;
        file.close();
     
        return 0;
    }
    View Code

    其中,yaml文件里的内容为:

    bool_param: true
    int_param: 2
    double_param: 0.5
    str_param: "123"

    也可采用Emit来生成yaml文件,代码如下:

    #include <ros/ros.h>
    #include <yaml-cpp/yaml.h>
    #include <iostream>
    #include <fstream>
     
    int main(int argc, char **argv)
    {
        std::ofstream fout("/home/user/param/param.yaml");
        YAML::Emitter out(fout);
        out << YAML::BeginMap;
        out << YAML::Key << "int_param";
        out << YAML::Value << 1;
        out << YAML::Key << "double_param";
        out << YAML::Value << 0.5;
        out << YAML::Key << "bool_param";
        out << YAML::Value << false;
        out << YAML::Comment("bool parameter");
        out << YAML::Key << "str_param";
        out << YAML::Value << "test";
        out << YAML::EndMap;
        
        return 0;
    }
    View Code

    yml文件的其他操作可参见博文《.yaml参数文件的编写和使用》,

    其综合运用的案例可参见博文:ros-opencv-qt-yaml综合运用之滤波

  • 相关阅读:
    svn的差异查看器和合并工具换成BCompare.exe
    Java经典编程题50道之十四
    Java经典编程题50道之十三
    Java经典编程题50道之十二
    Java经典编程题50道之十一
    Java经典编程题50道之十
    Java经典编程题50道之九
    Java经典编程题50道之八
    Java经典编程题50道之七
    Java经典编程题50道之六
  • 原文地址:https://www.cnblogs.com/gary-guo/p/10608339.html
Copyright © 2011-2022 走看看