9 #include <gtest/gtest.h> 18 using namespace signed_distance_field;
20 TEST(testSignedDistance3d, flatTerrain) {
23 const float resolution = 0.1;
24 const float terrainHeight = 0.5;
25 const Matrix map = Matrix::Constant(n, m, terrainHeight);
26 const float minHeight = map.minCoeff();
27 const float maxHeight = map.maxCoeff();
29 const float testHeightAboveTerrain = 3.0;
31 const auto signedDistanceAbove =
signedDistanceAtHeight(map, testHeightAboveTerrain, resolution, minHeight, maxHeight);
32 ASSERT_TRUE(
isEqualSdf(signedDistanceAbove, naiveSignedDistanceAbove, 1e-4));
34 const float testHeightBelowTerrain = -3.0;
36 const auto signedDistanceBelow =
signedDistanceAtHeight(map, testHeightBelowTerrain, resolution, minHeight, maxHeight);
37 ASSERT_TRUE(
isEqualSdf(signedDistanceBelow, naiveSignedDistanceBelow, 1e-4));
40 TEST(testSignedDistance3d, randomTerrain) {
43 const float resolution = 0.1;
44 Matrix map = Matrix::Random(n, m);
45 const float minHeight = map.minCoeff();
46 const float maxHeight = map.maxCoeff();
49 float heightStep = 0.1;
50 for (
float height = -1.0 - heightStep; height < 1.0 + heightStep; height += heightStep) {
54 ASSERT_TRUE(
isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)) <<
"height: " << height;
58 TEST(testSignedDistance3d, randomTerrainInterpolation) {
61 const float resolution = 0.1;
63 map.
setGeometry({n * resolution, m * resolution}, resolution);
65 map.
get(
"elevation").setRandom();
66 const Matrix mapData = map.
get(
"elevation");
67 const float minHeight = mapData.minCoeff();
68 const float maxHeight = mapData.maxCoeff();
73 for (
float height = minHeight; height < maxHeight; height += resolution) {
76 for (
int i = 0; i < mapData.rows(); ++i) {
77 for (
int j = 0; j < mapData.rows(); ++j) {
81 const auto sdfValue = sdf.
value({position2d.x(), position2d.y(), height});
82 const auto sdfCheck = naiveSignedDistance(i, j);
83 ASSERT_LT(std::abs(sdfValue - sdfCheck), 1e-4);
89 TEST(testSignedDistance3d, randomTerrainDerivative) {
92 const float resolution = 0.1;
94 map.
setGeometry({n * resolution, m * resolution}, resolution);
96 map.
get(
"elevation").setRandom();
97 const Matrix mapData = map.
get(
"elevation");
98 const float minHeight = mapData.minCoeff();
99 const float maxHeight = mapData.maxCoeff();
104 int numLayers = (maxHeight - minHeight) / resolution;
105 for (
int k = 0; k <= numLayers; ++k) {
106 const float height = minHeight + k * resolution;
111 for (
int i = 0; i < mapData.rows(); ++i) {
112 for (
int j = 0; j < mapData.rows(); ++j) {
116 const auto sdfCheck = naiveSignedDistance(i, j);
117 ASSERT_LT(std::abs(sdfderivative.first - sdfCheck), 1e-4);
122 if (i + 1 < mapData.rows()) {
123 dx = (naiveSignedDistance(i + 1, j) - naiveSignedDistance(i - 1, j)) / (-2.0 * resolution);
125 dx = (naiveSignedDistance(i, j) - naiveSignedDistance(i - 1, j)) / (-resolution);
128 dx = (naiveSignedDistance(i + 1, j) - naiveSignedDistance(i, j)) / (-resolution);
130 ASSERT_LT(std::abs(dx - sdfderivative.second.x()), 1e-4);
134 if (j + 1 < mapData.cols()) {
135 dy = (naiveSignedDistance(i, j + 1) - naiveSignedDistance(i, j - 1)) / (-2.0 * resolution);
137 dy = (naiveSignedDistance(i, j) - naiveSignedDistance(i, j - 1)) / (-resolution);
140 dy = (naiveSignedDistance(i, j + 1) - naiveSignedDistance(i, j)) / (-resolution);
142 ASSERT_LT(std::abs(dy - sdfderivative.second.y()), 1e-4);
147 dz = (naiveSignedDistanceNext(i, j) - naiveSignedDistancePrevious(i, j)) / (2.0 * resolution);
149 dz = (naiveSignedDistance(i, j) - naiveSignedDistancePrevious(i, j)) / (resolution);
152 dz = (naiveSignedDistanceNext(i, j) - naiveSignedDistance(i, j)) / (resolution);
154 ASSERT_LT(std::abs(dz - sdfderivative.second.z()), 1e-4);
160 TEST(testSignedDistance3d, extrapolation) {
163 const float resolution = 0.1;
166 map.
setGeometry({n * resolution, m * resolution}, resolution);
167 map.
add(
"elevation");
168 map.
get(
"elevation").setConstant(h);
169 const Matrix mapData = map.
get(
"elevation");
170 const float minHeight = h - resolution;
171 const float maxHeight = h + resolution;
176 for (
float height = h - 1.0; height < h + 1.0; height += resolution) {
179 for (
int i = 0; i < mapData.rows(); ++i) {
180 for (
int j = 0; j < mapData.rows(); ++j) {
184 const auto sdfValueAndDerivative = sdf.
valueAndDerivative({position2d.x(), position2d.y(), height});
185 const auto sdfCheck = naiveSignedDistance(i, j);
186 ASSERT_LT(std::abs(sdfValueAndDerivative.first - sdfCheck), 1e-4);
189 ASSERT_LT((sdfValueAndDerivative.second - SignedDistanceField::Derivative3::UnitZ()).norm(), 1e-4);
void setGeometry(const Length &length, const double resolution, const Position &position=Position::Zero())
const Matrix & get(const std::string &layer) const
Matrix signedDistanceAtHeight(const Matrix &elevationMap, float height, float resolution, float minHeight, float maxHeight)
double value(const Position3 &position) const noexcept
Matrix naiveSignedDistanceAtHeight(const Matrix &elevationMap, float height, float resolution)
std::pair< double, Derivative3 > valueAndDerivative(const Position3 &position) const noexcept
void add(const std::string &layer, const double value=NAN)
Eigen::Vector3d Position3
TEST(GridMap, CopyConstructor)
bool getPosition(const Index &index, Position &position) const
bool isEqualSdf(const Matrix &sdf0, const Matrix &sdf1, float tol)