object_configuration_generator.cpp
Go to the documentation of this file.
1 
18 //Global includes
19 #include <string>
20 #include <vector>
21 
22 //Pkg includes
23 #include <ros/ros.h>
24 #include <ros/package.h>
25 
26 #include <visualization_msgs/Marker.h>
27 #include <visualization_msgs/MarkerArray.h>
28 
29 #include <asr_ism_visualizations/VizHelperRVIZ.hpp>
30 
31 #include <ISM/utility/TableHelper.hpp>
32 #include <ISM/common_type/Pose.hpp>
33 #include <ISM/common_type/Track.hpp>
34 #include <ISM/common_type/Tracks.hpp>
35 
36 #include <ISM/utility/GeometryHelper.hpp>
37 #include <ISM/utility/Util.hpp>
38 
39 #include <termios.h> //termios, TCSANOW, ECHO, ICANON
40 #include <unistd.h> //STDIN_FILENO
41 
42 #include <iostream>
43 #include <fstream>
44 
45 #include <rapidxml.hpp>
46 #include <rapidxml_utils.hpp>
47 
48 #include <boost/lexical_cast.hpp>
49 #include <boost/algorithm/string.hpp>
50 #include <boost/filesystem/path.hpp>
51 
52 
53 
54 struct termios originalSettings, modifiedSettings;
56 
57 #define KEY_NEXT_OBJECT 0x77 //w
58 #define KEY_PREV_OBJECT 0x73 //s
59 #define KEY_NEXT_POSE 0x64 //d
60 #define KEY_PREV_POSE 0x61 //a
61 #define KEY_SWITCH_EDIT 0x65 //e
62 #define KEY_MARK 0x6D //m
63 #define KEY_SAVE 0x6F //o
64 #define KEY_SHOW 0x70 //p
65 
67 {
68 
69 public:
70 
72  {
73  std::vector<std::string> patternNames;
74  std::string configFilePath;
75  getNodeParameters(patternNames, configFilePath);
76 
77  if (boost::filesystem::exists(configFilePath))
78  {
79  ISM::printGreen("Load objects from config-file.\n");
80  loadConstellationFromConfigFile(configFilePath);
81  }
82  else if (boost::filesystem::exists(mDbFilename))
83  {
84  ISM::printGreen("Load objects from database.\n");
85  if (patternNames.empty())
86  {
87  std::stringstream ss;
88  ss << "Parameter object_configuration_pattern_names must be specified, if database is used!";
89  ROS_ERROR_STREAM(ss.str());
90  throw std::runtime_error(ss.str());
91  }
92 
93  tableHandler = ISM::TableHelperPtr(new ISM::TableHelper(mDbFilename));
94  if(!tableHandler->recordDataExists())
95  {
96  std::stringstream ss;
97  ss << "The database \"" << mDbFilename << "\" doesn't contain any recordings!\n";
98  ROS_ERROR_STREAM(ss.str());
99  throw std::runtime_error(ss.str());
100  }
101 
102  initFromDatabase(patternNames);
103  }
104  else
105  {
106  std::stringstream ss;
107  ss << "Couldn't load any data! Check path to config-file or to database in the launch-file." << std::endl;
108  ROS_ERROR_STREAM(ss.str());
109  throw std::runtime_error(ss.str());
110  }
111 
112  visualization_pub = nh.advertise<visualization_msgs::MarkerArray>(visualizationTopic, 100);
113 
114  ISM::printGreen("WAITING FOR SUBSCRIBER\n");
115  while (visualization_pub.getNumSubscribers() == 0) {
116  ros::Duration(0.5).sleep();
117  }
118  visualize();
119 
120  ISM::printGreen("Started Object Configuration Generator!\n\n");
121 
123  }
124 
125 #include <boost/filesystem/path.hpp>
126 
128  {
129 
130  }
131 
132 private:
133 
138  void getNodeParameters(std::vector<std::string>& patternNames, std::string& configFilePath)
139  {
140  if (!nh.getParam("dbfilename", mDbFilename))
141  {
142  mDbFilename = "";
143  }
144  ROS_INFO_STREAM("dbfilename: " << mDbFilename);
145 
146  nh.getParam("object_configuration_pattern_names", patternNames);
147  ROS_INFO_STREAM("object_configuration_pattern_names: ");
148  for (unsigned int i = 0; i < patternNames.size(); ++i)
149  {
150  ROS_INFO_STREAM(patternNames.at(i));
151  }
152 
153  if (!nh.getParam("baseFrame", baseFrame))
154  {
155  baseFrame = "";
156  }
157  ROS_INFO_STREAM("baseFrame: " << baseFrame);
158 
159  if (!nh.getParam("visualization_topic", visualizationTopic))
160  {
161  visualizationTopic = "";
162  }
163  ROS_INFO_STREAM("visualization_topic: " << visualizationTopic);
164 
165  if (!nh.getParam("output_file_path", output_file_path) || output_file_path.empty())
166  {
167  std::stringstream ss;
168  ss << "Parameter output_file_path must be specified!";
169  ROS_ERROR_STREAM(ss.str());
170  throw std::runtime_error(ss.str());
171  }
172  ROS_INFO_STREAM("output_file_path: " << output_file_path);
173 
174  if (!nh.getParam("config_file_path", configFilePath))
175  {
176  configFilePath = "";
177  }
178  ROS_INFO_STREAM("config_file_path: " << configFilePath);
179 
180  }
181 
185  void visualize()
186  {
187  for (unsigned int i = 0; i < markerArray.markers.size(); ++i)
188  {
189  markerArray.markers[i].action = visualization_msgs::Marker::DELETE;
190  }
192  markerArray.markers.clear();
193 
194  unsigned int markerCount = 0;
195 
196  for (unsigned int i = 0; i < objectAndPoses.size(); ++i)
197  {
198  std::pair<ISM::ObjectPtr, std::vector<ISM::PosePtr>> pair = objectAndPoses[i];
199  std::string path = pair.first->ressourcePath.string();
200 
201  bool marked = isMarked(pair.first);
202 
203  if (i == objectCounter)
204  {
205  //visualize selected object
206  unsigned int idx = poseCounters[objectCounter];
207  markerArray.markers.push_back(VIZ::VizHelperRVIZ::createMeshMarker(pair.second[idx], baseFrame, markerNamespace, markerCount, SELECTED, markerLifetime, path));
208  markerCount++;
209 
210  ISM::PosePtr pose = pair.second[idx];
211 
212  Eigen::Quaternion<double> rot = ISM::GeometryHelper::quatToEigenQuat(pose->quat);
213  Eigen::Matrix3d rotation = rot.toRotationMatrix();
214 
215  Eigen::Vector3d xAxis = rotation * Eigen::Vector3d::UnitX() * 0.5;
216  Eigen::Vector3d yAxis = rotation * Eigen::Vector3d::UnitY() * 0.5;
217  Eigen::Vector3d zAxis = rotation * Eigen::Vector3d::UnitZ() * 0.5;
218 
219  ISM::PointPtr xEnd = ISM::PointPtr(new ISM::Point(pose->point->eigen.x() + xAxis[0],
220  pose->point->eigen.y() + xAxis[1],
221  pose->point->eigen.z() + xAxis[2]));
222  ISM::PointPtr yEnd = ISM::PointPtr(new ISM::Point(pose->point->eigen.x() + yAxis[0],
223  pose->point->eigen.y() + yAxis[1],
224  pose->point->eigen.z() + yAxis[2]));
225  ISM::PointPtr zEnd = ISM::PointPtr(new ISM::Point(pose->point->eigen.x() + zAxis[0],
226  pose->point->eigen.y() + zAxis[1],
227  pose->point->eigen.z() + zAxis[2]));
228  markerArray.markers.push_back(VIZ::VizHelperRVIZ::createArrowMarkerToPoint(pair.second[idx]->point, xEnd, baseFrame, markerNamespace, markerCount, 0.01f, 0.01f, 0.01f, X_AXIS, markerLifetime));
229  markerCount++;
230  markerArray.markers.push_back(VIZ::VizHelperRVIZ::createArrowMarkerToPoint(pair.second[idx]->point, yEnd, baseFrame, markerNamespace, markerCount, 0.01f, 0.01f, 0.01f, Y_AXIS, markerLifetime));
231  markerCount++;
232  markerArray.markers.push_back(VIZ::VizHelperRVIZ::createArrowMarkerToPoint(pair.second[idx]->point, zEnd, baseFrame, markerNamespace, markerCount, 0.01f, 0.01f, 0.01f, Z_AXIS, markerLifetime));
233  markerCount++;
234 
235  //visualize trajectory of selected object
236  for (unsigned int j = 0; j < pair.second.size(); ++j)
237  {
238  if (marked && poseCounters[objectCounter] == j)
239  {
240  markerArray.markers.push_back(VIZ::VizHelperRVIZ::createSphereMarker(pair.second[j]->point, baseFrame, markerNamespace, markerCount, sphere_radius, MARKED, markerLifetime));
241  }
242  else
243  {
244  markerArray.markers.push_back(VIZ::VizHelperRVIZ::createSphereMarker(pair.second[j]->point, baseFrame, markerNamespace, markerCount, sphere_radius, IN_CURRENT_TRACK, markerLifetime));
245  }
246  markerCount++;
247  }
248  }
249  else
250  {
251  //visualize remaining objects
252  if (marked)
253  {
254  markerArray.markers.push_back(VIZ::VizHelperRVIZ::createMeshMarker(pair.second[poseCounters[i]], baseFrame, markerNamespace, markerCount, MARKED, markerLifetime, path));
255  }
256  else
257  {
258  std_msgs::ColorRGBA color = VIZ::VizHelperRVIZ::getColorOfObject(pair.first);
259  markerArray.markers.push_back(VIZ::VizHelperRVIZ::createMeshMarker(pair.second[poseCounters[i]], baseFrame, markerNamespace, markerCount, color, markerLifetime, path));
260  }
261  markerCount++;
262  }
263  }
264 
266  }
267 
272  {
273  ISM::ObjectPtr obj = objectAndPoses[objectCounter].first;
274  if (isMarked(obj))
275  {
276  ISM::printBlue("\tUNMARKED OBJECT\n");
277  markedObjects.erase(obj->type + obj->observedId);
278  }
279  else
280  {
281  ISM::printBlue("\tMARKED OBJECT\n");
282  markedObjects.insert(obj->type + obj->observedId);
283  }
284  }
285 
290  void initFromDatabase(std::vector<std::string>& patternNames)
291  {
292  bool gotAnyObjects = false;
293  std::vector<ISM::ObjectSetPtr> objectsInPattern;
294  for(unsigned int i = 0; i < patternNames.size(); ++i)
295  {
296  std::string patternName = patternNames.at(i);
297  if (tableHandler->getRecordedPatternId(patternName) == 0)
298  {
299  std::stringstream ss;
300  ss << "Could not find pattern " + patternName + " in database " + mDbFilename + "!";
301  ROS_ERROR_STREAM(ss.str());
302  continue;
303  }
304  else
305  {
306  ISM::printGreen("Load pattern \"" + patternName + "\" from database.\n");
307  }
308 
309  std::vector<ISM::ObjectSetPtr> objects = tableHandler->getRecordedPattern(patternName)->objectSets;
310  objectsInPattern.insert(objectsInPattern.end(), objects.begin(), objects.end());
311 
312  gotAnyObjects = gotAnyObjects || !objects.empty();
313  }
314  if (!gotAnyObjects)
315  {
316  std::stringstream ss;
317  ss << "Couldn't load any data! Check your database or selected pattern." << std::endl;
318  ROS_ERROR_STREAM(ss.str());
319  throw std::runtime_error(ss.str());
320  }
321  ISM::TracksPtr tracksInPattern = ISM::TracksPtr(new ISM::Tracks(objectsInPattern));
322 
323  for (size_t it = 0; it < tracksInPattern->tracks.size(); ++it)
324  {
325  if (it < tracksInPattern->tracks.size() - 1 && !tracksInPattern->tracks[it]->objects.size() == tracksInPattern->tracks[it + 1]->objects.size())
326  {
327  std::cerr<<"Corrupt database\n";
328  exit(-6);
329  }
330  }
331 
332  for (unsigned int i = 0; i < tracksInPattern->tracks.size(); ++i)
333  {
334  std::vector<ISM::ObjectPtr> objects = tracksInPattern->tracks[i]->objects;
335  std::vector<ISM::PosePtr> poses;
336  ISM::ObjectPtr obj;
337 
338  for (ISM::ObjectPtr object : objects)
339  {
340  if (object)
341  {
342  poses.push_back(object->pose);
343 
344  if(!obj)
345  {
346  obj = ISM::ObjectPtr(new ISM::Object(*object));
347  }
348  }
349  }
350 
351  std::stringstream ss;
352  ss << "Loaded " << obj->type << " " << obj->observedId << " from database with " << poses.size() << " poses." << std::endl;
353  ISM::printGreen(ss.str());
354 
355  objectAndPoses.push_back(std::make_pair(obj, poses));
356  poseCounters.push_back(0);
357  editFlags.push_back(false);
358  }
359  }
360 
361  enum SelectEntity{Previous = -1, Next = 1};
362 
366  void switchObject(SelectEntity neighbor)
367  {
368  if(objectAndPoses.size() <= 0)
369  return;
370  objectCounter = ((objectCounter + objectAndPoses.size()) + neighbor) % objectAndPoses.size();
371 
372 
373  std::string pose_str = " at ";
375  {
376  pose_str += "edited pose";
377  }
378  else
379  {
380  pose_str += "pose " + std::to_string(poseCounters[objectCounter]);
381  }
382  ISM::printBlue("\tNOW AT OBJECT " + objectAndPoses[objectCounter].first->type + " " + objectAndPoses[objectCounter].first->observedId + pose_str + "\n" );
383  }
384 
388  void switchPose(SelectEntity neighbor)
389  {
390  if(objectAndPoses.size() <= 0)
391  return;
394  {
395  ISM::printBlue("\tSWITCHED TO EDITED POSE\n" );
396  }
397  else
398  {
399  ISM::printBlue("\tSWITCHED TO POSE " + std::to_string(poseCounters[objectCounter]) + "\n" );
400  }
401  }
402 
407  {
409 
410  //Set-up everything for keyboard input
411  tcgetattr( STDIN_FILENO, &originalSettings); // save original terminal settings
412  modifiedSettings = originalSettings;
413  modifiedSettings.c_lflag &= ~(ICANON | ECHO); // disable buffering
414  modifiedSettings.c_iflag |= IUCLC; // map upper case to lower case
415  modifiedSettings.c_cc[VMIN] = 0; // minimal characters awaited
416  modifiedSettings.c_cc[VTIME] = 0; // time keep reading after last byte
417  tcsetattr( STDIN_FILENO, TCSANOW, &modifiedSettings); // apply modified terminal settings
418  //Timer to poll for keyboard inputtrack
420  return;
421  }
422 
427  {
428  std::stringstream commands;
429  commands << "Possible commands:\n"
430  << "\tpress \"w\"\tchoose next object for pose configuration\n"
431  << "\tpress \"s\"\tchoose previous object for pose configuration\n"
432  << "\tpress \"a\"\tchoose previous object pose for pose configuration\n"
433  << "\tpress \"d\"\tchoose next object pose for pose configuration\n"
434  << "\tpress \"m\"\tmark selected pose\n"
435  << "\tpress \"p\"\tshow marked objects\n"
436  << "\tpress \"o\"\tsave marked (red) object poses to file\n"
437  << "\tpress \"e\"\tchange into edit mode\n";
438 
439  ISM::printYellow(commands.str() + "\n");
440  ISM::printBlue("\tNOW AT OBJECT " + objectAndPoses[objectCounter].first->type + " " + objectAndPoses[objectCounter].first->observedId + "\n" );
441 
442  return;
443  }
444 
449  {
450  ISM::printRed("");
451  ISM::printRed("X-Axis is red\n");
452  ISM::printGreen("Y-Axis is green\n");
453  ISM::printBlue("Z-Axis is blue\n");
454 
455  std::stringstream commands;
456  commands << "\nPossible commands:\n"
457  << "\ttype \"s\" and enter\tsave pose changes\n"
458  << "\ttype \"d\" and enter\tdiscard pose changes\n";
459 
460  ISM::printYellow(commands.str() + "\n");
461  }
462 
463 
468  {
469  ISM::printBlue("MARKED OBJECTS:\n");
470  for (unsigned int i = 0; i < objectAndPoses.size(); i++)
471  {
472  if (isMarked(objectAndPoses[i].first))
473  {
474  std::string pose_str = " at ";
475  if(editFlags[i] && (poseCounters[i] == objectAndPoses[i].second.size() - 1))
476  {
477  pose_str += "edited pose";
478  }
479  else
480  {
481  pose_str += "pose " + std::to_string(poseCounters[i]);
482  }
483 
484  ISM::printYellow("\t" + objectAndPoses[i].first->type + " " + objectAndPoses[i].first->observedId + pose_str + "\n");
485  }
486  }
487 
488  return;
489  }
490 
491 
497  {
498  int tempKeyValue = getchar();
499  tcflush(STDIN_FILENO, TCIFLUSH); //flush unread input, because we don't want to process old input from buffer.
500 
501  // don't accept repeated key input if a key is still pressed.
502  if (tempKeyValue < 0)
503  {
504  keyPressed = false;
505  return;
506  }
507  else if(!keyPressed)
508  {
509  keyPressed =true;
510  }
511  else
512  {
513  return;
514  }
515 
516 
517  switch(tempKeyValue)
518  {
519  case KEY_NEXT_OBJECT:
520  switchObject(SelectEntity::Next);
521  break;
522  case KEY_PREV_OBJECT:
523  switchObject(SelectEntity::Previous);
524  break;
525  case KEY_NEXT_POSE:
526  switchPose(SelectEntity::Next);
527  break;
528  case KEY_PREV_POSE:
529  switchPose(SelectEntity::Previous);
530  break;
531  case KEY_SWITCH_EDIT:
532  ISM::printBlue("\tSWITCHED INTO EDITING MODE\n");
534  tcsetattr( STDIN_FILENO, TCSANOW, &originalSettings);
535  runEditMode();
536  break;
537  case KEY_MARK:
538  markOrUnmark();
539  break;
540  case KEY_SAVE:
542  ISM::printBlue("\tSAVED OBJECT CONFIGURATION TO " + output_file_path + "\n");
543  break;
544  case KEY_SHOW:
546  break;
547  }
548 
549  visualize();
550  return;
551  }
552 
556  void runEditMode()
557  {
558  std::vector<double> editParameters;
559  editParameters.reserve(6);
560  unsigned int editCounter = 0;
561 
562  ISM::PosePtr copy = ISM::PosePtr(new ISM::Pose(*objectAndPoses[objectCounter].second[poseCounters[objectCounter]]));
563  ISM::PosePtr pose = objectAndPoses[objectCounter].second[poseCounters[objectCounter]];
564 
566 
567  while (true)
568  {
569  if (editCounter < 3)
570  {
571  ISM::printGreen("\tEnter offset along ");
572  }
573  else
574  {
575  ISM::printGreen("\tEnter rotation around ");
576  }
577 
578  if (editCounter % 3 == 0) ISM::printRed("x-axis ");
579  if (editCounter % 3 == 1) ISM::printGreen("y-axis ");
580  if (editCounter % 3 == 2) ISM::printBlue("z-axis ");
581 
582  if (editCounter < 3)
583  {
584  ISM::printGreen("(in meters): \n\t");
585  }
586  else
587  {
588  ISM::printGreen("(in degree): \n\t");
589  }
590 
591  std::string value;
592  std::getline(std::cin, value);
593 
594  if (value.compare("s") == 0)
595  {
596  ISM::printBlue("\tSAVED CHANGES\n\tEXITED EDITING MODE\n");
597 
599  if (editFlags[objectCounter])
600  {
601  objectAndPoses[objectCounter].second.back() = pose;
602  }
603  else
604  {
605  objectAndPoses[objectCounter].second.push_back(pose);
606  editFlags[objectCounter] = true;
607  }
609 
610  markedObjects.insert(objectAndPoses[objectCounter].first->type + objectAndPoses[objectCounter].first->observedId);
611  ISM::printBlue("\tOBJECT MARKED\n");
612 
614  break;
615  }
616  else if (value.compare("d") == 0)
617  {
618  ISM::printRed("\tDISCARDED CHANGES\n");
619  ISM::printBlue("\tEXITED EDITING MODE\n");
620 
622 
624  break;
625  }
626  else
627  {
628  try
629  {
630  double offset = value.empty() ? 0.0 : boost::lexical_cast<double>(value);
631  switch (editCounter)
632  {
633  case 0 :
634  translate(offset, 0, 0, pose);
635  break;
636  case 1 :
637  translate(0, offset, 0, pose);
638  break;
639  case 2 :
640  translate(0, 0, offset, pose);
641  break;
642  case 3 :
643  rotate(offset, 0, 0, pose);
644  break;
645  case 4 :
646  rotate(0, offset, 0, pose);
647  break;
648  case 5 :
649  rotate(0, 0, offset, pose);
650  break;
651  }
652 
653  editCounter = (editCounter + 1) % 6;
654  visualize();
655  }
656  catch(boost::bad_lexical_cast& e)
657  {
659  }
660 
661  }
662  }
663  }
664 
665 
669  bool isMarked(const ISM::ObjectPtr& obj)
670  {
671  return markedObjects.count(obj->type + obj->observedId);
672  }
673 
678  {
679  std::ofstream myfile;
680  std::ostringstream s;
681  myfile.open (output_file_path);
682  myfile << "<Objects>";
683 
684  for (unsigned int i = 0; i < objectAndPoses.size(); i++)
685  {
686  ISM::ObjectPtr obj = objectAndPoses[i].first;
687  if (isMarked(obj))
688  {
689  ISM::PosePtr pose = objectAndPoses[i].second[poseCounters[i]];
690  Eigen::Quaterniond poseQuat(pose->quat->eigen.w(),
691  pose->quat->eigen.x(),
692  pose->quat->eigen.y(),
693  pose->quat->eigen.z());
694  Eigen::Matrix3d poseMat = poseQuat.toRotationMatrix();
695  Eigen::Vector3d poseAngles = poseMat.eulerAngles(0,1,2);
696 
697  myfile << "<Object "
698  << "type=\"" << obj->type
699  << "\" id=\"" << obj->observedId
700  << "\" mesh=\"" << obj->ressourcePath.string()
701  << "\" angles=\"euler\">" << pose->point->eigen.x()
702  << "," << pose->point->eigen.y()
703  << "," << pose->point->eigen.z()
704  << "," << poseAngles[0]*180/M_PI
705  << "," << poseAngles[1]*180/M_PI
706  << "," << poseAngles[2]*180/M_PI
707  << " </Object>";
708  }
709  }
710  myfile << "</Objects>";
711  myfile.close();
712  }
713 
714 
722  void rotate(double alpha, double beta, double gamma, ISM::PosePtr pose)
723  {
724  Eigen::Matrix3d rotateBy;
725  rotateBy = Eigen::AngleAxisd(alpha * (M_PI / 180), Eigen::Vector3d::UnitX())
726  * Eigen::AngleAxisd(beta * (M_PI / 180), Eigen::Vector3d::UnitY())
727  * Eigen::AngleAxisd(gamma * (M_PI / 180), Eigen::Vector3d::UnitZ());
728 
729  Eigen::Quaternion<double> rot = ISM::GeometryHelper::quatToEigenQuat(pose->quat);
730  Eigen::Matrix3d original = rot.toRotationMatrix();
731  original = original * rotateBy;
732  Eigen::Quaternion<double> result(original);
733  pose->quat = ISM::GeometryHelper::eigenQuatToQuat(result);
734  }
735 
743  void translate(double x, double y, double z, ISM::PosePtr pose)
744  {
745  Eigen::Quaternion<double> rot = ISM::GeometryHelper::quatToEigenQuat(pose->quat);
746  Eigen::Matrix3d rotationMat = rot.toRotationMatrix();
747 
748  Eigen::Vector3d xAxis = rotationMat * Eigen::Vector3d::UnitX() * x;
749  Eigen::Vector3d yAxis = rotationMat * Eigen::Vector3d::UnitY() * y;
750  Eigen::Vector3d zAxis = rotationMat * Eigen::Vector3d::UnitZ() * z;
751 
752  Eigen::Vector3d add = xAxis + yAxis + zAxis;
753 
754  pose->point->eigen.x() = pose->point->eigen.x() + add[0];
755  pose->point->eigen.y() = pose->point->eigen.y() + add[1];
756  pose->point->eigen.z() = pose->point->eigen.z() + add[2];
757  }
758 
759 
764  void loadConstellationFromConfigFile(const std::string& configFilePath)
765  {
766  std::string xml_path = configFilePath;
767  ROS_DEBUG_STREAM("Path to objects.xml: " << xml_path);
768 
769  try {
770  rapidxml::file<> xmlFile(xml_path.c_str());
771  rapidxml::xml_document<> doc;
772  doc.parse<0>(xmlFile.data());
773 
774  rapidxml::xml_node<> *root_node = doc.first_node();
775  if (root_node) {
776  rapidxml::xml_node<> *child_node = root_node->first_node();
777  while (child_node) {
778  rapidxml::xml_attribute<> *type_attribute = child_node->first_attribute("type");
779  rapidxml::xml_attribute<> *id_attribute = child_node->first_attribute("id");
780  rapidxml::xml_attribute<> *mesh_attribute = child_node->first_attribute("mesh");
781  rapidxml::xml_attribute<> *angles_attribute = child_node->first_attribute("angles");
782 
783  if (type_attribute && id_attribute && mesh_attribute && angles_attribute)
784  {
785  std::string angle = angles_attribute->value();
786  std::string pose_string = child_node->value();
787 
788  ISM::PosePtr pose;
789  if (parsePoseString(pose_string, pose, " ,", angle)) {
790 
791  ISM::ObjectPtr obj = ISM::ObjectPtr(new ISM::Object(type_attribute->value(), id_attribute->value(), mesh_attribute->value()));
792  std::vector<ISM::PosePtr> poses;
793  poses.push_back(pose);
794  objectAndPoses.push_back(std::make_pair(obj, poses));
795  markedObjects.insert(obj->type + obj->observedId);
796  poseCounters.push_back(0);
797  editFlags.push_back(false);
798 
799  std::stringstream ss;
800  ss << "Loaded " << obj->type << " " << obj->observedId << " from config-file." << std::endl;
801  ISM::printGreen(ss.str());
802  }
803  else
804  {
805  std::stringstream ss;
806  ss << "Couldn't parse pose for " << type_attribute->value() << " " << id_attribute->value() << " from config-file!" << std::endl;
807  ISM::printRed(ss.str());
808  }
809  }
810  else
811  {
812  ISM::printRed("Couldn't load object from config-file! Check format of the file.\n");
813  }
814  child_node = child_node->next_sibling();
815  }
816  }
817  } catch(std::runtime_error err) {
818  ROS_DEBUG_STREAM("Can't parse xml-file. Runtime error: " << err.what());
819  } catch (rapidxml::parse_error err) {
820  ROS_DEBUG_STREAM("Can't parse xml-file Parse error: " << err.what());
821  }
822  }
823 
831  bool parsePoseString(std::string pose_string, ISM::PosePtr& pose, std::string delim, std::string angles)
832  {
833  std::vector<std::string> strvec;
834 
835  boost::algorithm::trim_if(pose_string, boost::algorithm::is_any_of(delim));
836  boost::algorithm::split(strvec, pose_string, boost::algorithm::is_any_of(delim), boost::algorithm::token_compress_on);
837  if (strvec.size() == 6 || strvec.size() == 7 ) {
838  try {
839  double x = boost::lexical_cast<double>(strvec[0]);
840  double y = boost::lexical_cast<double>(strvec[1]);
841  double z = boost::lexical_cast<double>(strvec[2]);
842  ISM::PointPtr pointPtr = ISM::PointPtr(new ISM::Point(x, y, z));
843 
844  if(angles == "quaternion" && strvec.size() == 7)
845  {
846  double qW = boost::lexical_cast<double>(strvec[3]);
847  double qX = boost::lexical_cast<double>(strvec[4]);
848  double qY = boost::lexical_cast<double>(strvec[5]);
849  double qZ = boost::lexical_cast<double>(strvec[6]);
850  ISM::QuaternionPtr quatPtr = ISM::QuaternionPtr(new ISM::Quaternion(qW, qX, qY, qZ));
851  pose = ISM::PosePtr(new ISM::Pose(pointPtr, quatPtr));
852  return true;
853 
854  }
855  else if(angles == "euler" && strvec.size() == 6)
856  {
857  double qX = boost::lexical_cast<double>(strvec[3]) * (M_PI / 180);
858  double qY = boost::lexical_cast<double>(strvec[4]) * (M_PI / 180);
859  double qZ = boost::lexical_cast<double>(strvec[5]) * (M_PI / 180);
860  Eigen::Matrix3d rotMat;
861  rotMat = Eigen::AngleAxisd(qX, Eigen::Vector3d::UnitX())
862  * Eigen::AngleAxisd(qY, Eigen::Vector3d::UnitY())
863  * Eigen::AngleAxisd(qZ, Eigen::Vector3d::UnitZ());
864 
865  Eigen::Quaterniond quat(rotMat);
866  ISM::QuaternionPtr quatPtr = ISM::QuaternionPtr(new ISM::Quaternion(quat.w(), quat.x(), quat.y(), quat.z()));
867  pose = ISM::PosePtr(new ISM::Pose(pointPtr, quatPtr));
868  return true;
869  }
870  return false;
871  } catch (boost::bad_lexical_cast err) {
872  ROS_DEBUG_STREAM("Can't cast node-value. Cast error: " << err.what());
873  return false;
874  }
875  }
876  return false;
877  }
878 
879 
880 
881 private:
883  ISM::TableHelperPtr tableHandler;
884 
885  std::vector<std::pair<ISM::ObjectPtr, std::vector<ISM::PosePtr>>> objectAndPoses;
886  std::set<std::string> markedObjects;
887 
888  std::string mDbFilename;
889  std::string baseFrame;
891 
892  std::string visualizationTopic;
893  std::string markerNamespace = "object_configuration";
894 
895  const double markerLifetime = 0.0;
896 
897  unsigned int objectCounter = 0;
898  std::vector<unsigned int> poseCounters;
899  std::vector<bool> editFlags;
900 
901  std::string output_file_path;
902 
903 
905 
906  float sphere_radius = 0.01;
907 
908  const std_msgs::ColorRGBA SELECTED = VIZ::VizHelperRVIZ::createColorRGBA(1.0, 0.0, 1.0, 1.0);
909  const std_msgs::ColorRGBA MARKED = VIZ::VizHelperRVIZ::createColorRGBA(1.0, 0.0, 0.0, 1.0);
910  const std_msgs::ColorRGBA IN_CURRENT_TRACK = VIZ::VizHelperRVIZ::createColorRGBA(0, 1.0, 0, 1);
911 
912  const std_msgs::ColorRGBA X_AXIS = VIZ::VizHelperRVIZ::createColorRGBA(1.0, 0.0, 0.0, 0.5);
913  const std_msgs::ColorRGBA Y_AXIS = VIZ::VizHelperRVIZ::createColorRGBA(0.0, 1.0, 0.0, 0.5);
914  const std_msgs::ColorRGBA Z_AXIS = VIZ::VizHelperRVIZ::createColorRGBA(0.0, 0.0, 1.0, 0.5);
915 
916  visualization_msgs::MarkerArray markerArray;
917 
918 
920 
921 };
922 
923 
924 
925 int main(int argc, char **argv) {
926 
927  //Usual ros node stuff
928  ros::init(argc, argv, "object_configuration_generator");
930  ros::spin();
931  delete ocg;
932 
935  tcsetattr( STDIN_FILENO, TCSANOW, &originalSettings); // restore original terminal settings
936 
937 }
938 
void markOrUnmark()
If the currently selected pose is marked, it gets unmarked, else it gets marked.
#define KEY_PREV_OBJECT
void publish(const boost::shared_ptr< M > &message) const
struct termios originalSettings modifiedSettings
void switchObject(SelectEntity neighbor)
Switch to the neighbor object.
void visualize()
Visulize the currently selected pose, all poses that are in the same trajectory and one pose of each ...
XmlRpcServer s
bool sleep() const
void stop()
visualization_msgs::MarkerArray markerArray
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void rotate(double alpha, double beta, double gamma, ISM::PosePtr pose)
Rotates the given pose by the values specified by the arguments.
bool parsePoseString(std::string pose_string, ISM::PosePtr &pose, std::string delim, std::string angles)
Creates a ISM::PosePtr from a pose_string.
bool add(const actionlib::TwoIntsGoal &req, actionlib::TwoIntsResult &res)
TFSIMD_FORCE_INLINE const tfScalar & y() const
void initInteractiveControl()
Sets up keyboard control.
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
ROSCPP_DECL void spin(Spinner &spinner)
void initFromDatabase(std::vector< std::string > &patternNames)
Read tracks from the scenes specified by patternNames from database and store them in the appropriate...
void switchPose(SelectEntity neighbor)
Switch to the neighbor pose in the trajectory.
#define KEY_NEXT_OBJECT
void loadConstellationFromConfigFile(const std::string &configFilePath)
Loads a configuration from an xml file located at configFilePath;mDbFilename.
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
TFSIMD_FORCE_INLINE const tfScalar & x() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void getNodeParameters(std::vector< std::string > &patternNames, std::string &configFilePath)
Read node parameters.
void keyboardInputCallback(const ros::TimerEvent &e)
Function that handles user keyboard input and calls the appropriate functions.
bool isMarked(const ISM::ObjectPtr &obj)
Checks if object is marked.
#define ROS_DEBUG_STREAM(args)
void writeMarkedPosesToFile()
Writes the type, observedId, path to the mesh and its pose to an xml file.
TFSIMD_FORCE_INLINE const tfScalar & z() const
#define ROS_INFO_STREAM(args)
bool getParam(const std::string &key, std::string &s) const
void translate(double x, double y, double z, ISM::PosePtr pose)
Translates the given pose by the values specified by the arguments.
int main(int argc, char **argv)
void runEditMode()
Start and run edit mode in which the pose of the selected object can be manipulated.
#define ROS_ERROR_STREAM(args)
std::vector< std::pair< ISM::ObjectPtr, std::vector< ISM::PosePtr > > > objectAndPoses
#define KEY_SWITCH_EDIT


asr_ism
Author(s): Borella Jocelyn, Hanselmann Fabian, Heller Florian, Heizmann Heinrich, Kübler Marcel, Mehlhaus Jonas, Meißner Pascal, Qattan Mohamad, Reckling Reno, Stroh Daniel
autogenerated on Thu Jan 9 2020 07:20:58