GaussianKernelVisualizer.cpp
Go to the documentation of this file.
1 
19 
20 namespace Visualization {
21 
24  {
25  }
26 
28  {
29  }
30 
31  void GaussianKernelVisualizer::setSigmaMultiplicator(const float pSigmaMultiplicator)
32  {
33  mSigmaMultiplicator = pSigmaMultiplicator;
34  }
35 
37  {
38  // Check, if pointer is valid.
39  if(!pPose)
40  throw std::out_of_range("Invalid pointer: absolute pose of primary scene object.");
41 
42  // Set absolute position of the primary scene object.
43  mParentPose = pPose;
44  }
45 
47  unsigned int& pMarkerId,
48  const Eigen::Vector3d& pMean,
49  const Eigen::Matrix3d& pCovariance)
50  {
51  // Check, if publisher is available.
52  if(!pPublisher)
53  throw std::invalid_argument("Empty ros::publisher cannot be used to publish marker messages.");
54 
55  // Marker array that will contain the visualization messages for the covariance ellipse and the rings.
56  visualization_msgs::MarkerArray modelMarkers;
57 
58  /************************************
59  * Create surface model.
60  ************************************/
61 
62  // Check for errors with non 3D-positions.
63  try {
64  // Light gray color for ellipse because we already use color codes in the rings.
65  std_msgs::ColorRGBA pEllipseColor;
66  pEllipseColor.r = pEllipseColor.g = pEllipseColor.b = 0.45;
67  pEllipseColor.a = 0.33;
68 
69  // Generate marker message that differs for other object locations in same scene by color.
70  modelMarkers.markers.push_back(generateCovarianceEllipsoidMarker(pMarkerId++, visualization_msgs::Marker::SPHERE, std::vector<std::vector<float> >(), pEllipseColor, pMean, pCovariance));
71  }
72  catch(std::exception& exception) {
73  std::cerr << exception.what() << std::endl;
74  }
75 
76  /************************************
77  * Create wire frame model (rings).
78  ************************************/
79 
80  // Wire-frame model of ellipsoid expressed by multiple closen 3D point sequences as integers in [mm].
81  std::vector<std::vector<std::vector<int> > > integerWireFrame;
82 
83  // Access one of the ellipse-shaped wires making up the wire-frame.
84  std::vector<std::vector<std::vector<int> > >::iterator wireIterator;
85 
86  // Access one of the points in the polygon representing a wire in the frame.
87  std::vector<std::vector<int> >::iterator pointInterator;
88 
89  // Access one of the coordinates of a point.
90  std::vector<int>::iterator coordinatesIterator;
91 
92  // Calculation of ellipse polygon is based on integers, so we express size of ellipsoid that way.
93  std::vector<int> ellipsoidHalfAxes;
94 
95  // Transform dimensions of ellipsoid back to half-axes and scale from unit usually used in ROS [m] to [mm].
96  ellipsoidHalfAxes.push_back(static_cast<int>((0.5f * modelMarkers.markers[0].scale.x * 1000.0f) / mSigmaMultiplicator));
97  ellipsoidHalfAxes.push_back(static_cast<int>((0.5f * modelMarkers.markers[0].scale.y * 1000.0f) / mSigmaMultiplicator));
98  ellipsoidHalfAxes.push_back(static_cast<int>((0.5f * modelMarkers.markers[0].scale.z * 1000.0f) / mSigmaMultiplicator));
99 
100  // Calculate integer polygon points for the wire-frame to be visualized. Discretization is hard-coded to 1 degree as this is as we don't care.
101  calculateCoordinatePlaneEllipses(ellipsoidHalfAxes, 5, integerWireFrame);
102 
103  // Wire-frame model of ellipsoid expressed by multiple closen 3D point sequences as floating points in [m].
104  std::vector<std::vector<std::vector<float> > > floatWireFrame;
105 
106  // Go through all wires.
107  for(wireIterator = integerWireFrame.begin(); wireIterator != integerWireFrame.end(); wireIterator++)
108  {
109  // One wire of the frame scaled down to [m] newly created for conversion from integer to float.
110  std::vector<std::vector<float> > pointSequence;
111 
112  // Go through all points of a polygon.
113  for(pointInterator = wireIterator->begin(); pointInterator != wireIterator->end(); pointInterator++)
114  {
115  // One point of the wire scaled down to [m] newly created for conversion from integer to float.
116  std::vector<float> point;
117 
118  // Go through all coordinates of a point.
119  for(coordinatesIterator = pointInterator->begin();coordinatesIterator != pointInterator->end(); coordinatesIterator++)
120  {
121  // Here real conversion of data types and scaling to [m] takes place.
122  point.push_back(static_cast<float>(*coordinatesIterator) / 1000.0f);
123  }
124 
125  // Add floating point polygon point to already calculated elements of wire.
126  pointSequence.push_back(point);
127  }
128 
129  // Add newly calculated wire to floating point frame.
130  floatWireFrame.push_back(pointSequence);
131  }
132 
133  // Check for errors with non 3D-positions.
134  try {
135  double factor = 1.0;
136  std_msgs::ColorRGBA pRingColor;
137  pRingColor.r = getColor(0).r * factor;
138  pRingColor.g = getColor(0).g * factor;
139  pRingColor.b = getColor(0).b * factor;
140  pRingColor.a = 1.0;
141 
142  // Generate all marker messages. Width of wires is set to five [mm] as this seems plausible and we don't think people should care about.
143  for(unsigned int i = 0; i < floatWireFrame.size(); i++)
144  {
145  // Create the marker containing the ring.
146  visualization_msgs::Marker marker = generateCovarianceEllipsoidMarker(pMarkerId++, visualization_msgs::Marker::LINE_LIST, floatWireFrame[i], pRingColor, pMean, pCovariance);
147 
148  // Add marker to marker array.
149  modelMarkers.markers.push_back(marker);
150  }
151  } catch(std::exception& exception) {
152  std::cerr << exception.what() << std::endl;
153  }
154 
155  /************************************
156  * Create coordinate system.
157  ************************************/
158 
159  // Generate all three axis of the covariance ellipse coordinate system.
160 // for(unsigned int i = 0; i < 3; i++)
161 // modelMarkers.markers.push_back(generateAxis(pMarkerId++, i, pMean, pCovariance));
162 
163  /************************************
164  * Create arrow from the parent position to the kernel.
165  ************************************/
166  modelMarkers.markers.push_back(generateArrowMessage(pMarkerId, mParentPose->point->getEigen(), mParentPose->point->getEigen() + mParentPose->quat->getEigen().toRotationMatrix() * pMean));
167  modelMarkers.markers.push_back(generateSphereMessage(pMarkerId, mParentPose->point->getEigen()));
168 
169  /************************************
170  * Publish the results.
171  ************************************/
172 
173  // Publish the marker array.
174  pPublisher->publish(modelMarkers);
175  }
176 
177  void GaussianKernelVisualizer::calculateCoordinatePlaneEllipses(const std::vector<int>& pEllipsoidHalfAxes,
178  const int pDiscretizationResolution,
179  std::vector<std::vector<std::vector<int> > >& pEllipsePolygons)
180  {
181  // Check whether we got size values for all three dimensions.
182  if(pEllipsoidHalfAxes.size() != 3)
183  throw std::length_error("Only supporting three dimensional ellipsoids at the moment, not " + boost::lexical_cast<std::string>(pEllipsoidHalfAxes.size()) + "D.");
184 
185  // Make sure no points remain from other calculations.
186  pEllipsePolygons.clear();
187 
188  // Vector containing half axis indices of ellipses for each possible coordinate plane.
189  std::vector<cv::Point> coordinatePlaneHalfAxisIndices;
190 
191  // First use x axis as normal of cross secting plane and choose ellipsoid half axes in that plane as ellipse half axes.
192  coordinatePlaneHalfAxisIndices.push_back(cv::Point(1, 2));
193 
194  // Then y axis.
195  coordinatePlaneHalfAxisIndices.push_back(cv::Point(0, 2));
196 
197  // Then z axis.
198  coordinatePlaneHalfAxisIndices.push_back(cv::Point(0, 1));
199 
200  // Go through all possible coordinate planes.
201  for(unsigned int i = 0; i < coordinatePlaneHalfAxisIndices.size(); i++)
202  {
203  // Polygon representing ellipse (in coordinate plane currently taken into account) in 3D space.
204  std::vector<std::vector<int> > threeDEllipsePolygon;
205 
206  // Two dimensional representation (in corresponding coordinate plane) of ellipse polygon.
207  std::vector<cv::Point> twoDEllipsePolygon;
208 
209  // Multiply the half axes of the ellipsoid with a multiplicator parameter set for visualization purposes. Then assign 3D half axes to 2D half axes according to which coordinate plane is taken into account.
210  cv::Size ellipseHalfAxes(static_cast<float>(pEllipsoidHalfAxes.at(coordinatePlaneHalfAxisIndices.at(i).x)) * mSigmaMultiplicator, static_cast<float>(pEllipsoidHalfAxes.at(coordinatePlaneHalfAxisIndices.at(i).y)) * mSigmaMultiplicator);
211 
212  // Calculate sequence of points representing entire non-rotated ellipse centered in origin lying in coordinate plane currently taken into account. Estimate half axes based on indices.
213  cv::ellipse2Poly(cv::Point(0, 0), ellipseHalfAxes, 0, 0, 360, pDiscretizationResolution, twoDEllipsePolygon);
214 
215  // Go through all 2D points constituting polygon.
216  for(unsigned int j = 0; j < twoDEllipsePolygon.size(); j++) {
217 
218  // Create three dimensional point initialized with zeros as only two coordinates (in the coordinate plane) are going to be non-zero.
219  std::vector<int> threeDPolygonPoint(3, 0);
220 
221  // X coordinate of polygon point corresponds to half axis coordinate assigned to x coordinate of coordinate plane.
222  threeDPolygonPoint.at(coordinatePlaneHalfAxisIndices.at(i).x) = twoDEllipsePolygon.at(j).x;
223 
224  // Y coordinate of polygon point corresponds to half axis coordinate assigned to y coordinate of coordinate plane.
225  threeDPolygonPoint.at(coordinatePlaneHalfAxisIndices.at(i).y) = twoDEllipsePolygon.at(j).y;
226 
227  // Complete 3D coordinate plane ellipse with another polygon point.
228  threeDEllipsePolygon.push_back(threeDPolygonPoint);
229  }
230 
231  // Add entire ellipse for one of the three coordinate planes to results container.
232  pEllipsePolygons.push_back(threeDEllipsePolygon);
233  }
234  }
235 
236  visualization_msgs::Marker GaussianKernelVisualizer::generateCovarianceEllipsoidMarker(const unsigned int pMarkerId,
237  const int pMarkerShape, const std::vector<std::vector<float> >& pWireFramePolygons,
238  const std_msgs::ColorRGBA& pColor,
239  const Eigen::Vector3d& pMean,
240  const Eigen::Matrix3d& pCovariance)
241  {
242  if(pMarkerShape != visualization_msgs::Marker::SPHERE && pMarkerShape != visualization_msgs::Marker::LINE_LIST)
243  throw std::invalid_argument("Chosen marker shape is not supported to visualize.");
244 
245  // The message that will contain the visualization marker.
246  visualization_msgs::Marker msg;
247 
248  // Use the learners frame_id relative to which all locations in this model are given.
249  msg.header.frame_id = getFrameId();
250 
251  // Set timestamp. See the TF tutorials for information on this.
252  msg.header.stamp = ros::Time::now();
253 
254  // Marker namespace are associated to different types of shapes used to represent object location distributions.
255  msg.ns = getNamespace();
256 
257  // Markers with different namespaces but same id represent same object location distribution with different shapes.
258  msg.id = pMarkerId;
259 
260  // The marker type decides on shape of marker and accordingly how marker parameters are interpreted by RViz.
261  // Here we choose a sphere.
262  msg.type = pMarkerShape;
263 
264  // We always want to show a marker by publishing ros messages here.
265  msg.action = visualization_msgs::Marker::ADD;
266 
267  // Columns of eigen matrix are eigen vectors representing the axes of the coordinate frame of the ellipsoid. Therefore eigen matrix is equal to an orientation matrix of the ellipsoid. This solver calculates the eigen matrix and vectors.
268  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> es(pCovariance);
269 
270  // Create the rotation matrix that is required for rotating the base vectors of the covariance ellipse into the world coordinate system.
271  Eigen::Matrix3d rotationFromParentToWorld = mParentPose->quat->getEigen().toRotationMatrix();
272 
273  // Extract the tree base vectors and rotate them according to the relative orientation of this secondary scene object to the primary scene object.
274  Eigen::Vector3d baseX = rotationFromParentToWorld * es.eigenvectors().col(0);
275  Eigen::Vector3d baseY = rotationFromParentToWorld * es.eigenvectors().col(1);
276  Eigen::Vector3d baseZ = rotationFromParentToWorld * es.eigenvectors().col(2);
277 
278  // We need to rotate the position of the covariance ellipse based on the orientation of the parent object.
279  Eigen::Vector3d positionInParentFrame = rotationFromParentToWorld * pMean;
280 
281  // The position of the ellipsoid is equal to the mean vector of the normal distribution.
282  Eigen::Vector3d position = mParentPose->point->getEigen();
283  tf::Vector3 tfEllipsoidPosition(position[0] + positionInParentFrame[0],
284  position[1] + positionInParentFrame[1],
285  position[2] + positionInParentFrame[2]);
286 
287  // Calculate the cross product of the first and second eigenvector.
288  Eigen::Vector3d cross = baseY.cross(baseX);
289 
290  // The new base coordinate system for the covariance ellipse.
291  tf::Matrix3x3 tfRotationMatrixOrientation;
292 
293  // Extract eigen values of covariance matrix which represent the relative scaling factors for the axes of the coordinate frame of the ellipoid extracted above or the variances in the diagonalized matrix.
294  Eigen::Vector3d squaredEllipsoidLengths;
295 
296  // Transform ellipsoid orientation matrix to ros tf representation to be able to transform it to a quaternion.
297  // Based on wolfram alpha the first and second eigen vectors should be inverted. But the visual inspection (based on the learning samples
298  // and the coordinate frame of the ellipse shows, that the right combination is e0, e1, -e2.
299  // If it is not right hand, order is e0,e2,e21 Otherwise order is e0,e1,e2.
300  if(std::signbit(cross[0]) != std::signbit(baseZ[0]) ||
301  std::signbit(cross[1]) != std::signbit(baseZ[1]) ||
302  std::signbit(cross[2]) != std::signbit(baseZ[2]))
303  {
304  tfRotationMatrixOrientation = tf::Matrix3x3(baseX[0], -baseZ[0], baseY[0],
305  baseX[1], -baseZ[1], baseY[1],
306  baseX[2], -baseZ[2], baseY[2]);
307 
308  squaredEllipsoidLengths = Eigen::Vector3d(es.eigenvalues()[0], es.eigenvalues()[2], es.eigenvalues()[1]);
309 
310  } else {
311  tfRotationMatrixOrientation = tf::Matrix3x3(baseX[0], baseY[0], -baseZ[0],
312  baseX[1], baseY[1], -baseZ[1],
313  baseX[2], baseY[2], -baseZ[2]);
314 
315  squaredEllipsoidLengths = es.eigenvalues();
316  }
317 
318  // Get transform needed for conversion to ros pose msg representation.
319  tf::Transform tfEllipsoidPose(tfRotationMatrixOrientation, tfEllipsoidPosition);
320 
321  // Fill marker pose with tf transform.
322  tf::poseTFToMsg(tfEllipsoidPose, msg.pose);
323 
324  // Scale position.
325  msg.pose.position.x *= getScaleFactor();
326  msg.pose.position.y *= getScaleFactor();
327  msg.pose.position.z *= getScaleFactor();
328 
329  // Apply the given color and alpha value.
330  msg.color = pColor;
331 
332  // If surface model of ellipsoid is desired, set size of ellipsoid directly in marker using scale parameter
333  if(pMarkerShape == visualization_msgs::Marker::SPHERE)
334  {
335  // Multiply the relative lengths (square roots of corresponding eigen values) of the half axes of the ellipse with a multiplicator parameter set for visualization purposes. Then double value as scale does not represent radius, but diameter of the marker.
336  msg.scale.x = 2.0f * std::sqrt(squaredEllipsoidLengths[0]) * getScaleFactor() * mSigmaMultiplicator;
337  msg.scale.y = 2.0f * std::sqrt(squaredEllipsoidLengths[1]) * getScaleFactor() * mSigmaMultiplicator;
338  msg.scale.z = 2.0f * std::sqrt(squaredEllipsoidLengths[2]) * getScaleFactor() * mSigmaMultiplicator;
339  } else {
340 
341  // Access a point on the ellipse-shaped polygon.
342  std::vector<std::vector<float> >::const_iterator polygonPointIterator = pWireFramePolygons.begin();
343 
344  // Geometry_msgs representation of 3D point for polygon point...
345  geometry_msgs::Point rosPolygonPoint;
346 
347  // ...is needed for insertion into marker message.
348  stlVectorToPointMsg(*polygonPointIterator, rosPolygonPoint);
349 
350  // Add starting of first segment of ellipse to points array containing all segments as pairs of starting- and endpoints.
351  msg.points.push_back(rosPolygonPoint);
352 
353  // Go through all points in the polygon ignoring first try.
354  for(polygonPointIterator++; polygonPointIterator != pWireFramePolygons.end(); polygonPointIterator++)
355  {
356  // Add end point of segment already being processed.
357  stlVectorToPointMsg(*polygonPointIterator, rosPolygonPoint);
358  msg.points.push_back(rosPolygonPoint);
359 
360  // Add starting point of next segment
361  msg.points.push_back(rosPolygonPoint);
362  }
363 
364  // Close the loop with the polygon segment [end(),begin()].
365  stlVectorToPointMsg(*(pWireFramePolygons.begin()), rosPolygonPoint);
366  msg.points.push_back(rosPolygonPoint);
367 
368  // Nevertheless the width of the wires is set solely using x component of scale parameter.
369  msg.scale.x = 0.005;
370  }
371 
372  // How long the object should last before being automatically deleted. (Here forever.)
373  msg.lifetime = ros::Duration();
374 
375  return msg;
376  }
377 
378  visualization_msgs::Marker GaussianKernelVisualizer::generateAxis(const unsigned int pMarkerId,
379  const unsigned int pAxis,
380  const Eigen::Vector3d& pMean,
381  const Eigen::Matrix3d& pCovariance)
382  {
383  visualization_msgs::Marker msg;
384 
385  // Columns of eigen matrix are eigen vectors representing the axes of the coordinate frame of the ellipsoid. Therefore eigen matrix is equal to an orientation matrix of the ellipsoid. This solver calculates the eigen matrix and vectors.
386  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> es(pCovariance);
387 
388  /***************************************************************************************************************************************************
389  * Before we start we need to choose the second and third axis (based on the eigenvectors) so that they form a right hand coordinate system.
390  * Therefore we calulate the cross product of the first and every other eigenvector.
391  * The eigenvector, that creates a right hand coordinate system, is choosen.
392  ***************************************************************************************************************************************************/
393 
394  // This will be the axis number to use.
395  unsigned int axisForRightHandFrame = pAxis;
396 
397  // Extract the axes.
398  Eigen::Vector3d firstAxis = es.eigenvectors().col(0) * std::sqrt(es.eigenvalues()[0]);
399  Eigen::Vector3d secondAxis = es.eigenvectors().col(1) * std::sqrt(es.eigenvalues()[1]);
400  Eigen::Vector3d thirdAxis = es.eigenvectors().col(2) * std::sqrt(es.eigenvalues()[2]);
401 
402  // Calculate the cross product of the first and second eigenvector.
403  Eigen::Vector3d cross = secondAxis.cross(firstAxis);
404 
405  // If it is right hand, order is e0,e1,e2. Otherwise (as considered here) order is e0,e2,e1.
406  if(std::signbit(cross[0]) != std::signbit(thirdAxis[0]) ||
407  std::signbit(cross[1]) != std::signbit(thirdAxis[1]) ||
408  std::signbit(cross[2]) != std::signbit(thirdAxis[2]))
409  {
410  if(pAxis == 1) axisForRightHandFrame = 2;
411  if(pAxis == 2) axisForRightHandFrame = 1;
412  }
413 
414  /***************************************************************************************************************************************************
415  * Continue with the visualization.
416  ***************************************************************************************************************************************************/
417 
418  // Use the learners frame_id relative to which all locations in this model are given.
419  msg.header.frame_id = getFrameId();
420 
421  // Set timestamp. See the TF tutorials for information on this.
422  msg.header.stamp = ros::Time::now();
423 
424  // Marker namespace are associated to different types of shapes used to represent object location distributions.
425  msg.ns = getNamespace();
426 
427  // Markers with different namespaces but same id represent same object location distribution with different shapes.
428  msg.id = pMarkerId;
429 
430  // The marker type decides on shape of marker and accordingly how marker parameters are interpreted by RViz.
431  // Here we choose a sphere.
432  msg.type = visualization_msgs::Marker::ARROW;
433 
434  // We always want to show a marker by publishing ros messages here.
435  msg.action = visualization_msgs::Marker::ADD;
436 
437  // Arrows should be pretty small. Don't set z here, because we are using start and endpoint here.
438  msg.scale.x = msg.scale.y = 0.005;
439 
440  // Create the rotation matrix that is required for rotating the base vectors of the covariance ellipse into the world coordinate system.
441  Eigen::Matrix3d rotationFromParentToWorld = mParentPose->quat->getEigen().toRotationMatrix();
442 
443  // Extract the axis vector and rotate it from the parent coordinate frame into world coordinates.
444  // The axis vector is composed of the eigenvector scaled by the eigen value.
445  Eigen::Vector3d axis = rotationFromParentToWorld * (es.eigenvectors().col(axisForRightHandFrame) * std::sqrt(es.eigenvalues()[axisForRightHandFrame]));
446 
447  // We need to rotate the position of the covariance ellipse based on the orientation of the parent object.
448  Eigen::Vector3d positionInParentFrame = rotationFromParentToWorld * pMean;
449 
450  // Extract position of parent object.
451  Eigen::Vector3d position = mParentPose->point->getEigen();
452 
453  // Create the starting point.
454  geometry_msgs::Point start;
455  start.x = (position[0] + positionInParentFrame[0]) * getScaleFactor();
456  start.y = (position[1] + positionInParentFrame[1]) * getScaleFactor();
457  start.z = (position[2] + positionInParentFrame[2]) * getScaleFactor();
458  msg.points.push_back(start);
459 
460  // Create the point to point to ;).
461  geometry_msgs::Point stop;
462  stop.x = ((position[0] + positionInParentFrame[0]) + (axis[0] * mSigmaMultiplicator)) * getScaleFactor();
463  stop.y = ((position[1] + positionInParentFrame[1]) + (axis[1] * mSigmaMultiplicator)) * getScaleFactor();
464  stop.z = ((position[2] + positionInParentFrame[2]) + (axis[2] * mSigmaMultiplicator)) * getScaleFactor();
465  msg.points.push_back(stop);
466 
467  // Set the colors based on the axis number. The axis with the biggest eigenvalue will be the new X axis.
468  // So the colors RGB stand for the axis XYZ.
469  msg.color.b = (pAxis == 0) ? 1.0 : 0.0;
470  msg.color.g = (pAxis - 1 == 0) ? 1.0 : 0.0;
471  msg.color.r = (pAxis - 2 == 0) ? 1.0 : 0.0;
472  msg.color.a = 1.0;
473 
474  // Return the message.
475  return msg;
476  }
477 
478  visualization_msgs::MarkerArray GaussianKernelVisualizer::generateSamplesMarker(const unsigned int pMarkerId, const std::vector<boost::shared_ptr<Eigen::Quaternion<double> > >& pSamples)
479  {
480  // ONE MESSAGE TO RULE THEM ALL! Well, kind of. Stop talking, Sauron :=)!
481  visualization_msgs::MarkerArray msgArray;
482  visualization_msgs::Marker msg;
483 
484  // Set time and frame id.
485  msg.header.stamp = ros::Time::now();
486  msg.header.frame_id = getFrameId();
487 
488  // Namespace will represent the nature of the message.
489  msg.ns = getNamespace();
490 
491  // Every sample has its own id.
492  msg.id = pMarkerId;
493 
494  // Point is represented by a sphere.
495  msg.type = visualization_msgs::Marker::SPHERE_LIST;
496 
497  // We always want to show a marker by publishing ros messages here.
498  msg.action = visualization_msgs::Marker::ADD;
499 
500  // Iterate over all samples and add them to the visualization marker.
501  for(boost::shared_ptr<Eigen::Quaternion<double> > sample : pSamples)
502  {
503  geometry_msgs::Point point;
504  point.x = sample->x() * getScaleFactor();
505  point.y = sample->y() * getScaleFactor();
506  point.z = sample->z() * getScaleFactor();
507  msg.points.push_back(point);
508  }
509 
510  // Draw the points relative to the parent scene object.
511  Eigen::Vector3d position = mParentPose->point->getEigen();
512  msg.pose.position.x = position[0] * getScaleFactor();
513  msg.pose.position.y = position[1] * getScaleFactor();
514  msg.pose.position.z = position[2] * getScaleFactor();
515 
516  Eigen::Quaternion<double> orientation = mParentPose->quat->getEigen();
517  msg.pose.orientation.w = orientation.w();
518  msg.pose.orientation.x = orientation.x();
519  msg.pose.orientation.y = orientation.y();
520  msg.pose.orientation.z = orientation.z();
521 
522  // Spheres shall be very small, but must be scaled, too.
523  msg.scale.x = msg.scale.y = msg.scale.z = 0.0025 * getScaleFactor();
524 
525  // And black! We love black!
526  msg.color.r = 0.0;
527  msg.color.g = 0.0;
528  msg.color.b = 0.0;
529  msg.color.a = 1.0;
530 
531  // Add message to marker array.
532  msgArray.markers.push_back(msg);
533 
534  // Return the message containing all samples.
535  return msgArray;
536  }
537 
538  visualization_msgs::Marker GaussianKernelVisualizer::generateSphereMessage(unsigned int& pMarkerId, Eigen::Vector3d pPos)
539  {
540  visualization_msgs::Marker msg;
541 
542  // Set time and frame id.
543  msg.header.stamp = ros::Time::now();
544  msg.header.frame_id = getFrameId();
545 
546  // Scale it to be very small and long.
547  msg.scale.x = msg.scale.y = msg.scale.z = 0.01;
548 
549  // This should be an arrow.
550  msg.type = visualization_msgs::Marker::SPHERE;
551 
552  // Namespace will represent the nature of the message.
553  msg.ns = getNamespace();
554 
555  // Markers with different namespaces but same id represent same object location distribution with different shapes.
556  msg.id = pMarkerId++;
557 
558  // We always want to show a marker by publishing ros messages here.
559  msg.action = visualization_msgs::Marker::ADD;
560 
561  // Set position.
562  msg.pose.position.x = pPos[0];
563  msg.pose.position.y = pPos[1];
564  msg.pose.position.z = pPos[2];
565  msg.pose.orientation.x = 0.0;
566  msg.pose.orientation.y = 0.0;
567  msg.pose.orientation.z = 0.0;
568  msg.pose.orientation.w = 1.0;
569 
570  // Take the second color, it stands for the secondary scene object.
571  double factor = 0.5;
572  msg.color.r = getColor(0).r * factor;
573  msg.color.g = getColor(0).g * factor;
574  msg.color.b = getColor(0).b * factor;
575  msg.color.a = 1.0;
576 
577  // Return the link message message.
578  return msg;
579  }
580 
581  visualization_msgs::Marker GaussianKernelVisualizer::generateArrowMessage(unsigned int& pMarkerId, Eigen::Vector3d pFrom, Eigen::Vector3d pTo)
582  {
583  visualization_msgs::Marker msg;
584 
585  // Set time and frame id.
586  msg.header.stamp = ros::Time::now();
587  msg.header.frame_id = getFrameId();
588 
589  // Scale it to be very small and long.
590 // msg.scale.x = 0.006;
591 // msg.scale.y = 0.013;
592 // msg.scale.z = 0.06;
593  msg.scale.x = 0.012;
594  msg.scale.y = 0.026;
595  msg.scale.z = 0.06;
596 
597  // This should be an arrow.
598  msg.type = visualization_msgs::Marker::ARROW;
599 
600  // Namespace will represent the nature of the message.
601  msg.ns = getNamespace();
602 
603  // Markers with different namespaces but same id represent same object location distribution with different shapes.
604  msg.id = pMarkerId++;
605 
606  // We always want to show a marker by publishing ros messages here.
607  msg.action = visualization_msgs::Marker::ADD;
608 
609  // Create the starting point.
610  geometry_msgs::Point start;
611  start.x = pFrom[0] * getScaleFactor();
612  start.y = pFrom[1] * getScaleFactor();
613  start.z = pFrom[2] * getScaleFactor();
614  msg.points.push_back(start);
615 
616  // Create the end point.
617  geometry_msgs::Point stop;
618  stop.x = pTo[0] * getScaleFactor();
619  stop.y = pTo[1] * getScaleFactor();
620  stop.z = pTo[2] * getScaleFactor();
621  msg.points.push_back(stop);
622 
623  // Take the second color, it stands for the secondary scene object.
624  double factor = 0.5;
625  msg.color.r = getColor(0).r * factor;
626  msg.color.g = getColor(0).g * factor;
627  msg.color.b = getColor(0).b * factor;
628  msg.color.a = 1.0;
629 
630  // Return the link message message.
631  return msg;
632  }
633 
634  template <class T> void GaussianKernelVisualizer::stlVectorToPointMsg(const std::vector<T> pPositionVector, geometry_msgs::Point& pROSPositionMsg)
635  {
636  // pPositionVector must represent a position to be converted.
637  if(pPositionVector.size() != 3)
638  throw std::invalid_argument("pPositionVector is not a position in terms of dimensionality.");
639 
640  // Copy position information per dimension.
641  pROSPositionMsg.x = pPositionVector.at(0);
642  pROSPositionMsg.y = pPositionVector.at(1);
643  pROSPositionMsg.z = pPositionVector.at(2);
644  }
645 }
void calculateCoordinatePlaneEllipses(const std::vector< int > &pEllipsoidHalfAxes, const int pDiscretizationResolution, std::vector< std::vector< std::vector< int > > > &pEllipsePolygons)
visualization_msgs::Marker generateArrowMessage(unsigned int &pMarkerId, Eigen::Vector3d pFrom, Eigen::Vector3d pTo)
void setSigmaMultiplicator(const float pSigmaMultiplicator)
f
TFSIMD_FORCE_INLINE Vector3 cross(const Vector3 &v) const
void setParentPose(boost::shared_ptr< ISM::Pose > pPose)
const std_msgs::ColorRGBA getColor(unsigned int pNumber)
static void poseTFToMsg(const Pose &bt, geometry_msgs::Pose &msg)
visualization_msgs::MarkerArray generateSamplesMarker(const unsigned int pMarkerId, const std::vector< boost::shared_ptr< Eigen::Quaternion< double > > > &pSamples)
visualization_msgs::Marker generateSphereMessage(unsigned int &pMarkerId, Eigen::Vector3d pPos)
static Time now()
void publishKernel(boost::shared_ptr< ros::Publisher > pPublisher, unsigned int &pMarkerId, const Eigen::Vector3d &pMean, const Eigen::Matrix3d &pCovariance)
visualization_msgs::Marker generateAxis(const unsigned int pMarkerId, const unsigned int pAxis, const Eigen::Vector3d &pMean, const Eigen::Matrix3d &pCovariance)
visualization_msgs::Marker generateCovarianceEllipsoidMarker(const unsigned int pMarkerId, const int pMarkerShape, const std::vector< std::vector< float > > &pWireFramePolygons, const std_msgs::ColorRGBA &pColor, const Eigen::Vector3d &pMean, const Eigen::Matrix3d &pCovariance)
void stlVectorToPointMsg(const std::vector< T > pPositionVector, geometry_msgs::Point &pROSPositionMsg)


asr_psm_visualizations
Author(s): Gehrung Joachim, Meißner Pascal
autogenerated on Sat Nov 9 2019 03:49:12