Skip to content

Commit 1a558fb

Browse files
kotaro-hiharamaxime-clemOwen-Liuyuxuancursoragentmkquda
authored
feat(traffic_light_compliance_checker): improve amber rejection stability (#3339)
* feat(traffic_light_compliance_checker): allow when close and cannot stop (#3222) feat(traffic_light_compliance_checker): allow when close and cannot stop (autowarefoundation#13028) Signed-off-by: Maxime CLEMENT <maxime.clement@tier4.jp> * fix(traffic_light_compliance_checker): improve stop point detection (#3203) Signed-off-by: Maxime CLEMENT <maxime.clement@tier4.jp> * fix(traffic_light_stop): floor scan length with min_lookahead_distance and wire stop time step (#3232) * fix(traffic_light_stop): check full traj horizon and wire stop time step At low ego speed the compliance checker capped the scan by comfortable stopping distance (~0.5 m), missing red stop lines ahead. Also assign trajectory_time_step_ so the existing 3-point stop fallback uses the configured step. Signed-off-by: YuxuanLiuTier4Desktop <619684051@qq.com> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(traffic_light): floor scan length with min_lookahead_distance Restore the comfortable-stop scan cap but floor it at 20 m so creeping ego still sees nearby stop lines, without rejecting far lights in the shared traffic_light_filter path. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Signed-off-by: YuxuanLiuTier4Desktop <619684051@qq.com> Co-authored-by: Cursor <cursoragent@cursor.com> * modify tl compliance checker to detect stop attempts at amber light and (optionally) add tl id to force rejection buffer - update traffic_light_stop params in modifier - update traffic_light filter params in validator - update modifier and validator parameter structs - implement logic to detect stops at ember light and optionally add to force rejection buffer - update & refactor traffic_light filter tests Signed-off-by: Mohammad <alqudah.mohammad@tier4.jp> * refactor tl compliance checker - update amber rejection hystory while checking for violations instead of post process - apply allow_if_cannot stop check while checking for violations instead of post process Signed-off-by: Mohammad Alqudah <alqudah.mohammad@tier4.jp> * improve crossig time limit logic compute dynamic time limit for amber light based on tracked tl duration instead of using fixed value param Signed-off-by: Mohammad <alqudah.mohammad@tier4.jp> * check the flag reject_if_stop_detected before adding tl to amber_rejection_history_ Signed-off-by: Mohammad <alqudah.mohammad@tier4.jp> * add test cases to traffic_light_stop and traffic_light_filter Signed-off-by: Mohammad <alqudah.mohammad@tier4.jp> * minor refactor Signed-off-by: Mohammad <alqudah.mohammad@tier4.jp> --------- Signed-off-by: Maxime CLEMENT <maxime.clement@tier4.jp> Signed-off-by: YuxuanLiuTier4Desktop <619684051@qq.com> Signed-off-by: Mohammad <alqudah.mohammad@tier4.jp> Signed-off-by: Mohammad Alqudah <alqudah.mohammad@tier4.jp> Co-authored-by: Maxime CLEMENT <78338830+maxime-clem@users.noreply.github.com> Co-authored-by: Yuxuan Liu <619684051@qq.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Mohammad <alqudah.mohammad@tier4.jp>
1 parent 73f5fa5 commit 1a558fb

17 files changed

Lines changed: 612 additions & 259 deletions

File tree

‎common/autoware_traffic_light_compliance_checker/README.md‎

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ The `traffic_light_compliance_checker` package provides a deterministic validati
55
## Core Features
66

77
1. **Signal State Tracking (`TrafficLightStatusTracker`)**
8+
89
- Eliminates perception jitter and signal flickering by maintaining a temporal state history for each traffic light group ID.
910
- Leverages stable duration thresholds before validating a transition to `RED` or `AMBER`.
1011
- Utilizes a hysteresis buffer to sustain known states during transient object occlusions.
@@ -22,7 +23,7 @@ The `traffic_light_compliance_checker` package provides a deterministic validati
2223
The execution flow follows a sequential logical from signal processing & filtering down to stop line interaction evaluations:
2324

2425
1. **Filter signals and update status tracker:** Feeds raw perception data into the status tracker to clean up transient noise and tracking dropouts.
25-
2. **Generate Geometric Trajectory Linestring:** Removes path points situated behind the ego vehicle, clamps the forward path length at the maximum required stop distance, and extends trajectory end to account for ego front offset.
26+
2. **Generate Geometric Trajectory Linestring:** Removes path points situated behind the ego vehicle, clamps the forward path length at `max(min_lookahead_distance, comfortable_stop_distance + stop_overshoot_margin)` (or until the first planned stop), and extends trajectory end to account for ego front offset.
2627
3. **Extract and group map stop lines:** Sorts overlapping intersection lines into separate evaluation queues for red and amber constraints.
2728
4. **Evaluate Stop Line Violations:** Checks the trajectory linesting against active stop lines, records detected violations and generate compliance result.
2829

@@ -34,7 +35,7 @@ skinparam backgroundColor #WHITE
3435
start
3536
3637
:Filter signals and update status tracker;<<#LightBlue>>
37-
:Generate Trajectory Linestring\n(Cull backward points & clamp at max stop distance);<<#LightBlue>>
38+
:Generate Trajectory Linestring\n(Cull backward points & clamp at max(min lookahead, stop distance));<<#LightBlue>>
3839
:Extend trajectory linestring\n(Add physical front bumper footprint offset);<<#LightBlue>>
3940
:Extract and group map stop lines\n(Categorize into RED vs. AMBER targets);<<#LightBlue>>
4041
@@ -116,19 +117,21 @@ The interfaces pass inputs and output results through the following standard dat
116117

117118
## Parameters
118119

119-
| Parameter Name | Type | Description |
120-
| :--------------------------------------------- | :------- | :----------------------------------------------------------------------------------------- |
121-
| `deceleration_limit` | `double` | Max deceleration limit during braking ($m/s^2$) for assessing stopping feasibility. |
122-
| `jerk_limit` | `double` | Max jerk limit during braking ($m/s^3$) for assessing stopping feasibility. |
123-
| `delay_response_time` | `double` | Combined latency buffer for compute cycle lag and brake actuation (seconds). |
124-
| `crossing_time_limit` | `double` | Maximum duration allowed for the vehicle to clear an amber light intersection (seconds). |
125-
| `stop_overshoot_margin` | `double` | Allowed physical distance buffer beyond a stop line for a stopped vehicle (meters). |
126-
| `stable_duration_threshold_red` | `double` | Required continuous duration for a `RED` state to be confirmed as valid (seconds). |
127-
| `stable_duration_threshold_amber` | `double` | Required continuous duration for an `AMBER` state to be confirmed as valid (seconds). |
128-
| `stable_duration_threshold_unknown` | `double` | Required continuous duration for an `UNKNOWN` state to be confirmed as valid (seconds). |
129-
| `amber_rejection_hysteresis_duration` | `double` | Duration to retain an active amber light state if perception updates drop out (seconds). |
130-
| `ego_stopped_velocity_threshold` | `double` | Velocity threshold beneath which the ego vehicle is considered completely stopped ($m/s$). |
131-
| `treat_amber_light_as_red_light` | `bool` | If true, disables amber passing logic and treats all amber states as strict red signals. |
132-
| `treat_unknown_light_as_red_light` | `bool` | If true, evaluates unclassified or blank signal states as strict red signals. |
133-
| `checked_trajectory_length.deceleration_limit` | `double` | Comfortable stop deceleration limit ($m/s^2$) for computing trajectory checking length. |
134-
| `checked_trajectory_length.jerk_limit` | `double` | Comfortable stop jerk limit ($m/s^3$) for computing trajectory checking length. |
120+
| Parameter Name | Type | Description |
121+
| :--------------------------------------------- | :------- | :--------------------------------------------------------------------------------------------------------- |
122+
| `deceleration_limit` | `double` | Max deceleration limit during braking ($m/s^2$) for assessing stopping feasibility. |
123+
| `jerk_limit` | `double` | Max jerk limit during braking ($m/s^3$) for assessing stopping feasibility. |
124+
| `delay_response_time` | `double` | Combined latency buffer for compute cycle lag and brake actuation (seconds). |
125+
| `crossing_time_limit` | `double` | Maximum duration allowed for the vehicle to clear an amber light intersection (seconds). |
126+
| `stop_overshoot_margin` | `double` | Allowed physical distance buffer beyond a stop line for a stopped vehicle (meters). |
127+
| `allow_if_cannot_stop_distance` | `double` | Distance within which a crossing trajectory is allowed when ego cannot stop before the stop line (meters). |
128+
| `min_lookahead_distance` | `double` | Minimum forward trajectory length to scan for stop lines, even at low ego speed (meters). |
129+
| `stable_duration_threshold_red` | `double` | Required continuous duration for a `RED` state to be confirmed as valid (seconds). |
130+
| `stable_duration_threshold_amber` | `double` | Required continuous duration for an `AMBER` state to be confirmed as valid (seconds). |
131+
| `stable_duration_threshold_unknown` | `double` | Required continuous duration for an `UNKNOWN` state to be confirmed as valid (seconds). |
132+
| `amber_rejection_hysteresis_duration` | `double` | Duration to retain an active amber light state if perception updates drop out (seconds). |
133+
| `ego_stopped_velocity_threshold` | `double` | Velocity threshold beneath which the ego vehicle is considered completely stopped ($m/s$). |
134+
| `treat_amber_light_as_red_light` | `bool` | If true, disables amber passing logic and treats all amber states as strict red signals. |
135+
| `treat_unknown_light_as_red_light` | `bool` | If true, evaluates unclassified or blank signal states as strict red signals. |
136+
| `checked_trajectory_length.deceleration_limit` | `double` | Comfortable stop deceleration limit ($m/s^2$) for computing trajectory checking length. |
137+
| `checked_trajectory_length.jerk_limit` | `double` | Comfortable stop jerk limit ($m/s^3$) for computing trajectory checking length. |

‎common/autoware_traffic_light_compliance_checker/include/autoware/traffic_light_compliance_checker/structs.hpp‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,12 @@ struct Violation
7777
return arc_length_to_cross_point < other.arc_length_to_cross_point;
7878
}
7979
};
80+
using Violations = std::vector<Violation>;
8081

8182
/// @brief result of compliance check
8283
struct ComplianceResult
8384
{
84-
std::vector<Violation> violations;
85+
Violations violations;
8586
};
8687

8788
/// @brief parameters for traffic light signal status tracking
@@ -102,16 +103,20 @@ struct Parameters
102103
bool treat_amber_light_as_red_light;
103104
bool treat_unknown_light_as_red_light;
104105
double stop_overshoot_margin;
105-
double stable_duration_threshold_red;
106-
double stable_duration_threshold_amber;
107-
double stable_duration_threshold_unknown;
108-
double amber_rejection_hysteresis_duration;
106+
double allow_if_cannot_stop_distance;
107+
double min_lookahead_distance;
109108
double ego_stopped_velocity_threshold;
109+
StatusTrackerParameters status_tracker_parameters;
110110
struct CheckedTrajectoryLength
111111
{
112112
double deceleration_limit;
113113
double jerk_limit;
114114
} checked_trajectory_length;
115+
struct AmberRejection
116+
{
117+
double hysteresis_duration;
118+
bool reject_if_stop_detected;
119+
} amber_rejection;
115120
};
116121

117122
} // namespace autoware::traffic_light_compliance_checker

‎common/autoware_traffic_light_compliance_checker/include/autoware/traffic_light_compliance_checker/traffic_light_compliance_checker.hpp‎

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,29 +70,26 @@ class TrafficLightComplianceChecker
7070
[[nodiscard]] std::vector<int64_t> get_force_reject_amber_ids(
7171
const rclcpp::Time & current_time, bool is_ego_stopped) const;
7272

73-
void update_amber_rejection_history(
74-
const ComplianceResult & result, const rclcpp::Time & current_time,
75-
const std::vector<int64_t> & force_reject_amber_ids);
76-
7773
void cleanup_amber_rejection_history(const rclcpp::Time & current_time);
7874

79-
[[nodiscard]] tl::expected<ComplianceResult, std::string> check_with_filtered_signals(
75+
[[nodiscard]] ComplianceResult check_with_filtered_signals(
8076
const Inputs & input,
8177
const autoware_perception_msgs::msg::TrafficLightGroupArray & filtered_signals,
8278
const std::vector<int64_t> & force_reject_amber_ids, const bool check_red_lights,
8379
const bool check_amber_lights) const;
8480

85-
std::vector<Violation> get_red_light_violations(
81+
Violations get_red_light_violations(
8682
const std::vector<StopLineInfo> & red_stop_lines,
8783
const lanelet::BasicLineString2d & trajectory_ls,
8884
const std::optional<lanelet::BasicPoint2d> & stop_point,
8985
const double distance_offset = 0.0) const;
90-
std::vector<Violation> get_amber_light_violations(
86+
Violations get_amber_light_violations(
9187
const std::vector<StopLineInfo> & amber_stop_lines,
9288
const std::vector<autoware_planning_msgs::msg::TrajectoryPoint> & trajectory,
9389
const lanelet::BasicLineString2d & trajectory_ls,
9490
const std::optional<lanelet::BasicPoint2d> & stop_point,
95-
const std::vector<int64_t> & force_reject_amber_ids, const double distance_offset = 0.0) const;
91+
const std::vector<int64_t> & force_reject_amber_ids, const rclcpp::Time & current_time,
92+
const double distance_offset = 0.0) const;
9693

9794
/// @brief return the red and amber stop lines related to the given traffic light groups
9895
[[nodiscard]] std::pair<std::vector<StopLineInfo>, std::vector<StopLineInfo>> get_stop_lines(
@@ -107,13 +104,17 @@ class TrafficLightComplianceChecker
107104

108105
/// @brief return true if ego can safely pass an amber traffic light
109106
[[nodiscard]] bool can_pass_amber_light(
110-
const double distance_to_stop_line, const double current_velocity,
111-
const double current_acceleration, const double time_to_cross_stop_line) const;
107+
const int64_t traffic_light_id, const double distance_to_stop_line,
108+
const double current_velocity, const double current_acceleration,
109+
const double time_to_cross_stop_line) const;
110+
111+
bool is_allow_if_cannot_stop(const double distance_to_cross_point) const;
112112

113113
Parameters params_;
114114
vehicle_info_utils::VehicleInfo vehicle_info_;
115115
std::unique_ptr<TrafficLightStatusTracker> status_tracker_;
116-
std::unordered_map<int64_t, rclcpp::Time> amber_rejection_history_;
116+
mutable std::unordered_map<int64_t, rclcpp::Time> amber_rejection_history_;
117+
std::optional<double> ego_stopping_distance_;
117118
};
118119

119120
} // namespace autoware::traffic_light_compliance_checker

‎common/autoware_traffic_light_compliance_checker/include/autoware/traffic_light_compliance_checker/traffic_light_status_tracker.hpp‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ class TrafficLightStatusTracker
4646
const autoware_perception_msgs::msg::TrafficLightGroupArray & signals,
4747
const rclcpp::Time & current_time, bool is_ego_stopped);
4848

49+
[[nodiscard]] double get_duration(const int64_t traffic_light_id) const
50+
{
51+
const auto it = signal_history_.find(traffic_light_id);
52+
if (it == signal_history_.end()) return 0.0;
53+
return (it->second.last_seen_time - it->second.first_seen_time).seconds();
54+
}
55+
4956
private:
5057
void cleanup_signal_history(const rclcpp::Time & current_time);
5158

0 commit comments

Comments
 (0)