scenario_simulator_v2 C++ API
lanelet_wrapper.hpp
Go to the documentation of this file.
1 // Copyright 2015 TIER IV, Inc. All rights reserved.
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 #ifndef TRAFFIC_SIMULATOR__LANELET_WRAPPER_HPP_
16 #define TRAFFIC_SIMULATOR__LANELET_WRAPPER_HPP_
17 
18 #include <lanelet2_routing/RoutingGraph.h>
19 #include <lanelet2_routing/RoutingGraphContainer.h>
20 #include <lanelet2_traffic_rules/TrafficRulesFactory.h>
21 
22 #include <autoware_lanelet2_extension/utility/utilities.hpp>
23 #include <filesystem>
25 #include <geometry_msgs/msg/point.hpp>
26 #include <geometry_msgs/msg/pose.hpp>
27 #include <geometry_msgs/msg/pose_stamped.hpp>
28 #include <geometry_msgs/msg/vector3.hpp>
29 #include <mutex>
34 #include <traffic_simulator_msgs/msg/bounding_box.hpp>
35 #include <traffic_simulator_msgs/msg/entity_type.hpp>
36 #include <traffic_simulator_msgs/msg/lanelet_pose.hpp>
37 
38 namespace std
39 {
40 template <>
41 struct hash<std::tuple<lanelet::Id, lanelet::Id, bool>>
42 {
43 public:
44  size_t operator()(const std::tuple<lanelet::Id, lanelet::Id, bool> & data) const
45  {
46  std::hash<lanelet::Id> lanelet_id_hash;
47  size_t seed = 0;
49  seed ^= lanelet_id_hash(std::get<0>(data)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
50  seed ^= lanelet_id_hash(std::get<1>(data)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
51  seed ^= std::hash<bool>{}(std::get<2>(data)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
52  return seed;
53  }
54 };
55 } // namespace std
56 
57 namespace traffic_simulator
58 {
59 namespace lanelet_wrapper
60 {
69 
71 {
72 public:
73  auto getRoute(
74  const lanelet::Id from_lanelet_id, const lanelet::Id to_lanelet_id,
75  const lanelet::LaneletMapPtr & lanelet_map, const RoutingConfiguration & routing_configuration,
76  const lanelet::routing::RoutingGraphConstPtr & routing_graph) -> lanelet::Ids
77  {
78  if (!exists(from_lanelet_id, to_lanelet_id, routing_configuration.allow_lane_change)) {
80  constexpr int routing_cost_id = 0;
81  const auto & from_lanelet = lanelet_map->laneletLayer.get(from_lanelet_id);
82  const auto & to_lanelet = lanelet_map->laneletLayer.get(to_lanelet_id);
83  if (const auto route = routing_graph->getRoute(
84  from_lanelet, to_lanelet, routing_cost_id, routing_configuration.allow_lane_change);
85  !route || route->shortestPath().empty()) {
86  appendData(
87  from_lanelet_id, to_lanelet_id, routing_configuration.allow_lane_change, lanelet::Ids());
88  } else {
89  lanelet::Ids shortest_path_ids;
90  for (const auto & lanelet : route->shortestPath()) {
91  shortest_path_ids.push_back(lanelet.id());
92  }
93  appendData(
94  from_lanelet_id, to_lanelet_id, routing_configuration.allow_lane_change,
95  shortest_path_ids);
96  }
97  }
98  return readData(from_lanelet_id, to_lanelet_id, routing_configuration.allow_lane_change);
99  }
100 
101  auto getRoute(const lanelet::Id from, const lanelet::Id to, const bool allow_lane_change)
102  -> decltype(auto)
103  {
104  if (!exists(from, to, allow_lane_change)) {
106  "route from : ", from, " to : ", to, (allow_lane_change ? " with" : " without"),
107  " lane change does not exists on route cache.");
108  } else {
109  return readData(from, to, allow_lane_change);
110  }
111  }
112 
113 private:
114  auto exists(const lanelet::Id from, const lanelet::Id to, const bool allow_lane_change) -> bool
115  {
116  std::lock_guard lock(mutex_);
117  std::tuple<lanelet::Id, lanelet::Id, bool> key = {from, to, allow_lane_change};
118  return data_.find(key) != data_.end();
119  }
120 
121  auto readData(const lanelet::Id from, const lanelet::Id to, const bool allow_lane_change)
122  -> lanelet::Ids
123  {
124  std::lock_guard lock(mutex_);
125  return data_.at({from, to, allow_lane_change});
126  }
127 
128  auto appendData(
129  const lanelet::Id from, const lanelet::Id to, const bool allow_lane_change,
130  const lanelet::Ids & route) -> void
131  {
132  std::lock_guard lock(mutex_);
133  data_[{from, to, allow_lane_change}] = route;
134  }
135 
136  std::unordered_map<std::tuple<lanelet::Id, lanelet::Id, bool>, lanelet::Ids> data_;
137  std::mutex mutex_;
138 };
139 
141 {
142 public:
143  auto centerPoints(lanelet::Id lanelet_id) -> decltype(auto)
144  {
145  if (!exists(lanelet_id)) {
146  THROW_SIMULATION_ERROR("center point of : ", lanelet_id, " does not exists on route cache.");
147  }
148  return readData(lanelet_id);
149  }
150 
151  auto centerPointsSpline(lanelet::Id lanelet_id) -> decltype(auto)
152  {
153  if (!exists(lanelet_id)) {
154  THROW_SIMULATION_ERROR("center point of : ", lanelet_id, " does not exists on route cache.");
155  }
156  return readDataSpline(lanelet_id);
157  }
158 
159  auto getCenterPoints(const lanelet::Id lanelet_id, const lanelet::LaneletMapPtr & lanelet_map)
160  -> std::vector<Point>
161  {
162  if (!exists(lanelet_id)) {
163  appendData(lanelet_id, centerPoints(lanelet_id, lanelet_map));
164  }
165  return readData(lanelet_id);
166  }
167 
169  const lanelet::Id lanelet_id, const lanelet::LaneletMapPtr & lanelet_map)
170  -> std::shared_ptr<Spline>
171  {
172  if (!exists(lanelet_id)) {
173  appendData(lanelet_id, centerPoints(lanelet_id, lanelet_map));
174  }
175  return readDataSpline(lanelet_id);
176  }
177 
178 private:
179  auto exists(const lanelet::Id lanelet_id) -> bool
180  {
181  std::lock_guard lock(mutex_);
182  return data_.find(lanelet_id) != data_.end();
183  }
184 
185  auto readData(const lanelet::Id lanelet_id) -> std::vector<Point>
186  {
187  std::lock_guard lock(mutex_);
188  return data_.at(lanelet_id);
189  }
190 
191  auto readDataSpline(const lanelet::Id lanelet_id) -> std::shared_ptr<Spline>
192  {
193  std::lock_guard lock(mutex_);
194  return splines_.at(lanelet_id);
195  }
196 
197  auto appendData(const lanelet::Id lanelet_id, const std::vector<Point> & route) -> void
198  {
199  std::lock_guard lock(mutex_);
200  data_[lanelet_id] = route;
201  splines_[lanelet_id] = std::make_shared<Spline>(route);
202  }
203 
204  auto centerPoints(const lanelet::Id lanelet_id, const lanelet::LaneletMapPtr & lanelet_map) const
205  -> std::vector<Point>
206  {
207  std::vector<Point> center_points;
208  for (const auto & point : lanelet_map->laneletLayer.get(lanelet_id).centerline()) {
209  center_points.push_back(geometry_msgs::build<Point>().x(point.x()).y(point.y()).z(point.z()));
210  }
211  if (center_points.size() == 2) {
212  const auto p0 = center_points[0];
213  const auto p2 = center_points[1];
214  const auto p1 = geometry_msgs::build<Point>()
215  .x((p0.x + p2.x) * 0.5)
216  .y((p0.y + p2.y) * 0.5)
217  .z((p0.z + p2.z) * 0.5);
218  center_points.clear();
219  center_points.push_back(p0);
220  center_points.push_back(p1);
221  center_points.push_back(p2);
222  }
223  return center_points;
224  }
225 
226  std::unordered_map<lanelet::Id, std::vector<Point>> data_;
227  std::unordered_map<lanelet::Id, std::shared_ptr<Spline>> splines_;
228  std::mutex mutex_;
229 };
230 
232 {
233 public:
234  auto getLength(lanelet::Id lanelet_id)
235  {
236  if (!exists(lanelet_id)) {
237  THROW_SIMULATION_ERROR("length of : ", lanelet_id, " does not exists on route cache.");
238  }
239  return readData(lanelet_id);
240  }
241 
242  auto getLength(const lanelet::Id lanelet_id, const lanelet::LaneletMapPtr & lanelet_map) -> double
243  {
244  if (!exists(lanelet_id)) {
245  appendData(
246  lanelet_id, lanelet::utils::getLaneletLength2d(lanelet_map->laneletLayer.get(lanelet_id)));
247  }
248  return readData(lanelet_id);
249  }
250 
251 private:
252  auto exists(const lanelet::Id lanelet_id) -> bool
253  {
254  std::lock_guard lock(mutex_);
255  return data_.find(lanelet_id) != data_.end();
256  }
257 
258  auto readData(const lanelet::Id lanelet_id) -> double
259  {
260  std::lock_guard lock(mutex_);
261  return data_.at(lanelet_id);
262  }
263 
264  auto appendData(const lanelet::Id lanelet_id, double length) -> void
265  {
266  std::lock_guard lock(mutex_);
267  data_[lanelet_id] = length;
268  }
269 
270  std::unordered_map<lanelet::Id, double> data_;
271  std::mutex mutex_;
272 };
273 
275 {
276  lanelet::traffic_rules::TrafficRulesPtr rules;
277  lanelet::routing::RoutingGraphConstPtr graph;
279 
281  const lanelet::LaneletMapPtr lanelet_map_ptr, const std::string & locations,
282  const std::string & participants)
283  {
284  rules = lanelet::traffic_rules::TrafficRulesFactory::create(locations, participants);
285  graph = lanelet::routing::RoutingGraph::build(*lanelet_map_ptr, *rules);
286  }
287 };
288 
290 {
291 public:
292  static auto activate(const std::string & lanelet_map_path) -> void;
293 
294  [[nodiscard]] static auto map() -> lanelet::LaneletMapPtr;
295  [[nodiscard]] static auto routingGraph(const RoutingGraphType type)
296  -> lanelet::routing::RoutingGraphConstPtr;
297  [[nodiscard]] static auto trafficRules(const RoutingGraphType type)
298  -> lanelet::traffic_rules::TrafficRulesPtr;
299 
300  [[nodiscard]] static auto routeCache(const RoutingGraphType type) -> RouteCache &;
301  [[nodiscard]] static auto centerPointsCache() -> CenterPointsCache &;
302  [[nodiscard]] static auto laneletLengthCache() -> LaneletLengthCache &;
303 
304 private:
305  explicit LaneletWrapper(const std::filesystem::path & lanelet_map_path);
306  static LaneletWrapper & getInstance();
307 
308  inline static std::unique_ptr<LaneletWrapper> instance{nullptr};
309  inline static std::string lanelet_map_path_{""};
310  inline static std::mutex mutex_;
311 
312  const lanelet::LaneletMapPtr lanelet_map_ptr_;
313 
314  const TrafficRulesWithRoutingGraph vehicle_;
315  const TrafficRulesWithRoutingGraph vehicle_with_road_shoulder_;
316  const TrafficRulesWithRoutingGraph pedestrian_;
317 
318  mutable CenterPointsCache center_points_cache_;
319  mutable LaneletLengthCache lanelet_length_cache_;
320 };
321 } // namespace lanelet_wrapper
322 } // namespace traffic_simulator
323 #endif // TRAFFIC_SIMULATOR__LANELET_WRAPPER_HPP_
Definition: catmull_rom_spline.hpp:32
auto getCenterPointsSpline(const lanelet::Id lanelet_id, const lanelet::LaneletMapPtr &lanelet_map) -> std::shared_ptr< Spline >
Definition: lanelet_wrapper.hpp:168
auto centerPointsSpline(lanelet::Id lanelet_id) -> decltype(auto)
Definition: lanelet_wrapper.hpp:151
auto centerPoints(lanelet::Id lanelet_id) -> decltype(auto)
Definition: lanelet_wrapper.hpp:143
auto getCenterPoints(const lanelet::Id lanelet_id, const lanelet::LaneletMapPtr &lanelet_map) -> std::vector< Point >
Definition: lanelet_wrapper.hpp:159
auto getLength(lanelet::Id lanelet_id)
Definition: lanelet_wrapper.hpp:234
auto getLength(const lanelet::Id lanelet_id, const lanelet::LaneletMapPtr &lanelet_map) -> double
Definition: lanelet_wrapper.hpp:242
Definition: lanelet_wrapper.hpp:290
static auto routingGraph(const RoutingGraphType type) -> lanelet::routing::RoutingGraphConstPtr
Definition: lanelet_wrapper.cpp:34
static auto centerPointsCache() -> CenterPointsCache &
Definition: lanelet_wrapper.cpp:84
static auto routeCache(const RoutingGraphType type) -> RouteCache &
Definition: lanelet_wrapper.cpp:68
static auto activate(const std::string &lanelet_map_path) -> void
Definition: lanelet_wrapper.cpp:23
static auto map() -> lanelet::LaneletMapPtr
Definition: lanelet_wrapper.cpp:32
static auto laneletLengthCache() -> LaneletLengthCache &
Definition: lanelet_wrapper.cpp:89
static auto trafficRules(const RoutingGraphType type) -> lanelet::traffic_rules::TrafficRulesPtr
Definition: lanelet_wrapper.cpp:51
Definition: lanelet_wrapper.hpp:71
auto getRoute(const lanelet::Id from_lanelet_id, const lanelet::Id to_lanelet_id, const lanelet::LaneletMapPtr &lanelet_map, const RoutingConfiguration &routing_configuration, const lanelet::routing::RoutingGraphConstPtr &routing_graph) -> lanelet::Ids
Definition: lanelet_wrapper.hpp:73
auto getRoute(const lanelet::Id from, const lanelet::Id to, const bool allow_lane_change) -> decltype(auto)
Definition: lanelet_wrapper.hpp:101
#define THROW_SIMULATION_ERROR(...)
Definition: exception.hpp:60
Definition: lanelet_wrapper.hpp:39
geometry_msgs::msg::Pose Pose
Definition: lanelet_wrapper.hpp:65
traffic_simulator_msgs::msg::BoundingBox BoundingBox
Definition: lanelet_wrapper.hpp:61
traffic_simulator_msgs::msg::LaneletPose LaneletPose
Definition: lanelet_wrapper.hpp:63
geometry_msgs::msg::Point Point
Definition: lanelet_wrapper.hpp:64
traffic_simulator_msgs::msg::EntityType EntityType
Definition: lanelet_wrapper.hpp:62
geometry_msgs::msg::PoseStamped PoseStamped
Definition: lanelet_wrapper.hpp:66
geometry_msgs::msg::Vector3 Vector3
Definition: lanelet_wrapper.hpp:68
auto route(Ts &&... xs)
Definition: route.hpp:30
RoutingGraphType
Definition: routing_graph_type.hpp:24
Definition: api.hpp:48
std::string string
Definition: junit5.hpp:26
traffic_simulator_msgs::EntityType EntityType
Definition: helper_functions.hpp:31
size_t operator()(const std::tuple< lanelet::Id, lanelet::Id, bool > &data) const
Definition: lanelet_wrapper.hpp:44
Definition: routing_configuration.hpp:24
RouteCache route_cache
Definition: lanelet_wrapper.hpp:278
TrafficRulesWithRoutingGraph(const lanelet::LaneletMapPtr lanelet_map_ptr, const std::string &locations, const std::string &participants)
Definition: lanelet_wrapper.hpp:280
lanelet::traffic_rules::TrafficRulesPtr rules
Definition: lanelet_wrapper.hpp:276
lanelet::routing::RoutingGraphConstPtr graph
Definition: lanelet_wrapper.hpp:277