15 #include <gtest/gtest.h>
18 #include <unordered_map>
33 Eigen::Matrix2Xd get_diagonal_covariance_2d(
double x_var = 0.5,
double y_var = 0.5) {
34 return Eigen::Vector2d{x_var, y_var}.asDiagonal();
37 using sparse_grid_2d_t = SparseValueGrid2<std::unordered_map<Eigen::Vector2i, NDTCell2d, detail::CellHasher<2>>>;
38 using sparse_grid_3d_t = SparseValueGrid3<std::unordered_map<Eigen::Vector3i, NDTCell3d, detail::CellHasher<3>>>;
41 TEST(NDTSensorModel2DTests, CanConstruct) {
45 TEST(NDTSensorModel2DTests, MinLikelihood) {
46 constexpr
double kMinimumLikelihood = 1e-6;
51 for (
const auto& val : {
52 Eigen::Vector2d{0.1, 0.1},
53 Eigen::Vector2d{0.15, 0.15},
54 Eigen::Vector2d{0.25, 0.25},
55 Eigen::Vector2d{0.35, 0.35},
56 Eigen::Vector2d{0.45, 0.45},
57 Eigen::Vector2d{0.50, 0.50},
58 Eigen::Vector2d{1.65, 0.65},
59 Eigen::Vector2d{0.75, 0.75},
62 ASSERT_DOUBLE_EQ(model.likelihood_at({val, get_diagonal_covariance_2d()}), kMinimumLikelihood);
66 TEST(NDTSensorModel2DTests, Likelihoood) {
67 typename sparse_grid_2d_t::map_type map;
69 Eigen::Array<double, 2, 2> cov;
74 const Eigen::Vector2d mean(0.5, 0.5);
75 map[Eigen::Vector2i(0, 0)] =
NDTCell2d{mean, cov};
78 Eigen::Array<double, 2, 2> cov;
83 const Eigen::Vector2d mean(1.5, 1.5);
84 map[Eigen::Vector2i(1, 1)] =
NDTCell2d{mean, cov};
86 sparse_grid_2d_t grid{std::move(map), 1.0};
88 constexpr
double kMinimumLikelihood = 1e-6;
92 EXPECT_DOUBLE_EQ(model.likelihood_at({{0.5, 0.5}, get_diagonal_covariance_2d()}), 1.3678794411714423);
93 EXPECT_DOUBLE_EQ(model.likelihood_at({{0.8, 0.5}, get_diagonal_covariance_2d()}), 1.4307317817730123);
94 EXPECT_DOUBLE_EQ(model.likelihood_at({{0.5, 0.8}, get_diagonal_covariance_2d()}), 1.4200370805919718);
96 EXPECT_DOUBLE_EQ(model.likelihood_at({{1.5, 1.5}, get_diagonal_covariance_2d()}), 1.3246524673583497);
97 EXPECT_DOUBLE_EQ(model.likelihood_at({{1.8, 1.5}, get_diagonal_covariance_2d()}), 1.1859229670198237);
98 EXPECT_DOUBLE_EQ(model.likelihood_at({{1.5, 1.8}, get_diagonal_covariance_2d()}), 1.1669230426687498);
101 TEST(NDTSensorModel2DTests, FitPoints) {
103 const std::vector meas{
104 Eigen::Vector2d{0.1, 0.2}, Eigen::Vector2d{0.1, 0.2}, Eigen::Vector2d{0.1, 0.2},
105 Eigen::Vector2d{0.1, 0.2}, Eigen::Vector2d{0.1, 0.2}, Eigen::Vector2d{0.1, 0.2},
108 ASSERT_TRUE(cell.mean.isApprox(Eigen::Vector2d{0.1, 0.2}));
110 ASSERT_FALSE(cell.covariance.isZero());
113 const std::vector meas{
114 Eigen::Vector2d{0.1, 0.2}, Eigen::Vector2d{0.1, 0.9}, Eigen::Vector2d{0.1, 0.2},
115 Eigen::Vector2d{0.1, 0.9}, Eigen::Vector2d{0.1, 0.2}, Eigen::Vector2d{0.1, 0.2},
118 ASSERT_TRUE(cell.mean.isApprox(Eigen::Vector2d{0.1, 0.433333}, 1e-6));
119 ASSERT_FALSE(cell.covariance.isZero());
120 ASSERT_GT(cell.covariance(1, 1), cell.covariance(0, 0));
124 TEST(NDTSensorModel2DTests, ToCellsNotEnoughPointsInCell) {
125 constexpr
double kMapResolution = 0.5;
126 const std::vector map_data{
127 Eigen::Vector2d{0.1, 0.2},
128 Eigen::Vector2d{0.112, 0.22},
129 Eigen::Vector2d{0.15, 0.23},
132 ASSERT_EQ(cells.size(), 0UL);
135 TEST(NDTSensorModel3DTests, ToCellsNotEnoughPointsInCell) {
136 constexpr
double kMapResolution = 0.5;
137 const std::vector map_data{
138 Eigen::Vector3d{0.1, 0.2, 0.0},
139 Eigen::Vector3d{0.112, 0.22, 0.0},
140 Eigen::Vector3d{0.15, 0.23, 0.0},
143 ASSERT_EQ(cells.size(), 0UL);
146 TEST(NDTSensorModel3DTests, FitPoints) {
148 const std::vector meas{
149 Eigen::Vector3d{0.1, 0.2, 0.3}, Eigen::Vector3d{0.1, 0.2, 0.3}, Eigen::Vector3d{0.1, 0.2, 0.3},
150 Eigen::Vector3d{0.1, 0.2, 0.3}, Eigen::Vector3d{0.1, 0.2, 0.3}, Eigen::Vector3d{0.1, 0.2, 0.3},
153 ASSERT_TRUE(cell.mean.isApprox(Eigen::Vector3d{0.1, 0.2, 0.3}));
155 ASSERT_FALSE(cell.covariance.isZero());
158 const std::vector meas{
159 Eigen::Vector3d{0.1, 0.2, 0.3}, Eigen::Vector3d{0.1, 0.2, 0.3}, Eigen::Vector3d{0.1, 0.2, 0.5},
160 Eigen::Vector3d{0.1, 0.2, 0.3}, Eigen::Vector3d{0.1, 0.9, 0.4}};
162 ASSERT_TRUE(cell.mean.isApprox(Eigen::Vector3d{0.1, 0.34, 0.36}, 1e-6));
163 ASSERT_FALSE(cell.covariance.isZero());
164 ASSERT_GT(cell.covariance(1, 1), cell.covariance(0, 0));
165 ASSERT_GT(cell.covariance(1, 1), cell.covariance(2, 2));
166 ASSERT_GT(cell.covariance(2, 2), cell.covariance(0, 0));
170 TEST(NDTSensorModel3DTests, SensorModel) {
171 constexpr
double kMapResolution = 0.5;
172 const std::vector map_data{
173 Eigen::Vector3d{0.1, 0.2, 0.0}, Eigen::Vector3d{0.112, 0.22, 0.1}, Eigen::Vector3d{0.15, 0.23, 0.1},
174 Eigen::Vector3d{0.1, 0.24, 0.1}, Eigen::Vector3d{0.16, 0.25, 0.1}, Eigen::Vector3d{0.1, 0.26, 0.0},
178 typename sparse_grid_3d_t::map_type map_cells_data;
180 for (
const auto& cell : cells) {
181 map_cells_data[(cell.mean.array() / kMapResolution).floor().cast<
int>()] = cell;
184 std::vector perfect_measurement = map_data;
185 const NDTSensorModel model{{}, sparse_grid_3d_t{map_cells_data, kMapResolution}};
186 auto state_weighing_fn = model(std::move(perfect_measurement));
213 TEST(NDTSensorModel2DTests, SensorModel) {
214 constexpr
double kMapResolution = 0.5;
215 const std::vector map_data{
216 Eigen::Vector2d{0.1, 0.2}, Eigen::Vector2d{0.112, 0.22}, Eigen::Vector2d{0.15, 0.23},
217 Eigen::Vector2d{0.1, 0.24}, Eigen::Vector2d{0.16, 0.25}, Eigen::Vector2d{0.1, 0.26},
221 typename sparse_grid_2d_t::map_type map_cells_data;
222 for (
const auto& cell : cells) {
223 map_cells_data[(cell.mean.array() / kMapResolution).cast<int>()] = cell;
225 std::vector perfect_measurement = map_data;
226 const NDTSensorModel model{{}, sparse_grid_2d_t{map_cells_data, kMapResolution}};
227 auto state_weighing_fn = model(std::move(perfect_measurement));
238 TEST(NDTSensorModel2DTests, LoadFromHDF5HappyPath) {
239 const auto ndt_map_representation = io::load_from_hdf5<sparse_grid_2d_t>(
"./test_data/turtlebot3_world.hdf5");
240 ASSERT_EQ(ndt_map_representation.size(), 30UL);
243 TEST(NDTSensorModel2DTests, LoadFromHDF5NonExistingFile) {
244 ASSERT_THROW(io::load_from_hdf5<sparse_grid_2d_t>(
"bad_file.hdf5"), std::invalid_argument);
247 TEST(NDTSensorModel3DTests, LoadFromHDF5NonExistingFile) {
248 ASSERT_THROW(io::load_from_hdf5<sparse_grid_3d_t>(
"bad_file.hdf5"), std::invalid_argument);
251 TEST(NDTSensorModel3DTests, LoadFromHDF5HappyPath) {
252 const auto ndt_map_representation = io::load_from_hdf5<sparse_grid_3d_t>(
"./test_data/sample_3d_ndt_map.hdf5");
253 ASSERT_EQ(ndt_map_representation.size(), 398);