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