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