System Info
Apollo side
- OS: Ubuntu 20.04.1 LTS
- GPU: NVIDIA GeForce RTX 2080 Ti
- Apollo version: 7.0, with a self-patched modification to the Pull Over feature (fixes an issue where the vehicle fails to merge into the rightmost lane and instead stops in the current lane)
- Modules enabled: Localization, Perception, Transform, Routing, Prediction, Planning, Traffic Light, Control, Recorder
- Prediction module modification: Perception input replaced with 3D ground truth (gt_perception)
- Map: SanFrancisco_correct, with a correction applied to several lanes whose width was incorrectly set to 3.5m instead of the standard 3.7m
Simulator side
Bug Description
In this scenario, the Ego vehicle is required to change from the left lane to the right lane in order to enter a stop sign scenario. However, an NPC vehicle is stopped at the stop line in the right lane, preventing the Ego vehicle from completing the lane change before reaching the stop line. The Ego vehicle first enters the STOP_SIGN_UNPROTECTED scenario and stops as expected, then begins to creep forward. At some point, the scenario switches to the default LANE_FOLLOW scenario, and the vehicle comes to a permanent stop.
From the attached video, the PRE_STOP, STOP, and CREEP stages can be seen repeating twice before the scenario switches to LANE_FOLLOW.
To Reproduce
Our Scenario
- Ego initial pose: (55.58, 10.2, -53.46)
- Ego goal pose: (50.05, 10.2, -3.51)
- NPC initial pose: (40.56, 10.2, -33.48)
- NPC maneuver: Stops at the stop line. In our case the NPC is stationary at the stop line, but any NPC behavior that prevents the Ego vehicle from completing its own lane change in time should be sufficient to reproduce this issue.
Video and rosbag are attached below.
Expected Behavior
After stopping near the stop line, the Ego vehicle should reroute to first turn left, then come back around, complete the right lane change, and re-attempt the right turn at the stop sign, rather than switching to LANE_FOLLOW and stopping indefinitely.
Suspected Root Cause
(Note: given the complexity of ADS planning logic, this may not be the sole factor. We are sharing our analysis in case it is useful, but a full fix likely requires closer review from maintainers familiar with this code path.)
This appears to be related to a similar underlying pattern we described in #15805 (rerouting causing an unexpected scenario/stage transition), though the mechanism here is somewhat different.
|
const double adc_distance_to_stop_sign = |
|
stop_sign_overlap.start_s - adc_front_edge_s; |
|
ADEBUG << "adc_distance_to_stop_sign[" << adc_distance_to_stop_sign |
|
<< "] stop_sign[" << stop_sign_overlap.object_id |
|
<< "] stop_sign_overlap_start_s[" << stop_sign_overlap.start_s << "]"; |
|
|
|
const bool stop_sign_scenario = |
|
(adc_distance_to_stop_sign > 0.0 && |
|
adc_distance_to_stop_sign <= |
|
scenario_config.start_stop_sign_scenario_distance()); |
|
const bool stop_sign_all_way = false; // TODO(all) |
In modules/planning/scenarios/scenario_manager.cc (SelectStopSignScenario, lines 444-454), the distance from the Ego vehicle to the stop sign is computed using the front edge of the vehicle body (adc_front_edge_s), and the STOP_SIGN_UNPROTECTED scenario is only selected when this distance is strictly positive (adc_distance_to_stop_sign > 0.0).
When the lane change fails and a rerouting occurs, the scenario manager re-evaluates which scenario to select. On the first rerouting, the Ego vehicle is still behind the stop sign, so STOP_SIGN_UNPROTECTED is correctly re-selected. However, by the time a second rerouting occurs, the vehicle has already crept slightly forward during the CREEP stage, causing the front edge of the vehicle to pass the stop sign's start_s. This makes adc_distance_to_stop_sign negative, so the condition above no longer holds, and the scenario manager falls back to the default LANE_FOLLOW scenario instead.
|
// build stop decision |
|
ADEBUG << "BuildStopDecision: stop_sign[" << stop_sign_overlap.object_id |
|
<< "] start_s[" << stop_sign_overlap.start_s << "]"; |
|
const std::string virtual_obstacle_id = |
|
STOP_SIGN_VO_ID_PREFIX + stop_sign_overlap.object_id; |
|
const std::vector<std::string> wait_for_obstacle_ids( |
|
stop_sign_status.wait_for_obstacle_id().begin(), |
|
stop_sign_status.wait_for_obstacle_id().end()); |
|
util::BuildStopDecision(virtual_obstacle_id, stop_sign_overlap.start_s, |
|
config_.stop_sign().stop_distance(), |
|
StopReasonCode::STOP_REASON_STOP_SIGN, |
|
wait_for_obstacle_ids, |
|
TrafficRuleConfig::RuleId_Name(config_.rule_id()), |
|
frame, reference_line_info); |
Separately, in modules/planning/traffic_rules/stop_sign.cc (lines 71-84), the stop decision created for the stop sign is only maintained through the STOP and CREEP stages, and is not carried over once the scenario falls back to LANE_FOLLOW. Since the default LANE_FOLLOW scenario has no mechanism to clear or supersede this now-orphaned stop decision, the vehicle remains permanently stopped.
Suggested Fix Direction
In our tests, using the rear edge of the vehicle body (adc_back_edge_s) instead of the front edge when computing the distance to the stop sign resolved this specific case. However, we believe the more fundamental issue is that certain scenario/planning context is not preserved across rerouting, and a more complete fix would involve maintaining relevant stop-sign scenario context through a rerouting event rather than relying purely on distance-based re-entry conditions.
System Info
Apollo side
Simulator side
Bug Description
In this scenario, the Ego vehicle is required to change from the left lane to the right lane in order to enter a stop sign scenario. However, an NPC vehicle is stopped at the stop line in the right lane, preventing the Ego vehicle from completing the lane change before reaching the stop line. The Ego vehicle first enters the STOP_SIGN_UNPROTECTED scenario and stops as expected, then begins to creep forward. At some point, the scenario switches to the default LANE_FOLLOW scenario, and the vehicle comes to a permanent stop.
From the attached video, the PRE_STOP, STOP, and CREEP stages can be seen repeating twice before the scenario switches to LANE_FOLLOW.
To Reproduce
Our Scenario
Video and rosbag are attached below.
Expected Behavior
After stopping near the stop line, the Ego vehicle should reroute to first turn left, then come back around, complete the right lane change, and re-attempt the right turn at the stop sign, rather than switching to LANE_FOLLOW and stopping indefinitely.
Suspected Root Cause
(Note: given the complexity of ADS planning logic, this may not be the sole factor. We are sharing our analysis in case it is useful, but a full fix likely requires closer review from maintainers familiar with this code path.)
This appears to be related to a similar underlying pattern we described in #15805 (rerouting causing an unexpected scenario/stage transition), though the mechanism here is somewhat different.
apollo/modules/planning/scenarios/scenario_manager.cc
Lines 444 to 454 in 463fb82
In modules/planning/scenarios/scenario_manager.cc (SelectStopSignScenario, lines 444-454), the distance from the Ego vehicle to the stop sign is computed using the front edge of the vehicle body (adc_front_edge_s), and the STOP_SIGN_UNPROTECTED scenario is only selected when this distance is strictly positive (
adc_distance_to_stop_sign> 0.0).When the lane change fails and a rerouting occurs, the scenario manager re-evaluates which scenario to select. On the first rerouting, the Ego vehicle is still behind the stop sign, so STOP_SIGN_UNPROTECTED is correctly re-selected. However, by the time a second rerouting occurs, the vehicle has already crept slightly forward during the CREEP stage, causing the front edge of the vehicle to pass the stop sign's
start_s. This makesadc_distance_to_stop_signnegative, so the condition above no longer holds, and the scenario manager falls back to the default LANE_FOLLOW scenario instead.apollo/modules/planning/traffic_rules/stop_sign.cc
Lines 71 to 84 in 463fb82
Separately, in modules/planning/traffic_rules/stop_sign.cc (lines 71-84), the stop decision created for the stop sign is only maintained through the STOP and CREEP stages, and is not carried over once the scenario falls back to LANE_FOLLOW. Since the default LANE_FOLLOW scenario has no mechanism to clear or supersede this now-orphaned stop decision, the vehicle remains permanently stopped.
Suggested Fix Direction
In our tests, using the rear edge of the vehicle body (
adc_back_edge_s) instead of the front edge when computing the distance to the stop sign resolved this specific case. However, we believe the more fundamental issue is that certain scenario/planning context is not preserved across rerouting, and a more complete fix would involve maintaining relevant stop-sign scenario context through a rerouting event rather than relying purely on distance-based re-entry conditions.