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