00001
00002
00003
00004
00005
00006
00007
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>
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
00047
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
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
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
00090 else if (std::string(frmt) == std::string("%color"))
00091 {
00092
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
00112
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
00125 yaw = DEG2RAD(yaw);
00126
00127 const mrpt::poses::CPose2D p(x, y, yaw);
00128
00129
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
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
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);
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);
00220
00221 int na =
00222 ::sscanf(s.c_str(), "%lf %lf %lf", &v.vals[0], &v.vals[1], &v.vals[2]);
00223
00224
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 }