24std::vector<lanelet::ConstLanelet>
getLaneletsFromPoint(
const lanelet::LaneletMapConstPtr& semantic_map,
const lanelet::BasicPoint2d&
point,
28 if (!semantic_map || semantic_map->laneletLayer.size() == 0)
30 throw std::invalid_argument(
"Map is not set or does not contain lanelets");
32 std::vector<lanelet::ConstLanelet> possible_lanelets;
33 auto nearestLanelets = lanelet::geometry::findNearest(semantic_map->laneletLayer,
point, n);
34 if (nearestLanelets.size() == 0)
40 while (boost::geometry::within(
point, nearestLanelets[
id].second.polygon2d()))
42 possible_lanelets.push_back(nearestLanelets[
id].second);
44 if (
id >= nearestLanelets.size())
47 return possible_lanelets;
53 lanelet::LaneletMapConstPtr const_ptr = semantic_map;
55 std::vector<lanelet::Lanelet> return_lanelets;
56 for (
auto llt : possible_lanelets)
58 return_lanelets.push_back(semantic_map->laneletLayer.get(llt.id()));
60 return return_lanelets;
67 lanelet::LaneletMapConstPtr const_ptr = semantic_map;
71 std::vector<lanelet::Lanelet> return_lanelets;
72 for (
auto llt : possible_lanelets)
74 return_lanelets.push_back(semantic_map->laneletLayer.get(llt.id()));
76 return return_lanelets;
79std::vector<lanelet::ConstLanelet>
nonConnectedAdjacentLeft(
const lanelet::LaneletMapConstPtr& semantic_map,
const lanelet::BasicPoint2d& input_point,
84 if (!semantic_map || semantic_map->laneletLayer.size() == 0)
86 throw std::invalid_argument(
"Map is not set or does not contain lanelets");
91 if (input_lanelets.empty())
93 throw std::invalid_argument(
"Input point x: " +
std::to_string(input_point.x()) +
", y: " +
std::to_string(input_point.y()) +
" is not in the map");
96 auto input_lanelet = input_lanelets[0];
102 auto point_on_ls = input_lanelet.leftBound2d()[std::round((input_lanelet.leftBound2d().size()- 1) * point_downtrack_ratio) ];
106 auto point_on_opposite_lane = lanelet::BasicPoint2d{2 * point_on_ls.x() - input_point.x(), 2 * point_on_ls.y() - input_point.y()};
113 return opposite_lanelets;
117lanelet::ConstLaneletOrAreas
getAffectedLaneletOrAreas(
const lanelet::Points3d& gf_pts,
const lanelet::LaneletMapPtr& lanelet_map, std::shared_ptr<const lanelet::routing::RoutingGraph> routing_graph,
double max_lane_width)
120 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Get affected lanelets loop");
121 std::unordered_set<lanelet::Lanelet> affected_lanelets;
122 for (
size_t idx = 0; idx < gf_pts.size(); idx ++)
124 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Index: " << idx <<
" Point: " << gf_pts[idx].
x() <<
", " << gf_pts[idx].
y());
125 std::unordered_set<lanelet::Lanelet> possible_lanelets;
131 bool continue_search =
true;
132 size_t nearest_count = 0;
133 while (continue_search) {
137 for (
const auto& ll_pair : lanelet::geometry::findNearest(lanelet_map->laneletLayer, gf_pts[idx].basicPoint2d(), nearest_count)) {
138 auto ll = std::get<1>(ll_pair);
140 if (possible_lanelets.find(ll) != possible_lanelets.end()) {
144 double dist = std::get<0>(ll_pair);
145 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Distance to lanelet " << ll.id() <<
": " << dist <<
" max_lane_width: " << max_lane_width);
147 if (dist > max_lane_width) {
148 continue_search =
false;
154 possible_lanelets.insert(ll);
159 if (nearest_count >= lanelet_map->laneletLayer.size()) {
160 continue_search =
false;
165 if (idx + 1 == gf_pts.size())
167 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Last point");
168 std::unordered_set<lanelet::Lanelet> filtered =
filterSuccessorLanelets(possible_lanelets, affected_lanelets, lanelet_map, routing_graph);
169 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Got successor lanelets of size: " << filtered.size());
170 affected_lanelets.insert(filtered.begin(), filtered.end());
173 if (affected_lanelets.empty() && !possible_lanelets.empty() && idx !=0 )
175 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Checking if it is the edge case where only last point falls on a valid (correct direction) lanelet");
176 for (
auto llt: possible_lanelets)
178 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Evaluating lanelet: " << llt.id());
179 lanelet::BasicLineString2d gf_dir_line({gf_pts[idx - 1].basicPoint2d(), gf_pts[idx].basicPoint2d()});
180 lanelet::BasicLineString2d llt_boundary({(llt.leftBound2d().begin())->basicPoint2d(), (llt.rightBound2d().begin())->basicPoint2d()});
183 if (boost::geometry::intersects(llt_boundary, gf_dir_line))
185 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Overlaps starting line... Picking llt: " << llt.id());
186 affected_lanelets.insert(llt);
194 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Checking possible lanelets");
196 for (
auto llt: possible_lanelets)
198 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Evaluating lanelet: " << llt.id());
199 lanelet::BasicLineString2d gf_dir_line({gf_pts[idx].basicPoint2d(), gf_pts[idx+1].basicPoint2d()});
200 lanelet::BasicLineString2d llt_boundary({(llt.leftBound2d().end() -1)->basicPoint2d(), (llt.rightBound2d().end() - 1)->basicPoint2d()});
203 if (boost::geometry::intersects(llt_boundary, gf_dir_line))
205 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Overlaps end line");
206 affected_lanelets.insert(llt);
209 else if (boost::geometry::within(gf_pts[idx+1].basicPoint2d(), llt.polygon2d()) &&
210 affected_lanelets.find(llt) == affected_lanelets.end())
212 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"Within new lanelet");
213 lanelet::BasicPoint2d median({((llt.leftBound2d().end() - 1)->basicPoint2d().x() + (llt.rightBound2d().end() - 1)->basicPoint2d().x())/2 ,
214 ((llt.leftBound2d().end() - 1)->basicPoint2d().y() + (llt.rightBound2d().end() - 1)->basicPoint2d().y())/2});
216 Eigen::Vector2d vec_to_median(median);
217 Eigen::Vector2d vec_to_gf_start(gf_pts[idx].basicPoint2d());
218 Eigen::Vector2d vec_to_gf_end(gf_pts[idx + 1].basicPoint2d());
221 Eigen::Vector2d start_to_median = vec_to_median - vec_to_gf_start;
224 Eigen::Vector2d start_to_end = vec_to_gf_end - vec_to_gf_start;
229 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"vec_to_median: " << vec_to_median.x() <<
", " << vec_to_median.y());
230 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"vec_to_gf_start: " << vec_to_gf_start.x() <<
", " << vec_to_gf_start.y());
231 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"vec_to_gf_end: " << vec_to_gf_end.x() <<
", " << vec_to_gf_end.y());
232 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"start_to_median: " << start_to_median.x() <<
", " << start_to_median.y());
233 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"start_to_end: " << start_to_end.x() <<
", " << start_to_end.y());
234 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"interior_angle: " << interior_angle);
237 if (interior_angle < M_PI_2 && interior_angle >= 0)
238 affected_lanelets.insert(llt);
242 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"------ Did not record anything...");
248 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm::query"),
"affected_lanelets size: " << affected_lanelets.size());
251 lanelet::ConstLaneletOrAreas affected_parts;
253 std::vector<std::pair<double, lanelet::Lanelet>> sorted_parts;
255 for (
auto llt : affected_lanelets)
259 std::sort(sorted_parts.begin(), sorted_parts.end(), [](
const auto&
x,
const auto&
y){return x.first > y.first;});
261 for (
auto pair : sorted_parts)
263 affected_parts.push_back(pair.second);
266 return affected_parts;
270std::unordered_set<lanelet::Lanelet>
filterSuccessorLanelets(
const std::unordered_set<lanelet::Lanelet>& possible_lanelets,
const std::unordered_set<lanelet::Lanelet>& root_lanelets,
271 const lanelet::LaneletMapPtr& lanelet_map, std::shared_ptr<const lanelet::routing::RoutingGraph> routing_graph)
273 if (!routing_graph) {
274 throw std::invalid_argument(
"No routing graph available");
277 std::unordered_set<lanelet::Lanelet> filtered_lanelets;
281 for (
auto recorded_llt: root_lanelets)
283 for (
auto following_llt: routing_graph->following(recorded_llt,
false))
285 auto mutable_llt = lanelet_map->laneletLayer.get(following_llt.id());
286 auto it = possible_lanelets.find(mutable_llt);
287 if (it != possible_lanelets.end())
289 filtered_lanelets.insert(mutable_llt);
293 return filtered_lanelets;
302uint32_t
get32BitId(uint16_t intersection_id, uint8_t signal_group_id)
305 temp |= intersection_id;
307 temp |= signal_group_id;
auto to_string(const UtmZone &zone) -> std::string
double getAngleBetweenVectors(const Eigen::Vector2d &vec1, const Eigen::Vector2d &vec2)
Calculates the angle between two vectors.
TrackPos trackPos(const lanelet::ConstLanelet &lanelet, const lanelet::BasicPoint2d &point)
Returns the TrackPos, computed in 2d, of the provided point relative to the centerline of the provide...
std::unordered_set< lanelet::Lanelet > filterSuccessorLanelets(const std::unordered_set< lanelet::Lanelet > &possible_lanelets, const std::unordered_set< lanelet::Lanelet > &root_lanelets, const lanelet::LaneletMapPtr &lanelet_map, std::shared_ptr< const lanelet::routing::RoutingGraph > routing_graph)
A function that filters successor lanelets of root_lanelets from possible_lanelets.
std::vector< lanelet::ConstLanelet > getLaneletsFromPoint(const lanelet::LaneletMapConstPtr &semantic_map, const lanelet::BasicPoint2d &point, const unsigned int n=10)
carma_wm::query namespace contains implementations for query functions (input and output read or writ...
lanelet::ConstLaneletOrAreas getAffectedLaneletOrAreas(const lanelet::Points3d &gf_pts, const lanelet::LaneletMapPtr &lanelet_map, std::shared_ptr< const lanelet::routing::RoutingGraph > routing_graph, double max_lane_width)
Gets the affected lanelet or areas based on the points in the given map's frame.
std::vector< lanelet::ConstLanelet > nonConnectedAdjacentLeft(const lanelet::LaneletMapConstPtr &semantic_map, const lanelet::BasicPoint2d &input_point, const unsigned int n=10)
Given the cartesian point on the map, tries to get the opposite direction lanelet on the left This fu...
uint32_t get32BitId(uint16_t intersection_id, uint8_t signal_group_id)
Get 32bit id by concatenating 16bit id with 8bit signal_group_id.