21#include <unordered_set>
41 const std::shared_ptr<const LaneInfo> lane_info,
const double s) {
43 return {point.
x(), point.
y()};
47 const std::shared_ptr<const LaneInfo> lane_info,
const double s) {
48 return lane_info->Heading(s);
53 std::shared_ptr<const hdmap::LaneInfo> lane_info =
LaneById(lane_id);
54 if (lane_info ==
nullptr) {
55 AERROR <<
"Null lane_info ptr found";
58 return lane_info->Curvature(s);
62 const std::shared_ptr<const hdmap::LaneInfo> lane_info,
const double s) {
65 lane_info->GetWidth(s, &left, &right);
70 const std::string& str_id) {
75 const std::string& str_id) {
80 const std::string& str_id) {
85 const Eigen::Vector2d& pos,
const std::shared_ptr<const LaneInfo> lane_info,
86 double* s,
double* l) {
87 if (lane_info ==
nullptr) {
90 return lane_info->GetProjection({pos.x(), pos.y()}, s, l);
94 const double radius) {
98 std::vector<std::shared_ptr<const LaneInfo>> lanes;
100 return (!lanes.empty());
104 std::shared_ptr<const LaneInfo> lane_info,
const double s,
106 if (lane_info ==
nullptr) {
111 path_point->
set_x(point.
x());
112 path_point->
set_y(point.
y());
118 std::shared_ptr<const LaneInfo> lane_info =
120 if (lane_info ==
nullptr) {
124 bool left_virtual = lane.has_left_boundary() &&
127 bool right_virtual = lane.has_right_boundary() &&
130 return left_virtual && right_virtual;
134 const double radius) {
135 std::vector<std::shared_ptr<const LaneInfo>> lanes;
137 hdmap_point.set_x(point[0]);
138 hdmap_point.set_y(point[1]);
140 for (
const auto& lane : lanes) {
149 const std::vector<std::shared_ptr<const LaneInfo>>& prev_lanes,
150 const Eigen::Vector2d& point,
const double heading,
const double radius,
151 const bool on_lane,
const int max_num_lane,
152 const double max_lane_angle_diff,
153 std::vector<std::shared_ptr<const LaneInfo>>* lanes) {
154 std::vector<std::shared_ptr<const LaneInfo>> candidate_lanes;
157 hdmap_point.set_x(point.x());
158 hdmap_point.set_y(point.y());
161 &candidate_lanes) != 0) {
165 std::vector<std::pair<std::shared_ptr<const LaneInfo>,
double>> lane_pairs;
166 for (
const auto& candidate_lane : candidate_lanes) {
167 if (candidate_lane ==
nullptr) {
170 if (on_lane && !candidate_lane->IsOnLane({point.x(), point.y()})) {
173 if (!FLAGS_use_navigation_mode &&
180 double distance = 0.0;
182 candidate_lane->GetNearestPoint({point.x(), point.y()}, &distance);
183 double nearest_point_heading =
PathHeading(candidate_lane, nearest_point);
186 if (diff <= max_lane_angle_diff) {
187 lane_pairs.emplace_back(candidate_lane, diff);
190 if (lane_pairs.empty()) {
193 std::sort(lane_pairs.begin(), lane_pairs.end(),
194 [](
const std::pair<std::shared_ptr<const LaneInfo>,
double>& p1,
195 const std::pair<std::shared_ptr<const LaneInfo>,
double>& p2) {
196 return p1.second < p2.second;
200 for (
const auto& lane_pair : lane_pairs) {
201 lanes->push_back(lane_pair.first);
203 if (count >= max_num_lane) {
210 const common::PointENU& position,
const double radius,
const double heading,
211 const double angle_diff_threshold) {
212 std::vector<std::shared_ptr<const LaneInfo>> candidate_lanes;
214 angle_diff_threshold,
215 &candidate_lanes) != 0) {
218 double min_angle_diff = 2.0 * M_PI;
219 std::shared_ptr<const LaneInfo> curr_lane_ptr =
nullptr;
220 for (
auto candidate_lane : candidate_lanes) {
221 if (!candidate_lane->IsOnLane({position.x(), position.y()})) {
224 double distance = 0.0;
226 {position.
x(), position.
y()}, &distance);
227 double nearest_point_heading =
PathHeading(candidate_lane, nearest_point);
230 if (angle_diff < min_angle_diff) {
231 min_angle_diff = angle_diff;
232 curr_lane_ptr = candidate_lane;
235 return curr_lane_ptr;
239 const Eigen::Vector2d& ego_position,
const std::string& lane_id) {
241 const auto& lane_points = ptr_lane->points();
242 if (lane_points.size() < 2) {
246 const auto& start_point = lane_points.front();
247 const auto& end_point = lane_points.back();
249 auto lane_vec = end_point - start_point;
251 auto approx_lane_length = lane_vec.Length();
252 if (approx_lane_length < 1.0e-3) {
259 auto projection_length = dist_vec.
InnerProd(lane_vec) / approx_lane_length;
261 if (projection_length < 0.0 || projection_length > approx_lane_length) {
268 const double radius) {
270 hdmap_point.set_x(point.x());
271 hdmap_point.set_y(point.y());
272 std::vector<std::shared_ptr<const JunctionInfo>> junctions;
274 return junctions.size() > 0;
278 const double x,
const double y,
279 const std::shared_ptr<const JunctionInfo> junction_info_ptr) {
280 if (junction_info_ptr ==
nullptr) {
283 const Polygon2d& polygon = junction_info_ptr->polygon();
288 const Eigen::Vector2d& point,
const double radius) {
290 hdmap_point.set_x(point.x());
291 hdmap_point.set_y(point.y());
292 std::vector<std::shared_ptr<const JunctionInfo>> junctions;
297std::vector<std::shared_ptr<const PNCJunctionInfo>>
299 const double radius) {
301 hdmap_point.set_x(point.x());
302 hdmap_point.set_y(point.y());
303 std::vector<std::shared_ptr<const PNCJunctionInfo>> junctions;
309 const double radius) {
311 if (junction_infos.empty()) {
314 for (
const auto junction_info : junction_infos) {
315 if (junction_info ==
nullptr || !junction_info->junction().has_polygon()) {
318 std::vector<Vec2d> vertices;
319 for (
const auto& point : junction_info->junction().polygon().point()) {
320 vertices.emplace_back(point.x(), point.y());
322 if (vertices.size() < 3) {
326 if (junction_polygon.IsPointIn({point.x(), point.y()})) {
334 const std::shared_ptr<const LaneInfo> lane_info,
335 const std::string& junction_id) {
336 if (lane_info ==
nullptr) {
346 if (lane_info->lane().has_junction_id() &&
347 lane_info->lane().junction_id().id() == junction_id) {
353 if (ptr_road_info->has_junction_id() &&
354 ptr_road_info->junction_id().id() == junction_id) {
365 if (lane_info->GetProjection({point.x(), point.y()}, &s, &l)) {
373 const double l, Eigen::Vector2d* point,
375 if (point ==
nullptr || heading ==
nullptr) {
378 std::shared_ptr<const LaneInfo> lane =
LaneById(
id);
381 point->x() = hdmap_point.
x() - std::sin(*heading) * l;
382 point->y() = hdmap_point.
y() + std::cos(*heading) * l;
387 const Eigen::Vector2d& point,
const double heading,
const double radius,
388 const std::vector<std::shared_ptr<const LaneInfo>>& lanes,
389 const int max_num_lane,
390 std::vector<std::shared_ptr<const LaneInfo>>* nearby_lanes) {
392 std::vector<std::shared_ptr<const LaneInfo>> prev_lanes;
393 OnLane(prev_lanes, point, heading, radius,
false, max_num_lane,
394 FLAGS_max_lane_angle_diff, nearby_lanes);
396 std::unordered_set<std::string> lane_ids;
397 for (
auto& lane_ptr : lanes) {
398 if (lane_ptr ==
nullptr) {
401 for (
auto& lane_id : lane_ptr->lane().left_neighbor_forward_lane_id()) {
402 const std::string&
id = lane_id.id();
403 if (lane_ids.find(
id) != lane_ids.end()) {
406 std::shared_ptr<const LaneInfo> nearby_lane =
LaneById(
id);
410 if (s < 0.0 || s >= nearby_lane->total_length() ||
411 std::fabs(l) > radius) {
415 nearby_lanes->push_back(nearby_lane);
417 for (
auto& lane_id : lane_ptr->lane().right_neighbor_forward_lane_id()) {
418 const std::string&
id = lane_id.id();
419 if (lane_ids.find(
id) != lane_ids.end()) {
422 std::shared_ptr<const LaneInfo> nearby_lane =
LaneById(
id);
426 if (s < 0.0 || s >= nearby_lane->total_length() ||
427 std::fabs(l) > radius) {
431 nearby_lanes->push_back(nearby_lane);
438 const std::shared_ptr<const LaneInfo>& ptr_ego_lane,
439 const Eigen::Vector2d& ego_position,
const double threshold) {
440 std::vector<std::string> neighbor_ids;
441 for (
const auto& lane_id :
442 ptr_ego_lane->lane().left_neighbor_forward_lane_id()) {
443 neighbor_ids.push_back(lane_id.id());
446 return GetNeighborLane(ptr_ego_lane, ego_position, neighbor_ids, threshold);
450 const std::shared_ptr<const LaneInfo>& ptr_ego_lane,
451 const Eigen::Vector2d& ego_position,
const double threshold) {
452 std::vector<std::string> neighbor_ids;
453 for (
const auto& lane_id :
454 ptr_ego_lane->lane().right_neighbor_forward_lane_id()) {
455 neighbor_ids.push_back(lane_id.id());
458 return GetNeighborLane(ptr_ego_lane, ego_position, neighbor_ids, threshold);
461std::shared_ptr<const LaneInfo> PredictionMap::GetNeighborLane(
462 const std::shared_ptr<const LaneInfo>& ptr_ego_lane,
463 const Eigen::Vector2d& ego_position,
464 const std::vector<std::string>& neighbor_lane_ids,
const double threshold) {
469 double s_diff_min = std::numeric_limits<double>::max();
470 std::shared_ptr<const LaneInfo> ptr_lane_min =
nullptr;
472 for (
auto& lane_id : neighbor_lane_ids) {
473 std::shared_ptr<const LaneInfo> ptr_lane =
LaneById(lane_id);
478 double s_diff = std::fabs(s - ego_s);
479 if (s_diff < s_diff_min) {
481 ptr_lane_min = ptr_lane;
485 if (s_diff_min > threshold) {
492 const Eigen::Vector2d& point,
const double radius) {
493 std::vector<std::string> lane_ids;
494 std::vector<std::shared_ptr<const LaneInfo>> lanes;
496 hdmap_point.set_x(point[0]);
497 hdmap_point.set_y(point[1]);
499 for (
const auto& lane : lanes) {
500 lane_ids.push_back(lane->id().id());
506 std::shared_ptr<const LaneInfo> target_lane,
507 std::shared_ptr<const LaneInfo> curr_lane) {
508 if (curr_lane ==
nullptr) {
511 if (target_lane ==
nullptr) {
514 for (
const auto& left_lane_id :
515 curr_lane->lane().left_neighbor_forward_lane_id()) {
516 if (target_lane->id().id() == left_lane_id.id()) {
524 std::shared_ptr<const LaneInfo> target_lane,
525 const std::vector<std::shared_ptr<const LaneInfo>>& lanes) {
529 for (
auto& lane : lanes) {
538 std::shared_ptr<const LaneInfo> target_lane,
539 std::shared_ptr<const LaneInfo> curr_lane) {
540 if (curr_lane ==
nullptr) {
543 if (target_lane ==
nullptr) {
546 for (
auto& right_lane_id :
547 curr_lane->lane().right_neighbor_forward_lane_id()) {
548 if (target_lane->id().id() == right_lane_id.id()) {
556 std::shared_ptr<const LaneInfo> target_lane,
557 const std::vector<std::shared_ptr<const LaneInfo>>& lanes) {
561 for (
const auto& lane : lanes) {
570 std::shared_ptr<const LaneInfo> curr_lane) {
571 if (curr_lane ==
nullptr) {
574 if (target_lane ==
nullptr) {
577 for (
const auto& successor_lane_id : curr_lane->lane().successor_id()) {
578 if (target_lane->id().id() == successor_lane_id.id()) {
586 std::shared_ptr<const LaneInfo> target_lane,
587 const std::vector<std::shared_ptr<const LaneInfo>>& lanes) {
591 for (
auto& lane : lanes) {
600 std::shared_ptr<const LaneInfo> target_lane,
601 std::shared_ptr<const LaneInfo> curr_lane) {
602 if (curr_lane ==
nullptr) {
605 if (target_lane ==
nullptr) {
608 for (
const auto& predecessor_lane_id : curr_lane->lane().predecessor_id()) {
609 if (target_lane->id().id() == predecessor_lane_id.id()) {
617 std::shared_ptr<const LaneInfo> target_lane,
618 const std::vector<std::shared_ptr<const LaneInfo>>& lanes) {
622 for (
auto& lane : lanes) {
631 std::shared_ptr<const LaneInfo> curr_lane) {
632 if (curr_lane ==
nullptr || other_lane ==
nullptr) {
635 return other_lane->id().id() == curr_lane->id().id();
639 std::shared_ptr<const LaneInfo> other_lane,
640 const std::vector<std::shared_ptr<const LaneInfo>>& lanes) {
644 for (
auto& lane : lanes) {
653 std::shared_ptr<const LaneInfo> lane =
LaneById(lane_id);
654 if (lane !=
nullptr) {
655 return static_cast<int>(lane->lane().turn());
662 ACHECK(position.has_x() && position.has_y() && position.has_z());
663 ACHECK(nearby_radius > 0.0);
665 std::vector<std::shared_ptr<const LaneInfo>> nearby_lanes;
672 const std::vector<std::shared_ptr<const LaneInfo>>& lane_infos) {
673 ACHECK(!lane_infos.empty());
674 size_t sample_size = FLAGS_sample_size_for_average_lane_curvature;
675 std::shared_ptr<const hdmap::LaneInfo> selected_lane_info = lane_infos[0];
676 if (selected_lane_info ==
nullptr) {
677 AERROR <<
"Lane Vector first element: selected_lane_info is nullptr.";
680 double smallest_curvature =
682 for (
size_t i = 1; i < lane_infos.size(); ++i) {
683 std::shared_ptr<const hdmap::LaneInfo> lane_info = lane_infos[i];
684 if (lane_info ==
nullptr) {
685 AWARN <<
"Lane vector element: one lane_info is nullptr.";
689 if (curvature < smallest_curvature) {
690 smallest_curvature = curvature;
691 selected_lane_info = lane_info;
694 return selected_lane_info;
698 const size_t sample_size) {
699 CHECK_GT(sample_size, 0U);
700 std::shared_ptr<const hdmap::LaneInfo> lane_info_ptr =
702 if (lane_info_ptr ==
nullptr) {
705 double lane_length = lane_info_ptr->total_length();
706 double s_gap = lane_length /
static_cast<double>(sample_size);
707 double curvature_sum = 0.0;
708 for (
size_t i = 0; i < sample_size; ++i) {
709 double s = s_gap *
static_cast<double>(i);
712 return curvature_sum /
static_cast<double>(sample_size);
The class of polygon in 2-D.
bool IsPointIn(const Vec2d &point) const
Check if a point is within the polygon.
Implements a class of 2-dimensional vectors.
void set_x(const double x)
Setter for x component
double InnerProd(const Vec2d &other) const
Returns the inner product between these two Vec2d.
void set_y(const double y)
Setter for y component
static const HDMap * BaseMapPtr()
static const HDMap & BaseMap()
int GetLanes(const apollo::common::PointENU &point, double distance, std::vector< LaneInfoConstPtr > *lanes) const
get all lanes in certain range
LaneInfoConstPtr GetLaneById(const Id &id) const
RoadInfoConstPtr GetRoadById(const Id &id) const
JunctionInfoConstPtr GetJunctionById(const Id &id) const
OverlapInfoConstPtr GetOverlapById(const Id &id) const
int GetPNCJunctions(const apollo::common::PointENU &point, double distance, std::vector< PNCJunctionInfoConstPtr > *pnc_junctions) const
get all pnc junctions in certain range
int GetJunctions(const apollo::common::PointENU &point, double distance, std::vector< JunctionInfoConstPtr > *junctions) const
get all junctions in certain range
void set_heading(const double heading)
static bool IsProjectionApproximateWithinLane(const Eigen::Vector2d &ego_position, const std::string &lane_id)
Check whether the projection of ego vehicle is on the target lane.
static bool IsSuccessorLane(std::shared_ptr< const hdmap::LaneInfo > target_lane, std::shared_ptr< const hdmap::LaneInfo > curr_lane)
Check if the target lane is a successor of another lane.
static bool InJunction(const Eigen::Vector2d &point, const double radius)
Check if the obstacle is in a junction.
static bool IsPointInJunction(const double x, const double y, const std::shared_ptr< const hdmap::JunctionInfo > junction_info_ptr)
Check if a point with coord x and y is in the junction.
static std::vector< std::shared_ptr< const hdmap::LaneInfo > > GetNearbyLanes(const common::PointENU &position, const double nearby_radius)
Get all nearby lanes within certain radius given a position
static void OnLane(const std::vector< std::shared_ptr< const hdmap::LaneInfo > > &prev_lanes, const Eigen::Vector2d &point, const double heading, const double radius, const bool on_lane, const int max_num_lane, const double max_lane_angle_diff, std::vector< std::shared_ptr< const hdmap::LaneInfo > > *lanes)
Get the connected lanes from some specified lanes.
static std::shared_ptr< const hdmap::JunctionInfo > JunctionById(const std::string &id)
Get a shared pointer to a junction by junction ID.
static bool IsIdenticalLane(std::shared_ptr< const hdmap::LaneInfo > other_lane, std::shared_ptr< const hdmap::LaneInfo > curr_lane)
Check if two lanes are identical.
static bool IsRightNeighborLane(std::shared_ptr< const hdmap::LaneInfo > target_lane, std::shared_ptr< const hdmap::LaneInfo > curr_lane)
Check if a lane is a right neighbor of another lane.
static std::vector< std::string > NearbyLaneIds(const Eigen::Vector2d &point, const double radius)
Get nearby lanes by a position.
static bool IsPredecessorLane(std::shared_ptr< const hdmap::LaneInfo > target_lane, std::shared_ptr< const hdmap::LaneInfo > curr_lane)
Check if the target lane is a predecessor of another lane.
static double LaneTotalWidth(const std::shared_ptr< const hdmap::LaneInfo > lane_info, const double s)
Get the width on a specified distance on a lane.
static double HeadingOnLane(const std::shared_ptr< const hdmap::LaneInfo > lane_info, const double s)
Get the heading of a point on a specific distance along a lane.
static bool ProjectionFromLane(std::shared_ptr< const hdmap::LaneInfo > lane_info, const double s, hdmap::MapPathPoint *path_point)
Get the nearest path point to a longitudinal coordinate on a lane.
static double AverageCurvature(const std::string &lane_id, const size_t sample_size)
Get the average curvature along a lane with the ID lane_id
static bool OnVirtualLane(const Eigen::Vector2d &position, const double radius)
Determine if a point is on a virtual lane.
static bool IsLeftNeighborLane(std::shared_ptr< const hdmap::LaneInfo > target_lane, std::shared_ptr< const hdmap::LaneInfo > curr_lane)
Check if a lane is a left neighbor of another lane.
static Eigen::Vector2d PositionOnLane(const std::shared_ptr< const hdmap::LaneInfo > lane_info, const double s)
Get the position of a point on a specific distance along a lane.
static std::shared_ptr< const hdmap::LaneInfo > GetRightNeighborLane(const std::shared_ptr< const hdmap::LaneInfo > &ptr_ego_lane, const Eigen::Vector2d &ego_position, const double threshold)
static bool HasNearbyLane(const double x, const double y, const double radius)
If there is a lane in the range with radius
static int LaneTurnType(const std::string &lane_id)
Get lane turn type.
static std::shared_ptr< const hdmap::LaneInfo > GetLeftNeighborLane(const std::shared_ptr< const hdmap::LaneInfo > &ptr_ego_lane, const Eigen::Vector2d &ego_position, const double threshold)
static bool NearJunction(const Eigen::Vector2d &point, const double radius)
Check if there are any junctions within the range centered at a certain point with a radius.
static void NearbyLanesByCurrentLanes(const Eigen::Vector2d &point, const double heading, const double radius, const std::vector< std::shared_ptr< const hdmap::LaneInfo > > &lanes, const int max_num_lane, std::vector< std::shared_ptr< const hdmap::LaneInfo > > *nearby_lanes)
Get nearby lanes by a position and current lanes.
static bool Ready()
Check if map is ready
static bool SmoothPointFromLane(const std::string &id, const double s, const double l, Eigen::Vector2d *point, double *heading)
Get the smooth point on a lane by a longitudinal coordinate.
static bool IsVirtualLane(const std::string &lane_id)
Determine if a lane is a virtual lane.
static std::shared_ptr< const hdmap::LaneInfo > LaneWithSmallestAverageCurvature(const std::vector< std::shared_ptr< const hdmap::LaneInfo > > &lane_infos)
Get the pointer to the lane with the smallest average curvature
static std::shared_ptr< const apollo::hdmap::LaneInfo > GetMostLikelyCurrentLane(const common::PointENU &position, const double radius, const double heading, const double angle_diff_threshold)
Get the lane that the position is on with minimal angle diff
static double CurvatureOnLane(const std::string &lane_id, const double s)
Get the curvature of a point on a specific distance along a lane.
static std::vector< std::shared_ptr< const apollo::hdmap::PNCJunctionInfo > > GetPNCJunctions(const Eigen::Vector2d &point, const double radius)
Get a list of junctions given a point and a search radius
static std::vector< std::shared_ptr< const apollo::hdmap::JunctionInfo > > GetJunctions(const Eigen::Vector2d &point, const double radius)
Get a list of junctions given a point and a search radius
static bool IsLaneInJunction(const std::shared_ptr< const hdmap::LaneInfo > lane_info, const std::string &junction_id)
Check if a lane is in a junction
static std::shared_ptr< const hdmap::LaneInfo > LaneById(const std::string &id)
Get a shared pointer to a lane by lane ID.
static double PathHeading(std::shared_ptr< const hdmap::LaneInfo > lane_info, const common::PointENU &point)
Get the lane heading on a point.
static bool GetProjection(const Eigen::Vector2d &position, const std::shared_ptr< const hdmap::LaneInfo > lane_info, double *s, double *l)
Get the frenet coordinates (s, l) on a lane by a position.
static std::shared_ptr< const hdmap::OverlapInfo > OverlapById(const std::string &id)
Get a shared pointer to an overlap by overlap ID.
double AngleDiff(const double from, const double to)
Calculate the difference between angle from and to
apollo::hdmap::Id MakeMapId(const std::string &id)
create a Map ID given a string.
optional LaneBoundary right_boundary
optional LaneBoundary left_boundary