【머리말】
ROS에 익숙한 친구들이라면 엔지니어링 환경과 ROS를 분리해야 할 때 많은 불편함을 겪게 될 것입니다. 가장 먼저 감수해야 할 것은 파라미터 획득인데, 기존에는 ROS에서 제공하는 파라미터 서버, 런치 파일 등을 통해 설정 파일에 있는 파라미터를 쉽게 얻을 수 있었지만, 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;
}
【추신】
이 블로그가 도움이 되셨다면 좋아요를 눌러주세요! !