@@ -1446,8 +1446,104 @@ BehaviorModuleOutput GoalPlannerModule::planPullOverAsCandidate(
1446
1446
return stop_path;
1447
1447
}
1448
1448
1449
+ // NOTE: following block is intentionally dirty to refactor and extract only necessary codes in
1450
+ // planAsCandidate/planAsOutput/setOutput
1451
+ BehaviorModuleOutput pull_over_output{};
1452
+ {
1453
+ auto pull_over_path_with_velocity_opt = context_data.pull_over_path_opt ;
1454
+ const bool is_freespace =
1455
+ pull_over_path_with_velocity_opt &&
1456
+ pull_over_path_with_velocity_opt.value ().type () == PullOverPlannerType::FREESPACE;
1457
+ const std::optional<GoalCandidate> modified_goal_opt =
1458
+ pull_over_path_with_velocity_opt ? std::make_optional<GoalCandidate>(
1459
+ pull_over_path_with_velocity_opt.value ().modified_goal ())
1460
+ : std::nullopt;
1461
+ const auto & last_path_update_time = context_data.last_path_update_time ;
1462
+ if (
1463
+ path_decision_controller_.get_current_state ().state ==
1464
+ PathDecisionState::DecisionKind::NOT_DECIDED &&
1465
+ !is_freespace &&
1466
+ needPathUpdate (
1467
+ planner_data_->self_odometry ->pose .pose , 1.0 /* path_update_duration*/ , clock_->now (),
1468
+ modified_goal_opt, last_path_update_time, parameters_)) {
1469
+ // if the final path is not decided and enough time has passed since last path update,
1470
+ // select safe path from lane parking pull over path candidates
1471
+ // and set it to thread_safe_data_
1472
+ RCLCPP_INFO (getLogger (), " Update pull over path candidates" );
1473
+
1474
+ context_data.pull_over_path_opt = std::nullopt;
1475
+ context_data.last_path_update_time = std::nullopt;
1476
+ context_data.last_path_idx_increment_time = std::nullopt;
1477
+
1478
+ // Select a path that is as safe as possible and has a high priority.
1479
+ const auto & pull_over_path_candidates =
1480
+ context_data.lane_parking_response .pull_over_path_candidates ;
1481
+ const auto lane_pull_over_path_opt = selectPullOverPath (
1482
+ context_data, pull_over_path_candidates,
1483
+ context_data.lane_parking_response .sorted_bezier_indices_opt );
1484
+
1485
+ // update thread_safe_data_
1486
+ const auto & pull_over_path_opt =
1487
+ lane_pull_over_path_opt ? lane_pull_over_path_opt
1488
+ : context_data.freespace_parking_response .freespace_pull_over_path ;
1489
+ if (pull_over_path_opt) {
1490
+ const auto & pull_over_path = pull_over_path_opt.value ();
1491
+ context_data.pull_over_path_opt = pull_over_path;
1492
+ context_data.last_path_update_time = clock_->now ();
1493
+ context_data.last_path_idx_increment_time = std::nullopt;
1494
+
1495
+ if (pull_over_path_with_velocity_opt) {
1496
+ auto & pull_over_path_with_velocity = pull_over_path_with_velocity_opt.value ();
1497
+ // copy the path for later setOutput()
1498
+ pull_over_path_with_velocity = pull_over_path;
1499
+ // modify the velocity for latest setOutput()
1500
+ deceleratePath (pull_over_path_with_velocity);
1501
+ }
1502
+ RCLCPP_DEBUG (
1503
+ getLogger (), " selected pull over path: path_id: %ld, goal_id: %ld" , pull_over_path.id (),
1504
+ pull_over_path.modified_goal ().id );
1505
+ }
1506
+ }
1507
+
1508
+ // set output and status
1509
+ {
1510
+ if (!pull_over_path_with_velocity_opt) {
1511
+ // situation : not safe against static objects use stop_path
1512
+ // TODO(soblin): goal_candidates_.empty() is impossible
1513
+ pull_over_output.path = generateStopPath (
1514
+ context_data, (goal_candidates_.empty () ? " no goal candidate" : " no static safe path" ));
1515
+ RCLCPP_INFO_THROTTLE (
1516
+ getLogger (), *clock_, 5000 , " Not found safe pull_over path, generate stop path" );
1517
+ } else {
1518
+ const auto & pull_over_path = pull_over_path_with_velocity_opt.value ();
1519
+ if (!context_data.is_stable_safe_path && isActivated ()) {
1520
+ // situation : not safe against dynamic objects after approval
1521
+ // insert stop point in current path if ego is able to stop with acceleration and jerk
1522
+ // constraints
1523
+ pull_over_output.path = generateFeasibleStopPath (
1524
+ pull_over_path.getCurrentPath (), " unsafe against dynamic objects" );
1525
+ RCLCPP_INFO_THROTTLE (
1526
+ getLogger (), *clock_, 5000 , " Not safe against dynamic objects, generate stop path" );
1527
+ } else {
1528
+ // situation : (safe against static and dynamic objects) or (safe against static objects
1529
+ // and before approval) don't stop keep stop if not enough time passed, because it takes
1530
+ // time for the trajectory to be reflected
1531
+ auto current_path = pull_over_path.getCurrentPath ();
1532
+ keepStoppedWithCurrentPath (context_data, current_path);
1533
+ pull_over_output.path = current_path;
1534
+ }
1535
+
1536
+ setModifiedGoal (context_data, pull_over_output);
1537
+ }
1538
+ }
1539
+
1540
+ if (pull_over_path_with_velocity_opt) {
1541
+ path_candidate_ =
1542
+ std::make_shared<PathWithLaneId>(pull_over_path_with_velocity_opt.value ().full_path ());
1543
+ }
1544
+ }
1545
+
1449
1546
BehaviorModuleOutput output{};
1450
- const BehaviorModuleOutput pull_over_output = planPullOverAsOutput (context_data);
1451
1547
output.modified_goal = pull_over_output.modified_goal ;
1452
1548
output.path = generateStopPath (context_data, detail);
1453
1549
output.reference_path = getPreviousModuleOutput ().reference_path ;
0 commit comments