From e3e4542ef2aac3bfda0b70700f352147b6af5f8c Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Wed, 3 Jun 2026 16:04:14 -0500 Subject: [PATCH] My Collar's Blue & My Neck's Red --- selfdrive/car/card.py | 7 ++++++- selfdrive/car/redneck_cruise.py | 4 ++-- selfdrive/car/tests/test_redneck_cruise.py | 12 ++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/selfdrive/car/card.py b/selfdrive/car/card.py index 04ca316a8..a62a2e6d0 100644 --- a/selfdrive/car/card.py +++ b/selfdrive/car/card.py @@ -398,12 +398,16 @@ class Car: def _get_redneck_target_speed(self, CS: car.CarState) -> float: starpilot_target_speed = 0.0 + allow_plan_decrease = False if self.sm.seen['starpilotPlan'] and self.sm.valid['starpilotPlan']: starpilot_target_speed = float(self.sm['starpilotPlan'].vCruise) plan_speeds = [] if self.sm.seen['longitudinalPlan'] and self.sm.valid['longitudinalPlan']: - plan_speeds = [float(speed) for speed in self.sm['longitudinalPlan'].speeds if math.isfinite(float(speed))] + longitudinal_plan = self.sm['longitudinalPlan'] + plan_speeds = [float(speed) for speed in longitudinal_plan.speeds if math.isfinite(float(speed))] + allow_plan_decrease = bool(longitudinal_plan.hasLead or longitudinal_plan.shouldStop or + str(longitudinal_plan.longitudinalPlanSource) != "cruise") return select_redneck_target_speed( float(getattr(CS, "vCruise", 0.0)), @@ -411,6 +415,7 @@ class Car: starpilot_target_speed, plan_speeds, REDNECK_DECREASE_LOOKAHEAD_POINTS, + allow_plan_decrease=allow_plan_decrease, ) def _advance_redneck_button_feedback_filter(self) -> None: diff --git a/selfdrive/car/redneck_cruise.py b/selfdrive/car/redneck_cruise.py index 52f70c132..f9c33796b 100644 --- a/selfdrive/car/redneck_cruise.py +++ b/selfdrive/car/redneck_cruise.py @@ -25,14 +25,14 @@ CRUISE_BUTTON_TIMERS = { def select_redneck_target_speed(v_cruise_kph: float, speed_cluster_ms: float, starpilot_target_speed_ms: float, plan_speeds_ms: list[float], - lookahead_points: int) -> float: + lookahead_points: int, allow_plan_decrease: bool = True) -> float: target_speed_ms = float(speed_cluster_ms) if v_cruise_kph > 0: target_speed_ms = float(v_cruise_kph) * CV.KPH_TO_MS elif starpilot_target_speed_ms > 0: target_speed_ms = float(starpilot_target_speed_ms) - if len(plan_speeds_ms) > 0: + if allow_plan_decrease and len(plan_speeds_ms) > 0: decrease_target_speed_ms = min(plan_speeds_ms[:lookahead_points]) if decrease_target_speed_ms < min(target_speed_ms, float(speed_cluster_ms)): return decrease_target_speed_ms diff --git a/selfdrive/car/tests/test_redneck_cruise.py b/selfdrive/car/tests/test_redneck_cruise.py index d24596bf6..524d8b6d2 100644 --- a/selfdrive/car/tests/test_redneck_cruise.py +++ b/selfdrive/car/tests/test_redneck_cruise.py @@ -119,6 +119,17 @@ class TestRedneckCruise(unittest.TestCase): ) self.assertAlmostEqual(120.0 * CV.KPH_TO_MS, target_speed) + def test_target_speed_ignores_plan_drift_during_free_cruise(self): + target_speed = select_redneck_target_speed( + 104.4, + 63.0 * CV.MPH_TO_MS, + 0.0, + [62.55 * CV.MPH_TO_MS, 62.44 * CV.MPH_TO_MS, 62.36 * CV.MPH_TO_MS], + 10, + allow_plan_decrease=False, + ) + self.assertAlmostEqual(104.4 * CV.KPH_TO_MS, target_speed) + def test_target_speed_returns_plan_minimum_when_slowing_down(self): target_speed = select_redneck_target_speed( 120.0, @@ -126,6 +137,7 @@ class TestRedneckCruise(unittest.TestCase): 0.0, [74.0 * CV.MPH_TO_MS, 72.0 * CV.MPH_TO_MS, 71.0 * CV.MPH_TO_MS], 10, + allow_plan_decrease=True, ) self.assertAlmostEqual(71.0 * CV.MPH_TO_MS, target_speed)