45#include <visp3/core/vpXmlParserHomogeneousMatrix.h>
51#define LABEL_XML_ROOT "root"
52#define LABEL_XML_M "homogeneous_transformation"
53#define LABEL_XML_M_NAME "name"
54#define LABEL_XML_VALUE "values"
55#define LABEL_XML_TRANSLATION "translation"
56#define LABEL_XML_TX "tx"
57#define LABEL_XML_TY "ty"
58#define LABEL_XML_TZ "tz"
59#define LABEL_XML_ROTATION "rotation"
60#define LABEL_XML_TUX "theta_ux"
61#define LABEL_XML_TUY "theta_uy"
62#define LABEL_XML_TUZ "theta_uz"
64#ifndef DOXYGEN_SHOULD_SKIP_THIS
65class vpXmlParserHomogeneousMatrix::Impl
85 Impl() : m_M(), m_name() {}
89 pugi::xml_document doc;
90 if (!doc.load_file(filename.c_str())) {
91 std::cerr << std::endl <<
"ERROR:" << std::endl;
92 std::cerr <<
" I cannot open the file " << filename << std::endl;
94 return SEQUENCE_ERROR;
97 pugi::xml_node node = doc.document_element();
99 return SEQUENCE_ERROR;
102 int ret = read(node, name);
116 int read(
const pugi::xml_node &node_,
const std::string &name)
120 vpXmlCodeSequenceType back = SEQUENCE_OK;
121 unsigned int nbM = 0;
123 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
124 if (node.type() != pugi::node_element)
127 if (SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
128 prop = CODE_XML_OTHER;
129 back = SEQUENCE_ERROR;
132 if (prop == CODE_XML_M) {
133 if (SEQUENCE_OK == read_matrix(node, name))
136 back = SEQUENCE_ERROR;
140 back = SEQUENCE_ERROR;
141 std::cerr <<
"No Homogeneous matrix is available" << std::endl <<
"with name: " << name << std::endl;
142 }
else if (nbM > 1) {
143 back = SEQUENCE_ERROR;
144 std::cerr << nbM <<
" There are more Homogeneous matrix" << std::endl
145 <<
"with the same name : " << std::endl
146 <<
"precise your choice..." << std::endl;
160 int read_matrix(
const pugi::xml_node &node_,
const std::string &name)
164 std::string M_name_tmp =
"";
167 vpXmlCodeSequenceType back = SEQUENCE_OK;
169 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
170 if (node.type() != pugi::node_element)
173 if (SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
174 prop = CODE_XML_OTHER;
175 back = SEQUENCE_ERROR;
179 case CODE_XML_M_NAME: {
180 M_name_tmp = node.text().as_string();
185 if (name == M_name_tmp) {
186 std::cout <<
"Found Homogeneous Matrix with name: \"" << M_name_tmp <<
"\"" << std::endl;
187 back = read_values(node, M_tmp);
202 back = SEQUENCE_ERROR;
207 if (!(name == M_name_tmp)) {
208 back = SEQUENCE_ERROR;
213 this->m_name = M_name_tmp;
240 vpXmlCodeSequenceType back = SEQUENCE_OK;
242 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
243 if (node.type() != pugi::node_element)
246 if (SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
247 prop = CODE_XML_OTHER;
248 back = SEQUENCE_ERROR;
253 tx_ = node.text().as_double();
257 ty_ = node.text().as_double();
261 tz_ = node.text().as_double();
265 tux_ = node.text().as_double();
269 tuy_ = node.text().as_double();
273 tuz_ = node.text().as_double();
280 case CODE_XML_M_NAME:
284 back = SEQUENCE_ERROR;
290 std::cerr <<
"ERROR in 'model' field:\n";
291 std::cerr <<
"it must contain 6 parameters\n";
293 return SEQUENCE_ERROR;
297 M.
buildFrom(tx_, ty_, tz_, tux_, tuy_, tuz_);
310 int save(
const vpHomogeneousMatrix &M,
const std::string &filename,
const std::string &name)
312 pugi::xml_document doc;
315 if (!doc.load_file(filename.c_str(), pugi::parse_default | pugi::parse_comments)) {
316 node = doc.append_child(pugi::node_declaration);
317 node.append_attribute(
"version") =
"1.0";
318 node = doc.append_child(LABEL_XML_ROOT);
319 pugi::xml_node nodeComment = node.append_child(pugi::node_comment);
320 nodeComment.set_value(
"This file stores homogeneous matrix used\n"
321 " in the vpHomogeneousMatrix Class of ViSP available\n"
322 " at https://visp.inria.fr/download/ .\n"
323 " It can be read with the parse method of\n"
324 " the vpXmlParserHomogeneousMatrix class.");
327 node = doc.document_element();
329 return SEQUENCE_ERROR;
334 int M_isFound = count(node, name);
337 std::cout <<
"There is already an homogeneous matrix " << std::endl
338 <<
"available in the file with the input name: " << name <<
"." << std::endl
339 <<
"Please delete it manually from the xml file." << std::endl;
340 return SEQUENCE_ERROR;
345 doc.save_file(filename.c_str(), PUGIXML_TEXT(
" "));
360 int count(
const pugi::xml_node &node_,
const std::string &name)
365 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
366 if (node.type() != pugi::node_element)
369 if (SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
370 prop = CODE_XML_OTHER;
372 if (prop == CODE_XML_M) {
373 if (SEQUENCE_OK == read_matrix(node, name))
389 int write(pugi::xml_node &node,
const std::string &name)
391 int back = SEQUENCE_OK;
393 pugi::xml_node node_tmp;
394 pugi::xml_node node_matrix;
395 pugi::xml_node node_values;
404 node_tmp = node.append_child(pugi::node_comment);
405 node_tmp.set_value(
"Homogeneous Matrix");
406 node_matrix = node.append_child(LABEL_XML_M);
410 node_tmp = node_matrix.append_child(pugi::node_comment);
411 node_tmp.set_value(
"Name of the homogeneous matrix");
412 node_matrix.append_child(LABEL_XML_M_NAME).append_child(pugi::node_pcdata).set_value(name.c_str());
416 node_values = node_matrix.append_child(LABEL_XML_VALUE);
418 node_tmp = node_values.append_child(pugi::node_comment);
419 node_tmp.set_value(
"Translation vector with values in meters");
422 node_values.append_child(LABEL_XML_TX).append_child(pugi::node_pcdata).text() = m_M[0][3];
425 node_values.append_child(LABEL_XML_TY).append_child(pugi::node_pcdata).text() = m_M[1][3];
428 node_values.append_child(LABEL_XML_TZ).append_child(pugi::node_pcdata).text() = m_M[2][3];
430 node_tmp = node_values.append_child(pugi::node_comment);
431 node_tmp.set_value(
"Rotational vector expressed in angle axis "
432 "representation with values in radians");
435 node_values.append_child(LABEL_XML_TUX).append_child(pugi::node_pcdata).text() = tu[0];
438 node_values.append_child(LABEL_XML_TUY).append_child(pugi::node_pcdata).text() = tu[1];
441 node_values.append_child(LABEL_XML_TUZ).append_child(pugi::node_pcdata).text() = tu[2];
455 vpXmlCodeSequenceType str2xmlcode(
const char *str, vpXmlCodeType &res)
457 vpXmlCodeType val_int = CODE_XML_BAD;
460 if (!strcmp(str, LABEL_XML_M)) {
461 val_int = CODE_XML_M;
462 }
else if (!strcmp(str, LABEL_XML_M_NAME)) {
463 val_int = CODE_XML_M_NAME;
464 }
else if (!strcmp(str, LABEL_XML_VALUE)) {
465 val_int = CODE_XML_VALUE;
466 }
else if (!strcmp(str, LABEL_XML_TX)) {
467 val_int = CODE_XML_TX;
468 }
else if (!strcmp(str, LABEL_XML_TY)) {
469 val_int = CODE_XML_TY;
470 }
else if (!strcmp(str, LABEL_XML_TZ)) {
471 val_int = CODE_XML_TZ;
472 }
else if (!strcmp(str, LABEL_XML_TUX)) {
473 val_int = CODE_XML_TUX;
474 }
else if (!strcmp(str, LABEL_XML_TUY)) {
475 val_int = CODE_XML_TUY;
476 }
else if (!strcmp(str, LABEL_XML_TUZ)) {
477 val_int = CODE_XML_TUZ;
479 val_int = CODE_XML_OTHER;
487 std::string getHomogeneousMatrixName()
const {
return m_name; }
489 void setHomogeneousMatrixName(
const std::string &name) { m_name = name; }
511 return m_impl->parse(M, filename, name);
523 const std::string &name)
525 return m_impl->save(M, filename, name);
530 return m_impl->getHomogeneousMatrix();
535 return m_impl->getHomogeneousMatrixName();
540 m_impl->setHomogeneousMatrixName(name);
Implementation of an homogeneous matrix and operations on such kind of matrices.
void buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
Implementation of a rotation matrix and operations on such kind of matrices.
Implementation of a rotation vector as axis-angle minimal representation.
vpHomogeneousMatrix getHomogeneousMatrix() const
int parse(vpHomogeneousMatrix &M, const std::string &filename, const std::string &name)
std::string getHomogeneousMatrixName() const
int save(const vpHomogeneousMatrix &M, const std::string &filename, const std::string &name)
vpXmlParserHomogeneousMatrix()
~vpXmlParserHomogeneousMatrix()
void setHomogeneousMatrixName(const std::string &name)