Skip to content

feat(map_based_prediction): suppress undetected lane-change paths when a lane-follow path exists (cherry-pick autowarefoundation#13525) - #3637

Open
YoshiRi wants to merge 1 commit into
feat/v0.64/e2efrom
PDDP-713-cherry-pick-awf-13525
Open

YoshiRi wants to merge 1 commit into
feat/v0.64/e2efrom
PDDP-713-cherry-pick-awf-13525

Conversation

@YoshiRi

@YoshiRi YoshiRi commented Oct 22, 2026

Copy link
Copy Markdown

Description

Cherry-pick of autowarefoundation#13525 (merged as 2cee537) onto feat/v0.64/e2e.

map_based_prediction emitted left/right lane-change branches with a fixed weight of 0.3 for every vehicle, even without any observed lateral motion. collision_check_filter evaluates every predicted path, so these branches of neighboring and rear vehicles made the ego vehicle yield to cars that are driving straight (false DANGER/FATAL; 15 of the 26 HIGH/FATAL segments in the Odaiba replay).

With this change a vehicle judged as LANE_FOLLOW emits only its lane-follow path. Lane-change paths are still generated when lateral motion has been observed (LANE_CHANGE_* judgement), when the current lane ends within speed x lane_end_rescue_time_horizon (merge / lane drop), or when the current lanelet has no lane-follow candidate. Suppression and restoration are decided per current lanelet; enable: false reproduces the previous behavior exactly. Pedestrians, bicycles and unknown objects are unchanged.

Differences from upstream (port only, no behavior change):

  • declare_lane_change_path_suppression_params and the test fixture take rclcpp::Node because this branch does not use autoware::agnocast_wrapper::Node in map_based_prediction yet.
  • The anonymous-namespace declare_object_deceleration_params helper of upstream is not part of this branch, so only the suppression helper is added.

Related links

Parent Issue:

How was this PR tested?

  • colcon build + colcon test of autoware_map_based_prediction on this branch in the pilot-auto.x2 (Humble) container: 182 tests, 0 failures (25 suppression tests included).
  • Upstream: replay of 8 recorded Odaiba scenarios with reconstructed TrackedObjects through the modified node and unmodified collision_check_filter: HIGH/FATAL segments 26 -> 12, no new segments; predicted paths per vehicle 1.98 -> 1.31; median latency 10-20 ms.

Notes for reviewers

Merge together with the autoware_launch.x2 companion PR: the node declares lane_change_path_suppression.enable / keep_when_lane_ends without defaults, so the launch parameter file must contain the keys.

Interface changes

ROS Parameter Changes

Additions and removals

Change type Parameter Name Type Default Value Description
Added lane_change_path_suppression.enable bool true false restores the previous behavior
Added lane_change_path_suppression.keep_when_lane_ends bool true keep LC paths when the current lane ends within the rescue horizon
Added lane_change_path_suppression.lane_end_rescue_time_horizon double 5.0 rescue horizon in seconds (speed x horizon, speed floored at 1.0 m/s)

Effects on system behavior

  • Vehicles without observed lateral motion no longer get lane-change predicted paths, so collision_check_filter (and any consumer of all predicted paths, e.g. behavior_path with use_all_predicted_paths) no longer reacts to them.
  • Between the start of a real cut-in and its detection by the lane-change judgement (lat_diff_distance, about 1 s history) no LC path is predicted; RSS / obstacle_stop are unchanged.

🤖 Generated with Claude Code

…n a lane-follow path exists (autowarefoundation#13525)

* feat(map_based_prediction): suppress undetected lane-change paths when a lane-follow path exists

Vehicles judged as LANE_FOLLOW no longer get the fixed-weight (0.3) left/right
lane-change branches; only the lane-follow path is emitted. Lane-change paths
are still generated when lateral motion has been observed (LANE_CHANGE_*
judgement), when the current lane ends within speed x
lane_end_rescue_time_horizon (merge / lane drop), or when no lane-follow path
can be built. Suppressed candidates are restored if no lane-follow path
survives the later conversion and lateral-acceleration checks, so an object
never loses all map-based paths.

Downstream, collision_check_filter evaluates every predicted path, and the
undetected lane-change branches of neighboring vehicles were the main source
of false DANGER/FATAL assessments in urban replays (26 -> 12 segments, no new
ones, on 8 recorded Odaiba scenarios).

New parameters under lane_change_path_suppression: enable (true),
keep_when_lane_ends (true), lane_end_rescue_time_horizon (5.0 s).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: yoshiri <yoshiyoshidetteiu@gmail.com>

* style(pre-commit): autofix

* refactor(map_based_prediction): split lane-change path suppression helpers to reduce method complexity

No behavior change. Addresses the CodeScene findings on autowarefoundation#13525:

- getPredictedReferencePath (212 lines) is split into makeReferencePathSearchContext,
  calcRoutingCostLimit, getPathsForLanelet, getLeftOrRightLanelet,
  collectLaneletReferencePaths, updateFuturePossibleLanelets and
  logLaneChangeSuppressionDecisions; the per-lanelet candidate generation no longer
  lives in lambdas capturing a dozen locals.
- predictOnLane's conversion loop is moved to generateOnLanePaths with an
  OnLanePathCandidates accumulator.
- The lane_change_path_suppression parameter declarations move out of the node
  constructor into declare_lane_change_path_suppression_params.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: yoshiri <yoshiyoshidetteiu@gmail.com>

* fix(map_based_prediction): fix build and cpplint findings after the refactor

- getPathsForLanelet cannot be const: isIsolatedLanelet takes a non-const
  RoutingGraphPtr reference.
- Format the lanelet id with std::to_string instead of a C long cast
  (cpplint runtime/int).
- Include <utility> in test_path_processor_suppression.cpp for std::make_pair.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: yoshiri <yoshiyoshidetteiu@gmail.com>

* fix(map_based_prediction): suppress and restore lane-change paths per origin lanelet

- Suppress an undetected LC candidate only when its own current lanelet has a
  lane-follow candidate; a current lanelet without a center keeps all of its
  candidates instead of relying on a global "any center exists" flag.
- Restore held LC candidates only for origin lanelets whose lane-follow
  prediction (two or more reference points) was not accepted; origins whose
  center survived keep their suppression.
- Keep the original handling of one-point lane-follow references: the straight
  path of the path generator is emitted as before, so enable=false (or nothing
  suppressed) reproduces the previous behavior exactly.
- Record the origin lanelet in PredictedRefPath and the per-origin center
  existence in LaneChangePathSuppressionInfo; update DEBUG decisions, tests and
  README accordingly.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: yoshiri <yoshiyoshidetteiu@gmail.com>

* docs(map_based_prediction): expand CCF/LC abbreviations and merge duplicated brief comment

- README: spell out CCF (Collision Check Filter) and LC (lane change) where they
  first appear in the suppression section.
- map_based_prediction_node.cpp: move the deceleration-parameter brief back onto
  declare_object_deceleration_params; it had been left above the new
  lane-change suppression helper.

Signed-off-by: yoshiri <yoshiyoshidetteiu@gmail.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Signed-off-by: yoshiri <yoshiyoshidetteiu@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
(cherry picked from commit 2cee537)
@mergify

mergify Bot commented Oct 22, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@sonarqubecloud

Copy link
Copy Markdown

@YoshiRi
YoshiRi requested a review from mkquda October 23, 2026 01:45
@YoshiRi

YoshiRi commented Oct 26, 2026

Copy link
Copy Markdown
Author

@mkquda Could you review this PR when you have time? It is a cherry-pick of autowarefoundation#13525 (already merged upstream and in dev via tier4/pilot_auto_sensing_perception#45) onto feat/v0.64/e2e. The only port differences are the rclcpp::Node helper/test fixture. It should be merged together with the launch parameter PR https://github.com/tier4/autoware_launch.x2/pull/3025 (the node declares the new parameters without defaults).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant