naiveSignedDistance.hpp
Go to the documentation of this file.
1 /*
2  * naiveSignedDistance.h
3  *
4  * Created on: Aug 10, 2020
5  * Author: Ruben Grandia
6  * Institute: ETH Zurich
7  */
8 
9 #pragma once
10 
11 namespace grid_map {
12 namespace signed_distance_field {
13 
14 inline Eigen::Matrix<bool, -1, -1> occupancyAtHeight(const Matrix& elevationMap, float height) {
15  Eigen::Matrix<bool, -1, -1> occupancy = elevationMap.unaryExpr([=](float val) { return val > height; });
16  return occupancy;
17 }
18 
19 inline bool isEqualSdf(const Matrix& sdf0, const Matrix& sdf1, float tol) {
20  if (sdf0.cols() != sdf1.cols() || sdf0.rows() != sdf1.rows()) {
21  return false;
22  }
23 
24  for (Eigen::Index col = 0; col < sdf0.cols(); ++col) {
25  for (Eigen::Index row = 0; row < sdf0.rows(); ++row) {
26  if (sdf0(row, col) == sdf1(row, col) || std::abs(sdf0(row, col) - sdf1(row, col)) < tol) {
27  continue;
28  } else {
29  return false;
30  }
31  }
32  }
33  return true;
34 }
35 
36 // N^2 naive implementation, for testing purposes
37 inline Matrix naiveSignedDistanceAtHeight(const Matrix& elevationMap, float height, float resolution) {
38  Matrix signedDistance(elevationMap.rows(), elevationMap.cols());
39 
40  // For each point
41  for (Eigen::Index col = 0; col < elevationMap.cols(); ++col) {
42  for (Eigen::Index row = 0; row < elevationMap.rows(); ++row) {
43  if (elevationMap(row, col) >= height) { // point in the SDF is below surface
44  signedDistance(row, col) = -INF;
45  // find closest open space over all other points
46  for (Eigen::Index j = 0; j < elevationMap.cols(); ++j) {
47  for (Eigen::Index i = 0; i < elevationMap.rows(); ++i) {
48  // Compute distance to free cube at location (i, j)
49  const float dx{resolution * pixelBorderDistance(i, row)};
50  const float dy{resolution * pixelBorderDistance(j, col)};
51  const float dz{std::max(elevationMap(i, j) - height, 0.0F)};
52  const float currentSignedDistance{-std::sqrt(dx * dx + dy * dy + dz * dz)};
53  signedDistance(row, col) = std::max(signedDistance(row, col), currentSignedDistance);
54  }
55  }
56  } else { // point in the SDF is above surface
57  signedDistance(row, col) = INF;
58  // find closest object over all other points
59  for (Eigen::Index j = 0; j < elevationMap.cols(); ++j) {
60  for (Eigen::Index i = 0; i < elevationMap.rows(); ++i) {
61  // Compute distance to occupied cube at location (i, j)
62  const float dx{resolution * pixelBorderDistance(i, row)};
63  const float dy{resolution * pixelBorderDistance(j, col)};
64  const float dz{std::max(height - elevationMap(i, j), 0.0F)};
65  const float currentSignedDistance{std::sqrt(dx * dx + dy * dy + dz * dz)};
66  signedDistance(row, col) = std::min(signedDistance(row, col), currentSignedDistance);
67  }
68  }
69  }
70  }
71  }
72 
73  return signedDistance;
74 }
75 
76 inline Matrix naiveSignedDistanceFromOccupancy(const Eigen::Matrix<bool, -1, -1>& occupancyGrid, float resolution) {
77  Matrix signedDistance(occupancyGrid.rows(), occupancyGrid.cols());
78 
79  // For each point
80  for (Eigen::Index col = 0; col < occupancyGrid.cols(); ++col) {
81  for (Eigen::Index row = 0; row < occupancyGrid.rows(); ++row) {
82  if (occupancyGrid(row, col)) { // This point is an obstable
83  signedDistance(row, col) = -INF;
84  // find closest open space over all other points
85  for (Eigen::Index j = 0; j < occupancyGrid.cols(); ++j) {
86  for (Eigen::Index i = 0; i < occupancyGrid.rows(); ++i) {
87  if (!occupancyGrid(i, j)) {
88  const float dx{resolution * pixelBorderDistance(i, row)};
89  const float dy{resolution * pixelBorderDistance(j, col)};
90  const float currentSignedDistance{-std::sqrt(dx * dx + dy * dy)};
91  signedDistance(row, col) = std::max(signedDistance(row, col), currentSignedDistance);
92  }
93  }
94  }
95  } else { // This point is in free space
96  signedDistance(row, col) = INF;
97  // find closest object over all other points
98  for (Eigen::Index j = 0; j < occupancyGrid.cols(); ++j) {
99  for (Eigen::Index i = 0; i < occupancyGrid.rows(); ++i) {
100  if (occupancyGrid(i, j)) {
101  const float dx{resolution * pixelBorderDistance(i, row)};
102  const float dy{resolution * pixelBorderDistance(j, col)};
103  const float currentSignedDistance{std::sqrt(dx * dx + dy * dy)};
104  signedDistance(row, col) = std::min(signedDistance(row, col), currentSignedDistance);
105  }
106  }
107  }
108  }
109  }
110  }
111 
112  return signedDistance;
113 }
114 
115 } // namespace signed_distance_field
116 } // namespace grid_map
Matrix naiveSignedDistanceFromOccupancy(const Eigen::Matrix< bool, -1, -1 > &occupancyGrid, float resolution)
float pixelBorderDistance(float i, float j)
Eigen::Matrix< bool, -1, -1 > occupancyAtHeight(const Matrix &elevationMap, float height)
Matrix naiveSignedDistanceAtHeight(const Matrix &elevationMap, float height, float resolution)
Eigen::MatrixXf Matrix
constexpr float INF
Distance value that is considered infinite.
Definition: Utils.hpp:18
bool isEqualSdf(const Matrix &sdf0, const Matrix &sdf1, float tol)


grid_map_sdf
Author(s): Takahiro Miki , Péter Fankhauser
autogenerated on Wed Jul 5 2023 02:23:42