12
12
// See the License for the specific language governing permissions and
13
13
// limitations under the License.
14
14
15
- #include < grid_map_cv/grid_map_cv.hpp>
16
- #include < grid_map_ros/grid_map_ros.hpp>
17
- #include < lanelet2_extension/regulatory_elements/road_marking.hpp>
18
- #include < lanelet2_extension/utility/message_conversion.hpp>
19
- #include < lanelet2_extension/utility/query.hpp>
20
- #include < lanelet2_extension/utility/utilities.hpp>
21
-
22
- #if __has_include(<cv_bridge/cv_bridge.hpp>)
23
- #include < cv_bridge/cv_bridge.hpp>
24
- #else
25
- #include < cv_bridge/cv_bridge.h>
26
- #endif
27
- // #include <sensor_msgs/image_encodings.h>
28
- // #include <opencv2/highgui/highgui.hpp>
29
15
#include " scene_intersection.hpp"
16
+
30
17
#include " util.hpp"
31
18
32
19
#include < behavior_velocity_planner_common/utilization/boost_geometry_helper.hpp>
33
20
#include < behavior_velocity_planner_common/utilization/path_utilization.hpp>
34
21
#include < behavior_velocity_planner_common/utilization/util.hpp>
22
+ #include < lanelet2_extension/regulatory_elements/road_marking.hpp>
23
+ #include < lanelet2_extension/utility/message_conversion.hpp>
24
+ #include < lanelet2_extension/utility/query.hpp>
25
+ #include < lanelet2_extension/utility/utilities.hpp>
35
26
#include < magic_enum.hpp>
36
27
#include < opencv2/imgproc.hpp>
37
28
@@ -93,10 +84,6 @@ IntersectionModule::IntersectionModule(
93
84
planner_param_.collision_detection .state_transit_margin_time );
94
85
before_creep_state_machine_.setMarginTime (planner_param_.occlusion .before_creep_stop_time );
95
86
before_creep_state_machine_.setState (StateMachine::State::STOP);
96
- if (enable_occlusion_detection) {
97
- occlusion_grid_pub_ = node_.create_publisher <grid_map_msgs::msg::GridMap>(
98
- " ~/debug/intersection/occlusion_grid" , rclcpp::QoS (1 ).transient_local ());
99
- }
100
87
stuck_private_area_timeout_.setMarginTime (planner_param_.stuck_vehicle .timeout_private_area );
101
88
stuck_private_area_timeout_.setState (StateMachine::State::STOP);
102
89
}
@@ -1176,7 +1163,7 @@ bool IntersectionModule::isOcclusionCleared(
1176
1163
}
1177
1164
}
1178
1165
for (const auto & poly : attention_area_cv_polygons) {
1179
- cv::fillPoly (attention_mask, poly, cv::Scalar (255 ), cv::LINE_AA );
1166
+ cv::fillPoly (attention_mask, poly, cv::Scalar (255 ), cv::LINE_4 );
1180
1167
}
1181
1168
// (1.1)
1182
1169
// reset adjacent_lanelets area to 0 on attention_mask
@@ -1201,8 +1188,8 @@ bool IntersectionModule::isOcclusionCleared(
1201
1188
for (const auto & common_area : common_areas) {
1202
1189
std::vector<cv::Point > adjacent_lane_cv_polygon;
1203
1190
for (const auto & p : common_area.outer ()) {
1204
- const int idx_x = static_cast <int >((p.x () - origin.x ) / resolution);
1205
- const int idx_y = static_cast <int >((p.y () - origin.y ) / resolution);
1191
+ const int idx_x = std:: floor <int >((p.x () - origin.x ) / resolution);
1192
+ const int idx_y = std:: floor <int >((p.y () - origin.y ) / resolution);
1206
1193
adjacent_lane_cv_polygon.emplace_back (idx_x, height - 1 - idx_y);
1207
1194
}
1208
1195
adjacent_lane_cv_polygons.push_back (adjacent_lane_cv_polygon);
@@ -1231,7 +1218,7 @@ bool IntersectionModule::isOcclusionCleared(
1231
1218
cv::bitwise_and (attention_mask, unknown_mask, occlusion_mask_raw);
1232
1219
// (3.1) apply morphologyEx
1233
1220
cv::Mat occlusion_mask;
1234
- const int morph_size = std::ceil (planner_param_.occlusion .denoise_kernel / resolution);
1221
+ const int morph_size = static_cast < int > (planner_param_.occlusion .denoise_kernel / resolution);
1235
1222
cv::morphologyEx (
1236
1223
occlusion_mask_raw, occlusion_mask, cv::MORPH_OPEN,
1237
1224
cv::getStructuringElement (cv::MORPH_RECT, cv::Size (morph_size, morph_size)));
@@ -1337,59 +1324,70 @@ bool IntersectionModule::isOcclusionCleared(
1337
1324
}
1338
1325
}
1339
1326
1340
- // clean-up and find nearest risk
1327
+ const auto & possible_object_bbox = planner_param_.occlusion .possible_object_bbox ;
1328
+ const double possible_object_bbox_x = possible_object_bbox.at (0 ) / resolution;
1329
+ const double possible_object_bbox_y = possible_object_bbox.at (1 ) / resolution;
1330
+ const double possible_object_area = possible_object_bbox_x * possible_object_bbox_y;
1331
+ std::vector<std::vector<cv::Point >> contours;
1332
+ cv::findContours (occlusion_mask, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
1333
+ std::vector<std::vector<cv::Point >> valid_contours;
1334
+ for (const auto & contour : contours) {
1335
+ std::vector<cv::Point > valid_contour;
1336
+ for (const auto & p : contour) {
1337
+ if (distance_grid.at <unsigned char >(p.y , p.x ) == undef_pixel) {
1338
+ continue ;
1339
+ }
1340
+ valid_contour.push_back (p);
1341
+ }
1342
+ if (valid_contour.size () <= 2 ) {
1343
+ continue ;
1344
+ }
1345
+ std::vector<cv::Point > approx_contour;
1346
+ cv::approxPolyDP (
1347
+ valid_contour, approx_contour,
1348
+ std::round (std::min (possible_object_bbox_x, possible_object_bbox_y) / std::sqrt (2.0 )), true );
1349
+ if (approx_contour.size () <= 1 ) continue ;
1350
+ // check area
1351
+ const double poly_area = cv::contourArea (approx_contour);
1352
+ if (poly_area < possible_object_area) continue ;
1353
+
1354
+ valid_contours.push_back (approx_contour);
1355
+ geometry_msgs::msg::Polygon polygon_msg;
1356
+ geometry_msgs::msg::Point32 point_msg;
1357
+ for (const auto & p : approx_contour) {
1358
+ const double glob_x = (p.x + 0.5 ) * resolution + origin.x ;
1359
+ const double glob_y = (height - 0.5 - p.y ) * resolution + origin.y ;
1360
+ point_msg.x = glob_x;
1361
+ point_msg.y = glob_y;
1362
+ point_msg.z = origin.z ;
1363
+ polygon_msg.points .push_back (point_msg);
1364
+ }
1365
+ debug_data_.occlusion_polygons .push_back (polygon_msg);
1366
+ }
1367
+
1341
1368
const int min_cost_thr = dist2pixel (occlusion_dist_thr);
1342
1369
int min_cost = undef_pixel - 1 ;
1343
- int max_cost = 0 ;
1344
- std::optional<int > min_cost_projection_ind = std::nullopt;
1345
1370
geometry_msgs::msg::Point nearest_occlusion_point;
1346
- for (int i = 0 ; i < width; ++i ) {
1347
- for (int j = 0 ; j < height; ++j ) {
1348
- const int pixel = static_cast <int >(distance_grid.at <unsigned char >(height - 1 - j, i ));
1349
- const bool occluded = (occlusion_mask.at <unsigned char >(height - 1 - j, i ) == 255 );
1371
+ for (const auto & occlusion_contour : valid_contours ) {
1372
+ for (const auto & p : occlusion_contour ) {
1373
+ const int pixel = static_cast <int >(distance_grid.at <unsigned char >(p. y , p. x ));
1374
+ const bool occluded = (occlusion_mask.at <unsigned char >(p. y , p. x ) == 255 );
1350
1375
if (pixel == undef_pixel || !occluded) {
1351
- // ignore outside of cropped
1352
- // some cell maybe undef still
1353
- distance_grid.at <unsigned char >(height - 1 - j, i) = 0 ;
1354
1376
continue ;
1355
1377
}
1356
- if (max_cost < pixel) {
1357
- max_cost = pixel;
1358
- }
1359
- const int projection_ind = projection_ind_grid.at <int >(height - 1 - j, i);
1360
1378
if (pixel < min_cost) {
1361
- assert (projection_ind >= 0 );
1362
1379
min_cost = pixel;
1363
- min_cost_projection_ind = projection_ind;
1364
- nearest_occlusion_point.x = origin.x + i * resolution;
1365
- nearest_occlusion_point.y = origin.y + j * resolution;
1366
- nearest_occlusion_point.z = origin.z + distance_max * pixel / max_cost_pixel;
1380
+ nearest_occlusion_point.x = origin.x + p.x * resolution;
1381
+ nearest_occlusion_point.y = origin.y + (height - 1 - p.y ) * resolution;
1382
+ nearest_occlusion_point.z = origin.z ;
1367
1383
}
1368
1384
}
1369
1385
}
1370
- debug_data_.nearest_occlusion_point = nearest_occlusion_point;
1371
-
1372
- if (planner_param_.occlusion .pub_debug_grid ) {
1373
- cv::Mat distance_grid_heatmap;
1374
- cv::applyColorMap (distance_grid, distance_grid_heatmap, cv::COLORMAP_JET);
1375
- grid_map::GridMap occlusion_grid ({" elevation" });
1376
- occlusion_grid.setFrameId (" map" );
1377
- occlusion_grid.setGeometry (
1378
- grid_map::Length (width * resolution, height * resolution), resolution,
1379
- grid_map::Position (origin.x + width * resolution / 2 , origin.y + height * resolution / 2 ));
1380
- cv::rotate (distance_grid, distance_grid, cv::ROTATE_90_COUNTERCLOCKWISE);
1381
- cv::rotate (distance_grid_heatmap, distance_grid_heatmap, cv::ROTATE_90_COUNTERCLOCKWISE);
1382
- grid_map::GridMapCvConverter::addLayerFromImage<unsigned char , 1 >(
1383
- distance_grid, " elevation" , occlusion_grid, origin.z /* elevation for 0 */ ,
1384
- origin.z + distance_max /* elevation for 255 */ );
1385
- grid_map::GridMapCvConverter::addColorLayerFromImage<unsigned char , 3 >(
1386
- distance_grid_heatmap, " color" , occlusion_grid);
1387
- occlusion_grid_pub_->publish (grid_map::GridMapRosConverter::toMessage (occlusion_grid));
1388
- }
1389
1386
1390
- if (min_cost > min_cost_thr || !min_cost_projection_ind. has_value () ) {
1387
+ if (min_cost > min_cost_thr) {
1391
1388
return true ;
1392
1389
} else {
1390
+ debug_data_.nearest_occlusion_point = nearest_occlusion_point;
1393
1391
return false ;
1394
1392
}
1395
1393
}
@@ -1418,9 +1416,8 @@ bool IntersectionModule::checkFrontVehicleDeceleration(
1418
1416
// get the nearest centerpoint to object
1419
1417
std::vector<double> dist_obj_center_points;
1420
1418
for (const auto & p : center_points)
1421
- dist_obj_center_points.push_back(tier4_autoware_utils::calcDistance2d(object_pose.position, p));
1422
- const int obj_closest_centerpoint_idx = std::distance(
1423
- dist_obj_center_points.begin(),
1419
+ dist_obj_center_points.push_back(tier4_autoware_utils::calcDistance2d(object_pose.position,
1420
+ p)); const int obj_closest_centerpoint_idx = std::distance( dist_obj_center_points.begin(),
1424
1421
std::min_element(dist_obj_center_points.begin(), dist_obj_center_points.end()));
1425
1422
// find two center_points whose distances from `closest_centerpoint` cross stopping_distance
1426
1423
double acc_dist_prev = 0.0, acc_dist = 0.0;
0 commit comments