asrPosePredictionEngine.cpp
Go to the documentation of this file.
1 
19 
20 namespace ASR
21 {
22 
24  std::string sceneName,
25  std::vector<boost::shared_ptr<asr_msgs::AsrObject>> objects,
26  int votes = 100,
27  std::string base_frame = "/map")
28  : path(pathToXML),
29  reference_object(objects.at(0)->type.c_str()),
30  number_obsereved_objects(1),
31  number_of_votes(votes),
32  publish_hypothesis(true),
33  publish_hypothesis_topic("pose_prediction_psm_hypothesis")
34 {
35  if (objects.size() < 1)
36  ROS_ERROR("There has to be at least one reference object");
37 
38  // get the name of the base frame
39  ros::NodeHandle n("~");
40 
41  if(!n.getParam("base_frame_id", baseFrameId))
42  baseFrameId = base_frame;
43 
44  std::string reference_object_name;
45  unsigned int counter = 0;
46 
47  do
48  {
49  boost::shared_ptr<asr_msgs::AsrObject> tempObject = objects.at(counter);
50 
51  if(!tempObject->sampledPoses.size()){
52  std::cerr << "Got a AsrObject without poses." << std::endl;
53  std::exit(1);
54  }
55 
56  geometry_msgs::PoseWithCovariance currentPose = tempObject->sampledPoses.front();
57 
58  ROS_INFO("\nStarted pose prediciton. Reference object name %s", tempObject->type.c_str());
59 
60 
61  // Transform the reference object to the base_frame
62  transformObject(tempObject, baseFrameId.c_str());
63 
64  Eigen::Vector3f position = Eigen::Vector3f(currentPose.pose.position.x,currentPose.pose.position.y, currentPose.pose.position.z);
65 
66  Eigen::Vector4f ori = Eigen::Vector4f(currentPose.pose.orientation.w,
67  currentPose.pose.orientation.x,
68  currentPose.pose.orientation.y,
69  currentPose.pose.orientation.z);
70 
71 
72  // Load the scene descritiption xml and build the scene graph
73  init(sceneName, tempObject->type.c_str(), position, ori, base_frame);
74 
75  reference_object_name = tempObject->type;
76 
77  counter++;
78  } while(!getSceneGraphRoot() && counter < objects.size());
79 
80 
81  // calculate initial hypothesis
82  if(getSceneGraphRoot())
83  getSceneGraphRoot()->calcChildPoseHypothesesRecursive();
84 
85  // integrate other observed objects
86  for(unsigned int i=0;i<objects.size();i++)
87  {
88  if(reference_object_name.compare(objects.at(i)->type) != 0)
89  onObjectMsg(objects.at(i));
90  }
91 }
92 
93 
95  std::string sceneName,
96  std::string reference_object_name,
97  Eigen::Vector3f reference_object_position,
98  Eigen::Vector4f reference_object_orientation,
99  int votes = 100,
100  std::string base_frame = "/map")
101  : path(pathToXML),
102  reference_object(reference_object_name),
104  number_of_votes(votes),
105  publish_hypothesis(true),
106  publish_hypothesis_topic("pose_prediction_psm_hypothesis")
107 
108 {
109  init( sceneName, reference_object_name, reference_object_position, reference_object_orientation, base_frame);
110  if(getSceneGraphRoot())
111  getSceneGraphRoot()->calcChildPoseHypothesesRecursive();
112 }
113 
114 
115 void asrPosePredictionEngine::init(std::string sceneName,
116  std::string reference_object_name,
117  Eigen::Vector3f reference_object_position,
118  Eigen::Vector4f reference_object_orientation,
119  std::string base_frame = "/map")
120 {
121  ros::NodeHandle n("~");
122 
123  if(!n.getParam("publish_hypothesis", publish_hypothesis))
124  publish_hypothesis = false;
125 
126  if(!n.getParam("publish_hypothesis_topic", publish_hypothesis_topic))
127  publish_hypothesis_topic = "pose_prediction_psm_hypothesis";
128 
129  if(!n.getParam("print_debug_messages", print_debug_messages))
130  print_debug_messages = false;
131 
132  if(!n.getParam("base_frame_id", baseFrameId))
133  baseFrameId = base_frame;
134 /*
135  if(!n.getParam("object_topic", pPbdObjectTopic))
136  throw std::runtime_error("Please specify parameter " + std::string("object_topic") + " when starting this node.");
137 */
139  hypothesis_publisher = n.advertise<asr_msgs::AsrAttributedPoint>(publish_hypothesis_topic, number_of_votes);
140 /*
141  if(!print_debug_messages)
142  ROS_INFO("-- Debug mode is disabled. Additional Messages are only printed to console if debug mode is enabled.\n");
143 */
144 
145  // Tell node how to react on messages from objects that could belong to scenes being looked for.
146  //printf("Object topic: %s\n", pPbdObjectTopic.c_str());
147  //mObjectListener = n.subscribe(pPbdObjectTopic, 100, &asrPosePredictionEngine::newObservationCallback, this);
148 
149  // Initialize the transformations of objects into the given frame.
150  mObjectTransform.setBaseFrame(baseFrameId);
151 
152  this->scene_name = sceneName;
153 
154  xml_document<> doc;
155  xml_node<> * root_node;
156  // Read the xml file into a vector
157 
158  std::ifstream file(path);
159  std::stringstream buffer;
160  buffer << file.rdbuf();
161  file.close();
162  std::string content(buffer.str());
163 
164  if(content.size() < 2)
165  {
166  ROS_ERROR("Loading XML failed");
167  return;
168  }
169 
170  // Parse the buffer using the xml file parsing library into doc
171  doc.parse<0>(&content[0]);
172 
173  // Find our root node
174  root_node = doc.first_node("psm");
175 
176  // Iterate over the psm attributes
177  for (xml_node<> * brewery_node = root_node->first_node("scenes"); brewery_node; brewery_node = brewery_node->next_sibling())
178  {
179 
180  // Interate over the scenes
181  for(xml_node<> * scene_node = brewery_node->first_node("scene"); scene_node; scene_node = scene_node->next_sibling())
182  {
183  std::string name = scene_node->first_attribute("name")->value();
184 
186  {
187  printf("Scene: %s, name: %s, priori %s \n",
188  scene_node->first_attribute("type")->value(),
189  name.c_str(),
190  scene_node->first_attribute("priori")->value());
191  }
192 
193 
194  // Iterate over all scenes in the xml until the right scene is found
195  if(name.compare(sceneName) == 0)
196  {
197  // // Interate over the objects
198  for(xml_node<> * object_node = scene_node->first_node("object"); object_node; object_node = object_node->next_sibling())
199  {
200 
201  // If object.name == reference_object_name then start building the scene shape
202  std::string object_name = object_node->first_attribute("name")->value();
203 
204  if(object_name.compare(reference_object_name) == 0)
205  {
207  {
208  printf("\nLoaded reference object. name: %s, type: %s, priori %s \n",
209  object_node->first_attribute("name")->value(),
210  object_node->first_attribute("type")->value(),
211  object_node->first_attribute("priori")->value());
212  }
213 
214  // get the number of objects in the scene
215  number_objects_in_scene = (int)atof(object_node->first_node("slots")->first_attribute("number")->value());
216  if(print_debug_messages) printf("Number of objects in the scene %i\n", number_objects_in_scene);
217  if(print_debug_messages) printf("Number of observed objects: %i\n", number_obsereved_objects);
218 
219  // calculate the number of votes for each unobserved node
220  votes_per_node = distributeVotes();
221  //if(print_debug_messages) printf("Votes per node %i \n", votes_per_node);
222 
223  // start building scene shape beginning with the root
224  root = ASR::asrSceneGraphNodePtr(new ASR::OcmSceneGraphNode(object_name, reference_object_position,reference_object_orientation, votes_per_node, print_debug_messages));
225 
226  // Interate over the object attributes
227  for(xml_node<> * object_attributes = object_node->first_node("shape"); object_attributes; object_attributes = object_attributes->next_sibling())
228  {
229  // Iterate over the shape term
230  for(xml_node<> * shape_attributes = object_attributes->first_node("root"); shape_attributes; shape_attributes = shape_attributes->next_sibling())
231  {
232 
233 
234  // Intialize the roots children
235  for(xml_node<> * root_children = shape_attributes->first_node("child"); root_children; root_children = root_children->next_sibling())
236  {
237  /*
238  if(print_debug_messages) printf("Child_name: %s, parent_name: %s \n", root_children->first_attribute("name")->value(),
239  "root");
240  */
242 
243 
244  // get position kernels
245  for(xml_node<> * position_node = root_children->first_node("position"); position_node; position_node = position_node->next_sibling())
246  {
247  for(xml_node<> * kernel_node = position_node->first_node("kernel"); kernel_node; kernel_node = kernel_node->next_sibling())
248  {
249  //if(print_debug_messages) printf("position %s \n", kernel_node->first_attribute("mean")->value());
250 
251  float kernel_weight = atof(kernel_node->first_attribute("weight")->value());
252  std::vector<float> pos;
253  std::vector<float> cov;
254  initVectorFromCSVString(pos, kernel_node->first_attribute("mean")->value());
255  initVectorFromCSVString(cov, kernel_node->first_attribute("covariance")->value());
256 
257  if (pos.size() == 3 && cov.size() == 9)
258  {
259  MatrixXf mat = initMatrixXf(cov, 3,3);
260  gmm->addGaussianModel(kernel_weight, pos, mat);
261  }
262  }
263 
264  }
265 
266  ASR::GMM_Ptr orientationGMM = boost::shared_ptr<ASR::GMM>(new ASR::GMM());
267 
268  // get orientation kernels
269  for(xml_node<> * orientation_node = root_children->first_node("orientation"); orientation_node; orientation_node = orientation_node->next_sibling())
270  {
271  for(xml_node<> * kernel_node2 = orientation_node->first_node("kernel"); kernel_node2; kernel_node2 = kernel_node2->next_sibling())
272  {
273  //if(print_debug_messages) printf("orientation %s node %s \n", kernel_node2->first_attribute("mean")->value(),
274  // root_children->first_attribute("name")->value());
275 
276  float kernel_weight = atof(kernel_node2->first_attribute("weight")->value());
277  std::vector<float> pos;
278  std::vector<float> cov;
279  initVectorFromCSVString(pos, kernel_node2->first_attribute("mean")->value());
280  initVectorFromCSVString(cov, kernel_node2->first_attribute("covariance")->value());
281 
282  if (pos.size() == 4 && cov.size() == 16)
283  {
284  MatrixXf mat = initMatrixXf(cov, 4, 4);
285  orientationGMM->addGaussianModel(kernel_weight, pos, mat);
286  }
287  }
288  }
289 
290 
291 
292  root->initNewChild(root_children->first_attribute("name")->value(), root, gmm, orientationGMM);
293 
294  // traverse tree recursive to add children to the roots children
295  std::string name = root_children->first_attribute("name")->value();
296  traverseSceneShapeRecursive(name, root_children, root);
297 
298  }
299  }
300  }
301  }
302  }
303  }
304  }
305  }
306 /*
307  if(!getSceneGraphRoot())
308  ROS_INFO("Warning there ist no root object. Object %s is probably not part of the scene. Building Scene Graph failed!\n\n", reference_object_name.c_str());
309 */
310 }
311 
312 
313 unsigned int asrPosePredictionEngine::distributeVotes()
314 {
315  // guard agains division through zero
316  if(getNumberOfMissingObjects() != 0)
318  else
319  return 0;
320 }
321 
322 
323 bool asrPosePredictionEngine::observeObject(std::string object_name, Eigen::Vector3f position, Eigen::Vector4f orientation)
324 {
325  if(!getSceneGraphRoot())
326  {
327  ROS_INFO("Warning there ist no root object. Bobserving obj failed!");
328  return false;
329  }
330 
331  bool integrated_evidence = false;
332 
333  asrSceneGraphNodePtr observed;
334 
335  //ROS_INFO("Searching node %s", object_name.c_str());
336 
337  // Check if a node with the given name exists and if it was observed previously
338  if(getSceneGraphRoot()->findNode(object_name, observed) && !observed->isObjectObserved())
339  {
340  if(print_debug_messages) printf("\n");
341 
343  observed->observe(position, orientation);
344  int n = distributeVotes();
345  getSceneGraphRoot()->setVotesPerNode(n);
346 
347  integrated_evidence = true;
348  if(print_debug_messages) printf("Observed object %s, Set votes per node to %i\n\n", object_name.c_str(), n);
349  } else
350  {
351  // The observed object doesnt exist in the scene or it was already observed.
352  integrated_evidence = false;
353  //ROS_ERROR("The observed object doesnt exist in the scene or it was already observed!\n");
354  }
355 
356  return integrated_evidence;
357 }
358 
359 
360 void asrPosePredictionEngine::publishHypothesisMessages(std::vector<ASR::AttributedPoint> hypothesis_list)
361 {
362  if (!publish_hypothesis || hypothesis_list.empty())
363  return;
364 
365  for(auto p : hypothesis_list)
366  {
367  asr_msgs::AsrAttributedPoint point;
368  point.type = p.objectType;
369  point.pose = p.pose;
371  }
372 }
373 
374 
375 void asrPosePredictionEngine::calcHypotheses()
376 {
377  if(print_debug_messages) ROS_INFO("Calling calcHypothesis(). scene_name: %s", scene_name.c_str());
378 
379  // ignore the background scene because there is no scene graph
380  if(scene_name.compare("background") == 0)
381  return;
382 
383  if(!getSceneGraphRoot())
384  {
385  ROS_ERROR("Warning: calcHypothesis: There is no Scene Graph build. Return.");
386  return;
387  }
388 
389  bool new_evidence_integrated = false;
390 
392  {
393 
394  if(!pObject->sampledPoses.size()){
395  std::cerr << "Got a AsrObject without poses." << std::endl;
396  std::exit(1);
397  }
398 
399  auto position = pObject->sampledPoses.front().pose.position;
400 
401  printf("A new was object observed! object %s at (%.2f, %.2f, %.2f) %s\n",
402  pObject->type.c_str(),
403  position.x, position.y, position.z,
404  pObject->header.frame_id.c_str());
405 
406  auto evidence = pObject;
407 
408  // Transform object to the base koordinate system
409  transformObject(pObject, this->baseFrameId.c_str());
410 
411 
412  auto orientation = pObject->sampledPoses.front().pose.orientation;
413 
417  bool b = observeObject(evidence->type,
418  Eigen::Vector3f(position.x, position.y, position.z),
419  Eigen::Vector4f(orientation.w, orientation.x, orientation.y, orientation.z));
420  new_evidence_integrated |= b;
421 
422  if(new_evidence_integrated)
423  {
424  ROS_INFO ("Object %s transformed to frame %s (%.2f, %.2f, %.2f) (w: %.2f, x: %.2f, y: %.2f, z: %.2f,)",
425  evidence->type.c_str(), this->baseFrameId.c_str(),
426  position.x, position.y, position.z,
427  orientation.w, orientation.x, orientation.y, orientation.z);
428  ROS_INFO("Object %s will be integrated into the scene graph", evidence->type.c_str());
429 
430  } else
431  {
432  //ROS_INFO("Integrating obj failed!");
433  }
434 
435  }
436 
437 
442  if(new_evidence_integrated)
443  {
444  if(getSceneGraphRoot())
445  {
446  getSceneGraphRoot()->calcChildPoseHypothesesRecursive();
447  ROS_INFO("Evidence(s) successfully integrated into scene graph");
448  }
449  }
450 
451  // clear the evidence buffer
452  evidence_buffer.clear();
453 }
454 
455 void asrPosePredictionEngine::collectPoseHypothesesRecursive(std::vector<ASR::AttributedPoint> &out_hypotheses,
456  std::vector<ASR::AttributedPoint> &out_found_objects)
457 {
458  if(print_debug_messages) ROS_INFO("Calling collectHypothesis(). scene_name: %s", scene_name.c_str());
459 
460  // ignore the background scene because there is no scene graph
461  if(scene_name.compare("background") == 0)
462  return;
463 
464  if(!getSceneGraphRoot())
465  {
466  ROS_ERROR("Warning: collectHypothesis: There is no Scene Graph build. Return.");
467  return;
468  }
469  getSceneGraphRoot()->collectPoseHypothesesRecursive(out_hypotheses, out_found_objects);
470 }
471 
472 
473 void asrPosePredictionEngine::onObjectMsg(const boost::shared_ptr<asr_msgs::AsrObject>& pObject)
474 {
475  // Check if the object is already in the buffer
476  for(auto o : evidence_buffer)
477  {
478  if(o->type.compare(pObject->type) == 0)
479  {
480  if(print_debug_messages) printf("Observation callback. Object %s already in buffer.\n", pObject->type.c_str());
481  return;
482  }
483  }
484 
486  printf("Observation callback. Put object %s to evidence buffer.\n", pObject->type.c_str());
487 
488  evidence_buffer.push_back(pObject);
489 }
490 
491 
492 bool asrPosePredictionEngine::transformObject(boost::shared_ptr<asr_msgs::AsrObject> in_out_object, std::string targetFrame)
493 {
494  // Check if the object is already in the target frame
495  if(in_out_object->header.frame_id.compare(targetFrame) == 0)
496  return true;
497 
498  try
499  {
500  mObjectTransform.setBaseFrame(targetFrame);
501 
502  // transform the object to the target frame
503  mObjectTransform.transform(in_out_object);
504 
505  } catch(std::exception e)
506  {
507  ROS_ERROR("Failed to resolve transformation in target coordinate frame. Object: %s frame: %s",
508  in_out_object->type.c_str(), targetFrame.c_str());
509  return false;
510  }
511 
512  if(!in_out_object->sampledPoses.size()){
513  std::cerr << "Got a AsrObject without poses." << std::endl;
514  std::exit(1);
515  }
516 
517  // get the transformed position
518  auto position = in_out_object->sampledPoses.front().pose.position;
519  auto orientation = in_out_object->sampledPoses.front().pose.orientation;
520 
521  ROS_INFO ("Object %s transformed to frame %s (%.2f, %.2f, %.2f) (w: %.2f, x: %.2f, y: %.2f, z: %.2f,)",
522  in_out_object->type.c_str(), targetFrame.c_str(),
523  position.x, position.y, position.z,
524  orientation.w, orientation.x, orientation.y, orientation.z);
525 
526  return true;
527 }
528 
529 
530 void asrPosePredictionEngine::traverseSceneShapeRecursive(std::string parent_name, xml_node<> * parent_node, ASR::asrSceneGraphNodePtr root)
531 {
532  // Intialize the roots children
533  for(xml_node<> * child = parent_node->first_node("child"); child; child = child->next_sibling())
534  {
536  ASR::GMM_Ptr orientationGMM = boost::shared_ptr<ASR::GMM>(new ASR::GMM());
537 
538  for(xml_node<> * position_node = child->first_node("position"); position_node; position_node = position_node->next_sibling())
539  {
540  for(xml_node<> * kernel_node = position_node->first_node("kernel"); kernel_node; kernel_node = kernel_node->next_sibling())
541  {
542  //if(print_debug_messages) printf("position %s \n", kernel_node->first_attribute("mean")->value());
543 
544  float kernel_weight = atof(kernel_node->first_attribute("weight")->value());
545  std::vector<float> pos;
546  std::vector<float> cov;
547  initVectorFromCSVString(pos, kernel_node->first_attribute("mean")->value());
548  initVectorFromCSVString(cov, kernel_node->first_attribute("covariance")->value());
549 
550  if (pos.size() == 3 && cov.size() == 9)
551  {
552  MatrixXf mat = initMatrixXf(cov, 3,3);
553  gmm->addGaussianModel(kernel_weight, pos, mat);
554  }
555  }
556  }
557 
558  // get orientation kernels
559  for(xml_node<> * orientation_node = child->first_node("orientation"); orientation_node; orientation_node = orientation_node->next_sibling())
560  {
561  for(xml_node<> * kernel_node2 = orientation_node->first_node("kernel"); kernel_node2; kernel_node2 = kernel_node2->next_sibling())
562  {
563  //if(print_debug_messages) printf("orientation %s \n", kernel_node2->first_attribute("mean")->value());
564 
565  float kernel_weight = atof(kernel_node2->first_attribute("weight")->value());
566  std::vector<float> pos;
567  std::vector<float> cov;
568  initVectorFromCSVString(pos, kernel_node2->first_attribute("mean")->value());
569  initVectorFromCSVString(cov, kernel_node2->first_attribute("covariance")->value());
570 
571  if (pos.size() == 4 && cov.size() == 16)
572  {
573  MatrixXf mat = initMatrixXf(cov, 4, 4);
574  orientationGMM->addGaussianModel(kernel_weight, pos, mat);
575  }
576 
577  }
578  }
579 /*
580  if(print_debug_messages) printf("Current Child_name: %s, parent_name: %s \n", child->first_attribute("name")->value(),
581  parent_name.c_str());
582 */
583  ASR::asrSceneGraphNodePtr node;
584  if(root->findNode(parent_name.c_str(), node))
585  {
586  //if(print_debug_messages) printf("Found parent node %s, adding child %s\n", parent_name.c_str(), child->first_attribute("name")->value());
587  node->initNewChild(child->first_attribute("name")->value(), node, gmm, orientationGMM);
588  } else
589  {
590  if(print_debug_messages) printf("Error node %s not found\n", parent_name.c_str());
591  }
592 
593  std::string child_name = child->first_attribute("name")->value();
594  traverseSceneShapeRecursive(child_name, child, root);
595  }
596 }
597 
598 
599 void asrPosePredictionEngine::initVectorFromCSVString(std::vector<float> &x, std::string csv)
600 {
601  std::stringstream ss(csv);
602  float i;
603  while (ss >> i)
604  {
605  x.push_back(i);
606 
607  if (ss.peek() == ',' || ss.peek() == ' ')
608  ss.ignore();
609  }
610 }
611 
612 
613 MatrixXf asrPosePredictionEngine::initMatrixXf(std::vector<float> values, unsigned int rows, unsigned int cols)
614 {
615  assert (rows > 0);
616  assert (cols > 0);
617 
618  MatrixXf x(rows, cols);
619  for(unsigned int i=0; i < rows;i++)
620  {
621  for(unsigned int j=0; j < cols; j++)
622  {
623  x(i,j) = values.at(i*cols + j);
624  }
625  }
626  return x;
627 }
628 
629 
630 
631 }
void publish(const boost::shared_ptr< M > &message) const
void publishHypothesisMessages(std::vector< ASR::AttributedPoint > hypothesis_list)
std::vector< double > values
ASR::asrSceneGraphNodePtr root
ASR::asrSceneGraphNodePtr getSceneGraphRoot()
Definition: GMM.h:32
ProbabilisticSceneRecognition::ObjectTransformation mObjectTransform
std::vector< boost::shared_ptr< asr_msgs::AsrObject > > evidence_buffer
#define ROS_INFO(...)
asrPosePredictionEngine(std::string pathToXML, std::string sceneName, std::vector< boost::shared_ptr< asr_msgs::AsrObject >> objects, int votes, std::string base_frame)
TFSIMD_FORCE_INLINE const tfScalar & x() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool getParam(const std::string &key, std::string &s) const
#define ROS_ERROR(...)


asr_recognizer_prediction_psm
Author(s): Braun Kai, Meißner Pascal
autogenerated on Wed Feb 19 2020 03:31:28