From 05e9dfd5d050eb004b2afe94c12c1e1aed30d241 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Fri, 21 Aug 2026 12:04:11 -0500 Subject: [PATCH] Require matching blinkers for navigation turn desires Cherry-picked Feature Request 1267242 from ab98ae54bbf927eb471405a4e23cf2e109f431e3. Prevent sharp or ordinary navigation turn desires from being issued unless the corresponding turn signal is active, and add regression coverage for missing and opposite signals. Co-Authored-By: Prabhaav Pillai --- selfdrive/controls/lib/desire_helper.py | 4 ++-- .../controls/tests/test_navigation_desires.py | 20 ++++++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/selfdrive/controls/lib/desire_helper.py b/selfdrive/controls/lib/desire_helper.py index 1a9585098..8d1330b49 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/selfdrive/controls/lib/desire_helper.py @@ -224,12 +224,12 @@ class DesireHelper: if desired_lane_width >= starpilot_toggles.lane_detection_width and self._nav_torque_applied(carstate, lane_change_direction): return log.Desire.keepRight elif modifier in ("left", "sharpLeft"): - turn_allowed = not carstate.rightBlinker and not carstate.leftBlindspot + turn_allowed = carstate.leftBlinker and not carstate.rightBlinker and not carstate.leftBlindspot turn_allowed &= carstate.vEgo < starpilot_toggles.minimum_lane_change_speed and not carstate.standstill if turn_allowed and self._nav_turn_is_imminent(carstate, maneuver_distance): return log.Desire.turnLeft elif modifier in ("right", "sharpRight"): - turn_allowed = not carstate.leftBlinker and not carstate.rightBlindspot + turn_allowed = carstate.rightBlinker and not carstate.leftBlinker and not carstate.rightBlindspot turn_allowed &= carstate.vEgo < starpilot_toggles.minimum_lane_change_speed and not carstate.standstill if turn_allowed and self._nav_turn_is_imminent(carstate, maneuver_distance): return log.Desire.turnRight diff --git a/selfdrive/controls/tests/test_navigation_desires.py b/selfdrive/controls/tests/test_navigation_desires.py index cc6a9f3fd..13128651e 100644 --- a/selfdrive/controls/tests/test_navigation_desires.py +++ b/selfdrive/controls/tests/test_navigation_desires.py @@ -71,7 +71,7 @@ def test_nav_desires_turn_right_below_lane_change_speed(): helper._nav_instruction_state = {"valid": True, "maneuverModifier": "right", "maneuverDistance": 10.0} helper.update( - make_car_state(vEgo=5.0), + make_car_state(vEgo=5.0, rightBlinker=True), True, 0.0, make_plan(), @@ -81,6 +81,24 @@ def test_nav_desires_turn_right_below_lane_change_speed(): assert helper.desire == log.Desire.turnRight +def test_nav_desires_turn_requires_matching_blinker(): + for modifier, opposite_blinker in (("left", "rightBlinker"), ("right", "leftBlinker")): + helper = DesireHelper() + helper.nav_desires_allowed = True + helper._update_nav_params = lambda: None + helper._nav_instruction_state = {"valid": True, "maneuverModifier": modifier, "maneuverDistance": 10.0} + + helper.update( + make_car_state(vEgo=5.0, **{opposite_blinker: True}), + True, + 0.0, + make_plan(), + make_toggles(minimum_lane_change_speed=10.0, nav_lane_positioning_allowed=False), + ) + + assert helper.desire == log.Desire.none + + def test_nav_desires_turn_right_waits_until_turn_is_close(): helper = DesireHelper() helper.nav_desires_allowed = True