我正在尝试编写一个程序,通过将模型数据从一个文件插入另一个文件来生成新的 Gazebo xml 世界文件。二进制文件应采用默认世界文件作为参数。
我的方法如下:
- 有一个默认的空世界文件
- 有一个
model.sdf
包含我想插入世界的模型的文件 - 将默认
world
文件读入 boostptree
。 - 查找
<world>
标签并将模型数据作为子项插入。
我找到标签没有问题<world>
,但是我不确定如何将文件中的数据“复制并粘贴”model.sdf
到我的world
文件中。
世界 XML
缩短以免在此处泛滥屏幕:
<sdf version='1.7'>
<world name='default'>
<light name='sun' type='directional'>
<cast_shadows>1</cast_shadows>
<pose>0 0 10 0 -0 0</pose>
<diffuse>0.8 0.8 0.8 1</diffuse>
<specular>0.2 0.2 0.2 1</specular>
<attenuation>
<range>1000</range>
<constant>0.9</constant>
<linear>0.01</linear>
<quadratic>0.001</quadratic>
</attenuation>
<direction>-0.5 0.1 -0.9</direction>
<spot>
<inner_angle>0</inner_angle>
<outer_angle>0</outer_angle>
<falloff>0</falloff>
</spot>
</light>
<!-- MODEL DATA TO GO HERE -->
</world>
模型.sdf
缩短:
<?xml version='1.0'?>
<sdf version='1.7'>
<model name='box'>
<link name='link'>
<inertial>
<mass>3.14999</mass>
<inertia>
<ixx>2.86712</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>2.86712</iyy>
<iyz>0</iyz>
<izz>0.524998</izz>
</inertia>
<pose>0 0 0 0 -0 0</pose>
</inertial>
</link>
</model>
</sdf>
预期产出
<sdf version='1.7'>
<world name='default'>
<light name='sun' type='directional'>
<cast_shadows>1</cast_shadows>
<pose>0 0 10 0 -0 0</pose>
<diffuse>0.8 0.8 0.8 1</diffuse>
<specular>0.2 0.2 0.2 1</specular>
<attenuation>
<range>1000</range>
<constant>0.9</constant>
<linear>0.01</linear>
<quadratic>0.001</quadratic>
</attenuation>
<direction>-0.5 0.1 -0.9</direction>
<spot>
<inner_angle>0</inner_angle>
<outer_angle>0</outer_angle>
<falloff>0</falloff>
</spot>
</light>
<model name='box'>
<link name='link'>
<inertial>
<mass>3.14999</mass>
<inertia>
<ixx>2.86712</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>2.86712</iyy>
<iyz>0</iyz>
<izz>0.524998</izz>
</inertia>
<pose>0 0 0 0 -0 0</pose>
</inertial>
</link>
</model>
</world>
</sdf>
代码:
#include <iostream>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <utility>
using namespace std;
boost::property_tree::xml_writer_settings<string> xml_settings(' ', 4);
int main(int argc, char **argv){
using boost::property_tree::ptree;
cout << BOOST_VERSION << endl;
cout << BOOST_LIB_VERSION << endl;
const string filename = argv[1];
ptree pt;
std::ifstream is(filename.c_str(),std::ifstream::binary);
std::ofstream newWorldFile("NEW_WORLD.xml");
read_xml(is, pt);
for(auto &it: pt){
if(it.first == "sdf" && pt.get_child_optional(it.first)){
ptree pt1 = pt.get_child(it.first);
for(auto &it1 : pt1){
cout << "it1.first = " << it1.first << endl;
if(it1.first == "world"){
// insert model data here. use pt1.put("model.<xmlattr>.name","IamABox"); ? or something similar?
}
boost::property_tree::write_xml(newWorldFile, pt1, xml_settings);
}
}
}
编辑:我考虑过这样做的一种方法是将两个 xml 文件读入单独stringstream
的文件,然后使用std::find
在主世界文件中定位标签,并将.str()
结果从我的模型插入到世界中。如果我确实解决了这个问题并且没有其他人添加了答案,我将添加一个答案。