21#include <lanelet2_routing/RoutingGraph.h>
22#include <lanelet2_traffic_rules/TrafficRulesFactory.h>
23#include <lanelet2_core/Attribute.h>
24#include <lanelet2_core/geometry/LineString.h>
25#include <lanelet2_core/primitives/Traits.h>
29#include <lanelet2_core/geometry/Polygon.h>
30#include <boost/geometry.hpp>
31#include <boost/geometry/geometries/polygon.hpp>
34#include <boost/math/special_functions/sign.hpp>
35#include <boost/date_time/posix_time/conversion.hpp>
45 throw std::invalid_argument(
"Route has not yet been loaded");
48 lanelet::ConstLineStrings3d outer_bound = area.outerBound();
50 if (outer_bound.empty())
52 throw std::invalid_argument(
"Provided area outer bound is invalid as it contains no points");
58 for (lanelet::ConstLineString3d sub_bound3d : outer_bound)
60 auto sub_bound = lanelet::utils::to2D(sub_bound3d);
61 for (lanelet::ConstPoint2d
point : sub_bound)
81 return std::make_pair(minPos, maxPos);
86 lanelet::Id inter_id = lanelet::InvalId;
87 lanelet::Id signal_id = lanelet::InvalId;
107 throw std::invalid_argument(
"Route has not yet been loaded");
110 lanelet::ConstLineString2d centerline = lanelet::utils::to2D(
lanelet.centerline());
111 if (centerline.empty())
113 throw std::invalid_argument(
"Provided lanelet has invalid centerline containing no points");
115 auto front = centerline.front();
124 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"carma_wm"),
"Map is not set or does not contain lanelets");
130 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"carma_wm"),
"Route has not yet been loaded");
133 std::vector<lanelet::BusStopRulePtr> bus_stop_list;
137 for (
const auto &ll :
route_->shortestPath())
139 auto bus_stops =
semantic_map_->laneletLayer.get(ll.id()).regulatoryElementsAs<lanelet::BusStopRule>();
140 if (bus_stops.empty())
145 for (
auto bus_stop : bus_stops)
147 auto stop_line = bus_stop->stopAndWaitLine();
148 if (stop_line.empty())
150 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"carma_wm"),
"No stop line");
155 double bus_stop_downtrack =
routeTrackPos(stop_line.front().front().basicPoint2d()).downtrack;
156 double distance_remaining_to_bus_stop = bus_stop_downtrack - curr_downtrack;
158 if (distance_remaining_to_bus_stop < 0)
162 bus_stop_list.push_back(bus_stop);
166 return bus_stop_list;
174 throw std::invalid_argument(
"Route has not yet been loaded");
178 lanelet::Points3d near_points =
186 if (lineString_1.size() == 0)
188 throw std::invalid_argument(
"Invalid route loaded. Shortest path does not have proper references");
204 lanelet::Id bestRouteSegId;
209 size_t ls_i = indexes.first;
210 size_t p_i = indexes.second;
212 if (near_points[0].
id() == lineString_1.front().id())
215 auto next_point = lineString_1[1];
220 bestRouteSegId = lineString_1.id();
227 const size_t prev_ls_i = ls_i - 1;
231 prev_centerline[prev_centerline.size() - 1].basicPoint());
233 bestRouteSegId = prev_centerline.id();
236 else if (near_points[0].
id() == lineString_1.back().id())
240 auto prev_prev_point = lineString_1[lineString_1.size() - 2];
241 auto prev_point = lineString_1[lineString_1.size() - 1];
245 double last_seg_length =
251 bestRouteSegId = lineString_1.id();
260 bestRouteSegId = next_centerline.id();
269 lanelet::BasicLineString2d subSegment = lanelet::BasicLineString2d(
270 { lineString_1[p_i - 1].basicPoint(), lineString_1[p_i].basicPoint(), lineString_1[p_i + 1].basicPoint() });
276 bestRouteSegId = lineString_1.id();
306 bool bounds_inclusive)
const
311 throw std::invalid_argument(
"Route has not yet been loaded");
315 throw std::invalid_argument(
"Start distance is greater than end distance");
318 std::vector<lanelet::ConstLanelet> output;
319 std::priority_queue<LaneletDowntrackPair, std::vector<LaneletDowntrackPair>, std::greater<LaneletDowntrackPair>>
320 prioritized_lanelets;
322 auto lanelet_map =
route_->laneletMap();
323 for (lanelet::ConstLanelet
lanelet : lanelet_map->laneletLayer)
329 lanelet::ConstLineString2d centerline = lanelet::utils::to2D(
lanelet.centerline());
331 auto front = centerline.front();
332 auto back = centerline.back();
336 if (!bounds_inclusive)
356 prioritized_lanelets.push(pair);
359 output.reserve(prioritized_lanelets.size());
360 while (!prioritized_lanelets.empty())
362 auto pair = prioritized_lanelets.top();
363 prioritized_lanelets.pop();
364 output.push_back(pair.lanelet_);
367 if (!shortest_path_only)
373 std::vector<lanelet::ConstLanelet> sorted_output;
374 for (
auto llt :
route_->shortestPath())
376 for (
size_t i = 0;
i < output.size();
i++)
378 if (llt.id() == output[
i].id())
380 sorted_output.push_back(llt);
386 return sorted_output;
390 double step_size)
const
392 std::vector<lanelet::BasicPoint2d> output;
395 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"carma_wm"),
"Route has not yet been loaded");
401 if (start_downtrack < 0 || start_downtrack > route_end || end_downtrack < 0 || end_downtrack > route_end ||
402 start_downtrack > end_downtrack)
404 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"carma_wm"),
"Invalid input downtracks");
408 TrackPos route_pos(start_downtrack, 0);
410 if (end_downtrack == start_downtrack)
416 output.reserve(2 + (end_downtrack - start_downtrack) / step_size);
417 double downtrack = start_downtrack;
418 while (downtrack < end_downtrack)
422 downtrack += step_size;
437 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm"),
"Route has not yet been loaded");
443 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm"),
"Tried to convert a downtrack of: " << downtrack
444 <<
" to map point, but it did not fit in route bounds of "
451 size_t ls_i = std::get<0>(indices);
452 size_t pt_i = std::get<1>(indices);
456 if (pt_i >= linestring.size())
463 double relative_downtrack = downtrack - ls_downtrack;
465 size_t centerline_size = linestring.size();
467 size_t prior_idx = std::min(pt_i, centerline_size - 1);
469 size_t next_idx = std::min(pt_i + 1, centerline_size - 1);
472 if (prior_idx == next_idx)
477 auto prior_point = linestring[prior_idx];
479 return lanelet::BasicPoint2d(prior_point.x(), prior_point.y());
482 lanelet::BasicPoint2d prior_point, next_point;
484 if (prior_idx < centerline_size - 1)
486 prior_point = linestring[prior_idx].basicPoint2d();
487 next_point = linestring[prior_idx + 1].basicPoint2d();
493 prior_point = linestring[prior_idx - 1].basicPoint2d();
494 next_point = linestring[prior_idx].basicPoint2d();
501 double theta = sigma + M_PI_2;
503 double delta_x = cos(theta) * -crosstrack;
504 double delta_y = sin(theta) * -crosstrack;
506 return lanelet::BasicPoint2d(
x + delta_x,
y + delta_y);
512 double prior_to_next_dist = next_downtrack - prior_downtrack;
513 double prior_to_target_dist = relative_downtrack - prior_downtrack;
514 double interpolation_percentage = 0;
516 if (prior_to_next_dist < 0.000001)
518 interpolation_percentage = 0;
522 interpolation_percentage = prior_to_target_dist / prior_to_next_dist;
525 auto prior_point = linestring[prior_idx].basicPoint2d();
526 auto next_point = linestring[next_idx].basicPoint2d();
527 auto delta_vec = next_point - prior_point;
529 double x = prior_point.x() + interpolation_percentage * delta_vec.x();
530 double y = prior_point.y() + interpolation_percentage * delta_vec.y();
535 double theta = sigma + M_PI_2;
537 double delta_x = cos(theta) * -crosstrack;
538 double delta_y = sin(theta) * -crosstrack;
544 return lanelet::BasicPoint2d(
x,
y);
549 return std::static_pointer_cast<lanelet::LaneletMap const>(
semantic_map_);
554 return std::static_pointer_cast<const lanelet::routing::Route>(
route_);
569 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"carma_wm"),
"First time map is set in carma_wm. Routing graph will be recomputed reguardless of method inputs.");
571 recompute_routing_graph =
true;
578 if (recompute_routing_graph)
581 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"carma_wm"),
"Building routing graph");
587 throw std::invalid_argument(
"Could not construct traffic rules for participant");
592 lanelet::routing::RoutingGraphUPtr map_graph = lanelet::routing::RoutingGraph::build(*
semantic_map_, *traffic_rules);
595 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"carma_wm"),
"Done building routing graph");
601 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"carma_wm"),
"Setting the routing graph with user or listener provided graph");
629 lanelet::ConstLanelets path_lanelets(
route_->shortestPath().begin(),
route_->shortestPath().end());
641 throw std::invalid_argument(
"Route endpoint set before route was available.");
644 lanelet::ConstPoint3d const_end_point{ lanelet::utils::getId(), end_point.x(), end_point.y(), end_point.z() };
646 route_->setEndPoint(const_end_point);
664 std::vector<lanelet::Point3d> coppied_points;
665 coppied_points.reserve(line.size());
667 for (
auto basic_p : line.basicLineString())
669 coppied_points.push_back(lanelet::Point3d(lanelet::utils::getId(), basic_p));
672 return lanelet::LineString3d(lanelet::utils::getId(), coppied_points);
679 lanelet::routing::LaneletPath shortest_path =
route_->shortestPath();
683 lanelet::routing::RoutingGraphUPtr shortest_path_graph =
686 std::vector<lanelet::LineString3d> lineStrings;
690 size_t next_index = 0;
692 for (lanelet::ConstLanelet ll : shortest_path)
700 if (next_index < shortest_path.size())
702 auto nextLanelet = shortest_path[next_index];
704 size_t connectionCount = shortest_path_graph->possiblePaths(ll, (uint32_t)2,
false).size();
706 if (connectionCount == 1)
711 lineStrings.size() == 0 || lineStrings.back().size() == 0 ?
714 if ((nextCenterline.size() <= 1) || (nextCenterline.size() <= 2 && offset == 1))
716 throw std::invalid_argument(
"Cannot process route with lanelet containing very short centerline");
718 lineStrings.back().insert(lineStrings.back().end(), nextCenterline.begin() + offset, nextCenterline.end());
720 else if (connectionCount == 0)
724 if (lineStrings.back().size() == 0)
727 lanelet::LineString3d empty_linestring;
728 empty_linestring.setId(lanelet::utils::getId());
729 distance_map.
pushBack(lanelet::utils::to2D(lineStrings.back()));
730 lineStrings.push_back(empty_linestring);
739 while (lineStrings.back().size() == 0)
740 lineStrings.pop_back();
758 return std::static_pointer_cast<const lanelet::routing::RoutingGraph>(
map_routing_graph_);
764 lanelet::Optional<TrafficRulesConstPtr> optional_ptr;
768 lanelet::traffic_rules::TrafficRulesUPtr traffic_rules = lanelet::traffic_rules::TrafficRulesFactory::create(
769 lanelet::traffic_rules::CarmaUSTrafficRules::Location, participant);
771 auto carma_traffic_rules = std::make_shared<lanelet::traffic_rules::CarmaUSTrafficRules>();
773 carma_traffic_rules = std::static_pointer_cast<lanelet::traffic_rules::CarmaUSTrafficRules>(
774 lanelet::traffic_rules::TrafficRulesPtr(std::move(traffic_rules)));
777 optional_ptr = std::static_pointer_cast<const lanelet::traffic_rules::CarmaUSTrafficRules>(carma_traffic_rules);
779 catch (
const lanelet::InvalidInputError& e)
793 lanelet::Optional<carma_perception_msgs::msg::RoadwayObstacle>
798 throw std::invalid_argument(
"Map is not set or does not contain lanelets");
801 lanelet::BasicPoint2d object_center(
object.pose.pose.position.x,
object.pose.pose.position.y);
805 if (!nearestLaneletBoost)
808 lanelet::Lanelet nearestLanelet = nearestLaneletBoost.get();
810 carma_perception_msgs::msg::RoadwayObstacle obs;
812 obs.connected_vehicle_type.type =
813 carma_perception_msgs::msg::ConnectedVehicleType::NOT_CONNECTED;
814 obs.lanelet_id = nearestLanelet.id();
817 obs.down_track = obj_track_pos.
downtrack;
820 for (
auto prediction :
object.predictions)
823 lanelet::BasicPolygon2d prediction_polygon =
825 lanelet::BasicPoint2d prediction_center(prediction.predicted_position.position.x,
826 prediction.predicted_position.position.y);
828 auto predNearestLanelet =
semantic_map_->laneletLayer.nearest(prediction_center, 1)[0];
832 obs.predicted_lanelet_ids.emplace_back(predNearestLanelet.id());
833 obs.predicted_cross_tracks.emplace_back(pred_track_pos.
crosstrack);
834 obs.predicted_down_tracks.emplace_back(pred_track_pos.
downtrack);
838 obs.predicted_lanelet_id_confidences.emplace_back(0.9 * prediction.predicted_position_confidence);
839 obs.predicted_cross_track_confidences.emplace_back(0.9 * prediction.predicted_position_confidence);
840 obs.predicted_down_track_confidences.emplace_back(0.9 * prediction.predicted_position_confidence);
860 std::vector<lanelet::ConstLanelet> lane =
getLane(
lanelet, section);
865 return std::vector<carma_perception_msgs::msg::RoadwayObstacle>{};
869 std::vector<carma_perception_msgs::msg::RoadwayObstacle> lane_objects, roadway_objects_copy =
roadway_objects_;
877 std::queue<int> obj_idxs_queue;
881 for (
size_t i = 0;
i < roadway_objects_copy.size();
i++)
883 obj_idxs_queue.push((
int)
i);
887 for (
auto llt : lane)
889 int checked_queue_items = 0, to_check = obj_idxs_queue.size();
891 while (checked_queue_items < to_check)
893 curr_idx = obj_idxs_queue.front();
894 obj_idxs_queue.pop();
895 checked_queue_items++;
898 auto curr_obj = roadway_objects_copy[curr_idx];
899 if (curr_obj.lanelet_id == llt.id())
902 lane_objects.push_back(curr_obj);
908 boost::geometry::intersects(
909 llt.polygon2d().basicPolygon(),
913 lane_objects.push_back(curr_obj);
918 obj_idxs_queue.push(curr_idx);
926 lanelet::Optional<lanelet::Lanelet>
932 throw std::invalid_argument(
"Map is not set or does not contain lanelets");
935 lanelet::BasicPoint2d object_center(
object.pose.pose.position.x,
object.pose.pose.position.y);
939 object_center, 1)[0];
943 if (!boost::geometry::intersects(nearestLanelet.polygon2d().basicPolygon(), object_polygon))
947 return nearestLanelet;
955 throw std::invalid_argument(
"Map is not set or does not contain lanelets");
963 auto curr_lanelet =
semantic_map_->laneletLayer.nearest(object_center, 1)[0];
966 if (!boost::geometry::within(object_center, curr_lanelet.polygon2d().basicPolygon()))
967 throw std::invalid_argument(
"Given point is not within any lanelet");
969 std::vector<carma_perception_msgs::msg::RoadwayObstacle> lane_objects =
getInLaneObjects(curr_lanelet);
972 if (lane_objects.size() == 0)
976 double min_dist = INFINITY;
982 double curr_dist = lanelet::geometry::distance(object_center, object_polygon);
983 if (min_dist > curr_dist)
984 min_dist = curr_dist;
991 lanelet::Optional<std::tuple<TrackPos, carma_perception_msgs::msg::RoadwayObstacle>>
997 throw std::invalid_argument(
"Map is not set or does not contain lanelets");
1005 auto curr_lanelet =
semantic_map_->laneletLayer.nearest(object_center, 1)[0];
1008 if (!boost::geometry::within(object_center, curr_lanelet.polygon2d().basicPolygon()))
1009 throw std::invalid_argument(
"Given point is not within any lanelet");
1012 std::vector<carma_perception_msgs::msg::RoadwayObstacle> lane_objects =
getInLaneObjects(curr_lanelet, section);
1015 if (lane_objects.size() == 0)
1019 std::vector<lanelet::ConstLanelet> lane_section =
getLane(curr_lanelet, section);
1021 std::vector<double> object_downtracks, object_crosstracks;
1022 std::vector<int> object_idxs;
1023 std::queue<int> obj_idxs_queue;
1024 double base_downtrack = 0;
1025 double input_obj_downtrack = 0;
1030 for (
size_t i = 0;
i < lane_objects.size();
i++)
1032 obj_idxs_queue.push((
int)
i);
1036 for (
auto llt : lane_section)
1038 int checked_queue_items = 0, to_check = obj_idxs_queue.size();
1041 while (checked_queue_items < to_check)
1043 curr_idx = obj_idxs_queue.front();
1044 obj_idxs_queue.pop();
1045 checked_queue_items++;
1048 if (lane_objects[curr_idx].lanelet_id == llt.id())
1050 object_downtracks.push_back(base_downtrack + lane_objects[curr_idx].down_track);
1051 object_crosstracks.push_back(lane_objects[curr_idx].cross_track);
1052 object_idxs.push_back(curr_idx);
1061 lanelet::BasicPoint2d obj_center(lane_objects[curr_idx].
object.pose.pose.position.x,
1062 lane_objects[curr_idx].object.pose.pose.position.y);
1064 object_downtracks.push_back(base_downtrack + new_tp.
downtrack);
1065 object_crosstracks.push_back(lane_objects[curr_idx].cross_track);
1066 object_idxs.push_back(curr_idx);
1071 obj_idxs_queue.push(curr_idx);
1075 if (curr_lanelet.id() == llt.id())
1080 geometry::trackPos(llt.centerline().back().basicPoint2d(), llt.centerline().front().basicPoint2d(),
1081 llt.centerline().back().basicPoint2d())
1087 double min_dist = INFINITY;
1088 for (
size_t idx = 0; idx < object_downtracks.size(); idx++)
1090 if (min_dist > std::fabs(object_downtracks[idx] - input_obj_downtrack))
1092 min_dist = std::fabs(object_downtracks[idx] - input_obj_downtrack);
1099 return std::tuple<TrackPos, carma_perception_msgs::msg::RoadwayObstacle>(
1100 TrackPos(object_downtracks[min_idx] - input_obj_downtrack,
1101 object_crosstracks[min_idx] -
geometry::trackPos(curr_lanelet, object_center).crosstrack),
1102 lane_objects[object_idxs[min_idx]]);
1105 lanelet::Optional<std::tuple<TrackPos, carma_perception_msgs::msg::RoadwayObstacle>>
1111 lanelet::Optional<std::tuple<TrackPos, carma_perception_msgs::msg::RoadwayObstacle>>
1122 throw std::invalid_argument(
"Map is not set or does not contain lanelets");
1128 throw std::invalid_argument(
"Lanelet is not on the map");
1134 throw std::invalid_argument(
"Undefined lane section is requested");
1137 std::vector<lanelet::ConstLanelet> following_lane = {
lanelet};
1138 std::stack<lanelet::ConstLanelet> prev_lane_helper;
1139 std::vector<lanelet::ConstLanelet> prev_lane;
1143 while (connecting_lanelet.size() != 0)
1145 following_lane.push_back(connecting_lanelet[0]);
1149 return following_lane;
1153 while (connecting_lanelet.size() != 0)
1155 prev_lane_helper.push(connecting_lanelet[0]);
1160 while (prev_lane_helper.size() != 0)
1162 prev_lane.push_back(prev_lane_helper.top());
1163 prev_lane_helper.pop();
1174 prev_lane.insert(prev_lane.end(), following_lane.begin(), following_lane.end());
1223 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"carma_wm"),
"Map is not set or does not contain lanelets");
1229 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"carma_wm"),
"Route has not yet been loaded");
1232 std::vector<lanelet::CarmaTrafficSignalPtr> light_list;
1236 for (
const auto &ll :
route_->shortestPath())
1238 auto lights =
semantic_map_->laneletLayer.get(ll.id()).regulatoryElementsAs<lanelet::CarmaTrafficSignal>();
1244 for (
auto light : lights)
1246 auto stop_line = light->getStopLine(ll);
1249 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"carma_wm"),
"No stop line");
1254 double light_downtrack =
routeTrackPos(stop_line.get().front().basicPoint2d()).downtrack;
1255 double distance_remaining_to_traffic_light = light_downtrack - curr_downtrack;
1257 if (distance_remaining_to_traffic_light < 0)
1261 light_list.push_back(light);
1270 if (!traffic_signal)
1272 throw std::invalid_argument(
"Empty traffic signal pointer has been passed!");
1275 std::pair<lanelet::ConstLanelet, lanelet::ConstLanelet> entry_exit;
1276 bool found_entry =
false;
1277 bool found_exit =
false;
1278 auto entry_lanelets = traffic_signal->getControlStartLanelets();
1279 auto exit_lanelets = traffic_signal->getControlEndLanelets();
1282 for (
const auto& ll:
route_->shortestPath())
1286 for (
const auto& entry: entry_lanelets)
1288 if (ll.id() == entry.id())
1290 entry_exit.first = entry;
1299 for (
const auto& exit: exit_lanelets)
1301 if (ll.id() == exit.id())
1303 entry_exit.second = exit;
1310 if (found_entry && found_exit)
1323 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"carma_wm"),
"Map is not set or does not contain lanelets");
1329 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"carma_wm"),
"Route has not yet been loaded");
1332 std::vector<std::shared_ptr<lanelet::AllWayStop>> intersection_list;
1335 for(
const auto& ll :
route_->shortestPath())
1337 auto intersections =
semantic_map_->laneletLayer.get(ll.id()).regulatoryElementsAs<lanelet::AllWayStop>();
1338 if (intersections.empty())
1342 for (
auto intersection : intersections)
1344 double intersection_downtrack =
routeTrackPos(intersection->stopLines().front().front().basicPoint2d()).downtrack;
1345 if (intersection_downtrack < curr_downtrack)
1349 intersection_list.push_back(intersection);
1352 return intersection_list;
1360 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"carma_wm"),
"Map is not set or does not contain lanelets");
1366 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"carma_wm"),
"Route has not yet been loaded");
1369 std::vector<lanelet::SignalizedIntersectionPtr> intersection_list;
1372 for (
const auto &ll :
route_->shortestPath())
1374 auto intersections =
semantic_map_->laneletLayer.get(ll.id()).regulatoryElementsAs<lanelet::SignalizedIntersection>();
1375 if (intersections.empty())
1379 for (
auto intersection : intersections)
1381 double intersection_downtrack =
routeTrackPos(ll.centerline().back().basicPoint2d()).downtrack;
1382 if (intersection_downtrack < curr_downtrack)
1386 intersection_list.push_back(intersection);
1389 return intersection_list;
1394 auto general_regem =
semantic_map_->regulatoryElementLayer.get(
id);
1396 auto lanelets_general =
semantic_map_->laneletLayer.findUsages(general_regem);
1397 if (lanelets_general.empty())
1399 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"carma_wm"),
"There was an error querying lanelet for traffic light with id: " <<
id);
1402 auto curr_light_list = lanelets_general[0].regulatoryElementsAs<lanelet::CarmaTrafficSignal>();
1404 if (curr_light_list.empty())
1406 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"carma_wm"),
"There was an error querying traffic light with id: " <<
id);
1410 lanelet::CarmaTrafficSignalPtr curr_light;
1412 for (
auto signal : lanelets_general[0].regulatoryElementsAs<lanelet::CarmaTrafficSignal>())
1414 if (signal->id() ==
id)
1416 curr_light = signal;
1423 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"carma_wm"),
"Was not able to find traffic signal with id: " <<
id <<
", ignoring...");
1432 double simulation_time_difference_in_seconds = 0.0;
1433 double wall_time_offset_in_seconds = 0.0;
1441 else if (is_simulation &&
ros1_clock_ && is_spat_wall_time)
1445 wall_time_offset_in_seconds = (std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch()).count()) -
ros1_clock_.value().seconds();
1448 min_end_time += lanelet::time::durationFromSec(simulation_time_difference_in_seconds);
1449 min_end_time -= lanelet::time::durationFromSec(wall_time_offset_in_seconds);
1453 auto inception_boost(boost::posix_time::time_from_string(
"1970-01-01 00:00:00.000"));
1454 auto duration_since_inception(lanelet::time::durationFromSec(std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch()).count()));
1455 auto curr_time_boost = inception_boost + duration_since_inception;
1457 int curr_year = curr_time_boost.date().year();
1460 if (is_simulation && !is_spat_wall_time)
1463 auto curr_year_start_boost(boost::posix_time::time_from_string(
std::to_string(curr_year)+
"-01-01 00:00:00.000"));
1465 auto curr_minute_stamp_boost = curr_year_start_boost + boost::posix_time::minutes((
int)moy);
1467 int hours_of_day = curr_minute_stamp_boost.time_of_day().hours();
1468 int curr_month = curr_minute_stamp_boost.date().month();
1469 int curr_day = curr_minute_stamp_boost.date().day();
1472 auto curr_hour_boost = curr_day_boost + boost::posix_time::hours(hours_of_day);
1474 min_end_time += lanelet::time::durationFromSec(lanelet::time::toSec(curr_hour_boost));
1475 return min_end_time;
1479 return min_end_time;
1487 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"carma_wm"),
"Map is not set yet.");
1491 if (spat_msg.intersection_state_list.empty())
1493 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"carma_wm"),
"No intersection_state_list in the newly received SPAT msg. Returning...");
1497 for (
const auto& curr_intersection : spat_msg.intersection_state_list)
1500 for (
const auto& current_movement_state : curr_intersection.movement_list)
1502 lanelet::Id curr_light_id =
getTrafficSignalId(curr_intersection.id.id, current_movement_state.signal_group);
1504 if (curr_light_id == lanelet::InvalId)
1509 lanelet::CarmaTrafficSignalPtr curr_light =
getTrafficSignal(curr_light_id);
1511 if (curr_light ==
nullptr)
1517 if (curr_light->revision_ != curr_intersection.revision)
1519 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm"),
"Received a new intersection geometry. intersection_id: " << (
int)curr_intersection.id.id <<
", and signal_group_id: " << (
int)current_movement_state.signal_group);
1525 if (current_movement_state.movement_event_list.empty())
1527 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm"),
"Movement_event_list is empty . intersection_id: " << (
int)curr_intersection.id.id <<
", and signal_group_id: " << (
int)current_movement_state.signal_group);
1532 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm"),
"Movement_event_list size: " << current_movement_state.movement_event_list.size() <<
" . intersection_id: " << (
int)curr_intersection.id.id <<
", and signal_group_id: " << (
int)current_movement_state.signal_group);
1535 curr_light->revision_ = curr_intersection.revision;
1540 for(
auto current_movement_event:current_movement_state.movement_event_list)
1543 boost::posix_time::ptime min_end_time_dynamic = lanelet::time::timeFromSec(current_movement_event.timing.min_end_time);
1544 boost::posix_time::ptime start_time_dynamic = lanelet::time::timeFromSec(current_movement_event.timing.start_time);
1549 auto received_state_dynamic =
static_cast<lanelet::CarmaTrafficSignalState
>(current_movement_event.event_state.movement_phase_state);
1551 sim_.
traffic_signal_states_[curr_intersection.id.id][current_movement_state.signal_group].push_back(std::make_pair(min_end_time_dynamic, received_state_dynamic));
1553 start_time_dynamic);
1555 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"carma_wm"),
"intersection id: " << (
int)curr_intersection.id.id <<
", signal: " << (
int)current_movement_state.signal_group
1556 <<
", start_time: " <<
std::to_string(lanelet::time::toSec(start_time_dynamic))
1557 <<
", end_time: " <<
std::to_string(lanelet::time::toSec(min_end_time_dynamic))
1558 <<
", state: " << received_state_dynamic);
1560 curr_light->recorded_time_stamps =
sim_.
traffic_signal_states_[curr_intersection.id.id][current_movement_state.signal_group];
1568 if (!
route_ || lanelets_to_filter.empty())
1570 return std::nullopt;
1574 for (
const auto& llt : lanelets_to_filter)
1576 auto shortest_path =
route_->shortestPath();
1577 if (std::find(shortest_path.begin(), shortest_path.end(), llt) != shortest_path.end())
1583 return std::nullopt;
IndexedDistanceMap shortest_path_distance_map_
std::vector< carma_perception_msgs::msg::RoadwayObstacle > roadway_objects_
void setTrafficLightIds(uint32_t id, lanelet::Id lanelet_id)
Sets the id mapping between intersection/signal group and lanelet::Id for traffic lights in the map.
lanelet::Optional< double > distToNearestObjInLane(const lanelet::BasicPoint2d &object_center) const override
Gets Cartesian distance to the closest object on the same lane as the given point.
std::pair< TrackPos, TrackPos > routeTrackPos(const lanelet::ConstArea &area) const override
Returns a pair of TrackPos, computed in 2d, of the provided area relative to the current route....
std::vector< carma_perception_msgs::msg::RoadwayObstacle > getInLaneObjects(const lanelet::ConstLanelet &lanelet, const LaneSection §ion=LANE_AHEAD) const override
Gets all roadway objects currently in the same lane as the given lanelet.
boost::optional< lanelet::BasicPoint2d > pointFromRouteTrackPos(const TrackPos &route_pos) const override
Converts a route track position into a map frame cartesian point.
lanelet::LineString3d copyConstructLineString(const lanelet::ConstLineString3d &line) const
Helper function to perform a deep copy of a LineString and assign new ids to all the elements....
std::optional< rclcpp::Time > ros1_clock_
boost::optional< std::pair< lanelet::ConstLanelet, lanelet::ConstLanelet > > getEntryExitOfSignalAlongRoute(const lanelet::CarmaTrafficSignalPtr &traffic_signal) const override
Returns the entry and exit lanelet of the signal along the SHORTEST PATH of route....
std::vector< lanelet::Lanelet > getLaneletsFromPoint(const lanelet::BasicPoint2d &point, const unsigned int n)
(non-const version) Gets the underlying lanelet, given the cartesian point on the map
lanelet::Optional< lanelet::Lanelet > getIntersectingLanelet(const carma_perception_msgs::msg::ExternalObject &object) const override
Gets the a lanelet the object is currently on determined by its position on the semantic map....
std::vector< lanelet::BusStopRulePtr > getBusStopsAlongRoute(const lanelet::BasicPoint2d &loc) const override
Return a list of bus stop along the current route. The bus stop along a route and the next bus stop a...
lanelet::Id getTrafficSignalId(uint16_t intersection_id, uint8_t signal_id)
helper for traffic signal Id
std::string participant_type_
void setVehicleParticipationType(const std::string &participant)
Set vehicle participation type.
boost::posix_time::ptime min_end_time_converter_minute_of_year(boost::posix_time::ptime min_end_time, bool moy_exists, uint32_t moy=0, bool is_simulation=true, bool is_spat_wall_time=false)
update minimum end time to account for minute of the year
void setConfigSpeedLimit(double config_lim)
std::optional< lanelet::ConstLanelet > getFirstLaneletOnShortestPath(const std::vector< lanelet::ConstLanelet > &lanelets_to_filter) const
Given the vector of lanelets, returns the lanelet that's on the shortest path. Returns earliest lanel...
lanelet::Optional< std::tuple< TrackPos, carma_perception_msgs::msg::RoadwayObstacle > > getNearestObjInLane(const lanelet::BasicPoint2d &object_center, const LaneSection §ion=LANE_AHEAD) const
This function is called by distanceToObjectBehindInLane or distanceToObjectAheadInLane....
lanelet::LaneletMapConstPtr getMap() const override
Get a pointer to the current map. If the underlying map has changed the pointer will also need to be ...
void setMap(lanelet::LaneletMapPtr map, size_t map_version=0, bool recompute_routing_graph=true)
Set the current map.
lanelet::LaneletSubmapConstUPtr shortest_path_view_
lanelet::CarmaTrafficSignalPtr getTrafficSignal(const lanelet::Id &id) const
helper for getting traffic signal with given lanelet::Id
LaneletRouteConstPtr getRoute() const override
Get a pointer to the current route. If the underlying route has changed the pointer will also need to...
void setRoutingGraph(LaneletRoutingGraphPtr graph)
Set the routing graph for the participant type. This function may serve as an optimization to recompu...
lanelet::Optional< TrafficRulesConstPtr > getTrafficRules() const override
Get the Traffic Rules object.
void computeDowntrackReferenceLine()
Helper function to compute the geometry of the route downtrack/crosstrack reference line This functio...
LaneletRoutingGraphPtr map_routing_graph_
std::optional< rclcpp::Time > simulation_clock_
std::unordered_map< uint32_t, lanelet::Id > traffic_light_ids_
void setRouteName(const std::string &route_name)
Set the name of the route.
void setSimulationClock(const rclcpp::Time &time_now)
Set simulation clock clock (only used in simulation runs)
void setRouteEndPoint(const lanelet::BasicPoint3d &end_point)
Set endpoint of the route.
std::vector< lanelet::ConstLanelet > getLane(const lanelet::ConstLanelet &lanelet, const LaneSection §ion=LANE_AHEAD) const override
Gets the specified lane section achievable without lane change, sorted from the start,...
std::string getVehicleParticipationType()
Get vehicle participation type.
std::vector< lanelet::ConstLanelet > getLaneletsBetween(double start, double end, bool shortest_path_only=false, bool bounds_inclusive=true) const override
Returns a list of lanelets which are part of the route and whose downtrack bounds exist within the pr...
void setRos1Clock(const rclcpp::Time &time_now)
Set current Ros1 clock (only used in simulation runs)
lanelet::Optional< std::tuple< TrackPos, carma_perception_msgs::msg::RoadwayObstacle > > nearestObjectBehindInLane(const lanelet::BasicPoint2d &object_center) const override
Gets Downtrack distance to AND copy of the closest object BEHIND on the same lane as the given point....
double config_speed_limit_
lanelet::LaneletMapPtr getMutableMap() const
Get a mutable version of the current map.
carma_wm::SignalizedIntersectionManager sim_
TrackPos getRouteEndTrackPos() const override
Get trackpos of the end of route point relative to the route.
std::vector< lanelet::Lanelet > nonConnectedAdjacentLeft(const lanelet::BasicPoint2d &input_point, const unsigned int n=10)
(non-const version) Given the cartesian point on the map, tries to get the opposite direction lanelet...
lanelet::LaneletMapUPtr shortest_path_filtered_centerline_view_
std::vector< std::shared_ptr< lanelet::AllWayStop > > getIntersectionsAlongRoute(const lanelet::BasicPoint2d &loc) const override
Return a list of all way stop intersections along the current route. The tall way stop intersections ...
std::shared_ptr< lanelet::LaneletMap > semantic_map_
void setRoute(LaneletRoutePtr route)
Set the current route. This route must match the current map for this class to function properly.
LaneletRoutingGraphConstPtr getMapRoutingGraph() const override
Get a pointer to the routing graph for the current map. If the underlying map has changed the pointer...
void processSpatFromMsg(const carma_v2x_msgs::msg::SPAT &spat_msg, bool use_sim_time=false, bool is_spat_wall_time=true)
processSpatFromMsg update map's traffic light states with SPAT msg
size_t getMapVersion() const override
Returns a monotonically increasing version number which represents the version stamp of the map geome...
void setRoadwayObjects(const std::vector< carma_perception_msgs::msg::RoadwayObstacle > &rw_objs)
Update internal records of roadway objects. These objects MUST be guaranteed to be on the road.
std::vector< lanelet::LineString3d > shortest_path_centerlines_
std::vector< lanelet::CarmaTrafficSignalPtr > getSignalsAlongRoute(const lanelet::BasicPoint2d &loc) const override
Return a list of traffic lights/intersections along the current route. The traffic lights along a rou...
std::vector< carma_perception_msgs::msg::RoadwayObstacle > getRoadwayObjects() const override
Get most recent roadway objects - all objects on the road detected by perception stack.
lanelet::Optional< carma_perception_msgs::msg::RoadwayObstacle > toRoadwayObstacle(const carma_perception_msgs::msg::ExternalObject &object) const override
Converts an ExternalObject in a RoadwayObstacle by mapping its position onto the semantic map....
std::vector< lanelet::BasicPoint2d > sampleRoutePoints(double start_downtrack, double end_downtrack, double step_size) const override
Samples the route centerline between the provided downtracks with the provided step size....
std::vector< lanelet::SignalizedIntersectionPtr > getSignalizedIntersectionsAlongRoute(const lanelet::BasicPoint2d &loc) const
Return a list of signalized intersections along the current route. The signalized intersections along...
lanelet::Optional< std::tuple< TrackPos, carma_perception_msgs::msg::RoadwayObstacle > > nearestObjectAheadInLane(const lanelet::BasicPoint2d &object_center) const override
Gets Downtrack distance to AND copy of the closest object AHEAD on the same lane as the given point....
std::string getRouteName() const override
Get the current route name.
O(1) distance lookup structure for quickly accessing route distance information. NOTE: This structure...
std::pair< size_t, size_t > getIndexFromId(const lanelet::Id &id) const
Returns the indexes of the element identified by the provided Id NOTE: It is up to the user to know i...
void pushBack(const lanelet::LineString2d &ls)
Add a linestring to this structure. This function will iterate over the line string to compute distan...
std::pair< size_t, size_t > getElementIndexByDistance(double distance, bool get_point=true) const
Returns index of the linestring which the provided distance is within. NOTE: Unlike the rest of this ...
double distanceToPointAlongElement(size_t index, size_t point_index) const
Get the along-line distance to the point on the provided linestring.
double distanceToElement(size_t index) const
Get the distance to the start of the linestring at the specified index.
size_t size() const
Returns number of linestrings in this structure.
double distanceBetween(size_t index, size_t p1_index, size_t p2_index) const
Get the distance between two points on the same linestring.
bool operator>(const LaneletDowntrackPair &pair) const
lanelet::ConstLanelet lanelet_
LaneletDowntrackPair(lanelet::ConstLanelet lanelet, double downtrack)
bool operator<(const LaneletDowntrackPair &pair) const
std::unordered_map< uint16_t, lanelet::Id > intersection_id_to_regem_id_
std::unordered_map< uint16_t, std::unordered_map< uint8_t, std::vector< boost::posix_time::ptime > > > traffic_signal_start_times_
std::unordered_map< uint16_t, std::unordered_map< uint8_t, std::vector< std::pair< boost::posix_time::ptime, lanelet::CarmaTrafficSignalState > > > > traffic_signal_states_
std::unordered_map< uint8_t, lanelet::Id > signal_group_to_traffic_light_id_
Position in a track based coordinate system where the axis are downtrack and crosstrack....
auto to_string(const UtmZone &zone) -> std::string
lanelet::BasicPolygon2d objectToMapPolygon(const geometry_msgs::msg::Pose &pose, const geometry_msgs::msg::Vector3 &size)
Uses the provided pose and size vector of an ExternalObject to compute what the polygon would be of t...
double point_to_point_yaw(const lanelet::BasicPoint2d &cur_point, const lanelet::BasicPoint2d &next_point)
Computes the 2d orientation of the vector from the provided start point to end point.
std::tuple< TrackPos, lanelet::BasicSegment2d > matchSegment(const lanelet::BasicPoint2d &p, const lanelet::BasicLineString2d &line_string)
Get the TrackPos of the provided point along the linestring and the segment of the line string which ...
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::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...
std::shared_ptr< lanelet::routing::RoutingGraph > LaneletRoutingGraphPtr
std::shared_ptr< const lanelet::traffic_rules::TrafficRules > TrafficRulesConstPtr
std::shared_ptr< const lanelet::routing::Route > LaneletRouteConstPtr
std::shared_ptr< const lanelet::routing::RoutingGraph > LaneletRoutingGraphConstPtr
std::shared_ptr< lanelet::routing::Route > LaneletRoutePtr