Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpXmlParserHomogeneousMatrix.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * XML parser to load and save Homogeneous Matrix in a XML file
32  *
33  * Authors:
34  * Giovanni Claudio
35  *
36  *****************************************************************************/
37 
38 
45 #include <visp3/core/vpXmlParserHomogeneousMatrix.h>
46 #ifdef VISP_HAVE_XML2
47 
48 #include <stdlib.h>
49 #include <string.h>
50 
51 #include <visp3/core/vpDebug.h>
52 #include <visp3/core/vpThetaUVector.h>
53 /* -------------------------------------------------------------------------- */
54 /* --- LABEL XML ------------------------------------------------------------ */
55 /* -------------------------------------------------------------------------- */
56 
57 #define LABEL_XML_ROOT "root"
58 #define LABEL_XML_M "homogeneous_transformation"
59 #define LABEL_XML_M_NAME "name"
60 #define LABEL_XML_VALUE "values"
61 #define LABEL_XML_TRANSLATION "translation"
62 #define LABEL_XML_TX "tx"
63 #define LABEL_XML_TY "ty"
64 #define LABEL_XML_TZ "tz"
65 #define LABEL_XML_ROTATION "rotation"
66 #define LABEL_XML_TUX "theta_ux"
67 #define LABEL_XML_TUY "theta_uy"
68 #define LABEL_XML_TUZ "theta_uz"
69 
74  : vpXmlParser(), m_M(), m_name()
75 {
76 }
82  : vpXmlParser(twinParser), m_M(), m_name()
83 {
84  *this = twinParser;
85 }
86 
94 {
95  this->m_M = twinParser.m_M;
96  this->m_name = twinParser.m_name;
97 
98  return *this ;
99 }
100 
109 int
111  const std::string &name)
112 {
113  xmlDocPtr doc;
114  xmlNodePtr node;
115 
116  doc = xmlParseFile(filename.c_str());
117  if (doc == NULL)
118  {
119  std::cerr << std::endl
120  << "ERROR:" << std::endl;
121  std::cerr << " I cannot open the file "<< filename << std::endl;
122 
123  return SEQUENCE_ERROR;
124  }
125 
126  node = xmlDocGetRootElement(doc);
127  if (node == NULL)
128  {
129  xmlFreeDoc(doc);
130  return SEQUENCE_ERROR;
131  }
132 
133  int ret = this ->read (doc, node, name);
134 
135  M = m_M ;
136 
137  xmlFreeDoc(doc);
138 
139  return ret;
140 }
141 
150 int
151 vpXmlParserHomogeneousMatrix::save(const vpHomogeneousMatrix &M, const std::string &filename,
152  const std::string &name)
153 {
154  xmlDocPtr doc;
155  xmlNodePtr node;
156 
157  doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOWARNING + XML_PARSE_NOERROR
158  + XML_PARSE_NOBLANKS);
159  if (doc == NULL){
160  doc = xmlNewDoc ((xmlChar*)"1.0");
161  node = xmlNewNode(NULL,(xmlChar*)LABEL_XML_ROOT);
162  xmlDocSetRootElement(doc,node);
163  xmlNodePtr node_tmp = xmlNewComment((xmlChar*)
164  "This file stores homogeneous matrix used\n"
165  " in the vpHomogeneousMatrix Class of ViSP available\n"
166  " at http://www.irisa.fr/lagadic/visp/visp.html .\n"
167  " It can be read with the parse method of\n"
168  " the vpXmlParserHomogeneousMatrix class.");
169  xmlAddChild(node,node_tmp);
170  }
171 
172  node = xmlDocGetRootElement(doc);
173  if (node == NULL)
174  {
175  xmlFreeDoc(doc);
176  return SEQUENCE_ERROR;
177  }
178 
179  this->m_M = M;
180 
181  int M_isFound = count(doc, node, name);
182 
183  if( M_isFound > 0){
184  //vpCERROR
185  std::cout << "There is already an homogeneous matrix "<< std::endl
186  << "available in the file with the input name: "<< name << "."<< std::endl
187  << "Please delete it manually from the xml file."<< std::endl;
188  xmlFreeDoc(doc);
189  return SEQUENCE_ERROR;
190  }
191 
192  write(node, name);
193 
194  xmlSaveFormatFile(filename.c_str(), doc, 1);
195  xmlFreeDoc(doc);
196 // std::cout << "Homogeneous matrix '"<< name << "' saved in the file named "<< filename << " correctly." << std::endl;
197 
198  return SEQUENCE_OK;
199 }
200 
201 
202 
211 int
212 vpXmlParserHomogeneousMatrix::read (xmlDocPtr doc, xmlNodePtr node,
213  const std::string& name)
214 {
215  // char * val_char;
216  vpXmlCodeType prop;
217 
219  unsigned int nbM = 0;
220 
221  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
222  {
223  if (node->type != XML_ELEMENT_NODE) continue;
224  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
225  {
226  prop = CODE_XML_OTHER;
227  back = SEQUENCE_ERROR;
228  }
229 
230  if (prop == CODE_XML_M){
231  if (SEQUENCE_OK == this->read_matrix (doc, node, name))
232  nbM++;
233  }
234  else back = SEQUENCE_ERROR;
235  }
236 
237  if (nbM == 0){
238  back = SEQUENCE_ERROR;
239  vpCERROR << "No Homogeneous matrix is available" << std::endl
240  << "with name: " << name << std::endl;
241  }
242  else if(nbM > 1){
243  back = SEQUENCE_ERROR;
244  vpCERROR << nbM << " There are more Homogeneous matrix" << std::endl
245  << "with the same name : " << std::endl
246  << "precise your choice..." << std::endl;
247  }
248 
249  return back;
250 }
261 int
262 vpXmlParserHomogeneousMatrix::count (xmlDocPtr doc, xmlNodePtr node,
263  const std::string& name)
264 {
265  // char * val_char;
266  vpXmlCodeType prop;
267  int nbM = 0;
268 
269  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
270  {
271  if (node->type != XML_ELEMENT_NODE) continue;
272  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
273  {
274  prop = CODE_XML_OTHER;
275  }
276  if (prop== CODE_XML_M) {
277  if (SEQUENCE_OK == this->read_matrix (doc, node, name))
278  nbM++;
279  }
280  }
281 
282  return nbM;
283 }
284 
295 int
296 vpXmlParserHomogeneousMatrix::read_matrix (xmlDocPtr doc, xmlNodePtr node,
297  const std::string& name)
298 {
299  vpXmlCodeType prop;
300  /* read value in the XML file. */
301  std::string M_name_tmp = "";
302  vpHomogeneousMatrix M_tmp;
303 
305 
306  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
307  {
308  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
309  if (node->type != XML_ELEMENT_NODE) continue;
310  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
311  {
312  prop = CODE_XML_OTHER;
313  back = SEQUENCE_ERROR;
314  }
315 
316 
317  switch (prop)
318  {
319  case CODE_XML_M_NAME: {
320  char * val_char = xmlReadCharChild(doc, node);
321  M_name_tmp = val_char;
322  xmlFree(val_char);
323  break;
324  }
325 
326  case CODE_XML_VALUE: //VALUE
327  if (name == M_name_tmp)
328  {
329  std::cout << "Found Homogeneous Matrix with name: \"" << M_name_tmp << "\"" << std::endl;
330  back = read_values(doc, node, M_tmp);
331  }
332  break;
333 
334  case CODE_XML_BAD:
335  case CODE_XML_OTHER:
336  case CODE_XML_M:
337  case CODE_XML_TX:
338  case CODE_XML_TY:
339  case CODE_XML_TZ:
340  case CODE_XML_TUX:
341  case CODE_XML_TUY:
342  case CODE_XML_TUZ:
343 
344  default:
345  back = SEQUENCE_ERROR;
346  break;
347  }
348 
349  }
350 
351  if( !(name == M_name_tmp)){
352  back = SEQUENCE_ERROR;
353  }
354  else{
355  this-> m_M = M_tmp;
356  //std::cout << "Convert in Homogeneous Matrix:"<< std::endl;
357  //std::cout << this-> M << std::endl;
358  this-> m_name = M_name_tmp;
359 
360  }
361  return back;
362 }
363 
364 
376 vpXmlParserHomogeneousMatrix::read_values (xmlDocPtr doc, xmlNodePtr node,
378 {
379  // counter of the number of read parameters
380  int nb = 0;
381  vpXmlCodeType prop;
382  /* read value in the XML file. */
383 
384  double tx_=0.;
385  double ty_=0.;
386  double tz_=0.;
387  double tux_=0.;
388  double tuy_=0.;
389  double tuz_=0.;
390 
392  //int validation = 0;
393 
394  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
395  {
396  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
397  if (node->type != XML_ELEMENT_NODE) continue;
398  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
399  {
400  prop = CODE_XML_OTHER;
401  back = SEQUENCE_ERROR;
402  }
403 
404  switch (prop)
405  {
406 
407  case CODE_XML_TX:
408  tx_ = xmlReadDoubleChild(doc, node);
409  nb++;
410  break;
411  case CODE_XML_TY:
412  ty_ = xmlReadDoubleChild(doc, node);
413  nb++;
414  break;
415  case CODE_XML_TZ:
416  tz_ = xmlReadDoubleChild(doc, node);
417  nb++;
418  break;
419  case CODE_XML_TUX:
420  tux_ = xmlReadDoubleChild(doc, node);
421  nb++;
422  break;
423  case CODE_XML_TUY:
424  tuy_ = xmlReadDoubleChild(doc, node);
425  nb++;
426  break;
427  case CODE_XML_TUZ:
428  tuz_ = xmlReadDoubleChild(doc, node);
429  nb++;
430  break;
431 
432  case CODE_XML_BAD:
433  case CODE_XML_OTHER:
434  case CODE_XML_M:
435  case CODE_XML_M_NAME:
436  case CODE_XML_VALUE:
437 
438  default:
439  back = SEQUENCE_ERROR;
440  break;
441  }
442  }
443 
444  if (nb != 6)
445  {
446  vpCERROR <<"ERROR in 'model' field:\n";
447  vpCERROR << "it must contain 6 parameters\n";
448 
449  return SEQUENCE_ERROR;
450  }
451 
452  // Create the Homogeneous matrix
453  M.buildFrom(tx_,ty_,tz_,tux_,tuy_,tuz_);
454 
455  // std::cout << "Read values from file:" << std::endl;
456  // std::cout << "tx:" << tx_<< std::endl;
457  // std::cout << "ty:" << ty_<< std::endl;
458  // std::cout << "tz:" << tz_<< std::endl;
459  // std::cout << "tux:" << tux_<< std::endl;
460  // std::cout << "tuy:" << tuy_<< std::endl;
461  // std::cout << "tuz:" << tuz_<< std::endl;
462 
463  return back;
464 }
465 
475 int vpXmlParserHomogeneousMatrix::
476 write (xmlNodePtr node, const std::string& name)
477 {
478  int back = SEQUENCE_OK;
479 
480  xmlNodePtr node_tmp;
481  xmlNodePtr node_matrix;
482  xmlNodePtr node_values;
483 
484  // Convert from Rotational matrix to Theta-U vector
486  m_M.extract(R);
487 
488  vpThetaUVector tu(R);
489 
490  // <homogeneous_transformation>
491  node_tmp = xmlNewComment((xmlChar*)"Homogeneous Matrix");
492  xmlAddChild(node,node_tmp);
493  node_matrix = xmlNewNode(NULL,(xmlChar*)LABEL_XML_M);
494  xmlAddChild(node,node_matrix);
495  {
496  //<name>
497 
498  if(!name.empty()){
499  node_tmp = xmlNewComment((xmlChar*)"Name of the homogeneous matrix");
500  xmlAddChild(node_matrix,node_tmp);
501  xmlNewTextChild(node_matrix,NULL,(xmlChar*)LABEL_XML_M_NAME, (xmlChar*)name.c_str());
502  }
503 
504  //<values>
505 
506  node_values = xmlNewNode(NULL,(xmlChar*)LABEL_XML_VALUE);
507  xmlAddChild(node_matrix,node_values);
508  {
509  char str[11];
510 
511  node_tmp = xmlNewComment((xmlChar*)"Translation vector with values in meters");
512  xmlAddChild(node_values,node_tmp);
513 
514  //<tx>
515  sprintf(str,"%f", m_M[0][3]);
516  xmlNewTextChild(node_values,NULL,(xmlChar*)LABEL_XML_TX,(xmlChar*)str);
517 
518  //<ty>
519  sprintf(str,"%f", m_M[1][3]);
520  xmlNewTextChild(node_values,NULL,(xmlChar*)LABEL_XML_TY,(xmlChar*)str);
521 
522  //<tz>
523  sprintf(str,"%f", m_M[2][3]);
524  xmlNewTextChild(node_values,NULL,(xmlChar*)LABEL_XML_TZ,(xmlChar*)str);
525 
526  node_tmp = xmlNewComment((xmlChar*)"Rotational vector expressed in angle axis representation with values in radians");
527  xmlAddChild(node_values,node_tmp);
528 
529  //<tux>
530  sprintf(str,"%f", tu[0]);
531  xmlNewTextChild(node_values,NULL,(xmlChar*)LABEL_XML_TUX,(xmlChar*)str);
532 
533  //<tuy>
534  sprintf(str,"%f", tu[1]);
535  xmlNewTextChild(node_values,NULL,(xmlChar*)LABEL_XML_TUY,(xmlChar*)str);
536 
537  //<tuz>
538  sprintf(str,"%f", tu[2]);
539  xmlNewTextChild(node_values,NULL,(xmlChar*)LABEL_XML_TUZ,(xmlChar*)str);
540  }
541  }
542  return back;
543 }
544 
554 vpXmlParserHomogeneousMatrix::str2xmlcode (char * str, vpXmlCodeType & res)
555 {
556  vpXmlCodeType val_int = CODE_XML_BAD;
558 
559  // DEBUG_TRACE (9, "# Entree :str=%s.", str);
560 
561  if (! strcmp (str, LABEL_XML_M))
562  {
563  val_int = CODE_XML_M;
564  }
565  else if (! strcmp (str, LABEL_XML_M_NAME))
566  {
567  val_int = CODE_XML_M_NAME;
568  }
569  else if (! strcmp (str, LABEL_XML_VALUE))
570  {
571  val_int = CODE_XML_VALUE;
572  }
573  else if (! strcmp (str, LABEL_XML_TX))
574  {
575  val_int = CODE_XML_TX;
576  }
577  else if (! strcmp (str, LABEL_XML_TY))
578  {
579  val_int = CODE_XML_TY;
580  }
581  else if (! strcmp (str, LABEL_XML_TZ))
582  {
583  val_int = CODE_XML_TZ;
584  }
585  else if (! strcmp (str, LABEL_XML_TUX))
586  {
587  val_int = CODE_XML_TUX;
588  }
589  else if (! strcmp (str, LABEL_XML_TUY))
590  {
591  val_int = CODE_XML_TUY;
592  }
593  else if (! strcmp (str, LABEL_XML_TUZ))
594  {
595  val_int = CODE_XML_TUZ;
596  }
597  else
598  {
599  val_int = CODE_XML_OTHER;
600  }
601  res = val_int;
602 
603  return back;
604 }
605 #elif !defined(VISP_BUILD_SHARED_LIBS)
606 // Work arround to avoid warning: libvisp_core.a(vpXmlParserHomogeneousMatrix.cpp.o) has no symbols
607 void dummy_vpXmlParserHomogeneousMatrix() {};
608 #endif //VISP_HAVE_XML2
int parse(vpHomogeneousMatrix &M, const std::string &filename, const std::string &name)
#define vpCERROR
Definition: vpDebug.h:365
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpXmlParserHomogeneousMatrix & operator=(const vpXmlParserHomogeneousMatrix &twinparser)
double xmlReadDoubleChild(xmlDocPtr doc, xmlNodePtr node)
char * xmlReadCharChild(xmlDocPtr doc, xmlNodePtr node)
Implementation of a rotation matrix and operations on such kind of matrices.
This class intends to simplify the creation of xml parser based on the libxml2 third party library...
Definition: vpXmlParser.h:175
int save(const vpHomogeneousMatrix &M, const std::string &filename, const std::string &name)
XML parser to load and save an homogeneous matrix in a file.
void extract(vpRotationMatrix &R) const
void buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
Implementation of a rotation vector as axis-angle minimal representation.