【前言】
ROS用习惯的朋友,当工程环境需要脱离ROS时,想必都会遇到很多的不适应吧。首当其冲的应该就是参数获取,之前可以通过ROS提供的参数服务器,launch文件之类的,轻松获取配置文件中的参数,但是脱离ROS了以后,这就成为了一个痛点。本篇博客就介绍一个我自己手写的XML参数获取工具!
【干货】
话不多说,直接上代码!
首先是头文件:
#ifndef XML_PARSER_H
#define XML_PARSER_H
#include "tinyxml2.h"
#include <string>
using namespace tinyxml2;
namespace util_data
{
class SimpleParam
{
public:
SimpleParam();
~SimpleParam();
bool loadXML(const std::string xml_path);
bool getParam(const std::string name, std::string &value);
bool getParam(const std::string name, int &value);
bool getParam(const std::string name, double &value);
bool getParam(const std::string name, float &value);
bool getParam(const std::string name, bool &value);
public:
XMLDocument doc;
};
}
#endif
其次是源文件:
#include "xml_parser/xml_parser.h"
#include <iostream>
using namespace util_data;
SimpleParam::SimpleParam()
{}
SimpleParam::~SimpleParam()
{}
bool SimpleParam::loadXML(const std::string xml_path)
{
if(doc.LoadFile(xml_path.c_str()) != 0)
{
printf( "load xml file failed \n" );
return false;
}
else {
return true;
}
}
bool SimpleParam::getParam(const std::string name, std::string &value)
{
XMLElement *config = doc.RootElement();
XMLElement *param = config->FirstChildElement("param");
while (param)
{
const XMLAttribute *attributeOfSurface = param->FirstAttribute();
// std::cout << attributeOfSurface->Name() << ":" << attributeOfSurface->Value() << std::endl;
if(name == attributeOfSurface->Value())
{
value = attributeOfSurface->Next()->Next()->Value();
return true;
}
// while(surfaceChild)
// {
// content = surfaceChild->GetText();
// surfaceChild = surfaceChild->NextSiblingElement();
// cout << content << endl;
// }
param = param->NextSiblingElement();
}
return false;
}
bool SimpleParam::getParam(const std::string name, int &value)
{
XMLElement *config = doc.RootElement();
XMLElement *param = config->FirstChildElement("param");
std::string value_str;
while (param)
{
const XMLAttribute *attributeOfSurface = param->FirstAttribute();
if(name == attributeOfSurface->Value())
{
value_str = attributeOfSurface->Next()->Next()->Value();
value = atoi(value_str.c_str());
return true;
}
param = param->NextSiblingElement();
}
return false;
}
bool SimpleParam::getParam(const std::string name, double &value)
{
XMLElement *config = doc.RootElement();
XMLElement *param = config->FirstChildElement("param");
std::string value_str;
while (param)
{
const XMLAttribute *attributeOfSurface = param->FirstAttribute();
if(name == attributeOfSurface->Value())
{
value_str = attributeOfSurface->Next()->Next()->Value();
value = atof(value_str.c_str());
return true;
}
param = param->NextSiblingElement();
}
return false;
}
bool SimpleParam::getParam(const std::string name, float &value)
{
XMLElement *config = doc.RootElement();
XMLElement *param = config->FirstChildElement("param");
std::string value_str;
while (param)
{
const XMLAttribute *attributeOfSurface = param->FirstAttribute();
if(name == attributeOfSurface->Value())
{
value_str = attributeOfSurface->Next()->Next()->Value();
value = std::stof(value_str.c_str());
return true;
}
param = param->NextSiblingElement();
}
return false;
}
bool SimpleParam::getParam(const std::string name, bool &value)
{
XMLElement *config = doc.RootElement();
XMLElement *param = config->FirstChildElement("param");
std::string value_str;
while (param)
{
const XMLAttribute *attributeOfSurface = param->FirstAttribute();
if(name == attributeOfSurface->Value())
{
value_str = attributeOfSurface->Next()->Next()->Value();
if(value_str == "true")
{
value = true;
}
else {
value = false;
}
return true;
}
param = param->NextSiblingElement();
}
return false;
}
再来一个测试代码:
#include <iostream>
#include "xml_parser/xml_parser.h"
using namespace std;
void example()
{
XMLDocument doc;
if(doc.LoadFile("/home/starlab/Box/test_ws/src/common/xml_parser/config/demo.xml")!=0)
{
cout << "load xml file failed" << endl;
return;
}
XMLElement *scene = doc.RootElement();
XMLElement *surface = scene->FirstChildElement("node");
while (surface)
{
XMLElement *surfaceChild = surface->FirstChildElement();
const char* content;
const XMLAttribute *attributeOfSurface = surface->FirstAttribute();
cout << attributeOfSurface->Name() << ":" << attributeOfSurface->Value() << endl;
while(surfaceChild)
{
content = surfaceChild->GetText();
surfaceChild = surfaceChild->NextSiblingElement();
cout << content << endl;
}
surface = surface->NextSiblingElement();
}
}
void example2()
{
util_data::SimpleParam tool;
std::string map_file;
int nFeatures;
double scaleFactor;
bool load_map;
if(tool.loadXML("/home/starlab/Box/test_ws/src/common/xml_parser/config/test_config.xml"))
{
tool.getParam("map_file", map_file);
std::cout << map_file << std::endl;
tool.getParam("/ORBextractor/nFeatures", nFeatures);
std::cout << nFeatures << std::endl;
tool.getParam("/ORBextractor/scaleFactor", scaleFactor);
std::cout << scaleFactor << std::endl;
tool.getParam("load_map", load_map);
std::cout << load_map << std::endl;
}
}
int main()
{
example2();
return 0;
}
【后言】
如果这篇博客对你起到了一定的帮助作用,还请点个赞!!