GridMapPclConverter.cpp
Go to the documentation of this file.
1 /*
2  * GridMapPclConverter.cpp
3  *
4  * Created on: Oct 19, 2016
5  * Author: Dominic Jud
6  * Institute: ETH Zurich, ANYbotics
7  */
8 
10 
11 namespace grid_map {
12 
14 {
15 }
16 
18 {
19 }
20 
21 bool GridMapPclConverter::initializeFromPolygonMesh(const pcl::PolygonMesh& mesh,
22  const double resolution,
23  grid_map::GridMap& gridMap)
24 {
25  pcl::PointCloud < pcl::PointXYZ > cloud;
26  pcl::fromPCLPointCloud2(mesh.cloud, cloud);
27  pcl::PointXYZ minBound;
28  pcl::PointXYZ maxBound;
29  pcl::getMinMax3D(cloud, minBound, maxBound);
30 
31  grid_map::Length length = grid_map::Length(maxBound.x - minBound.x, maxBound.y - minBound.y);
32  grid_map::Position position = grid_map::Position((maxBound.x + minBound.x) / 2.0,
33  (maxBound.y + minBound.y) / 2.0);
34  gridMap.setGeometry(length, resolution, position);
35 
36  return true;
37 }
38 
39 bool GridMapPclConverter::addLayerFromPolygonMesh(const pcl::PolygonMesh& mesh,
40  const std::string& layer,
41  grid_map::GridMap& gridMap)
42 {
43  // Adding a layer to the grid map to put data into
44  gridMap.add(layer);
45  // Converting out of binary cloud data
46  pcl::PointCloud <pcl::PointXYZ> cloud;
47  pcl::fromPCLPointCloud2(mesh.cloud, cloud);
48  // Direction and max height for projection ray
49  const Eigen::Vector3f ray = -Eigen::Vector3f::UnitZ();
50  pcl::PointXYZ minBound;
51  pcl::PointXYZ maxBound;
52  pcl::getMinMax3D(cloud, minBound, maxBound);
53 
54  // Iterating over the triangles in the mesh
55  for (const pcl::Vertices& polygon : mesh.polygons) {
56  // Testing this is a triangle
57  assert(polygon.vertices.size() == 3);
58  // Getting the vertices of the triangle (as a single matrix)
59  Eigen::Matrix3f triangleVertexMatrix;
60  triangleVertexMatrix.row(0) = cloud[polygon.vertices[0]].getVector3fMap();
61  triangleVertexMatrix.row(1) = cloud[polygon.vertices[1]].getVector3fMap();
62  triangleVertexMatrix.row(2) = cloud[polygon.vertices[2]].getVector3fMap();
63  // Getting the bounds in the XY plane (down projection)
64  float maxX = triangleVertexMatrix.col(0).maxCoeff();
65  float minX = triangleVertexMatrix.col(0).minCoeff();
66  float maxY = triangleVertexMatrix.col(1).maxCoeff();
67  float minY = triangleVertexMatrix.col(1).minCoeff();
68  // Iterating over the grid cells in the a submap below the triangle
69  grid_map::Length length(maxX - minX, maxY - minY);
70  grid_map::Position position((maxX + minX) / 2.0, (maxY + minY) / 2.0);
71  bool isSuccess;
72  SubmapGeometry submap(gridMap, position, length, isSuccess);
73  if (isSuccess) {
74  for (grid_map::SubmapIterator iterator(submap); !iterator.isPastEnd();
75  ++iterator) {
76  // Cell position
77  const Index index(*iterator);
78  grid_map::Position vertexPositionXY;
79  gridMap.getPosition(index, vertexPositionXY);
80  // Ray origin
81  Eigen::Vector3f point(vertexPositionXY.x(), vertexPositionXY.y(),
82  maxBound.z + 1.0);
83  // Vertical ray/triangle intersection
84  Eigen::Vector3f intersectionPoint;
85  if (rayTriangleIntersect(point, ray, triangleVertexMatrix, intersectionPoint)) {
86  // If data already present in this cell, taking the max, else setting the data
87  if (gridMap.isValid(index, layer)) {
88  gridMap.at(layer, index) = std::max(gridMap.at(layer, index), intersectionPoint.z());
89  } else {
90  gridMap.at(layer, index) = intersectionPoint.z();
91  }
92  }
93  }
94  }
95  }
96  // Success
97  return true;
98 }
99 
101  const Eigen::Vector3f& point, const Eigen::Vector3f& ray,
102  const Eigen::Matrix3f& triangleVertexMatrix,
103  Eigen::Vector3f& intersectionPoint) {
104  // Algorithm here is adapted from:
105  // http://softsurfer.com/Archive/algorithm_0105/algorithm_0105.htm#intersect_RayTriangle()
106  //
107  // Original copyright notice:
108  // Copyright 2001, softSurfer (www.softsurfer.com)
109  // This code may be freely used and modified for any purpose
110  // providing that this copyright notice is included with it.
111 
112  const Eigen::Vector3f a = triangleVertexMatrix.row(0);
113  const Eigen::Vector3f b = triangleVertexMatrix.row(1);
114  const Eigen::Vector3f c = triangleVertexMatrix.row(2);
115  const Eigen::Vector3f u = b - a;
116  const Eigen::Vector3f v = c - a;
117  const Eigen::Vector3f n = u.cross(v);
118  const float n_dot_ray = n.dot(ray);
119 
120  if (std::fabs(n_dot_ray) < 1e-9) return false;
121 
122  const float r = n.dot(a - point) / n_dot_ray;
123 
124  if (r < 0) return false;
125 
126  // Note(alexmillane): The addition of this comparison delta (not in the
127  // original algorithm) means that rays intersecting the edge of triangles are
128  // treated at hits.
129  constexpr float delta = 1e-5;
130 
131  const Eigen::Vector3f w = point + r * ray - a;
132  const float denominator = u.dot(v) * u.dot(v) - u.dot(u) * v.dot(v);
133  const float s_numerator = u.dot(v) * w.dot(v) - v.dot(v) * w.dot(u);
134  const float s = s_numerator / denominator;
135  if (s < (0 - delta) || s > (1 + delta)) return false;
136 
137  const float t_numerator = u.dot(v) * w.dot(u) - u.dot(u) * w.dot(v);
138  const float t = t_numerator / denominator;
139  if (t < (0 - delta) || s + t > (1 + delta)) return false;
140 
141  intersectionPoint = a + s * u + t * v;
142 
143  return true;
144 }
145 
146 } /* namespace */
Eigen::Array2i Index
void setGeometry(const Length &length, const double resolution, const Position &position=Position::Zero())
bool getPosition(const Index &index, Position &position) const
XmlRpcServer s
bool isValid(const Index &index) const
Eigen::Vector2d Position
float & at(const std::string &layer, const Index &index)
TFSIMD_FORCE_INLINE const tfScalar & w() const
void add(const std::string &layer, const double value=NAN)
static bool rayTriangleIntersect(const Eigen::Vector3f &point, const Eigen::Vector3f &ray, const Eigen::Matrix3f &triangleVertices, Eigen::Vector3f &intersectionPoint)
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
static bool addLayerFromPolygonMesh(const pcl::PolygonMesh &mesh, const std::string &layer, grid_map::GridMap &gridMap)
Eigen::Array2d Length
static bool initializeFromPolygonMesh(const pcl::PolygonMesh &mesh, const double resolution, grid_map::GridMap &gridMap)


grid_map_pcl
Author(s): Dominic Jud
autogenerated on Tue Jun 25 2019 20:02:17