diff --git a/selfdrive/controls/lib/latcontrol_vehicle_tunes.py b/selfdrive/controls/lib/latcontrol_vehicle_tunes.py index 2584d3420..f90171fe8 100644 --- a/selfdrive/controls/lib/latcontrol_vehicle_tunes.py +++ b/selfdrive/controls/lib/latcontrol_vehicle_tunes.py @@ -883,7 +883,7 @@ KONA_NON_SCC_TRANSITION_JERK_ONSET = 0.35 KONA_NON_SCC_TRANSITION_JERK_FULL = 1.20 KONA_NON_SCC_TRANSITION_LAT_FADE_START = 0.45 KONA_NON_SCC_TRANSITION_LAT_FADE_END = 1.60 -KONA_NON_SCC_CENTER_TAPER_MAX = 0.14 +KONA_NON_SCC_CENTER_TAPER_MAX = 0.20 KONA_NON_SCC_CENTER_TAPER_LAT = 0.28 KONA_NON_SCC_CENTER_TAPER_SPEED_ONSET = 12.0 KONA_NON_SCC_CENTER_TAPER_SPEED_FULL = 24.0 diff --git a/selfdrive/controls/tests/test_latcontrol.py b/selfdrive/controls/tests/test_latcontrol.py index 8902627f6..96bf53e76 100644 --- a/selfdrive/controls/tests/test_latcontrol.py +++ b/selfdrive/controls/tests/test_latcontrol.py @@ -838,7 +838,7 @@ class TestLatControl: def test_kona_non_scc_center_taper_curve(self): assert get_kona_non_scc_center_taper_scale(0.0, 10.0) == pytest.approx(1.0) - assert get_kona_non_scc_center_taper_scale(0.0, 25.0) == pytest.approx(0.86) + assert get_kona_non_scc_center_taper_scale(0.0, 25.0) == pytest.approx(0.80) assert get_kona_non_scc_center_taper_scale(0.28, 25.0) == pytest.approx(1.0) assert get_kona_non_scc_center_taper_scale(0.10, 25.0) < get_kona_non_scc_center_taper_scale(0.10, 15.0) diff --git a/starpilot/controls/starpilot_card.py b/starpilot/controls/starpilot_card.py index 7ebd93414..4db0a66a4 100644 --- a/starpilot/controls/starpilot_card.py +++ b/starpilot/controls/starpilot_card.py @@ -18,8 +18,6 @@ from openpilot.starpilot.common.favorite_slots import toggle_favorite_slot from openpilot.starpilot.common.starpilot_utilities import is_FrogsGoMoo from openpilot.starpilot.common.starpilot_variables import ERROR_LOGS_PATH, GearShifter, NON_DRIVING_GEARS -HYUNDAI_MAIN_CRUISE_AOL_CONFIRM_TIMEOUT_FRAMES = 100 - class StarPilotCard: @staticmethod @@ -46,9 +44,6 @@ class StarPilotCard: self.CP.brand == "hyundai" and not (hyundai_flags & HyundaiFlags.CANFD) and not hyundai_aol_before_engagement ) self.hyundai_aol_ready = False - self.main_cruise_aol_pending = False - self.main_cruise_aol_pending_frames = 0 - self.prev_cruise_available = None self.prev_active = False self.prev_cruise_enabled = False self.decel_pressed = False @@ -125,13 +120,9 @@ class StarPilotCard: button_event_types = [self._button_type_raw(be) for be in carState.buttonEvents] button_aol_supported = self.CP.brand == "hyundai" or starpilot_toggles.lkas_allowed_for_aol button_managed_aol = starpilot_toggles.always_on_lateral_lkas or (button_aol_supported and starpilot_toggles.main_cruise_aol_toggle) - hyundai_main_cruise_aol_managed = self.CP.brand == "hyundai" and starpilot_toggles.main_cruise_aol_toggle + hyundai_aol_needs_engagement = self.hyundai_aol_needs_engagement and not starpilot_toggles.lkas_allowed_for_aol - if carState.gearShifter in NON_DRIVING_GEARS or not hyundai_main_cruise_aol_managed: - self.main_cruise_aol_pending = False - self.main_cruise_aol_pending_frames = 0 - - if self.hyundai_aol_needs_engagement: + if hyundai_aol_needs_engagement: if carState.gearShifter in NON_DRIVING_GEARS: preserve_reverse_latch = self.hyundai_preserve_aol_across_reverse and carState.gearShifter == GearShifter.reverse if not preserve_reverse_latch: @@ -143,38 +134,19 @@ class StarPilotCard: if button_aol_supported: for be, be_type in zip(carState.buttonEvents, button_event_types, strict=False): if be_type == ButtonType.lkas and be.pressed and starpilot_toggles.always_on_lateral_lkas: - self.main_cruise_aol_pending = False - self.main_cruise_aol_pending_frames = 0 - if self.hyundai_aol_needs_engagement: + if hyundai_aol_needs_engagement: self.hyundai_aol_ready = True self.always_on_lateral_allowed = not self.always_on_lateral_allowed if carState.cruiseState.enabled or self.pause_lateral: self.pause_lateral = not self.always_on_lateral_allowed elif be_type == ButtonType.mainCruise and be.pressed: if starpilot_toggles.main_cruise_aol_toggle: - if self.hyundai_aol_needs_engagement: + if hyundai_aol_needs_engagement: self.hyundai_aol_ready = True - if hyundai_main_cruise_aol_managed: - # Panda permits Hyundai main-button AOL only after the vehicle reports main on. - self.main_cruise_aol_pending = True - self.main_cruise_aol_pending_frames = 0 - else: - self.always_on_lateral_allowed = not self.always_on_lateral_allowed + self.always_on_lateral_allowed = not self.always_on_lateral_allowed elif starpilot_toggles.main_cruise_slc_adopt and starpilot_toggles.speed_limit_controller: self.params_memory.put_bool("SLCAdoptSpeedLimit", True) - cruise_available_changed = self.prev_cruise_available is not None and carState.cruiseState.available != self.prev_cruise_available - if self.main_cruise_aol_pending: - if cruise_available_changed: - self.always_on_lateral_allowed = carState.cruiseState.available - self.main_cruise_aol_pending = False - self.main_cruise_aol_pending_frames = 0 - else: - self.main_cruise_aol_pending_frames += 1 - if self.main_cruise_aol_pending_frames >= HYUNDAI_MAIN_CRUISE_AOL_CONFIRM_TIMEOUT_FRAMES: - self.main_cruise_aol_pending = False - self.main_cruise_aol_pending_frames = 0 - if starpilot_toggles.always_on_lateral_main and not button_managed_aol: car_fingerprint = getattr(self.CP, "carFingerprint", None) pcm_cruise = getattr(self.CP, "pcmCruise", False) @@ -191,19 +163,16 @@ class StarPilotCard: # On rising edge of engagement (SET press enabling lat+long), auto-enable AOL # so that lateral persists when braking disengages longitudinal if sm["selfdriveState"].active and not self.prev_active and self.always_on_lateral_set and starpilot_toggles.always_on_lateral_lkas: - self.main_cruise_aol_pending = False - self.main_cruise_aol_pending_frames = 0 - if self.hyundai_aol_needs_engagement: + if hyundai_aol_needs_engagement: self.hyundai_aol_ready = True self.always_on_lateral_allowed = True self.prev_active = sm["selfdriveState"].active - self.prev_cruise_available = carState.cruiseState.available self.prev_cruise_enabled = carState.cruiseState.enabled self.always_on_lateral_enabled = self.always_on_lateral_allowed and self.always_on_lateral_set self.always_on_lateral_enabled &= carState.gearShifter not in NON_DRIVING_GEARS - self.always_on_lateral_enabled &= not self.hyundai_aol_needs_engagement or self.hyundai_aol_ready + self.always_on_lateral_enabled &= not hyundai_aol_needs_engagement or self.hyundai_aol_ready self.always_on_lateral_enabled &= sm["starpilotPlan"].lateralCheck self.always_on_lateral_enabled &= sm["liveCalibration"].calPerc >= 1 alert_types = sm["selfdriveState"].alertType + sm["starpilotSelfdriveState"].alertType diff --git a/starpilot/controls/tests/test_starpilot_card.py b/starpilot/controls/tests/test_starpilot_card.py index b8048f208..2a8c36860 100644 --- a/starpilot/controls/tests/test_starpilot_card.py +++ b/starpilot/controls/tests/test_starpilot_card.py @@ -1,5 +1,7 @@ from types import SimpleNamespace +import pytest + from opendbc.car.chrysler.values import CAR as CHRYSLER_CAR from openpilot.common.params import ParamKeyType @@ -317,7 +319,7 @@ def test_hyundai_canfd_lkas_button_wrapped_enum_can_toggle_aol(monkeypatch, tmp_ assert ret.alwaysOnLateralEnabled is False -def test_kia_forte_non_scc_main_cruise_button_waits_for_main_confirmation(monkeypatch, tmp_path): +def test_kia_forte_non_scc_main_cruise_button_toggles_aol_immediately(monkeypatch, tmp_path): monkeypatch.setattr(spc, "Params", FakeParams) monkeypatch.setattr(spc, "is_FrogsGoMoo", lambda: False) monkeypatch.setattr(spc, "ERROR_LOGS_PATH", tmp_path) @@ -336,19 +338,18 @@ def test_kia_forte_non_scc_main_cruise_button_waits_for_main_confirmation(monkey sm = make_sm() toggles = make_toggles(always_on_lateral=True, main_cruise_aol_toggle=True) - card.update(make_car_state(), starpilot_car_state, sm, toggles) ret = card.update(car_state, starpilot_car_state, sm, toggles) - assert ret.alwaysOnLateralAllowed is False - assert ret.alwaysOnLateralEnabled is False + assert ret.alwaysOnLateralAllowed is True + assert ret.alwaysOnLateralEnabled is True car_state.buttonEvents = [] - car_state.cruiseState.available = True + car_state.cruiseState.available = False ret = card.update(car_state, starpilot_car_state, sm, toggles) assert ret.alwaysOnLateralAllowed is True assert ret.alwaysOnLateralEnabled is True -def test_genesis_g90_main_cruise_button_waits_for_main_confirmation(monkeypatch, tmp_path): +def test_genesis_g90_main_cruise_button_toggles_aol_immediately(monkeypatch, tmp_path): monkeypatch.setattr(spc, "Params", FakeParams) monkeypatch.setattr(spc, "is_FrogsGoMoo", lambda: False) monkeypatch.setattr(spc, "ERROR_LOGS_PATH", tmp_path) @@ -363,19 +364,45 @@ def test_genesis_g90_main_cruise_button_waits_for_main_confirmation(monkeypatch, sm = make_sm() toggles = make_toggles(always_on_lateral=True, main_cruise_aol_toggle=True) - card.update(make_car_state(), starpilot_car_state, sm, toggles) ret = card.update(car_state, starpilot_car_state, sm, toggles) - assert ret.alwaysOnLateralAllowed is False - assert ret.alwaysOnLateralEnabled is False + assert ret.alwaysOnLateralAllowed is True + assert ret.alwaysOnLateralEnabled is True car_state.buttonEvents = [] - car_state.cruiseState.available = True + car_state.cruiseState.available = False ret = card.update(car_state, starpilot_car_state, sm, toggles) assert ret.alwaysOnLateralAllowed is True assert ret.alwaysOnLateralEnabled is True -def test_hyundai_main_cruise_button_follows_confirmed_main_state(monkeypatch, tmp_path): +@pytest.mark.parametrize("fingerprint", [spc.HYUNDAI_CAR.GENESIS_G70_2020, spc.HYUNDAI_CAR.HYUNDAI_PALISADE]) +def test_legacy_hyundai_main_cruise_button_toggles_aol_immediately(monkeypatch, tmp_path, fingerprint): + monkeypatch.setattr(spc, "Params", FakeParams) + monkeypatch.setattr(spc, "is_FrogsGoMoo", lambda: False) + monkeypatch.setattr(spc, "ERROR_LOGS_PATH", tmp_path) + + card = spc.StarPilotCard( + SimpleNamespace(brand="hyundai", carFingerprint=fingerprint), + SimpleNamespace(alternativeExperience=spc.ALTERNATIVE_EXPERIENCE.ALWAYS_ON_LATERAL), + ) + + car_state = make_car_state(button_events=[SimpleNamespace(type=spc.ButtonType.mainCruise, pressed=True)]) + starpilot_car_state = SimpleNamespace(distancePressed=False) + sm = make_sm() + toggles = make_toggles(always_on_lateral=True, main_cruise_aol_toggle=True) + + card.update(make_car_state(), starpilot_car_state, sm, toggles) + ret = card.update(car_state, starpilot_car_state, sm, toggles) + assert ret.alwaysOnLateralAllowed is True + assert ret.alwaysOnLateralEnabled is True + + car_state.buttonEvents = [SimpleNamespace(type=spc.ButtonType.mainCruise, pressed=True)] + ret = card.update(car_state, starpilot_car_state, sm, toggles) + assert ret.alwaysOnLateralAllowed is False + assert ret.alwaysOnLateralEnabled is False + + +def test_hyundai_main_cruise_button_toggles_aol_immediately(monkeypatch, tmp_path): monkeypatch.setattr(spc, "Params", FakeParams) monkeypatch.setattr(spc, "is_FrogsGoMoo", lambda: False) monkeypatch.setattr(spc, "ERROR_LOGS_PATH", tmp_path) @@ -390,25 +417,14 @@ def test_hyundai_main_cruise_button_follows_confirmed_main_state(monkeypatch, tm sm = make_sm() toggles = make_toggles(always_on_lateral=True, main_cruise_aol_toggle=True) - card.update(make_car_state(), starpilot_car_state, sm, toggles) - ret = card.update(car_state, starpilot_car_state, sm, toggles) - assert ret.alwaysOnLateralAllowed is False - assert ret.alwaysOnLateralEnabled is False - - car_state.buttonEvents = [] - car_state.cruiseState.available = True ret = card.update(car_state, starpilot_car_state, sm, toggles) assert ret.alwaysOnLateralAllowed is True assert ret.alwaysOnLateralEnabled is True car_state.buttonEvents = [SimpleNamespace(type=spc.ButtonType.mainCruise, pressed=True)] ret = card.update(car_state, starpilot_car_state, sm, toggles) - assert ret.alwaysOnLateralAllowed is True - - car_state.buttonEvents = [] - car_state.cruiseState.available = False - ret = card.update(car_state, starpilot_car_state, sm, toggles) assert ret.alwaysOnLateralAllowed is False + assert ret.alwaysOnLateralEnabled is False def test_hyundai_main_cruise_button_wrapped_enum_can_toggle_aol(monkeypatch, tmp_path): @@ -427,17 +443,6 @@ def test_hyundai_main_cruise_button_wrapped_enum_can_toggle_aol(monkeypatch, tmp toggles = make_toggles(always_on_lateral=True, main_cruise_aol_toggle=True) card.update(car_state, starpilot_car_state, sm, toggles) - car_state.buttonEvents = [make_wrapped_button_event(spc.ButtonType.mainCruise, True)] - ret = card.update(car_state, starpilot_car_state, sm, toggles) - assert ret.alwaysOnLateralAllowed is False - assert ret.alwaysOnLateralEnabled is False - - car_state.buttonEvents = [] - car_state.cruiseState.available = True - ret = card.update(car_state, starpilot_car_state, sm, toggles) - assert ret.alwaysOnLateralAllowed is True - assert ret.alwaysOnLateralEnabled is True - car_state.buttonEvents = [make_wrapped_button_event(spc.ButtonType.mainCruise, True)] ret = card.update(car_state, starpilot_car_state, sm, toggles) assert ret.alwaysOnLateralAllowed is True @@ -446,11 +451,16 @@ def test_hyundai_main_cruise_button_wrapped_enum_can_toggle_aol(monkeypatch, tmp car_state.buttonEvents = [] car_state.cruiseState.available = False ret = card.update(car_state, starpilot_car_state, sm, toggles) + assert ret.alwaysOnLateralAllowed is True + assert ret.alwaysOnLateralEnabled is True + + car_state.buttonEvents = [make_wrapped_button_event(spc.ButtonType.mainCruise, True)] + ret = card.update(car_state, starpilot_car_state, sm, toggles) assert ret.alwaysOnLateralAllowed is False assert ret.alwaysOnLateralEnabled is False -def test_hyundai_main_cruise_aol_ignores_unconfirmed_button_press(monkeypatch, tmp_path): +def test_hyundai_lda_platform_main_aol_can_start_before_set(monkeypatch, tmp_path): monkeypatch.setattr(spc, "Params", FakeParams) monkeypatch.setattr(spc, "is_FrogsGoMoo", lambda: False) monkeypatch.setattr(spc, "ERROR_LOGS_PATH", tmp_path) @@ -459,19 +469,14 @@ def test_hyundai_main_cruise_aol_ignores_unconfirmed_button_press(monkeypatch, t SimpleNamespace(brand="hyundai"), SimpleNamespace(alternativeExperience=spc.ALTERNATIVE_EXPERIENCE.ALWAYS_ON_LATERAL), ) - car_state = make_car_state(button_events=[SimpleNamespace(type=spc.ButtonType.mainCruise, pressed=True)]) + car_state = make_car_state(available=True) starpilot_car_state = SimpleNamespace(distancePressed=False) sm = make_sm() - toggles = make_toggles(always_on_lateral=True, main_cruise_aol_toggle=True) + toggles = make_toggles(always_on_lateral=True, always_on_lateral_main=True, lkas_allowed_for_aol=True) ret = card.update(car_state, starpilot_car_state, sm, toggles) - car_state.buttonEvents = [] - for _ in range(spc.HYUNDAI_MAIN_CRUISE_AOL_CONFIRM_TIMEOUT_FRAMES): - ret = card.update(car_state, starpilot_car_state, sm, toggles) - - assert ret.alwaysOnLateralAllowed is False - assert ret.alwaysOnLateralEnabled is False - assert card.main_cruise_aol_pending is False + assert ret.alwaysOnLateralAllowed is True + assert ret.alwaysOnLateralEnabled is True def test_honda_mapped_main_cruise_button_keeps_immediate_toggle(monkeypatch, tmp_path): @@ -490,7 +495,6 @@ def test_honda_mapped_main_cruise_button_keeps_immediate_toggle(monkeypatch, tmp assert ret.alwaysOnLateralAllowed is True assert ret.alwaysOnLateralEnabled is True - assert card.main_cruise_aol_pending is False def test_hyundai_main_cruise_button_adopts_slc_when_assigned_to_slc(monkeypatch, tmp_path):