test_likelihood_field_model.cpp
Go to the documentation of this file.
1 // Copyright 2022-2023 Ekumen, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17 
18 #include <utility>
19 #include <vector>
20 
21 #include <range/v3/range/conversion.hpp>
22 #include <range/v3/view/transform.hpp>
23 #include <sophus/common.hpp>
24 
27 
28 namespace {
29 
31 
33 
34 TEST(LikelihoodFieldModel, LikelihoodField) {
35  constexpr double kResolution = 0.5;
36  // clang-format off
37  const auto grid = StaticOccupancyGrid<5, 5>{{
38  false, false, false, false, true ,
39  false, false, false, true , false,
40  false, false, true , false, false,
41  false, true , false, false, false,
42  true , false, false, false, false},
43  kResolution};
44 
45  const double expected_likelihood_field[] = { // NOLINT(modernize-avoid-c-arrays)
46  0.025, 0.025, 0.025, 0.069, 1.022,
47  0.025, 0.027, 0.069, 1.022, 0.069,
48  0.025, 0.069, 1.022, 0.069, 0.025,
49  0.069, 1.022, 0.069, 0.027, 0.025,
50  1.022, 0.069, 0.025, 0.025, 0.025
51  };
52  // clang-format on
53 
54  const auto params = beluga::LikelihoodFieldModelParam{2.0, 20.0, 0.5, 0.5, 0.2};
55  auto sensor_model = UUT{params, grid};
56 
57  // the likelihood field model includes an optimization that stores the likelihood elevated to the cube
58  auto expected_cubed_likelihood =
59  expected_likelihood_field | ranges::views::transform([](auto v) { return v * v * v; }) | ranges::to<std::vector>;
60 
61  ASSERT_THAT(
62  sensor_model.likelihood_field().data(),
63  testing::Pointwise(testing::DoubleNear(0.003), expected_cubed_likelihood));
64 }
65 
66 TEST(LikelihoodFieldModel, ImportanceWeight) {
67  constexpr double kResolution = 0.5;
68  // clang-format off
69  const auto grid = StaticOccupancyGrid<5, 5>{{
70  false, false, false, false, false,
71  false, false, false, false, false,
72  false, false, true , false, false,
73  false, false, false, false, false,
74  false, false, false, false, false},
75  kResolution};
76  // clang-format on
77 
78  const auto params = beluga::LikelihoodFieldModelParam{2.0, 20.0, 0.5, 0.5, 0.2};
79  auto sensor_model = UUT{params, grid};
80 
81  {
82  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{1.25, 1.25}});
83  ASSERT_NEAR(2.068, state_weighting_function(grid.origin()), 0.003);
84  }
85 
86  {
87  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{2.25, 2.25}});
88  ASSERT_NEAR(1.000, state_weighting_function(grid.origin()), 0.003);
89  }
90 
91  {
92  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{-50.0, 50.0}});
93  ASSERT_NEAR(1.000, state_weighting_function(grid.origin()), 0.003);
94  }
95 
96  {
97  auto state_weighting_function =
98  sensor_model(std::vector<std::pair<double, double>>{{1.20, 1.20}, {1.25, 1.25}, {1.30, 1.30}});
99  ASSERT_NEAR(4.205, state_weighting_function(grid.origin()), 0.01);
100  }
101 
102  {
103  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{0.0, 0.0}});
104  ASSERT_NEAR(2.068, state_weighting_function(Sophus::SE2d{Sophus::SO2d{}, Eigen::Vector2d{1.25, 1.25}}), 0.003);
105  }
106 }
107 
108 TEST(LikelihoodFieldModel, GridWithOffset) {
109  constexpr double kResolution = 2.0;
110  // clang-format off
111  const auto grid = StaticOccupancyGrid<5, 5>{{
112  false, false, false, false, false,
113  false, false, false, false, false,
114  false, false, false, false, false,
115  false, false, false, false, false,
116  false, false, false, false, true },
117  kResolution,
118  Sophus::SE2d{Sophus::SO2d{}, Eigen::Vector2d{-5, -5}}};
119  // clang-format on
120 
121  const auto params = beluga::LikelihoodFieldModelParam{2.0, 20.0, 0.5, 0.5, 0.2};
122  auto sensor_model = UUT{params, grid};
123 
124  {
125  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{4.5, 4.5}});
126  ASSERT_NEAR(2.068, state_weighting_function(Sophus::SE2d{}), 0.003);
127  }
128 
129  {
130  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{9.5, 9.5}});
131  ASSERT_NEAR(2.068, state_weighting_function(grid.origin()), 0.003);
132  }
133 }
134 
135 TEST(LikelihoodFieldModel, GridWithRotation) {
136  constexpr double kResolution = 2.0;
137  // clang-format off
138  const auto grid = StaticOccupancyGrid<5, 5>{{
139  false, false, false, false, false,
140  false, false, false, false, false,
141  false, false, false, false, false,
142  false, false, false, false, false,
143  false, false, false, false, true },
144  kResolution,
145  Sophus::SE2d{Sophus::SO2d{Sophus::Constants<double>::pi() / 2}, Eigen::Vector2d{0.0, 0.0}}};
146  // clang-format on
147 
148  const auto params = beluga::LikelihoodFieldModelParam{2.0, 20.0, 0.5, 0.5, 0.2};
149  auto sensor_model = UUT{params, grid};
150 
151  {
152  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{-9.5, 9.5}});
153  ASSERT_NEAR(2.068, state_weighting_function(Sophus::SE2d{}), 0.003);
154  }
155 
156  {
157  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{9.5, 9.5}});
158  ASSERT_NEAR(2.068, state_weighting_function(grid.origin()), 0.003);
159  }
160 }
161 
162 TEST(LikelihoodFieldModel, GridWithRotationAndOffset) {
163  constexpr double kResolution = 2.0;
164  // clang-format off
165  const auto origin_rotation = Sophus::SO2d{Sophus::Constants<double>::pi() / 2};
166  const auto origin = Sophus::SE2d{origin_rotation, origin_rotation * Eigen::Vector2d{-5, -5}};
167 
168  const auto grid = StaticOccupancyGrid<5, 5>{{
169  false, false, false, false, false,
170  false, false, false, false, false,
171  false, false, false, false, false,
172  false, false, false, false, false,
173  false, false, false, false, true },
174  kResolution,
175  origin};
176  // clang-format on
177 
178  const auto params = beluga::LikelihoodFieldModelParam{2.0, 20.0, 0.5, 0.5, 0.2};
179  auto sensor_model = UUT{params, grid};
180 
181  {
182  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{-4.5, 4.5}});
183  ASSERT_NEAR(2.068, state_weighting_function(Sophus::SE2d{}), 0.003);
184  }
185 
186  {
187  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{9.5, 9.5}});
188  ASSERT_NEAR(2.068, state_weighting_function(grid.origin()), 0.003);
189  }
190 }
191 
192 TEST(LikelihoodFieldModel, GridUpdates) {
193  const auto origin = Sophus::SE2d{};
194 
195  constexpr double kResolution = 0.5;
196  // clang-format off
197  auto grid = StaticOccupancyGrid<5, 5>{{
198  false, false, false, false, false,
199  false, false, false, false, false,
200  false, false, true , false, false,
201  false, false, false, false, false,
202  false, false, false, false, false},
203  kResolution, origin};
204  // clang-format on
205 
206  const auto params = beluga::LikelihoodFieldModelParam{2.0, 20.0, 0.5, 0.5, 0.2};
207  auto sensor_model = UUT{params, std::move(grid)};
208 
209  {
210  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{1., 1.}});
211  EXPECT_NEAR(2.068577607986223, state_weighting_function(origin), 1e-6);
212  }
213 
214  // clang-format off
215  grid = StaticOccupancyGrid<5, 5>{{
216  false, false, false, false, false,
217  false, false, false, false, false,
218  false, false, false, false, false,
219  false, false, false, false, false,
220  false, false, false, false, true},
221  kResolution, origin};
222  // clang-format on
223  sensor_model.update_map(std::move(grid));
224 
225  {
226  auto state_weighting_function = sensor_model(std::vector<std::pair<double, double>>{{1., 1.}});
227  EXPECT_NEAR(1.0, state_weighting_function(origin), 1e-3);
228  }
229 }
230 
231 } // namespace
Sophus::SO2
static_occupancy_grid.hpp
beluga::UUT
beluga::BeamSensorModel< StaticOccupancyGrid< 5, 5 > > UUT
Definition: test_beam_model.cpp:27
common.hpp
beluga::LikelihoodFieldModel
Likelihood field sensor model for range finders.
Definition: likelihood_field_model.hpp:78
Sophus::SE2
beluga::testing::StaticOccupancyGrid
Definition: static_occupancy_grid.hpp:28
beluga::LikelihoodFieldModelParam
Parameters used to construct a LikelihoodFieldModel instance.
Definition: likelihood_field_model.hpp:43
Sophus::Constants::pi
static SOPHUS_FUNC Scalar pi()
likelihood_field_model.hpp
Implementation of a likelihood field sensor model for range finders.
beluga::TEST
TEST(Bresenham, MultiPassGuarantee)
Definition: test_bresenham.cpp:27


beluga
Author(s):
autogenerated on Tue Jul 16 2024 02:59:53