Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <mvsim/World.h>
00010
00011 #include <mrpt/utils/utils_defs.h>
00012 #include <mrpt/system/filesystem.h>
00013
00014 #include <iostream>
00015 #include <algorithm>
00016 #include <stdexcept>
00017 #include <map>
00018
00019
00020 #include <rapidxml.hpp>
00021 #include <rapidxml_print.hpp>
00022
00023 #include "xml_utils.h"
00024
00025 using namespace mvsim;
00026 using namespace std;
00027
00033 void World::load_from_XML(
00034 const std::string& xml_text, const std::string& fileNameForPath)
00035 {
00036 using namespace std;
00037 using namespace rapidxml;
00038
00039
00040 m_base_path =
00041 mrpt::system::trim(mrpt::system::extractFileDirectory(fileNameForPath));
00042
00043
00044 std::lock_guard<std::mutex> csl(m_world_cs);
00045
00046
00047 this->clear_all(false );
00048
00049
00050 rapidxml::xml_document<> xml;
00051 char* input_str = const_cast<char*>(xml_text.c_str());
00052 try
00053 {
00054 xml.parse<0>(input_str);
00055 }
00056 catch (rapidxml::parse_error& e)
00057 {
00058 unsigned int line =
00059 static_cast<long>(std::count(input_str, e.where<char>(), '\n') + 1);
00060 throw std::runtime_error(
00061 mrpt::format(
00062 "XML parse error (Line %u): %s", static_cast<unsigned>(line),
00063 e.what()));
00064 }
00065
00066
00067 const xml_node<>* root = xml.first_node();
00068 if (!root)
00069 throw runtime_error(
00070 "XML parse error: No root node found (empty file?)");
00071 if (0 != strcmp(root->name(), "mvsim_world"))
00072 throw runtime_error(
00073 mrpt::format(
00074 "XML root element is '%s' ('mvsim_world' expected)",
00075 root->name()));
00076
00077
00078 const xml_attribute<>* attrb_version = root->first_attribute("version");
00079 int version_major = 1, version_min = 0;
00080 if (attrb_version)
00081 {
00082 int ret = sscanf(
00083 attrb_version->value(), "%i.%i", &version_major, &version_min);
00084 if (ret != 2)
00085 throw runtime_error(
00086 mrpt::format(
00087 "Error parsing version attribute: '%s' ('%%i.%%i' "
00088 "expected)",
00089 attrb_version->value()));
00090 }
00091
00092
00093
00094 std::map<std::string, TParamEntry> other_world_params;
00095 other_world_params["gravity"] = TParamEntry("%lf", &this->m_gravity);
00096 other_world_params["simul_timestep"] =
00097 TParamEntry("%lf", &this->m_simul_timestep);
00098 other_world_params["b2d_vel_iters"] =
00099 TParamEntry("%i", &this->m_b2d_vel_iters);
00100 other_world_params["b2d_pos_iters"] =
00101 TParamEntry("%i", &this->m_b2d_pos_iters);
00102
00103
00104
00105 xml_node<>* node = root->first_node();
00106 while (node)
00107 {
00108
00109 if (!strcmp(node->name(), "element"))
00110 {
00111 WorldElementBase* we = WorldElementBase::factory(this, node);
00112 this->m_world_elements.push_back(we);
00113 }
00114
00115 else if (!strcmp(node->name(), "vehicle"))
00116 {
00117 VehicleBase* veh = VehicleBase::factory(this, node);
00118 veh->setVehicleIndex(
00119 m_vehicles.size());
00120
00121 MRPT_TODO("Check for duplicated names")
00122 m_vehicles.insert(TListVehicles::value_type(veh->getName(), veh));
00123 }
00124
00125 else if (!strcmp(node->name(), "vehicle:class"))
00126 {
00127 VehicleBase::register_vehicle_class(node);
00128 }
00129
00130 else if (!strcmp(node->name(), "block"))
00131 {
00132 Block* block = Block::factory(this, node);
00133 block->setBlockIndex(
00134 m_blocks.size());
00135
00136
00137 m_blocks.insert(TListBlocks::value_type(block->getName(), block));
00138 }
00139
00140 else if (!strcmp(node->name(), "block:class"))
00141 {
00142 Block::register_block_class(node);
00143 }
00144
00145 else if (!strcmp(node->name(), "gui"))
00146 {
00147 m_gui_options.parse_from(*node);
00148 }
00149 else
00150 {
00151
00152 if (!parse_xmlnode_as_param(*node, other_world_params))
00153 {
00154
00155 std::cerr << "[World::load_from_XML] *Warning* Ignoring "
00156 "unknown XML node type '"
00157 << node->name() << "'\n";
00158 }
00159 }
00160
00161
00162 node = node->next_sibling(NULL);
00163 }
00164 }