benchmark_raycasting.cpp
Go to the documentation of this file.
1 // Copyright 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 <benchmark/benchmark.h>
16 
17 #include <cstddef>
18 #include <initializer_list>
19 #include <vector>
20 
21 #include <Eigen/Core>
22 
23 #include <sophus/common.hpp>
24 #include <sophus/se2.hpp>
25 #include <sophus/so2.hpp>
26 
32 
33 namespace {
34 
35 void BM_Bresenham2i(benchmark::State& state, beluga::Bresenham2i::Variant variant) {
36  const auto n = state.range(0);
37  const auto algorithm = beluga::Bresenham2i{variant};
38  for (auto _ : state) {
39  Eigen::Vector2i storage;
40  for (const auto& cell : algorithm({0, 0}, {n, n})) {
41  benchmark::DoNotOptimize(storage = cell);
42  }
43  }
44  state.SetComplexityN(n);
45 }
46 
47 BENCHMARK_CAPTURE(BM_Bresenham2i, Standard, beluga::Bresenham2i::kStandard)
48  ->RangeMultiplier(2)
49  ->Range(128, 4096)
50  ->Complexity();
51 
52 BENCHMARK_CAPTURE(BM_Bresenham2i, Modified, beluga::Bresenham2i::kModified)
53  ->RangeMultiplier(2)
54  ->Range(128, 4096)
55  ->Complexity();
56 
58 
59 template <std::size_t Rows, std::size_t Cols>
60 class BaselineGrid : public beluga::BaseOccupancyGrid2<BaselineGrid<Rows, Cols>> {
61  public:
62  struct ValueTraits {
63  [[nodiscard]] bool is_free(bool value) const { return !value; }
64  [[nodiscard]] bool is_unknown(bool) const { return false; }
65  [[nodiscard]] bool is_occupied(bool value) const { return value; }
66  };
67 
68  explicit BaselineGrid(std::initializer_list<bool>, double resolution) : resolution_{resolution} {
69  std::fill(std::begin(data()), std::end(data()), false);
70  }
71 
72  [[nodiscard]] const Sophus::SE2d& origin() const { return origin_; }
73 
74  [[nodiscard]] auto& data() { return grid_; }
75  [[nodiscard]] const auto& data() const { return grid_; }
76  [[nodiscard]] std::size_t size() const { return grid_.size(); }
77 
78  [[nodiscard]] std::size_t width() const { return Cols; }
79  [[nodiscard]] std::size_t height() const { return Rows; }
80  [[nodiscard]] double resolution() const { return resolution_; }
81 
82  [[nodiscard]] auto value_traits() const { return ValueTraits{}; }
83 
84  private:
85  double resolution_;
86  Sophus::SE2d origin_;
87  std::array<bool, Rows * Cols> grid_;
88  static constexpr std::size_t kWidth = Cols;
89  static constexpr std::size_t kHeight = Rows;
90 };
91 
92 const auto kBearingAngles = std::array{
93  0., // Horizontal
94  Sophus::Constants<double>::pi() / 2., // Vertical
95  Sophus::Constants<double>::pi() / 4., // Diagonal
96 };
97 
98 const auto kBearingLabels = std::array{
99  "Horizontal",
100  "Vertical",
101  "Diagonal",
102 };
103 
104 template <template <std::size_t, std::size_t> class Grid>
105 void BM_RayCasting2d_BaselineRaycast(benchmark::State& state) {
106  constexpr double kMaxRange = 100.0;
107  constexpr double kResolution = 0.05;
108 
109  const auto bearing_index = static_cast<std::size_t>(state.range(0));
110  const auto n = static_cast<int>(state.range(1));
111  Grid<1280, 1280> grid{{}, kResolution};
112  grid.data()[grid.index_at(n, n)] = true;
113  grid.data()[grid.index_at(0, n)] = true;
114  grid.data()[grid.index_at(n, 0)] = true;
115 
116  const auto source_pose = Eigen::Vector2d{0., 0.};
117  const auto beam_bearing = Sophus::SO2d{kBearingAngles.at(bearing_index)};
118 
119  const auto source = grid.cell_near(source_pose);
120  const auto target = grid.cell_near(source_pose + kMaxRange * beam_bearing.unit_complex());
121 
122  for (auto _ : state) {
123  benchmark::DoNotOptimize(beluga::testing::raycast(grid, source, target));
124  }
125  state.SetComplexityN(n);
126  state.SetLabel(kBearingLabels.at(bearing_index));
127 }
128 
129 BENCHMARK_TEMPLATE(BM_RayCasting2d_BaselineRaycast, BaselineGrid)
130  ->Args({0, 128})
131  ->Args({0, 256})
132  ->Args({0, 512})
133  ->Args({0, 1024})
134  ->Args({1, 128})
135  ->Args({1, 256})
136  ->Args({1, 512})
137  ->Args({1, 1024})
138  ->Args({2, 128})
139  ->Args({2, 256})
140  ->Args({2, 512})
141  ->Args({2, 1024})
142  ->Complexity();
143 
144 BENCHMARK_TEMPLATE(BM_RayCasting2d_BaselineRaycast, StaticOccupancyGrid)
145  ->Args({0, 128})
146  ->Args({0, 256})
147  ->Args({0, 512})
148  ->Args({0, 1024})
149  ->Args({1, 128})
150  ->Args({1, 256})
151  ->Args({1, 512})
152  ->Args({1, 1024})
153  ->Args({2, 128})
154  ->Args({2, 256})
155  ->Args({2, 512})
156  ->Args({2, 1024})
157  ->Complexity();
158 
159 template <template <std::size_t, std::size_t> class Grid>
160 void BM_RayCasting2d(benchmark::State& state) {
161  constexpr double kMaxRange = 100.0;
162  constexpr double kResolution = 0.05;
163 
164  const auto bearing_index = static_cast<std::size_t>(state.range(0));
165  const auto n = static_cast<int>(state.range(1));
166  auto grid = Grid<1280, 1280>{{}, kResolution};
167  grid.data()[grid.index_at(n, n)] = true;
168  grid.data()[grid.index_at(0, n)] = true;
169  grid.data()[grid.index_at(n, 0)] = true;
170 
171  const auto source_pose = Sophus::SE2d{0., Eigen::Vector2d{0., 0.}};
172  const auto beam_bearing = Sophus::SO2d{kBearingAngles.at(bearing_index)};
173  const auto beam = beluga::Ray2d{grid, source_pose, kMaxRange};
174  for (auto _ : state) {
175  benchmark::DoNotOptimize(beam.cast(beam_bearing));
176  }
177  state.SetComplexityN(n);
178  state.SetLabel(kBearingLabels.at(bearing_index));
179 }
180 
181 BENCHMARK_TEMPLATE(BM_RayCasting2d, BaselineGrid)
182  ->Args({0, 128})
183  ->Args({0, 256})
184  ->Args({0, 512})
185  ->Args({0, 1024})
186  ->Args({1, 128})
187  ->Args({1, 256})
188  ->Args({1, 512})
189  ->Args({1, 1024})
190  ->Args({2, 128})
191  ->Args({2, 256})
192  ->Args({2, 512})
193  ->Args({2, 1024})
194  ->Complexity();
195 
196 BENCHMARK_TEMPLATE(BM_RayCasting2d, StaticOccupancyGrid)
197  ->Args({0, 128})
198  ->Args({0, 256})
199  ->Args({0, 512})
200  ->Args({0, 1024})
201  ->Args({1, 128})
202  ->Args({1, 256})
203  ->Args({1, 512})
204  ->Args({1, 1024})
205  ->Args({2, 128})
206  ->Args({2, 256})
207  ->Args({2, 512})
208  ->Args({2, 1024})
209  ->Complexity();
210 
211 } // namespace
raycasting.hpp
Sophus::SO2
raycasting.hpp
Implementation of raycasting algorithms.
beluga::Bresenham2i::kStandard
@ kStandard
Standard Bresenham's algorithm.
Definition: bresenham.hpp:38
beluga::state
constexpr state_detail::state_fn state
Customization point object for accessing the state of a particle.
Definition: primitives.hpp:163
static_occupancy_grid.hpp
bresenham.hpp
Implementation of Bresenham-like raytracing algorithms.
beluga::BaseOccupancyGrid2
Occupancy 2D grid base type.
Definition: occupancy_grid.hpp:85
se2.hpp
common.hpp
Sophus::SE2
beluga::Bresenham2i::Variant
Variant
Bresenham's 2D line drawing algorithm variants.
Definition: bresenham.hpp:37
beluga::testing::StaticOccupancyGrid
Definition: static_occupancy_grid.hpp:28
so2.hpp
occupancy_grid.hpp
Concepts and abstract implementations of occupancy grids.
beluga::testing::raycast
std::optional< double > raycast(const Map &map, Eigen::Vector2i source, Eigen::Vector2i target)
Definition: test/beluga/include/beluga/test/raycasting.hpp:23
Sophus::Constants::pi
static SOPHUS_FUNC Scalar pi()
beluga::Bresenham2i
Bresenham's 2D line drawing algorithm, optimized for integer arithmetic.
Definition: bresenham.hpp:34
beluga::Bresenham2i::kModified
@ kModified
Definition: bresenham.hpp:39
beluga::Ray2d
Castable 2D ray.
Definition: include/beluga/algorithm/raycasting.hpp:44


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