0

あるファイルから別のファイルにモデル データを挿入して、新しい Gazebo xml ワールド ファイルを生成するプログラムを作成しようとしています。バイナリは、デフォルトのワールド ファイルを引数として受け取る必要があります。

私のアプローチ方法は次のとおりです。

  1. デフォルトの空のワールド ファイルを用意する
  2. model.sdf世界に挿入したいモデルを含むファイルを持っている
  3. デフォルトworldのファイルを boost に読み込みますptree
  4. <world>タグを検索し、子としてモデル データを挿入します。

タグを見つけるのに問題はありませんが、ファイルからファイルに<world>データを「コピーして貼り付ける」方法がわかりません。model.sdfworld

世界の 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()、モデルからワールドに結果を挿入することです。これを解決し、他の誰も追加していない場合は、回答を追加します。

4

0 に答える 0