あるファイルから別のファイルにモデル データを挿入して、新しい Gazebo xml ワールド ファイルを生成するプログラムを作成しようとしています。バイナリは、デフォルトのワールド ファイルを引数として受け取る必要があります。
私のアプローチ方法は次のとおりです。
- デフォルトの空のワールド ファイルを用意する
model.sdf
世界に挿入したいモデルを含むファイルを持っている- デフォルト
world
のファイルを boost に読み込みますptree
。 <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);
}
}
}
編集:これを行うことについて私が考えた1つの方法は、両方のxmlファイルを別々stringstream
のファイルに読み込みstd::find
、メインのワールドファイルでタグを見つけて.str()
、モデルからワールドに結果を挿入することです。これを解決し、他の誰も追加していない場合は、回答を追加します。