From e49cfe44b9edd1b608c13f922a22da248d4fc9b5 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Tue, 5 May 2026 10:29:18 -0500 Subject: [PATCH] honda/ipedal --- .../opendbc/car/hyundai/carcontroller.py | 40 ++++++++++----- .../opendbc/car/hyundai/hyundaicanfd.py | 44 +++++++++++++++++ .../opendbc/car/hyundai/tests/test_hyundai.py | 34 +++++++++++-- .../opendbc/car/tesla/carcontroller.py | 2 +- selfdrive/controls/lib/latcontrol_torque.py | 49 +++++++++++++++---- selfdrive/controls/tests/test_latcontrol.py | 29 ++++++++++- 6 files changed, 172 insertions(+), 26 deletions(-) diff --git a/opendbc_repo/opendbc/car/hyundai/carcontroller.py b/opendbc_repo/opendbc/car/hyundai/carcontroller.py index d8108398d..ba6f194c8 100644 --- a/opendbc_repo/opendbc/car/hyundai/carcontroller.py +++ b/opendbc_repo/opendbc/car/hyundai/carcontroller.py @@ -241,6 +241,7 @@ class CarController(CarControllerBase): self._ioniq_6_always_ipedal_press_remaining = 0 self._ioniq_6_always_ipedal_retry_frame = 0 self._ioniq_6_always_ipedal_counter = 0 + self._ioniq_6_always_ipedal_startup_park_done = False self._ioniq_6_last_gear = structs.CarState.GearShifter.unknown self._genesis_g90_long_tuning = GenesisG90LongitudinalTuningState() @@ -249,41 +250,56 @@ class CarController(CarControllerBase): self._ioniq_6_always_ipedal_press_remaining = 0 self._ioniq_6_always_ipedal_retry_frame = 0 + def _arm_ioniq_6_always_ipedal(self) -> None: + self._ioniq_6_always_ipedal_pending = True + self._ioniq_6_always_ipedal_press_remaining = 0 + self._ioniq_6_always_ipedal_retry_frame = self.frame + def _update_ioniq_6_always_ipedal(self, CC, CS, starpilot_toggles): can_sends = [] if self.CP.carFingerprint != CAR.HYUNDAI_IONIQ_6 or not getattr(starpilot_toggles, "always_ipedal", False): self._reset_ioniq_6_always_ipedal() + self._ioniq_6_always_ipedal_startup_park_done = False self._ioniq_6_last_gear = CS.out.gearShifter return can_sends - drive = CS.out.gearShifter == structs.CarState.GearShifter.drive + gear = CS.out.gearShifter + drive = gear == structs.CarState.GearShifter.drive + park = gear == structs.CarState.GearShifter.park drive_edge = drive and self._ioniq_6_last_gear != structs.CarState.GearShifter.drive + startup_park = park and not self._ioniq_6_always_ipedal_startup_park_done + startup_park_edge = startup_park and self._ioniq_6_last_gear != structs.CarState.GearShifter.park + target_gear = drive or startup_park - if drive_edge: - self._ioniq_6_always_ipedal_pending = not CS.ipedal_active - self._ioniq_6_always_ipedal_press_remaining = 0 - self._ioniq_6_always_ipedal_retry_frame = self.frame - elif not drive or CS.ipedal_active: + if gear == structs.CarState.GearShifter.unknown: + self._ioniq_6_always_ipedal_startup_park_done = False + elif not park and not self._ioniq_6_always_ipedal_startup_park_done: + self._ioniq_6_always_ipedal_startup_park_done = True + + if (startup_park_edge or drive_edge) and not CS.ipedal_active: + self._arm_ioniq_6_always_ipedal() + elif not target_gear or CS.ipedal_active: self._reset_ioniq_6_always_ipedal() elif CC.enabled: self._ioniq_6_always_ipedal_pending = False self._ioniq_6_always_ipedal_press_remaining = 0 - if drive and self._ioniq_6_always_ipedal_pending and not CS.ipedal_active and not CC.enabled: + if target_gear and self._ioniq_6_always_ipedal_pending and not CS.ipedal_active and not CC.enabled: if self._ioniq_6_always_ipedal_press_remaining == 0 and self.frame >= self._ioniq_6_always_ipedal_retry_frame: self._ioniq_6_always_ipedal_press_remaining = IONIQ_6_IPEDAL_PRESS_SEND_COUNT - self._ioniq_6_always_ipedal_counter = (int(CS.buttons_counter) + 1) % 0x10 + self._ioniq_6_always_ipedal_counter = hyundaicanfd.get_ioniq_6_cruise_buttons_next_counter(CS.buttons_counter) if self._ioniq_6_always_ipedal_press_remaining > 0 and self.frame % 2 == 0: - can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, self._ioniq_6_always_ipedal_counter, - base_values=CS.cruise_buttons_msg, left_paddle=True)) - self._ioniq_6_always_ipedal_counter = (self._ioniq_6_always_ipedal_counter + 1) % 0x10 + can_sends.append(hyundaicanfd.create_ioniq_6_paddle_buttons(self.packer, self.CP, self.CAN, + self._ioniq_6_always_ipedal_counter, left_paddle=True)) + self._ioniq_6_always_ipedal_counter = hyundaicanfd.get_ioniq_6_cruise_buttons_next_counter( + self._ioniq_6_always_ipedal_counter) self._ioniq_6_always_ipedal_press_remaining -= 1 if self._ioniq_6_always_ipedal_press_remaining == 0: self._ioniq_6_always_ipedal_retry_frame = self.frame + IONIQ_6_IPEDAL_RETRY_WAIT_FRAMES - self._ioniq_6_last_gear = CS.out.gearShifter + self._ioniq_6_last_gear = gear return can_sends def update(self, CC, CS, now_nanos, starpilot_toggles): diff --git a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py index f5c2944f2..348553851 100644 --- a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py +++ b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py @@ -156,6 +156,50 @@ def create_suppress_lfa(packer, CAN, lfa_block_msg, lka_steering_alt): return packer.make_can_msg(suppress_msg, CAN.ACAN, values) +IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX = 15 +IONIQ_6_CRUISE_BUTTONS_BASE_CHECKSUMS = ( + 0x56, 0xEF, 0x39, 0x80, 0x88, + 0x31, 0xE7, 0x5E, 0xF7, 0x4E, + 0x98, 0x21, 0x29, 0x90, 0x46, +) +IONIQ_6_CRUISE_BUTTONS_LEFT_PADDLE_CHECKSUM_XOR = 0x77 +IONIQ_6_CRUISE_BUTTONS_RIGHT_PADDLE_CHECKSUM_XOR = 0xD4 + + +def get_ioniq_6_cruise_buttons_next_counter(counter: int) -> int: + return (int(counter) + 1) % IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX + + +def create_ioniq_6_paddle_buttons(packer, CP, CAN, cnt, left_paddle=False, right_paddle=False): + if left_paddle and right_paddle: + raise ValueError("Ioniq 6 paddle spoof only supports one paddle at a time") + if cnt < 0 or cnt >= IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX: + raise ValueError(f"Invalid Ioniq 6 cruise buttons counter: {cnt}") + + values = { + "COUNTER": cnt, + "SET_ME_1": 1, + "CRUISE_BUTTONS": 0, + "ADAPTIVE_CRUISE_MAIN_BTN": 0, + "NORMAL_CRUISE_MAIN_BTN": 0, + "LDA_BTN": 0, + "LEFT_PADDLE": int(left_paddle), + "RIGHT_PADDLE": int(right_paddle), + } + + address = packer.dbc.name_to_msg["CRUISE_BUTTONS"].address + dat = packer.pack(address, values) + checksum = IONIQ_6_CRUISE_BUTTONS_BASE_CHECKSUMS[cnt] + if left_paddle: + checksum ^= IONIQ_6_CRUISE_BUTTONS_LEFT_PADDLE_CHECKSUM_XOR + if right_paddle: + checksum ^= IONIQ_6_CRUISE_BUTTONS_RIGHT_PADDLE_CHECKSUM_XOR + dat[0] = checksum + + bus = CAN.ECAN if CP.flags & HyundaiFlags.CANFD_LKA_STEERING else CAN.CAM + return address, bytes(dat), bus + + def create_buttons(packer, CP, CAN, cnt, btn=0, base_values=None, left_paddle=False, right_paddle=False): values = {k: v for k, v in base_values.items() if k not in ("_CHECKSUM", "COUNTER")} if base_values else {} values.update({ diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index 363d1b77c..6442d1605 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -321,7 +321,25 @@ class TestHyundaiFingerprint: assert parser.vl["MANUAL_SPEED_LIMIT_ASSIST"]["EV_REGEN_STATE"] == 0x50 assert parser.vl["MANUAL_SPEED_LIMIT_ASSIST"]["EV_REGEN_STATE_2"] == 0x03 - def test_ioniq_6_always_ipedal_spoofs_left_paddle_until_latched(self): + @pytest.mark.parametrize(("counter", "expected_hex"), [ + (0, "2100002800000000"), + (7, "2970002800000000"), + (14, "31e0002800000000"), + ]) + def test_ioniq_6_left_paddle_message_matches_stock(self, counter, expected_hex): + CP = CarParams.new_message() + CP.carFingerprint = CAR.HYUNDAI_IONIQ_6 + CP.flags = int(HyundaiFlags.CANFD | HyundaiFlags.CANFD_LKA_STEERING) + + msg = hyundaicanfd.create_ioniq_6_paddle_buttons(CANPacker(DBC[CP.carFingerprint][Bus.pt]), CP, CanBus(CP), + counter, left_paddle=True) + assert msg[1].hex() == expected_hex + + def test_ioniq_6_buttons_counter_wraps_like_stock(self): + assert hyundaicanfd.get_ioniq_6_cruise_buttons_next_counter(13) == 14 + assert hyundaicanfd.get_ioniq_6_cruise_buttons_next_counter(14) == 0 + + def test_ioniq_6_always_ipedal_spoofs_left_paddle_in_startup_park_and_drive_until_latched(self): toggles = get_test_toggles() toggles.always_ipedal = True CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, gen_empty_fingerprint(), [], True, False, False, toggles) @@ -332,7 +350,7 @@ class TestHyundaiFingerprint: parser = CANParser(DBC[CP.carFingerprint][Bus.pt], [("CRUISE_BUTTONS", 0)], parser_bus) cs = SimpleNamespace( - out=SimpleNamespace(gearShifter=structs.CarState.GearShifter.drive), + out=SimpleNamespace(gearShifter=structs.CarState.GearShifter.park), ipedal_active=False, buttons_counter=5, cruise_buttons_msg={ @@ -349,16 +367,26 @@ class TestHyundaiFingerprint: ) cc = SimpleNamespace(enabled=False) - controller._ioniq_6_last_gear = structs.CarState.GearShifter.reverse sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles) parser.update([(1, sends)]) assert sends + assert sends[0][1].hex() == "9060002800000000" assert parser.vl["CRUISE_BUTTONS"]["LEFT_PADDLE"] == 1 assert parser.vl["CRUISE_BUTTONS"]["COUNTER"] == 6 assert controller._ioniq_6_always_ipedal_pending + assert not controller._ioniq_6_always_ipedal_startup_park_done controller.frame = 2 + cs.out.gearShifter = structs.CarState.GearShifter.drive + sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles) + + assert sends + assert sends[0][1].hex() == "9060002800000000" + assert controller._ioniq_6_always_ipedal_pending + assert controller._ioniq_6_always_ipedal_startup_park_done + + controller.frame = 4 cs.ipedal_active = True sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles) diff --git a/opendbc_repo/opendbc/car/tesla/carcontroller.py b/opendbc_repo/opendbc/car/tesla/carcontroller.py index ad8b1bd07..4e64ab258 100644 --- a/opendbc_repo/opendbc/car/tesla/carcontroller.py +++ b/opendbc_repo/opendbc/car/tesla/carcontroller.py @@ -6,7 +6,7 @@ from opendbc.car.interfaces import CarControllerBase from opendbc.car.tesla.teslacan import TeslaCAN from opendbc.car.tesla.preap.carcontroller import PreAPLongController, init_preap_can from opendbc.car.tesla.preap.stock_cc_spoofer import StockCCSpoofer -from opendbc.car.tesla.values import CAR, CarControllerParams +from opendbc.car.tesla.values import CANBUS, CAR, CarControllerParams from opendbc.car.vehicle_model import VehicleModel diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index d13138d83..77b137315 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -48,7 +48,8 @@ UNWIND_LAT_ACCEL_NEAR_ZERO = 0.3 MIN_LATERAL_CONTROL_SPEED = 0.3 CIVIC_BOSCH_MODIFIED_B_FIXED_FRICTION_THRESHOLD = 0.30 CIVIC_BOSCH_MODIFIED_B_LAT_ACCEL_FACTOR_MULT = 1.20 -CIVIC_BOSCH_MODIFIED_B_VARIANT_LAT_ACCEL_FACTOR_MULT = 1.10 +CIVIC_BOSCH_MODIFIED_A_VARIANT_LAT_ACCEL_FACTOR_MULT = 0.98 +CIVIC_BOSCH_MODIFIED_B_VARIANT_LAT_ACCEL_FACTOR_MULT = 1.14 CIVIC_BOSCH_MODIFIED_B_TRANSITION_SPEED = 12.0 CIVIC_BOSCH_MODIFIED_B_PHASE_SCALE = 0.10 CIVIC_BOSCH_MODIFIED_B_FF_ONSET = 0.18 @@ -65,16 +66,22 @@ CIVIC_BOSCH_MODIFIED_B_TURN_IN_FRICTION_BOOST_LEFT = 0.02 CIVIC_BOSCH_MODIFIED_B_TURN_IN_FRICTION_BOOST_RIGHT = 0.00 CIVIC_BOSCH_MODIFIED_B_UNWIND_FRICTION_REDUCTION_LEFT = 0.26 CIVIC_BOSCH_MODIFIED_B_UNWIND_FRICTION_REDUCTION_RIGHT = 0.40 -CIVIC_BOSCH_MODIFIED_B_VARIANT_FF_REDUCTION_LEFT = 0.10 -CIVIC_BOSCH_MODIFIED_B_VARIANT_FF_REDUCTION_RIGHT = 0.20 -CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_BOOST_LEFT = 0.04 +CIVIC_BOSCH_MODIFIED_A_VARIANT_FF_RESTORE_LEFT = 0.05 +CIVIC_BOSCH_MODIFIED_A_VARIANT_FF_RESTORE_RIGHT = 0.02 +CIVIC_BOSCH_MODIFIED_A_VARIANT_TURN_IN_BOOST_LEFT = 0.04 +CIVIC_BOSCH_MODIFIED_A_VARIANT_TURN_IN_BOOST_RIGHT = 0.01 +CIVIC_BOSCH_MODIFIED_A_VARIANT_TURN_IN_FRICTION_BOOST_LEFT = 0.02 +CIVIC_BOSCH_MODIFIED_A_VARIANT_TURN_IN_FRICTION_BOOST_RIGHT = 0.01 +CIVIC_BOSCH_MODIFIED_B_VARIANT_FF_REDUCTION_LEFT = 0.14 +CIVIC_BOSCH_MODIFIED_B_VARIANT_FF_REDUCTION_RIGHT = 0.22 +CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_BOOST_LEFT = 0.02 CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_BOOST_RIGHT = 0.00 -CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_TAPER_LEFT = 0.28 -CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_TAPER_RIGHT = 0.42 -CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_FRICTION_BOOST_LEFT = 0.02 +CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_TAPER_LEFT = 0.38 +CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_TAPER_RIGHT = 0.48 +CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_FRICTION_BOOST_LEFT = 0.01 CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_FRICTION_BOOST_RIGHT = 0.00 -CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_FRICTION_REDUCTION_LEFT = 0.16 -CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_FRICTION_REDUCTION_RIGHT = 0.28 +CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_FRICTION_REDUCTION_LEFT = 0.24 +CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_FRICTION_REDUCTION_RIGHT = 0.34 BOLT_2022_2023_CARS = ( GM_CAR.CHEVROLET_BOLT_ACC_2022_2023, @@ -359,6 +366,10 @@ def civic_bosch_modified_lateral_testing_ground_active() -> bool: return testing_ground.use("8", "B") +def civic_bosch_modified_a_lateral_testing_ground_active() -> bool: + return testing_ground.use("8", "A") + + def _civic_bosch_modified_b_low_speed_factor(v_ego: float) -> float: return 1.0 / (1.0 + (max(v_ego, 0.0) / CIVIC_BOSCH_MODIFIED_B_TRANSITION_SPEED) ** 2) @@ -386,7 +397,12 @@ def get_civic_bosch_modified_b_ff_scale(desired_lateral_accel: float, desired_la turn_in_weight = max(phase, 0.0) unwind_weight = max(-phase, 0.0) low_speed_factor = _civic_bosch_modified_b_low_speed_factor(v_ego) + a_variant_active = civic_bosch_modified_a_lateral_testing_ground_active() variant_active = civic_bosch_modified_lateral_testing_ground_active() + if a_variant_active: + base_reduction -= (_civic_bosch_modified_b_side_value(desired_lateral_accel, + CIVIC_BOSCH_MODIFIED_A_VARIANT_FF_RESTORE_LEFT, + CIVIC_BOSCH_MODIFIED_A_VARIANT_FF_RESTORE_RIGHT) * onset * cutoff) if variant_active: base_reduction += (_civic_bosch_modified_b_side_value(desired_lateral_accel, CIVIC_BOSCH_MODIFIED_B_VARIANT_FF_REDUCTION_LEFT, @@ -396,6 +412,11 @@ def get_civic_bosch_modified_b_ff_scale(desired_lateral_accel: float, desired_la CIVIC_BOSCH_MODIFIED_B_TURN_IN_BOOST_LEFT, CIVIC_BOSCH_MODIFIED_B_TURN_IN_BOOST_RIGHT) * turn_in_weight * (0.40 + 0.60 * low_speed_factor)) + if a_variant_active: + turn_in_boost *= 1.0 + (_civic_bosch_modified_b_side_value(desired_lateral_accel, + CIVIC_BOSCH_MODIFIED_A_VARIANT_TURN_IN_BOOST_LEFT, + CIVIC_BOSCH_MODIFIED_A_VARIANT_TURN_IN_BOOST_RIGHT) * + turn_in_weight * (0.40 + 0.60 * low_speed_factor)) if variant_active: turn_in_boost *= 1.0 + (_civic_bosch_modified_b_side_value(desired_lateral_accel, CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_BOOST_LEFT, @@ -424,6 +445,7 @@ def get_civic_bosch_modified_b_friction_scale(v_ego: float, desired_lateral_acce phase = _civic_bosch_modified_b_transition_phase(desired_lateral_accel, desired_lateral_jerk) turn_in_weight = max(phase, 0.0) unwind_weight = max(-phase, 0.0) + a_variant_active = civic_bosch_modified_a_lateral_testing_ground_active() variant_active = civic_bosch_modified_lateral_testing_ground_active() friction_scale = 1.0 @@ -431,6 +453,11 @@ def get_civic_bosch_modified_b_friction_scale(v_ego: float, desired_lateral_acce CIVIC_BOSCH_MODIFIED_B_TURN_IN_FRICTION_BOOST_LEFT, CIVIC_BOSCH_MODIFIED_B_TURN_IN_FRICTION_BOOST_RIGHT) * envelope * turn_in_weight) + if a_variant_active: + friction_scale += (_civic_bosch_modified_b_side_value(desired_lateral_accel, + CIVIC_BOSCH_MODIFIED_A_VARIANT_TURN_IN_FRICTION_BOOST_LEFT, + CIVIC_BOSCH_MODIFIED_A_VARIANT_TURN_IN_FRICTION_BOOST_RIGHT) * + envelope * turn_in_weight) if variant_active: friction_scale += (_civic_bosch_modified_b_side_value(desired_lateral_accel, CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_FRICTION_BOOST_LEFT, @@ -1113,6 +1140,8 @@ class LatControlTorque(LatControl): self.torque_params.latAccelFactor *= IONIQ_6_BASE_LAT_ACCEL_FACTOR_MULT if self.is_civic_bosch_modified: self.torque_params.latAccelFactor *= CIVIC_BOSCH_MODIFIED_B_LAT_ACCEL_FACTOR_MULT + if civic_bosch_modified_a_lateral_testing_ground_active(): + self.torque_params.latAccelFactor *= CIVIC_BOSCH_MODIFIED_A_VARIANT_LAT_ACCEL_FACTOR_MULT if civic_bosch_modified_lateral_testing_ground_active(): self.torque_params.latAccelFactor *= CIVIC_BOSCH_MODIFIED_B_VARIANT_LAT_ACCEL_FACTOR_MULT if self.is_bolt: @@ -1130,6 +1159,8 @@ class LatControlTorque(LatControl): latAccelFactor *= IONIQ_6_BASE_LAT_ACCEL_FACTOR_MULT if self.is_civic_bosch_modified: latAccelFactor *= CIVIC_BOSCH_MODIFIED_B_LAT_ACCEL_FACTOR_MULT + if civic_bosch_modified_a_lateral_testing_ground_active(): + latAccelFactor *= CIVIC_BOSCH_MODIFIED_A_VARIANT_LAT_ACCEL_FACTOR_MULT if civic_bosch_modified_lateral_testing_ground_active(): latAccelFactor *= CIVIC_BOSCH_MODIFIED_B_VARIANT_LAT_ACCEL_FACTOR_MULT self.torque_params.latAccelFactor = latAccelFactor diff --git a/selfdrive/controls/tests/test_latcontrol.py b/selfdrive/controls/tests/test_latcontrol.py index 0990e4a11..1735a4915 100644 --- a/selfdrive/controls/tests/test_latcontrol.py +++ b/selfdrive/controls/tests/test_latcontrol.py @@ -429,10 +429,16 @@ class TestLatControl: assert controller.torque_params.latAccelFactor == pytest.approx(3.0 * 1.20) + monkeypatch.setattr(latcontrol_torque, "civic_bosch_modified_a_lateral_testing_ground_active", lambda: True) + a_variant_controller = LatControlTorque(CP.as_reader(), CI, DT_CTRL) + + assert a_variant_controller.torque_params.latAccelFactor == pytest.approx(3.0 * 1.20 * 0.98) + + monkeypatch.setattr(latcontrol_torque, "civic_bosch_modified_a_lateral_testing_ground_active", lambda: False) monkeypatch.setattr(latcontrol_torque, "civic_bosch_modified_lateral_testing_ground_active", lambda: True) variant_controller = LatControlTorque(CP.as_reader(), CI, DT_CTRL) - assert variant_controller.torque_params.latAccelFactor == pytest.approx(3.0 * 1.20 * 1.10) + assert variant_controller.torque_params.latAccelFactor == pytest.approx(3.0 * 1.20 * 1.14) def test_modified_civic_b_torque_ff_scale_curve(self): steady_left = get_civic_bosch_modified_b_ff_scale(0.5, 0.0, 12.0) @@ -479,6 +485,27 @@ class TestLatControl: assert variant_unwind_right < base_unwind_right assert variant_unwind_right_friction < base_unwind_right_friction + def test_modified_civic_a_variant_extra_torque_shaping_curve(self, monkeypatch): + base_steady_left = get_civic_bosch_modified_b_ff_scale(0.5, 0.0, 12.0) + base_steady_right = get_civic_bosch_modified_b_ff_scale(-0.5, 0.0, 12.0) + base_turn_in_left = get_civic_bosch_modified_b_ff_scale(0.5, 0.8, 12.0) + base_turn_in_right = get_civic_bosch_modified_b_ff_scale(-0.5, -0.8, 12.0) + base_turn_in_left_friction = get_civic_bosch_modified_b_friction_scale(12.0, 0.5, 0.8) + + monkeypatch.setattr(latcontrol_torque, "civic_bosch_modified_a_lateral_testing_ground_active", lambda: True) + + a_variant_steady_left = get_civic_bosch_modified_b_ff_scale(0.5, 0.0, 12.0) + a_variant_steady_right = get_civic_bosch_modified_b_ff_scale(-0.5, 0.0, 12.0) + a_variant_turn_in_left = get_civic_bosch_modified_b_ff_scale(0.5, 0.8, 12.0) + a_variant_turn_in_right = get_civic_bosch_modified_b_ff_scale(-0.5, -0.8, 12.0) + a_variant_turn_in_left_friction = get_civic_bosch_modified_b_friction_scale(12.0, 0.5, 0.8) + + assert a_variant_steady_left > base_steady_left + assert a_variant_steady_right > base_steady_right + assert a_variant_turn_in_left > base_turn_in_left + assert a_variant_turn_in_right > base_turn_in_right + assert a_variant_turn_in_left_friction > base_turn_in_left_friction + def test_kia_ev6_testing_ground_update_path(self, monkeypatch): controller, VM, CS, params, starpilot_toggles = self._build_torque_controller(HYUNDAI.KIA_EV6) monkeypatch.setattr(latcontrol_torque, "kia_ev6_lateral_testing_ground_active", lambda: True)