diff --git a/opendbc_repo/opendbc/car/gm/interface.py b/opendbc_repo/opendbc/car/gm/interface.py index 72db19511..b8155bf8d 100755 --- a/opendbc_repo/opendbc/car/gm/interface.py +++ b/opendbc_repo/opendbc/car/gm/interface.py @@ -520,6 +520,10 @@ class CarInterface(CarInterfaceBase): ret.minEnableSpeed = -1. if candidate == CAR.CHEVROLET_BLAZER: ret.minEnableSpeed = 5 * CV.KPH_TO_MS + ret.stoppingDecelRate = 1.2 + ret.vEgoStopping = 0.35 + ret.vEgoStarting = 0.35 + ret.stopAccel = -0.40 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate == CAR.BUICK_BABYENCLAVE: diff --git a/opendbc_repo/opendbc/car/gm/tests/test_gm.py b/opendbc_repo/opendbc/car/gm/tests/test_gm.py index 1fe367ef8..743f14e56 100644 --- a/opendbc_repo/opendbc/car/gm/tests/test_gm.py +++ b/opendbc_repo/opendbc/car/gm/tests/test_gm.py @@ -88,12 +88,15 @@ class TestGMInterface: old_testing_ground = gm_interface.testing_ground gm_interface.testing_ground = SimpleNamespace(use_2=True) + params = Params() + params.put_bool("GMPedalLongitudinal", True) try: car_params = CarInterface.get_params(CAR.CHEVROLET_VOLT_ASCM, fingerprint, [], alpha_long=False, is_release=False, docs=False, starpilot_toggles=_test_starpilot_toggles()) finally: gm_interface.testing_ground = old_testing_ground + params.remove("GMPedalLongitudinal") if pedal_present: assert list(car_params.longitudinalTuning.kpV) == pytest.approx([0.10, 0.072, 0.05, 0.04]) @@ -136,6 +139,22 @@ class TestGMInterface: assert list(car_params.longitudinalTuning.kiBP) == pytest.approx([0.0, 5.0, 15.0, 35.0]) assert list(car_params.longitudinalTuning.kiV) == pytest.approx([0.28, 0.26, 0.20, 0.16]) + def test_blazer_uses_earlier_stronger_low_speed_stop_tune(self): + CarInterface = interfaces[CAR.CHEVROLET_BLAZER] + fingerprint = _empty_fingerprint() + fingerprint[0] = FINGERPRINTS[CAR.CHEVROLET_BLAZER][0].copy() + fingerprint[0][0x2FF] = 8 # SASCM present so alpha-long can enable on this platform + + car_params = CarInterface.get_params(CAR.CHEVROLET_BLAZER, fingerprint, [], alpha_long=True, is_release=False, + docs=False, starpilot_toggles=_test_starpilot_toggles()) + + assert car_params.openpilotLongitudinalControl + assert car_params.minEnableSpeed == pytest.approx(5 * CV.KPH_TO_MS) + assert car_params.stoppingDecelRate == pytest.approx(1.2) + assert car_params.vEgoStopping == pytest.approx(0.35) + assert car_params.vEgoStarting == pytest.approx(0.35) + assert car_params.stopAccel == pytest.approx(-0.40) + def test_volt_gateway_without_accel_pos_uses_brake_pedal_message(self): CarInterface = interfaces[CAR.CHEVROLET_VOLT] fingerprint = _empty_fingerprint() @@ -213,10 +232,12 @@ class TestGMInterface: params = Params() toggles = _test_starpilot_toggles() try: + params.put_bool("GMPedalLongitudinal", True) params.put_bool("RemapCancelToDistance", True) car_params = CarInterface.get_params(CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL, fingerprint, [], alpha_long=False, is_release=False, docs=False, starpilot_toggles=toggles) finally: + params.remove("GMPedalLongitudinal") params.remove("RemapCancelToDistance") assert car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.GM_REMAP_CANCEL_TO_DISTANCE diff --git a/opendbc_repo/opendbc/car/hyundai/carcontroller.py b/opendbc_repo/opendbc/car/hyundai/carcontroller.py index 621d0a0e8..cc294f6f1 100644 --- a/opendbc_repo/opendbc/car/hyundai/carcontroller.py +++ b/opendbc_repo/opendbc/car/hyundai/carcontroller.py @@ -571,7 +571,7 @@ class CarController(CarControllerBase): use_ioniq_6_smoothed_accel = use_ioniq_6_dynamic_long_tuning and CC.actuators.accel >= self._ioniq_6_long_tuning.actual_accel # steering control - preserve_stock_lkas = self.CP.carFingerprint == CAR.HYUNDAI_IONIQ_6 and not self.long_active_ecu + preserve_stock_lkas = bool(self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING) and not self.long_active_ecu can_sends.extend(hyundaicanfd.create_steering_messages(self.packer, self.CP, self.CAN, CC.enabled, apply_steer_req, apply_torque, apply_angle, CS.stock_lfa_msg, diff --git a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py index f1fec6c37..b7c8c1520 100644 --- a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py +++ b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py @@ -132,8 +132,8 @@ def create_steering_messages(packer, CP, CAN, enabled, lat_active, apply_torque, ret = [] if CP.flags & HyundaiFlags.CANFD_LKA_STEERING: lkas_msg = "LKAS_ALT" if CP.flags & HyundaiFlags.CANFD_LKA_STEERING_ALT else "LKAS" - if CP.openpilotLongitudinalControl: - ret.append(packer.make_can_msg("LFA", CAN.ECAN, lfa_values)) + # Keep the direct LFA packet shape aligned across stock-long and OP-long paths. + ret.append(packer.make_can_msg("LFA", CAN.ECAN, lfa_values)) ret.append(packer.make_can_msg(lkas_msg, CAN.ACAN, lkas_values)) else: if CP.flags & HyundaiFlags.CANFD_ANGLE_STEERING: diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index 1edc70705..e324f16d3 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -1386,6 +1386,100 @@ class TestHyundaiFingerprint: assert parser.can_valid assert parser.vl["LFA"]["LKA_ICON"] == 3 + def test_kia_ev6_lfa_helper_preserves_stock_ui_fields_with_stock_long(self): + CP = CarParams.new_message() + CP.carFingerprint = CAR.KIA_EV6 + CP.flags = int(HyundaiFlags.CANFD | HyundaiFlags.CANFD_LKA_STEERING) + CP.openpilotLongitudinalControl = False + + packer = CANPacker(DBC[CP.carFingerprint][Bus.pt]) + can_bus = CanBus(CP) + parser = CANParser(DBC[CP.carFingerprint][Bus.pt], [("LFA", 0)], can_bus.ECAN) + + stock_lfa = { + "CHECKSUM": 1234, + "COUNTER": 42, + "LKA_MODE": 6, + "NEW_SIGNAL_1": 3, + "LKA_WARNING": 1, + "LKA_ICON": 1, + "TORQUE_REQUEST": 17, + "STEER_REQ": 0, + "LFA_BUTTON": 1, + "LKA_ASSIST": 1, + "STEER_MODE": 5, + "NEW_SIGNAL_2": 2, + "NEW_SIGNAL_4": 7, + "HAS_LANE_SAFETY": 1, + "DAMP_FACTOR": 0x77, + } + + msgs = hyundaicanfd.create_steering_messages(packer, CP, can_bus, True, True, 123, 0.0, stock_lfa) + assert [(packer.dbc.addr_to_msg[addr].name, bus) for addr, _, bus in msgs] == [ + ("LFA", can_bus.ECAN), + ("LKAS", can_bus.ACAN), + ] + + lfa_msgs = [msg for msg in msgs if msg[0] == 0x12A] + assert len(lfa_msgs) == 1 + + parser.update([(1, lfa_msgs)]) + + assert parser.can_valid + assert parser.vl["LFA"]["NEW_SIGNAL_1"] == 3 + assert parser.vl["LFA"]["NEW_SIGNAL_2"] == 2 + assert parser.vl["LFA"]["HAS_LANE_SAFETY"] == 1 + assert parser.vl["LFA"]["DAMP_FACTOR"] == 0x77 + assert parser.vl["LFA"]["TORQUE_REQUEST"] == 123 + assert parser.vl["LFA"]["STEER_REQ"] == 1 + assert parser.vl["LFA"]["LKA_ICON"] == 2 + + def test_kia_ev6_lkas_helper_preserves_stock_camera_fields_with_stock_long(self): + CP = CarParams.new_message() + CP.carFingerprint = CAR.KIA_EV6 + CP.flags = int(HyundaiFlags.CANFD | HyundaiFlags.CANFD_LKA_STEERING) + CP.openpilotLongitudinalControl = False + + packer = CANPacker(DBC[CP.carFingerprint][Bus.pt]) + can_bus = CanBus(CP) + parser = CANParser(DBC[CP.carFingerprint][Bus.pt], [("LKAS", 0)], can_bus.ACAN) + + stock_lkas = { + "CHECKSUM": 1234, + "COUNTER": 42, + "LKA_MODE": 6, + "LKA_AVAILABLE": 3, + "LKA_WARNING": 1, + "LKA_ICON": 1, + "FCA_SYSWARN": 1, + "TORQUE_REQUEST": 17, + "STEER_REQ": 0, + "LFA_BUTTON": 1, + "LKA_ASSIST": 1, + "STEER_MODE": 5, + "NEW_SIGNAL_2": 2, + "HAS_LANE_SAFETY": 1, + "DAMP_FACTOR": 0x70, + } + + msgs = hyundaicanfd.create_steering_messages(packer, CP, can_bus, True, True, 123, 0.0, + lkas_base_values=stock_lkas) + lkas_msgs = [msg for msg in msgs if msg[0] == 0x50] + assert len(lkas_msgs) == 1 + + parser.update([(1, lkas_msgs)]) + + assert parser.can_valid + assert parser.vl["LKAS"]["LKA_AVAILABLE"] == 3 + assert parser.vl["LKAS"]["LKA_WARNING"] == 1 + assert parser.vl["LKAS"]["FCA_SYSWARN"] == 1 + assert parser.vl["LKAS"]["LFA_BUTTON"] == 1 + assert parser.vl["LKAS"]["HAS_LANE_SAFETY"] == 1 + assert parser.vl["LKAS"]["DAMP_FACTOR"] == 0x70 + assert parser.vl["LKAS"]["TORQUE_REQUEST"] == 123 + assert parser.vl["LKAS"]["STEER_REQ"] == 1 + assert parser.vl["LKAS"]["LKA_ICON"] == 2 + def test_ioniq_6_lkas_alt_helper_preserves_stock_camera_fields(self): CP = CarParams.new_message() CP.carFingerprint = CAR.HYUNDAI_IONIQ_6 diff --git a/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h b/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h index f589cbf5a..4380f9e09 100644 --- a/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h +++ b/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h @@ -8,11 +8,13 @@ #define HYUNDAI_CANFD_LKA_STEERING_COMMON_TX_MSGS(a_can, e_can) \ HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(e_can) \ + {0x12A, e_can, 16, .check_relay = (e_can) == 0}, /* LFA */ \ {0x50, a_can, 16, .check_relay = (a_can) == 0}, /* LKAS */ \ {0x2A4, a_can, 24, .check_relay = (a_can) == 0}, /* CAM_0x2A4 */ \ #define HYUNDAI_CANFD_LKA_STEERING_ALT_COMMON_TX_MSGS(a_can, e_can) \ HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(e_can) \ + {0x12A, e_can, 16, .check_relay = (e_can) == 0}, /* LFA */ \ {0x110, a_can, 32, .check_relay = (a_can) == 0}, /* LKAS_ALT */ \ {0x362, a_can, 32, .check_relay = (a_can) == 0}, /* CAM_0x362 */ \ @@ -221,8 +223,9 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *msg) { } // steering - const unsigned int steer_addr = (hyundai_canfd_lka_steering && !hyundai_longitudinal) ? hyundai_canfd_get_lka_addr() : 0x12aU; - if (msg->addr == steer_addr) { + const bool stock_lka_steering = hyundai_canfd_lka_steering && !hyundai_longitudinal; + const bool steer_msg = (msg->addr == 0x12aU) || (stock_lka_steering && (msg->addr == hyundai_canfd_get_lka_addr())); + if (steer_msg) { if (hyundai_canfd_angle_steering) { const int lkas_angle_active = (msg->data[9] >> 4U) & 0x3U; const bool steer_angle_req = lkas_angle_active != 1; diff --git a/opendbc_repo/opendbc/safety/tests/test_hyundai_canfd.py b/opendbc_repo/opendbc/safety/tests/test_hyundai_canfd.py index 77d367d0a..1d8f90785 100755 --- a/opendbc_repo/opendbc/safety/tests/test_hyundai_canfd.py +++ b/opendbc_repo/opendbc/safety/tests/test_hyundai_canfd.py @@ -470,7 +470,7 @@ class TestHyundaiCanfdCCNCSupportFrames(common.SafetyTestBase): class TestHyundaiCanfdLKASteeringEV(TestHyundaiCanfdBase): - TX_MSGS = [[0x50, 0], [0x1CF, 1], [0x2A4, 0]] + TX_MSGS = [[0x50, 0], [0x12A, 1], [0x1CF, 1], [0x2A4, 0]] RELAY_MALFUNCTION_ADDRS = {0: (0x50, 0x2a4)} # LKAS, CAM_0x2A4 FWD_BLACKLISTED_ADDRS = {2: [0x50, 0x2a4]} @@ -507,7 +507,7 @@ class TestHyundaiCanfdLKASteeringEV(TestHyundaiCanfdBase): # TODO: Handle ICE and HEV configurations once we see cars that use the new messages class TestHyundaiCanfdLKASteeringAltEV(TestHyundaiCanfdBase): - TX_MSGS = [[0x110, 0], [0x1CF, 1], [0x362, 0]] + TX_MSGS = [[0x110, 0], [0x12A, 1], [0x1CF, 1], [0x362, 0]] RELAY_MALFUNCTION_ADDRS = {0: (0x110, 0x362)} # LKAS_ALT, CAM_0x362 FWD_BLACKLISTED_ADDRS = {2: [0x110, 0x362]} diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index bef9e3e31..69ac8986a 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -495,18 +495,18 @@ IONIQ_6_PHASE_SCALE = 0.10 IONIQ_6_TURN_IN_BOOST_LEFT = 1.64 IONIQ_6_TURN_IN_BOOST_RIGHT = 1.88 IONIQ_6_UNWIND_TAPER_LEFT = 3.18 -IONIQ_6_UNWIND_TAPER_RIGHT = 6.55 +IONIQ_6_UNWIND_TAPER_RIGHT = 8.20 IONIQ_6_FRICTION_MULT = 0.928 IONIQ_6_FRICTION_LAT_RISE = 0.20 IONIQ_6_FRICTION_JERK_RISE = 0.24 IONIQ_6_TURN_IN_THRESHOLD_REDUCTION_LEFT = 0.78 IONIQ_6_TURN_IN_THRESHOLD_REDUCTION_RIGHT = 1.24 IONIQ_6_UNWIND_THRESHOLD_INCREASE_LEFT = 3.90 -IONIQ_6_UNWIND_THRESHOLD_INCREASE_RIGHT = 8.10 +IONIQ_6_UNWIND_THRESHOLD_INCREASE_RIGHT = 10.20 IONIQ_6_TURN_IN_FRICTION_BOOST_LEFT = 0.44 IONIQ_6_TURN_IN_FRICTION_BOOST_RIGHT = 0.78 IONIQ_6_UNWIND_FRICTION_REDUCTION_LEFT = 3.55 -IONIQ_6_UNWIND_FRICTION_REDUCTION_RIGHT = 7.65 +IONIQ_6_UNWIND_FRICTION_REDUCTION_RIGHT = 9.10 IONIQ_6_CENTER_TAPER_MAX = 0.082 IONIQ_6_CENTER_TAPER_LAT = 0.24 IONIQ_6_CENTER_TAPER_LAT_WIDTH = 0.025 @@ -529,7 +529,7 @@ IONIQ_6_DIRECTIONAL_TAPER_LAT_WIDTH = 0.06 IONIQ_6_DIRECTIONAL_TAPER_BASE_LEFT = 0.13 IONIQ_6_DIRECTIONAL_TAPER_BASE_RIGHT = 0.45 IONIQ_6_DIRECTIONAL_TAPER_UNWIND_LEFT = 1.82 -IONIQ_6_DIRECTIONAL_TAPER_UNWIND_RIGHT = 3.28 +IONIQ_6_DIRECTIONAL_TAPER_UNWIND_RIGHT = 4.25 IONIQ_6_DIRECTIONAL_TAPER_FLOOR_LEFT = 0.48 IONIQ_6_DIRECTIONAL_TAPER_FLOOR_RIGHT = 0.52 IONIQ_6_DIRECTIONAL_TAPER_UNWIND_FLOOR_LEFT = 0.10 @@ -552,7 +552,7 @@ IONIQ_6_HEAVY_DIRECTIONAL_TAPER_LAT_WIDTH = 0.12 IONIQ_6_HEAVY_DIRECTIONAL_TAPER_BASE_LEFT = 0.10 IONIQ_6_HEAVY_DIRECTIONAL_TAPER_BASE_RIGHT = 0.17 IONIQ_6_HEAVY_DIRECTIONAL_TAPER_UNWIND_LEFT = 0.62 -IONIQ_6_HEAVY_DIRECTIONAL_TAPER_UNWIND_RIGHT = 0.94 +IONIQ_6_HEAVY_DIRECTIONAL_TAPER_UNWIND_RIGHT = 1.18 IONIQ_6_OUTPUT_TAPER_SPEED = 8.5 IONIQ_6_OUTPUT_TAPER_SPEED_WIDTH = 2.5 IONIQ_6_OUTPUT_CENTER_TAPER_BLEND = 0.90