diff --git a/opendbc_repo/opendbc/car/hyundai/carcontroller.py b/opendbc_repo/opendbc/car/hyundai/carcontroller.py index 97de2af32..6b471682e 100644 --- a/opendbc_repo/opendbc/car/hyundai/carcontroller.py +++ b/opendbc_repo/opendbc/car/hyundai/carcontroller.py @@ -55,6 +55,7 @@ IONIQ_6_STOP_RELEASE_JERK_V = [3.6 * IONIQ_6_RESPONSE_MULTIPLIER, 4.8 * IONIQ_6_RESPONSE_MULTIPLIER] IONIQ_6_IPEDAL_PRESS_SEND_COUNT = 6 IONIQ_6_IPEDAL_LATCH_PRESS_SEND_COUNT = 10 +IONIQ_6_IPEDAL_PADDLE_BURST_COUNT = 3 IONIQ_6_MAX_REGEN_STATE = 0x3C IONIQ_6_MAX_REGEN_STATE_2 = 0x01 IONIQ_6_IPEDAL_REGEN_STATE = 0x50 @@ -319,12 +320,13 @@ class CarController(CarControllerBase): self._ioniq_6_regen_request_sent = False # Mirror the current stock counter after seeing the real CRUISE_BUTTONS frame land on the bus. - # Sending the next counter early creates a paddle frame that gets followed by the stock no-paddle - # frame for that same counter, which matches the "UI changed but drivetrain didn't latch" behavior. + # A single duplicate was enough to move the cluster-facing state, but not enough to reliably beat + # the stock no-paddle frame for the actual drivetrain latch path. if self._ioniq_6_always_ipedal_press_remaining > 0 and buttons_counter_changed and \ 0 <= buttons_counter < hyundaicanfd.IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX: - can_sends.append(hyundaicanfd.create_ioniq_6_paddle_buttons(self.packer, self.CP, self.CAN, - buttons_counter, left_paddle=True)) + paddle_msg = hyundaicanfd.create_ioniq_6_paddle_buttons(self.packer, self.CP, self.CAN, + buttons_counter, left_paddle=True) + can_sends.extend([paddle_msg] * IONIQ_6_IPEDAL_PADDLE_BURST_COUNT) self._ioniq_6_always_ipedal_press_remaining -= 1 if self._ioniq_6_always_ipedal_press_remaining == 0: retry_wait_frames = IONIQ_6_IPEDAL_PROGRESS_RETRY_WAIT_FRAMES if regen_state_changed else IONIQ_6_IPEDAL_RETRY_WAIT_FRAMES diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index 77b62f610..c338ee512 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -8,7 +8,8 @@ from opendbc.car import Bus, ButtonType, gen_empty_fingerprint, structs from opendbc.car.structs import CarControl, CarParams from opendbc.car.fw_versions import build_fw_dict, match_fw_to_car from opendbc.car.hyundai.carcontroller import CarController, Ioniq6LongitudinalTuningState, GenesisG90LongitudinalTuningState, \ - update_ioniq_6_longitudinal_tuning, update_genesis_g90_longitudinal_tuning + IONIQ_6_IPEDAL_PADDLE_BURST_COUNT, update_ioniq_6_longitudinal_tuning, \ + update_genesis_g90_longitudinal_tuning from opendbc.car.hyundai.carstate import CarState, decode_ioniq_6_blindspot_radar_state, decode_ioniq_6_ipedal_intermediate_state, \ decode_ioniq_6_ipedal_state, decode_ioniq_6_max_regen_state from opendbc.car.hyundai.interface import CarInterface @@ -401,6 +402,7 @@ class TestHyundaiFingerprint: parser.update([(1, sends)]) assert sends + assert len([msg for msg in sends if msg[0] == 0x1CF]) == IONIQ_6_IPEDAL_PADDLE_BURST_COUNT assert sends[0][1].hex() == "4650002800000000" assert parser.vl["CRUISE_BUTTONS"]["LEFT_PADDLE"] == 1 assert parser.vl["CRUISE_BUTTONS"]["COUNTER"] == 5 @@ -418,6 +420,7 @@ class TestHyundaiFingerprint: sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles) assert sends + assert len([msg for msg in sends if msg[0] == 0x1CF]) == IONIQ_6_IPEDAL_PADDLE_BURST_COUNT assert sends[0][1].hex() == "9060002800000000" assert controller._ioniq_6_always_ipedal_pending assert controller._ioniq_6_always_ipedal_startup_park_done @@ -527,7 +530,7 @@ class TestHyundaiFingerprint: controller._ioniq_6_last_regen_control_counter = 0x13 sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles) - assert any(msg[0] == 0x1CF for msg in sends) + assert len([msg for msg in sends if msg[0] == 0x1CF]) == IONIQ_6_IPEDAL_PADDLE_BURST_COUNT regen_cmd = next(msg for msg in sends if msg[0] == 0x25A) assert regen_cmd[1][24:28] == bytes.fromhex("c00c1200") checksum = hyundaicanfd.hkg_can_fd_checksum(regen_cmd[0], None, bytearray(regen_cmd[1])) @@ -538,7 +541,7 @@ class TestHyundaiFingerprint: cs.ioniq_6_regen_control_msg = dict(cs.ioniq_6_regen_control_msg, COUNTER=0x15) sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles) - assert any(msg[0] == 0x1CF for msg in sends) + assert len([msg for msg in sends if msg[0] == 0x1CF]) == IONIQ_6_IPEDAL_PADDLE_BURST_COUNT assert not any(msg[0] == 0x25A for msg in sends) def test_ioniq_6_longitudinal_params_match_canfd_tune(self): diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index aa5b96e75..4d56be495 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -49,7 +49,7 @@ 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_A_VARIANT_LAT_ACCEL_FACTOR_MULT = 1.00 -CIVIC_BOSCH_MODIFIED_B_VARIANT_LAT_ACCEL_FACTOR_MULT = 1.18 +CIVIC_BOSCH_MODIFIED_B_VARIANT_LAT_ACCEL_FACTOR_MULT = 1.16 CIVIC_BOSCH_MODIFIED_B_TRANSITION_SPEED = 12.0 CIVIC_BOSCH_MODIFIED_B_PHASE_SCALE = 0.10 CIVIC_BOSCH_MODIFIED_B_FF_ONSET = 0.18 @@ -76,16 +76,16 @@ CIVIC_BOSCH_MODIFIED_A_VARIANT_TURN_IN_FRICTION_BOOST_LEFT = 0.00 CIVIC_BOSCH_MODIFIED_A_VARIANT_TURN_IN_FRICTION_BOOST_RIGHT = 0.00 CIVIC_BOSCH_MODIFIED_A_VARIANT_UNWIND_FRICTION_REDUCTION_LEFT = 0.04 CIVIC_BOSCH_MODIFIED_A_VARIANT_UNWIND_FRICTION_REDUCTION_RIGHT = 0.10 -CIVIC_BOSCH_MODIFIED_B_VARIANT_FF_REDUCTION_LEFT = 0.18 -CIVIC_BOSCH_MODIFIED_B_VARIANT_FF_REDUCTION_RIGHT = 0.28 -CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_BOOST_LEFT = 0.04 -CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_BOOST_RIGHT = 0.02 -CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_TAPER_LEFT = 0.62 -CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_TAPER_RIGHT = 0.78 -CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_FRICTION_BOOST_LEFT = 0.02 -CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_FRICTION_BOOST_RIGHT = 0.01 -CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_FRICTION_REDUCTION_LEFT = 0.40 -CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_FRICTION_REDUCTION_RIGHT = 0.60 +CIVIC_BOSCH_MODIFIED_B_VARIANT_FF_REDUCTION_LEFT = 0.17 +CIVIC_BOSCH_MODIFIED_B_VARIANT_FF_REDUCTION_RIGHT = 0.25 +CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_BOOST_LEFT = 0.06 +CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_BOOST_RIGHT = 0.05 +CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_TAPER_LEFT = 0.68 +CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_TAPER_RIGHT = 0.86 +CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_FRICTION_BOOST_LEFT = 0.03 +CIVIC_BOSCH_MODIFIED_B_VARIANT_TURN_IN_FRICTION_BOOST_RIGHT = 0.03 +CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_FRICTION_REDUCTION_LEFT = 0.46 +CIVIC_BOSCH_MODIFIED_B_VARIANT_UNWIND_FRICTION_REDUCTION_RIGHT = 0.70 BOLT_2022_2023_CARS = ( GM_CAR.CHEVROLET_BOLT_ACC_2022_2023, diff --git a/selfdrive/controls/tests/test_latcontrol.py b/selfdrive/controls/tests/test_latcontrol.py index 85fd31bcb..3a844c047 100644 --- a/selfdrive/controls/tests/test_latcontrol.py +++ b/selfdrive/controls/tests/test_latcontrol.py @@ -438,7 +438,7 @@ class TestLatControl: 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.18) + assert variant_controller.torque_params.latAccelFactor == pytest.approx(3.0 * 1.20 * 1.16) 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) @@ -452,7 +452,7 @@ class TestLatControl: assert steady_right < 1.0 assert steady_right < steady_left assert turn_in_left > steady_left - assert turn_in_right > steady_right + assert turn_in_right >= steady_right assert unwind_left < steady_left assert unwind_right < steady_right @@ -463,27 +463,36 @@ class TestLatControl: unwind_right = get_civic_bosch_modified_b_friction_scale(12.0, -0.5, 0.8) assert turn_in_left > 1.0 - assert turn_in_right > turn_in_left + assert turn_in_right >= 1.0 + assert turn_in_left > turn_in_right assert unwind_left < 1.0 assert unwind_right < unwind_left def test_modified_civic_b_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_right = get_civic_bosch_modified_b_ff_scale(-0.5, -0.8, 12.0) base_unwind_right = get_civic_bosch_modified_b_ff_scale(-0.5, 0.8, 12.0) + base_turn_in_right_friction = get_civic_bosch_modified_b_friction_scale(12.0, -0.5, -0.8) base_unwind_right_friction = get_civic_bosch_modified_b_friction_scale(12.0, -0.5, 0.8) monkeypatch.setattr(latcontrol_torque, "civic_bosch_modified_lateral_testing_ground_active", lambda: True) + variant_steady_left = get_civic_bosch_modified_b_ff_scale(0.5, 0.0, 12.0) variant_steady_right = get_civic_bosch_modified_b_ff_scale(-0.5, 0.0, 12.0) variant_turn_in_right = get_civic_bosch_modified_b_ff_scale(-0.5, -0.8, 12.0) variant_unwind_right = get_civic_bosch_modified_b_ff_scale(-0.5, 0.8, 12.0) + variant_turn_in_left = get_civic_bosch_modified_b_ff_scale(0.5, 0.8, 12.0) variant_unwind_right_friction = get_civic_bosch_modified_b_friction_scale(12.0, -0.5, 0.8) + variant_turn_in_right_friction = get_civic_bosch_modified_b_friction_scale(12.0, -0.5, -0.8) assert variant_steady_right < base_steady_right assert variant_turn_in_right < base_turn_in_right + assert variant_turn_in_right > variant_steady_right + assert variant_turn_in_left > variant_steady_left assert variant_unwind_right < base_unwind_right assert variant_unwind_right_friction < base_unwind_right_friction + assert variant_turn_in_right_friction > base_turn_in_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)