grid_map_core/test/test_helpers.cpp
2026-01-14 15:04:54 +07:00

233 lines
5.4 KiB
C++

/*
* test_helpers.cpp
*
* Created on: Mar 3, 2020
* Author: Edo Jelavic
* Institute: ETH Zurich, Robotic Systems Lab
*/
#include "test_helpers.hpp"
#include "grid_map_core/GridMap.hpp"
#include "grid_map_core/iterators/GridMapIterator.hpp"
// gtest
#include <gtest/gtest.h>
namespace grid_map_test {
std::mt19937 rndGenerator;
AnalyticalFunctions createFlatWorld(grid_map::GridMap *map)
{
AnalyticalFunctions func;
func.f_ = [](double /*x*/, double /*y*/) {
return 0.0;
};
fillGridMap(map, func);
return func;
}
AnalyticalFunctions createRationalFunctionWorld(grid_map::GridMap *map)
{
AnalyticalFunctions func;
std::uniform_real_distribution<double> shift(-3.0, 3.0);
std::uniform_real_distribution<double> scale(1.0, 20.0);
const double x0 = shift(rndGenerator);
const double y0 = shift(rndGenerator);
const double s = scale(rndGenerator);
func.f_ = [x0, y0,s](double x, double y) {
return s / (1 + std::pow(x-x0, 2.0) + std::pow(y-y0, 2.0));
};
fillGridMap(map, func);
return func;
}
AnalyticalFunctions createSecondOrderPolyWorld(grid_map::GridMap *map)
{
AnalyticalFunctions func;
func.f_ = [](double x,double y) {
return (-x*x -y*y +2.0*x*y +x*x*y*y);
};
fillGridMap(map, func);
return func;
}
AnalyticalFunctions createSaddleWorld(grid_map::GridMap *map)
{
AnalyticalFunctions func;
func.f_ = [](double x,double y) {
return (x*x-y*y);
};
fillGridMap(map, func);
return func;
}
AnalyticalFunctions createSineWorld(grid_map::GridMap *map)
{
AnalyticalFunctions func;
std::uniform_real_distribution<double> Uw(0.1, 4.0);
const double w1 = Uw(rndGenerator);
const double w2 = Uw(rndGenerator);
const double w3 = Uw(rndGenerator);
const double w4 = Uw(rndGenerator);
func.f_ = [w1,w2,w3,w4](double x,double y) {
return std::cos(w1*x) + std::sin(w2*y) + std::cos(w3*x) + std::sin(w4*y);
};
fillGridMap(map, func);
return func;
}
AnalyticalFunctions createTanhWorld(grid_map::GridMap *map)
{
AnalyticalFunctions func;
std::uniform_real_distribution<double> scaling(0.1, 2.0);
const double s = scaling(rndGenerator);
func.f_ = [s](double x,double /*y*/) {
const double expZ = std::exp(2 *s* x);
return (expZ - 1) / (expZ + 1);
};
fillGridMap(map, func);
return func;
}
AnalyticalFunctions createGaussianWorld(grid_map::GridMap *map)
{
struct Gaussian
{
double x0, y0;
double varX, varY;
double s;
};
AnalyticalFunctions func;
std::uniform_real_distribution<double> var(0.1, 3.0);
std::uniform_real_distribution<double> mean(-4.0, 4.0);
std::uniform_real_distribution<double> scale(-3.0, 3.0);
constexpr int numGaussians = 3;
std::array<Gaussian, numGaussians> g;
for (int i = 0; i < numGaussians; ++i) {
g.at(i).x0 = mean(rndGenerator);
g.at(i).y0 = mean(rndGenerator);
g.at(i).varX = var(rndGenerator);
g.at(i).varY = var(rndGenerator);
g.at(i).s = scale(rndGenerator);
}
func.f_ = [g](double x,double y) {
double value = 0.0;
for (const auto & i : g) {
const double x0 = i.x0;
const double y0 = i.y0;
const double varX = i.varX;
const double varY = i.varY;
const double s = i.s;
value += s * std::exp(-(x-x0)*(x-x0) / (2.0*varX) - (y-y0)*(y-y0) / (2.0 * varY));
}
return value;
};
fillGridMap(map, func);
return func;
}
void fillGridMap(grid_map::GridMap *map, const AnalyticalFunctions &functions)
{
using grid_map::DataType;
using grid_map::GridMapIterator;
using grid_map::Index;
using grid_map::Matrix;
using grid_map::Position;
Matrix& data = (*map)[testLayer];
for (GridMapIterator iterator(*map); !iterator.isPastEnd(); ++iterator) {
const Index index(*iterator);
Position pos;
map->getPosition(index, pos);
data(index(0), index(1)) = static_cast<DataType>(functions.f_(pos.x(), pos.y()));
}
}
grid_map::GridMap createMap(const grid_map::Length &length, double resolution,
const grid_map::Position &pos)
{
grid_map::GridMap map;
map.setGeometry(length, resolution, pos);
map.add(testLayer, 0.0);
map.setFrameId("map");
return map;
}
std::vector<Point2D> uniformlyDitributedPointsWithinMap(const grid_map::GridMap &map,
unsigned int numPoints)
{
// stay away from the edges
// on the edges the cubic interp is invalid. Not enough points.
const double dimX = map.getLength().x() / 2.0 - 3.0 * map.getResolution();
const double dimY = map.getLength().y() / 2.0 - 3.0 * map.getResolution();
std::uniform_real_distribution<double> Ux(-dimX, dimX);
std::uniform_real_distribution<double> Uy(-dimY, dimY);
std::vector<Point2D> points(numPoints);
for (auto &point : points) {
point.x_ = Ux(rndGenerator);
point.y_ = Uy(rndGenerator);
}
return points;
}
void verifyValuesAtQueryPointsAreClose(const grid_map::GridMap &map, const AnalyticalFunctions &trueValues,
const std::vector<Point2D> &queryPoints,
grid_map::InterpolationMethods interpolationMethod){
for (const auto point : queryPoints) {
const grid_map::Position p(point.x_, point.y_);
const double trueValue = trueValues.f_(p.x(), p.y());
const double interpolatedValue = map.atPosition(
grid_map_test::testLayer, p, interpolationMethod);
EXPECT_NEAR(trueValue, interpolatedValue, grid_map_test::maxAbsErrorValue);
}
}
} /* namespace grid_map_test */