14
14
15
15
#include " scene.hpp"
16
16
17
+ #include " utils.hpp"
18
+
17
19
#include < autoware/behavior_velocity_planner_common/utilization/arc_lane_util.hpp>
18
20
#include < autoware/behavior_velocity_planner_common/utilization/util.hpp>
19
21
#include < autoware/motion_utils/trajectory/trajectory.hpp>
20
- #ifdef ROS_DISTRO_GALACTIC
21
- #include < tf2_eigen/tf2_eigen.h>
22
- #else
23
22
#include < tf2_eigen/tf2_eigen.hpp>
24
- #endif
25
23
26
24
#include < lanelet2_core/geometry/Polygon.h>
27
25
28
- #include < algorithm>
29
26
#include < memory>
30
27
#include < utility>
31
28
#include < vector>
32
29
33
30
namespace autoware ::behavior_velocity_planner
34
31
{
35
- namespace bg = boost::geometry;
36
32
using autoware::motion_utils::calcLongitudinalOffsetPose;
37
33
using autoware::motion_utils::calcSignedArcLength;
38
34
39
35
DetectionAreaModule::DetectionAreaModule (
40
36
const int64_t module_id, const int64_t lane_id,
41
37
const lanelet::autoware::DetectionArea & detection_area_reg_elem,
42
- const PlannerParam & planner_param, const rclcpp::Logger logger,
38
+ const PlannerParam & planner_param, const rclcpp::Logger & logger,
43
39
const rclcpp::Clock::SharedPtr clock)
44
40
: SceneModuleInterface(module_id, logger, clock),
45
41
lane_id_ (lane_id),
@@ -51,13 +47,6 @@ DetectionAreaModule::DetectionAreaModule(
51
47
velocity_factor_.init (PlanningBehavior::USER_DEFINED_DETECTION_AREA);
52
48
}
53
49
54
- LineString2d DetectionAreaModule::getStopLineGeometry2d () const
55
- {
56
- const lanelet::ConstLineString3d stop_line = detection_area_reg_elem_.stopLine ();
57
- return planning_utils::extendLine (
58
- stop_line[0 ], stop_line[1 ], planner_data_->stop_line_extend_length );
59
- }
60
-
61
50
bool DetectionAreaModule::modifyPathVelocity (PathWithLaneId * path, StopReason * stop_reason)
62
51
{
63
52
// Store original path
@@ -69,14 +58,16 @@ bool DetectionAreaModule::modifyPathVelocity(PathWithLaneId * path, StopReason *
69
58
*stop_reason = planning_utils::initializeStopReason (StopReason::DETECTION_AREA);
70
59
71
60
// Find obstacles in detection area
72
- const auto obstacle_points = getObstaclePoints ();
61
+ const auto obstacle_points = detection_area::get_obstacle_points (
62
+ detection_area_reg_elem_.detectionAreas (), *planner_data_->no_ground_pointcloud );
73
63
debug_data_.obstacle_points = obstacle_points;
74
64
if (!obstacle_points.empty ()) {
75
65
last_obstacle_found_time_ = std::make_shared<const rclcpp::Time>(clock_->now ());
76
66
}
77
67
78
68
// Get stop line geometry
79
- const auto stop_line = getStopLineGeometry2d ();
69
+ const auto stop_line = detection_area::get_stop_line_geometry2d (
70
+ detection_area_reg_elem_, planner_data_->stop_line_extend_length );
80
71
81
72
// Get self pose
82
73
const auto & self_pose = planner_data_->current_odometry ->pose ;
@@ -118,7 +109,8 @@ bool DetectionAreaModule::modifyPathVelocity(PathWithLaneId * path, StopReason *
118
109
setDistance (stop_dist);
119
110
120
111
// Check state
121
- setSafe (canClearStopState ());
112
+ setSafe (detection_area::can_clear_stop_state (
113
+ last_obstacle_found_time_, clock_->now (), planner_param_.state_clear_time ));
122
114
if (isActivated ()) {
123
115
state_ = State::GO;
124
116
last_obstacle_found_time_ = {};
@@ -165,7 +157,14 @@ bool DetectionAreaModule::modifyPathVelocity(PathWithLaneId * path, StopReason *
165
157
166
158
// Ignore objects if braking distance is not enough
167
159
if (planner_param_.use_pass_judge_line ) {
168
- if (state_ != State::STOP && !hasEnoughBrakingDistance (self_pose, stop_point->second )) {
160
+ const auto current_velocity = planner_data_->current_velocity ->twist .linear .x ;
161
+ const double pass_judge_line_distance = planning_utils::calcJudgeLineDistWithAccLimit (
162
+ current_velocity, planner_data_->current_acceleration ->accel .accel .linear .x ,
163
+ planner_data_->delay_response_time );
164
+ if (
165
+ state_ != State::STOP &&
166
+ !detection_area::has_enough_braking_distance (
167
+ self_pose, stop_point->second , pass_judge_line_distance, current_velocity)) {
169
168
RCLCPP_WARN_THROTTLE (
170
169
logger_, *clock_, std::chrono::milliseconds (1000 ).count (),
171
170
" [detection_area] vehicle is over stop border" );
@@ -206,138 +205,4 @@ bool DetectionAreaModule::modifyPathVelocity(PathWithLaneId * path, StopReason *
206
205
207
206
return true ;
208
207
}
209
-
210
- // calc smallest enclosing circle with average O(N) algorithm
211
- // reference:
212
- // https://erickimphotography.com/blog/wp-content/uploads/2018/09/Computational-Geometry-Algorithms-and-Applications-3rd-Ed.pdf
213
- std::pair<lanelet::BasicPoint2d, double > calcSmallestEnclosingCircle (
214
- const lanelet::ConstPolygon2d & poly)
215
- {
216
- // The `eps` is used to avoid precision bugs in circle inclusion checks.
217
- // If the value of `eps` is too small, this function doesn't work well. More than 1e-10 is
218
- // recommended.
219
- const double eps = 1e-5 ;
220
- lanelet::BasicPoint2d center (0.0 , 0.0 );
221
- double radius_squared = 0.0 ;
222
-
223
- auto cross = [](const lanelet::BasicPoint2d & p1, const lanelet::BasicPoint2d & p2) -> double {
224
- return p1.x () * p2.y () - p1.y () * p2.x ();
225
- };
226
-
227
- auto make_circle_3 = [&](
228
- const lanelet::BasicPoint2d & p1, const lanelet::BasicPoint2d & p2,
229
- const lanelet::BasicPoint2d & p3) -> void {
230
- // reference for circumcenter vector https://en.wikipedia.org/wiki/Circumscribed_circle
231
- const double A = (p2 - p3).squaredNorm ();
232
- const double B = (p3 - p1).squaredNorm ();
233
- const double C = (p1 - p2).squaredNorm ();
234
- const double S = cross (p2 - p1, p3 - p1);
235
- if (std::abs (S) < eps) return ;
236
- center = (A * (B + C - A) * p1 + B * (C + A - B) * p2 + C * (A + B - C) * p3) / (4 * S * S);
237
- radius_squared = (center - p1).squaredNorm () + eps;
238
- };
239
-
240
- auto make_circle_2 =
241
- [&](const lanelet::BasicPoint2d & p1, const lanelet::BasicPoint2d & p2) -> void {
242
- center = (p1 + p2) * 0.5 ;
243
- radius_squared = (center - p1).squaredNorm () + eps;
244
- };
245
-
246
- auto in_circle = [&](const lanelet::BasicPoint2d & p) -> bool {
247
- return (center - p).squaredNorm () <= radius_squared;
248
- };
249
-
250
- // mini disc
251
- for (size_t i = 1 ; i < poly.size (); i++) {
252
- const auto p1 = poly[i].basicPoint2d ();
253
- if (in_circle (p1)) continue ;
254
-
255
- // mini disc with point
256
- const auto p0 = poly[0 ].basicPoint2d ();
257
- make_circle_2 (p0, p1);
258
- for (size_t j = 0 ; j < i; j++) {
259
- const auto p2 = poly[j].basicPoint2d ();
260
- if (in_circle (p2)) continue ;
261
-
262
- // mini disc with two points
263
- make_circle_2 (p1, p2);
264
- for (size_t k = 0 ; k < j; k++) {
265
- const auto p3 = poly[k].basicPoint2d ();
266
- if (in_circle (p3)) continue ;
267
-
268
- // mini disc with tree points
269
- make_circle_3 (p1, p2, p3);
270
- }
271
- }
272
- }
273
-
274
- return std::make_pair (center, radius_squared);
275
- }
276
-
277
- std::vector<geometry_msgs::msg::Point > DetectionAreaModule::getObstaclePoints () const
278
- {
279
- std::vector<geometry_msgs::msg::Point > obstacle_points;
280
-
281
- const auto detection_areas = detection_area_reg_elem_.detectionAreas ();
282
- const auto & points = *(planner_data_->no_ground_pointcloud );
283
-
284
- for (const auto & detection_area : detection_areas) {
285
- const auto poly = lanelet::utils::to2D (detection_area);
286
- const auto circle = calcSmallestEnclosingCircle (poly);
287
- for (const auto p : points) {
288
- const double squared_dist = (circle.first .x () - p.x ) * (circle.first .x () - p.x ) +
289
- (circle.first .y () - p.y ) * (circle.first .y () - p.y );
290
- if (squared_dist <= circle.second ) {
291
- if (bg::within (Point2d{p.x , p.y }, poly.basicPolygon ())) {
292
- obstacle_points.push_back (autoware::universe_utils::createPoint (p.x , p.y , p.z ));
293
- // get all obstacle point becomes high computation cost so skip if any point is found
294
- break ;
295
- }
296
- }
297
- }
298
- }
299
-
300
- return obstacle_points;
301
- }
302
-
303
- bool DetectionAreaModule::canClearStopState () const
304
- {
305
- // vehicle can clear stop state if the obstacle has never appeared in detection area
306
- if (!last_obstacle_found_time_) {
307
- return true ;
308
- }
309
-
310
- // vehicle can clear stop state if the certain time has passed since the obstacle disappeared
311
- const auto elapsed_time = clock_->now () - *last_obstacle_found_time_;
312
- if (elapsed_time.seconds () >= planner_param_.state_clear_time ) {
313
- return true ;
314
- }
315
-
316
- // rollback in simulation mode
317
- if (elapsed_time.seconds () < 0.0 ) {
318
- return true ;
319
- }
320
-
321
- return false ;
322
- }
323
-
324
- bool DetectionAreaModule::hasEnoughBrakingDistance (
325
- const geometry_msgs::msg::Pose & self_pose, const geometry_msgs::msg::Pose & line_pose) const
326
- {
327
- // get vehicle info and compute pass_judge_line_distance
328
- const auto current_velocity = planner_data_->current_velocity ->twist .linear .x ;
329
- const double max_acc = planner_data_->max_stop_acceleration_threshold ;
330
- const double delay_response_time = planner_data_->delay_response_time ;
331
- const double pass_judge_line_distance =
332
- planning_utils::calcJudgeLineDistWithAccLimit (current_velocity, max_acc, delay_response_time);
333
-
334
- // prevent from being judged as not having enough distance when the current velocity is zero
335
- // and the vehicle crosses the stop line
336
- if (current_velocity < 1e-3 ) {
337
- return true ;
338
- }
339
-
340
- return arc_lane_utils::calcSignedDistance (self_pose, line_pose.position ) >
341
- pass_judge_line_distance;
342
- }
343
208
} // namespace autoware::behavior_velocity_planner
0 commit comments