Skip to content

Commit 00aab65

Browse files
yuki-takagi-66karishma1911
authored andcommittedMay 26, 2024
feat(map_based_prediction): cope with consecutive crosswalks (autowarefoundation#6009)
* ready for consecutive crosswalks Signed-off-by: Yuki Takagi <yuki.takagi@tier4.jp>
1 parent b2e694f commit 00aab65

File tree

1 file changed

+86
-81
lines changed

1 file changed

+86
-81
lines changed
 

‎perception/map_based_prediction/src/map_based_prediction_node.cpp

+86-81
Original file line numberDiff line numberDiff line change
@@ -415,17 +415,21 @@ bool withinRoadLanelet(
415415
}
416416

417417
boost::optional<CrosswalkEdgePoints> isReachableCrosswalkEdgePoints(
418-
const TrackedObject & object, const CrosswalkEdgePoints & edge_points,
419-
const lanelet::LaneletMapPtr & lanelet_map_ptr, const double time_horizon,
420-
const double min_object_vel)
418+
const TrackedObject & object, const lanelet::ConstLanelet & target_crosswalk,
419+
const CrosswalkEdgePoints & edge_points, const lanelet::LaneletMapPtr & lanelet_map_ptr,
420+
const double time_horizon, const double min_object_vel)
421421
{
422422
using Point = boost::geometry::model::d2::point_xy<double>;
423-
using Line = boost::geometry::model::linestring<Point>;
424423

425424
const auto & obj_pos = object.kinematics.pose_with_covariance.pose.position;
426425
const auto & obj_vel = object.kinematics.twist_with_covariance.twist.linear;
427426
const auto yaw = tier4_autoware_utils::getRPY(object.kinematics.pose_with_covariance.pose).z;
428427

428+
lanelet::BasicPoint2d obj_pos_as_lanelet(obj_pos.x, obj_pos.y);
429+
if (boost::geometry::within(obj_pos_as_lanelet, target_crosswalk.polygon2d().basicPolygon())) {
430+
return {};
431+
}
432+
429433
const auto & p1 = edge_points.front_center_point;
430434
const auto & p2 = edge_points.back_center_point;
431435

@@ -442,62 +446,66 @@ boost::optional<CrosswalkEdgePoints> isReachableCrosswalkEdgePoints(
442446
const auto estimated_velocity = std::hypot(obj_vel.x, obj_vel.y);
443447
const auto is_stop_object = estimated_velocity < stop_velocity_th;
444448
const auto velocity = std::max(min_object_vel, estimated_velocity);
445-
446-
lanelet::BasicPoint2d search_point(obj_pos.x, obj_pos.y);
447-
// nearest lanelet
448449
const auto surrounding_lanelets = lanelet::geometry::findNearest(
449-
lanelet_map_ptr->laneletLayer, search_point, time_horizon * velocity);
450+
lanelet_map_ptr->laneletLayer, obj_pos_as_lanelet, time_horizon * velocity);
450451

451-
bool first_intersect_load = false;
452-
bool second_intersect_load = false;
453-
std::vector<Point> intersects_first;
454-
std::vector<Point> intersects_second;
455-
for (const auto & lanelet : surrounding_lanelets) {
456-
if (withinLanelet(object, lanelet.second)) {
457-
return {};
458-
}
452+
const auto isAcrossAnyRoad = [&surrounding_lanelets](const Point & p_src, const Point & p_dst) {
453+
const auto withinAnyCrosswalk = [&surrounding_lanelets](const Point & p) {
454+
for (const auto & lanelet : surrounding_lanelets) {
455+
const lanelet::Attribute attr = lanelet.second.attribute(lanelet::AttributeName::Subtype);
456+
if (
457+
(attr.value() == lanelet::AttributeValueString::Crosswalk ||
458+
attr.value() == lanelet::AttributeValueString::Walkway) &&
459+
boost::geometry::within(p, lanelet.second.polygon2d().basicPolygon())) {
460+
return true;
461+
}
462+
}
463+
return false;
464+
};
459465

460-
lanelet::Attribute attr = lanelet.second.attribute(lanelet::AttributeName::Subtype);
461-
if (attr.value() != "road") {
462-
continue;
463-
}
466+
const auto isExist = [](const Point & p, const std::vector<Point> & points) {
467+
for (const auto & existingPoint : points) {
468+
if (boost::geometry::distance(p, existingPoint) < 1e-1) {
469+
return true;
470+
}
471+
}
472+
return false;
473+
};
464474

465-
{
466-
const Line object_to_entry_point{
467-
{obj_pos.x, obj_pos.y}, {ret.front_center_point.x(), ret.front_center_point.y()}};
468-
std::vector<Point> tmp_intersects;
469-
boost::geometry::intersection(
470-
object_to_entry_point, lanelet.second.polygon2d().basicPolygon(), tmp_intersects);
471-
for (const auto & p : tmp_intersects) {
472-
intersects_first.push_back(p);
475+
std::vector<Point> points_of_intersect;
476+
const boost::geometry::model::linestring<Point> line{p_src, p_dst};
477+
for (const auto & lanelet : surrounding_lanelets) {
478+
const lanelet::Attribute attr = lanelet.second.attribute(lanelet::AttributeName::Subtype);
479+
if (attr.value() != lanelet::AttributeValueString::Road) {
480+
continue;
473481
}
474-
}
475482

476-
{
477-
const Line object_to_entry_point{
478-
{obj_pos.x, obj_pos.y}, {ret.back_center_point.x(), ret.back_center_point.y()}};
479483
std::vector<Point> tmp_intersects;
480484
boost::geometry::intersection(
481-
object_to_entry_point, lanelet.second.polygon2d().basicPolygon(), tmp_intersects);
485+
line, lanelet.second.polygon2d().basicPolygon(), tmp_intersects);
482486
for (const auto & p : tmp_intersects) {
483-
intersects_second.push_back(p);
487+
if (isExist(p, points_of_intersect) || withinAnyCrosswalk(p)) {
488+
continue;
489+
}
490+
points_of_intersect.push_back(p);
491+
if (points_of_intersect.size() >= 2) {
492+
return true;
493+
}
484494
}
485495
}
486-
}
487-
488-
if (1 < intersects_first.size()) {
489-
first_intersect_load = true;
490-
}
496+
return false;
497+
};
491498

492-
if (1 < intersects_second.size()) {
493-
second_intersect_load = true;
494-
}
499+
const bool first_intersects_road = isAcrossAnyRoad(
500+
{obj_pos.x, obj_pos.y}, {ret.front_center_point.x(), ret.front_center_point.y()});
501+
const bool second_intersects_road =
502+
isAcrossAnyRoad({obj_pos.x, obj_pos.y}, {ret.back_center_point.x(), ret.back_center_point.y()});
495503

496-
if (first_intersect_load && second_intersect_load) {
504+
if (first_intersects_road && second_intersects_road) {
497505
return {};
498506
}
499507

500-
if (first_intersect_load && !second_intersect_load) {
508+
if (first_intersects_road && !second_intersects_road) {
501509
ret.swap();
502510
}
503511

@@ -1197,48 +1205,45 @@ PredictedObject MapBasedPredictionNode::getPredictedObjectAsCrosswalkUser(
11971205
predicted_object.kinematics.predicted_paths.push_back(predicted_path);
11981206
}
11991207
}
1208+
}
1209+
// try to find the edge points for all crosswalks and generate path to the crosswalk edge
1210+
for (const auto & crosswalk : crosswalks_) {
1211+
const auto edge_points = getCrosswalkEdgePoints(crosswalk);
1212+
1213+
const auto reachable_first = hasPotentialToReach(
1214+
object, edge_points.front_center_point, edge_points.front_right_point,
1215+
edge_points.front_left_point, prediction_time_horizon_, min_crosswalk_user_velocity_,
1216+
max_crosswalk_user_delta_yaw_threshold_for_lanelet_);
1217+
const auto reachable_second = hasPotentialToReach(
1218+
object, edge_points.back_center_point, edge_points.back_right_point,
1219+
edge_points.back_left_point, prediction_time_horizon_, min_crosswalk_user_velocity_,
1220+
max_crosswalk_user_delta_yaw_threshold_for_lanelet_);
1221+
1222+
if (!reachable_first && !reachable_second) {
1223+
continue;
1224+
}
12001225

1201-
// If the object is not crossing the crosswalk, not in the road lanelets, try to find the edge
1202-
// points for all crosswalks and generate path to the crosswalk edge
1203-
} else {
1204-
for (const auto & crosswalk : crosswalks_) {
1205-
const auto edge_points = getCrosswalkEdgePoints(crosswalk);
1206-
1207-
const auto reachable_first = hasPotentialToReach(
1208-
object, edge_points.front_center_point, edge_points.front_right_point,
1209-
edge_points.front_left_point, prediction_time_horizon_, min_crosswalk_user_velocity_,
1210-
max_crosswalk_user_delta_yaw_threshold_for_lanelet_);
1211-
const auto reachable_second = hasPotentialToReach(
1212-
object, edge_points.back_center_point, edge_points.back_right_point,
1213-
edge_points.back_left_point, prediction_time_horizon_, min_crosswalk_user_velocity_,
1214-
max_crosswalk_user_delta_yaw_threshold_for_lanelet_);
1215-
1216-
if (!reachable_first && !reachable_second) {
1217-
continue;
1218-
}
1219-
1220-
const auto reachable_crosswalk = isReachableCrosswalkEdgePoints(
1221-
object, edge_points, lanelet_map_ptr_, prediction_time_horizon_,
1222-
min_crosswalk_user_velocity_);
1223-
1224-
if (!reachable_crosswalk) {
1225-
continue;
1226-
}
1226+
const auto reachable_crosswalk = isReachableCrosswalkEdgePoints(
1227+
object, crosswalk, edge_points, lanelet_map_ptr_, prediction_time_horizon_,
1228+
min_crosswalk_user_velocity_);
12271229

1228-
PredictedPath predicted_path =
1229-
path_generator_->generatePathForCrosswalkUser(object, reachable_crosswalk.get());
1230-
predicted_path.confidence = 1.0;
1230+
if (!reachable_crosswalk) {
1231+
continue;
1232+
}
12311233

1232-
if (predicted_path.path.empty()) {
1233-
continue;
1234-
}
1235-
// If the predicted path to the crosswalk is crossing the fence, don't use it
1236-
if (doesPathCrossAnyFence(predicted_path)) {
1237-
continue;
1238-
}
1234+
PredictedPath predicted_path =
1235+
path_generator_->generatePathForCrosswalkUser(object, reachable_crosswalk.get());
1236+
predicted_path.confidence = 1.0;
12391237

1240-
predicted_object.kinematics.predicted_paths.push_back(predicted_path);
1238+
if (predicted_path.path.empty()) {
1239+
continue;
12411240
}
1241+
// If the predicted path to the crosswalk is crossing the fence, don't use it
1242+
if (doesPathCrossAnyFence(predicted_path)) {
1243+
continue;
1244+
}
1245+
1246+
predicted_object.kinematics.predicted_paths.push_back(predicted_path);
12421247
}
12431248

12441249
const auto n_path = predicted_object.kinematics.predicted_paths.size();

0 commit comments

Comments
 (0)
Please sign in to comment.