xml_utils.cpp
Go to the documentation of this file.
00001 /*+-------------------------------------------------------------------------+
00002   |                       MultiVehicle simulator (libmvsim)                 |
00003   |                                                                         |
00004   | Copyright (C) 2014  Jose Luis Blanco Claraco (University of Almeria)    |
00005   | Copyright (C) 2017  Borys Tymchenko (Odessa Polytechnic University)     |
00006   | Distributed under GNU General Public License version 3                  |
00007   |   See <http://www.gnu.org/licenses/>                                    |
00008   +-------------------------------------------------------------------------+ */
00009 
00010 #include <mvsim/basic_types.h>
00011 #include "xml_utils.h"
00012 
00013 #include <cstdio>
00014 #include <mrpt/poses/CPose2D.h>
00015 #include <mrpt/poses/CPose3D.h>
00016 #include <mrpt/math/lightweight_geom_data.h>
00017 #include <mrpt/system/string_utils.h>
00018 
00019 #include <mrpt/version.h>
00020 #if MRPT_VERSION<0x199
00021 #include <mrpt/utils/utils_defs.h>  // mrpt::format()
00022 #include <mrpt/utils/TColor.h>
00023 using mrpt::utils::TColor;
00024 using mrpt::utils::DEG2RAD;
00025 using mrpt::utils::RAD2DEG;
00026 #else
00027 #include <mrpt/core/format.h>
00028 #include <mrpt/core/bits_math.h>
00029 #include <mrpt/img/TColor.h>
00030 using mrpt::img::TColor;
00031 using mrpt::DEG2RAD;
00032 using mrpt::RAD2DEG;
00033 #endif
00034 
00035 using namespace rapidxml;
00036 using namespace mvsim;
00037 
00042 void TParamEntry::parse(
00043         const std::string& str, const std::string& varName,
00044         const char* function_name_context) const
00045 {
00046         // Special cases:
00047         // "%s" ==> std::strings
00048         if (std::string(frmt) == std::string("%s"))
00049         {
00050                 char auxStr[512];
00051                 if (1 != ::sscanf(str.c_str(), frmt, auxStr))
00052                         throw std::runtime_error(
00053                                 mrpt::format(
00054                                         "%s Error parsing '%s'='%s' (Expected format:'%s')",
00055                                         function_name_context, varName.c_str(), str.c_str(), frmt));
00056                 std::string& str = *reinterpret_cast<std::string*>(val);
00057                 str = mrpt::system::trim(auxStr);
00058         }
00059         // "%lf_deg" ==> DEG2RAD()
00060         else if (std::string(frmt) == std::string("%lf_deg"))
00061         {
00062                 if (1 != ::sscanf(str.c_str(), frmt, val))
00063                         throw std::runtime_error(
00064                                 mrpt::format(
00065                                         "%s Error parsing attribute '%s'='%s' (Expected "
00066                                         "format:'%s')",
00067                                         function_name_context, varName.c_str(), str.c_str(), frmt));
00068                 double& ang = *reinterpret_cast<double*>(val);
00069                 ang = DEG2RAD(ang);
00070         }
00071         // "%bool" ==> bool*
00072         else if (std::string(frmt) == std::string("%bool"))
00073         {
00074                 bool& bool_val = *reinterpret_cast<bool*>(val);
00075 
00076                 const std::string sStr =
00077                         mrpt::system::lowerCase(mrpt::system::trim(std::string(str)));
00078                 if (sStr == "1" || sStr == "true")
00079                         bool_val = true;
00080                 else if (sStr == "0" || sStr == "false")
00081                         bool_val = false;
00082                 else
00083                         throw std::runtime_error(
00084                                 mrpt::format(
00085                                         "%s Error parsing 'bool' attribute '%s'='%s' (Expected "
00086                                         "'true' or 'false')",
00087                                         function_name_context, varName.c_str(), str.c_str()));
00088         }
00089         // "%color" ==> TColor
00090         else if (std::string(frmt) == std::string("%color"))
00091         {
00092                 // HTML-like format:
00093                 if (!(str.size() > 1 && str[0] == '#'))
00094                         throw std::runtime_error(
00095                                 mrpt::format(
00096                                         "%s Error parsing '%s'='%s' (Expected "
00097                                         "format:'#RRGGBB[AA]')",
00098                                         function_name_context, varName.c_str(), str.c_str()));
00099 
00100                 unsigned int r, g, b, a = 0xff;
00101                 int ret = ::sscanf(str.c_str() + 1, "%2x%2x%2x%2x", &r, &g, &b, &a);
00102                 if (ret != 3 && ret != 4)
00103                         throw std::runtime_error(
00104                                 mrpt::format(
00105                                         "%s Error parsing '%s'='%s' (Expected "
00106                                         "format:'#RRGGBB[AA]')",
00107                                         function_name_context, varName.c_str(), str.c_str()));
00108                 TColor& col = *reinterpret_cast<TColor*>(val);
00109                 col = TColor(r, g, b, a);
00110         }
00111         // "%pose2d"
00112         // "%pose2d_ptr3d"
00113         else if (!strncmp(frmt, "%pose2d", strlen("%pose2d")))
00114         {
00115                 double x, y, yaw;
00116                 int ret = ::sscanf(str.c_str(), "%lf %lf %lf", &x, &y, &yaw);
00117                 if (ret != 3)
00118                         throw std::runtime_error(
00119                                 mrpt::format(
00120                                         "%s Error parsing '%s'='%s' (Expected format:'X Y "
00121                                         "YAW_DEG')",
00122                                         function_name_context, varName.c_str(), str.c_str()));
00123 
00124                 // User provides angles in deg:
00125                 yaw = DEG2RAD(yaw);
00126 
00127                 const mrpt::poses::CPose2D p(x, y, yaw);
00128 
00129                 // Sub-cases:
00130                 if (!strcmp(frmt, "%pose2d"))
00131                 {
00132                         mrpt::poses::CPose2D& pp =
00133                                 *reinterpret_cast<mrpt::poses::CPose2D*>(val);
00134                         pp = p;
00135                 }
00136                 else if (!strcmp(frmt, "%pose2d_ptr3d"))
00137                 {
00138                         mrpt::poses::CPose3D& pp =
00139                                 *reinterpret_cast<mrpt::poses::CPose3D*>(val);
00140                         pp = mrpt::poses::CPose3D(p);
00141                 }
00142                 else
00143                         throw std::runtime_error(
00144                                 mrpt::format(
00145                                         "%s Error: Unknown format specifier '%s'",
00146                                         function_name_context, frmt));
00147         }
00148         else
00149         {
00150                 // Generic parse:
00151                 if (1 != ::sscanf(str.c_str(), frmt, val))
00152                         throw std::runtime_error(
00153                                 mrpt::format(
00154                                         "%s Error parsing attribute '%s'='%s' (Expected "
00155                                         "format:'%s')",
00156                                         function_name_context, varName.c_str(), str.c_str(), frmt));
00157         }
00158 }
00159 
00160 void mvsim::parse_xmlnode_attribs(
00161         const rapidxml::xml_node<char>& xml_node,
00162         const std::map<std::string, TParamEntry>& params,
00163         const char* function_name_context)
00164 {
00165         for (std::map<std::string, TParamEntry>::const_iterator it = params.begin();
00166                  it != params.end(); ++it)
00167         {
00168                 const rapidxml::xml_attribute<char>* attr =
00169                         xml_node.first_attribute(it->first.c_str());
00170                 if (attr && attr->value())
00171                         it->second.parse(
00172                                 attr->value(), attr->name(), function_name_context);
00173         }
00174 }
00175 
00176 bool mvsim::parse_xmlnode_as_param(
00177         const rapidxml::xml_node<char>& xml_node,
00178         const std::map<std::string, TParamEntry>& params,
00179         const char* function_name_context)
00180 {
00181         std::map<std::string, TParamEntry>::const_iterator it_param =
00182                 params.find(xml_node.name());
00183 
00184         if (it_param != params.end())
00185         {
00186                 // parse parameter:
00187                 it_param->second.parse(
00188                         xml_node.value(), xml_node.name(), function_name_context);
00189                 return true;
00190         }
00191         return false;
00192 }
00193 
00196 void mvsim::parse_xmlnode_children_as_param(
00197         const rapidxml::xml_node<char>& root,
00198         const std::map<std::string, TParamEntry>& params,
00199         const char* function_name_context)
00200 {
00201         rapidxml::xml_node<>* node = root.first_node();
00202         while (node)
00203         {
00204                 parse_xmlnode_as_param(*node, params, function_name_context);
00205                 node = node->next_sibling(NULL);  // Move on to next node
00206         }
00207 }
00208 
00214 vec3 mvsim::parseXYPHI(
00215         const std::string& s, bool allow_missing_angle,
00216         double default_angle_radians)
00217 {
00218         vec3 v;
00219         v.vals[2] = RAD2DEG(default_angle_radians);  // Default ang.
00220 
00221         int na =
00222                 ::sscanf(s.c_str(), "%lf %lf %lf", &v.vals[0], &v.vals[1], &v.vals[2]);
00223 
00224         // User provides numbers as degrees:
00225         v.vals[2] = DEG2RAD(v.vals[2]);
00226 
00227         if ((na != 3 && !allow_missing_angle) ||
00228                 (na != 2 && na != 3 && allow_missing_angle))
00229                 throw std::runtime_error(
00230                         mrpt::format("Malformed pose string: '%s'", s.c_str()));
00231 
00232         return v;
00233 }
00234 
00239 void mvsim::parse_xmlnode_shape(
00240         const rapidxml::xml_node<char>& xml_node, mrpt::math::TPolygon2D& out_poly,
00241         const char* function_name_context)
00242 {
00243         out_poly.clear();
00244 
00245         for (rapidxml::xml_node<char>* pt_node = xml_node.first_node("pt"); pt_node;
00246                  pt_node = pt_node->next_sibling("pt"))
00247         {
00248                 if (!pt_node->value())
00249                         throw std::runtime_error(
00250                                 mrpt::format(
00251                                         "%s Error: <pt> node seems empty.", function_name_context));
00252 
00253                 mrpt::math::TPoint2D pt;
00254                 const char* str_val = pt_node->value();
00255                 if (2 != ::sscanf(str_val, "%lf %lf", &pt.x, &pt.y))
00256                         throw std::runtime_error(
00257                                 mrpt::format(
00258                                         "%s Error parsing <pt> node: '%s' (Expected format:'<pt>X "
00259                                         "Y</pt>')",
00260                                         function_name_context, str_val));
00261 
00262                 out_poly.push_back(pt);
00263         }
00264 
00265         if (out_poly.size() < 3)
00266                 throw std::runtime_error(
00267                         mrpt::format(
00268                                 "%s Error: <shape> node requires 3 or more <pt>X Y</pt> "
00269                                 "entries.",
00270                                 function_name_context));
00271 }


mvsim
Author(s):
autogenerated on Thu Jun 6 2019 22:08:35