776

阿木币

1

精华

1377 小时

在线时间

管理员

Rank: 9Rank: 9Rank: 9

发表于 2022-2-24 17:18:47 1308 浏览 0 回复

[杂言讨论] 技术分享 | SLAM工程中使用配置文件加载程序参数的实现方法

我们在SLAM工程中有许多用于调试结果的参数,但每次修改后的编译都会占用很多时间和资源,当工程较大的时候,工作效率也会明显下降,因此,从配置文件中读取程序参数便是一个很方便的功能。而配置文件有许多种,并且在不同的系统上配置成了不同的库或源。在工程后期成型时,把这样的一系列内容做成tools,用的方法也会比较相似。个人认为YAML比XML在中小规模的开发中更优,在多人合作的大项目中,使用XML是比较好的选择。

本篇记录的是YAML文件的使用(Yet Another Markup Language,直译为另一种标记语言),还有XML(Extensible Markup Language,可扩展标记语言)。XML是一种具备自己结构的语言文件,其在信息的可表达度上更为丰富,应用方面也更为广泛,适配许多种语言交互(例如C++,JS,PHP等),信息传递以及系统调用,但同样的在表现上相对会比较冗长;而YAML虽然也是一种语言型文件,但其更像是一种数据形式,其表达简单的数据比较好,且其良好的可读性与易于实现的特性,在工程中效率非常高。

XML文件的基本写法与调用方法

C++中读取XML文件主要是针对不同节点来配置不同的参数,功能针对性比较强,其对应的数据在代码中可以直接写成一成不变的量,俗称“写死”,然后通过修改XML时来改变其具体的数值。常用的包括配置tinyXML库。

1、XML文件的基本写法:

<!-- 应用的时候主要是:节点名称、节点属性、节点内容及参数 -->
<!-- 如下标准形式 -->
<?xml version = "1.0"?>
<event1>
    <variable1>variable_value1</variable1>
    <variable2>variable_value2</variable2>
</event1>
<event2>
    <variable3>variable_value3</variable3>
    <variable4>variable_value4</variable4>
</event2>

<!-- 举个例子,node定义了一个2.5*2.5*2.5的box -->
<?xml version="1.0" encoding="UTF-8"?>
<box>
    <node id="0" type="0">
        <width>2.5</width>
        <height>2.5</height>
        <depth>2.5</depth>
    </node>
    <!--  有N+1个这样的node节点 -->
</box>
<!-- 在需要修改的时候就可以直接将2.5的值修改掉 -->

2、XML文件的调用方法

调用的时候,按照上述举例的XML部分进行读入解析,有如下C++代码参考:

#include "tinystr.h"  
#include "tinyxml.h"

int main()
{   
    double w,h,d;
    BOX* box;//自行定义的box结构指针
    //box初始化,假定有n个box,得到的数组长度为BOX_SET
    iXmlDocument doc(FILENAME);    // 读入XML文件
    if(!doc.LoadFile()) return -1;  // 如果无法读取文件,则返回
    TiXmlHandle hDoc(&doc);         // hDoc是&doc指向的对象
    TiXmlElement* pElem;            // 指向元素的指针
    pElem = hDoc.FirstChildElement().Element(); //指向根节点
    TiXmlHandle hRoot(pElem);       // hRoot是根节点

    TiXmlElement* nodeElem = hRoot.FirstChild("box").FirstChild("node").Element(); //当前指向了node节点
    count = 0;//node的角标,记录当前到哪一个
    for(nodeElem; nodeElem; nodeElem = nodeElem->NextSiblingElement()) // 挨个读取node节点的信息
    { 
        box= BOX_SET[count];  // box节点,用count来记录
        TiXmlHandle node(nodeElem);  // nodeElem所指向的节点
        TiXmlElement* width = node.FirstChild("width").Element();  // width节点
        TiXmlElement* height = node.FirstChild("height").Element();  // height节点
        TiXmlElement* depth = node.FirstChild("depth").Element();  // depth节点
        //可以根据node的属性值,例如id进行移位读取
        //例如nodeElem->QueryIntAttribute("id", &temp); box->setID(temp);temp代表的就是其属性
        w = atof(width ->GetText());    // char转double,记录数据,后面根据自己需要可直接调用
        h = atof(height ->GetText());
        d = atof(depth->GetText());
        count ++;
    }
    return 1;
}

YAML文件的基本写法与调用方法

C++中读取YAML方法也借助于yaml库,其安装可以直接使用apt工具。

1、YAML的基本写法

这里写一个非常简单的YAML文件,比起XML的规则来说,实在是方便太多了。直接“变量名“ + “:”+“ ‘变量值’”就行,需要注意的是这里的变量值保存的是string,如果与代码中应用的类型不同,则应该存在类型转换的步骤。

#data path
data_path: '/home/data/'
#记录了数据的读取路径

2、YAML的调用方法

根据上面的data_path,直接用如下方式调用就可以了,非常方便,读进去的data_path值在data_root中。

#include "yaml-cpp/yaml.h"

int main(int argc, char const *argv[])
{
  std::string data_root;
  std::string yaml_path = "../data_path.yaml";
  YAML::Node basenode = YAML::LoadFile(yaml_path);
  data_root = basenode["data_path"].as<std::string>();
  if (data_root.empty())
    std::cout << BOLDRED << "[Error]" << RESET << " : param data_root is empty" << std::endl;
        //Operations
        return 1;
}

另外需要注意的就是编译时,如果采用Cmake工具,则在CmakeLists.txt中应该有如下的写法:

cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(project)
include_directories(include)
find_package(yaml-cpp REQUIRED)
link_directories(src)
aux_source_directory(src SOURCE)
add_executable(project${SOURCE} main.cpp)
target_link_libraries(project yaml-cpp)

即find_package,target_link_libraries时包含yaml的库,写时注意其为yaml-cpp。

转自知乎作者:佳浩(SLAM算法工程师)

链接:https://zhuanlan.zhihu.com/p/467707462

阿木实验室致力于为机器人研发提供开源软硬件工具和课程服务,让研发更高效!

公众号:阿木实验室 ( 领取免费资料包)

官方淘宝店:阿木实验室(可购买硬件配件)

硬件咨询:yanyue199506(欢迎洽谈合作)

课程咨询:jiayue199506 (免费领取机器人工程师学习计划)

  • End -

技术发展的日新月异,阿木实验室将紧跟技术的脚步,不断把机器人行业最新的技术和硬件推荐给大家。看到经过我们培训的学员在技术上突飞猛进,是我们培训最大的价值。如果你在机器人行业,就请关注我们的公众号,我们将持续发布机器人行业最有价值的信息和技术。


扫一扫浏览分享
回复

使用道具 举报

返回列表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表