diff --git a/opendbc_repo/opendbc/car/chrysler/carcontroller.py b/opendbc_repo/opendbc/car/chrysler/carcontroller.py index a616daf9c..e7df5068b 100644 --- a/opendbc_repo/opendbc/car/chrysler/carcontroller.py +++ b/opendbc_repo/opendbc/car/chrysler/carcontroller.py @@ -2,7 +2,7 @@ from opendbc.can import CANPacker from opendbc.car import Bus, DT_CTRL from opendbc.car.lateral import apply_meas_steer_torque_limits from opendbc.car.chrysler import chryslercan -from opendbc.car.chrysler.values import RAM_CARS, RAM_DT, CarControllerParams, ChryslerFlags +from opendbc.car.chrysler.values import RAM_CARS, RAM_DT, CarControllerParams, ChryslerFlags, ChryslerStarPilotFlags from opendbc.car.interfaces import CarControllerBase @@ -50,7 +50,9 @@ class CarController(CarControllerBase): # TODO: can we make this more sane? why is it different for all the cars? lkas_control_bit = self.lkas_control_bit_prev - if self.CP.carFingerprint in RAM_DT: + if self.FPCP is not None and self.FPCP.flags & ChryslerStarPilotFlags.NO_MIN_STEERING_SPEED: + lkas_control_bit = CC.latActive + elif self.CP.carFingerprint in RAM_DT: if self.CP.minEnableSpeed <= CS.out.vEgo <= self.CP.minEnableSpeed + 0.5: lkas_control_bit = True if (self.CP.minEnableSpeed >= 14.5) and (CS.out.gearShifter != 2): diff --git a/opendbc_repo/opendbc/car/chrysler/values.py b/opendbc_repo/opendbc/car/chrysler/values.py index ef04f841c..087f1c342 100644 --- a/opendbc_repo/opendbc/car/chrysler/values.py +++ b/opendbc_repo/opendbc/car/chrysler/values.py @@ -21,6 +21,7 @@ class ChryslerFlags(IntFlag): class ChryslerStarPilotFlags(IntFlag): RAM_HD_ALT_BUTTONS = 1 + NO_MIN_STEERING_SPEED = 2 @dataclass diff --git a/opendbc_repo/opendbc/car/interfaces.py b/opendbc_repo/opendbc/car/interfaces.py index 16ec09e55..6b7b54f89 100644 --- a/opendbc_repo/opendbc/car/interfaces.py +++ b/opendbc_repo/opendbc/car/interfaces.py @@ -134,6 +134,7 @@ class CarInterfaceBase(ABC): dbc_names = {bus: cp.dbc_name for bus, cp in self.can_parsers.items()} self.CC: CarControllerBase = self.CarController(dbc_names, CP) + self.CC.FPCP = FPCP self.FPCP = FPCP @@ -215,6 +216,9 @@ class CarInterfaceBase(ABC): if candidate == CHRYSLER.RAM_HD_5TH_GEN: if 570 not in fingerprint[0]: fp_ret.flags |= ChryslerStarPilotFlags.RAM_HD_ALT_BUTTONS.value + if 0x4FF in fingerprint[0]: + fp_ret.flags |= ChryslerStarPilotFlags.NO_MIN_STEERING_SPEED.value + CP.minSteerSpeed = 0. elif platform in GM: fp_ret.canUsePedal = True @@ -505,6 +509,7 @@ class CarStateBase(ABC): class CarControllerBase(ABC): def __init__(self, dbc_names: dict[StrEnum, str], CP: structs.CarParams): self.CP = CP + self.FPCP: custom.StarPilotCarParams | None = None self.frame = 0 self.secoc_key: bytes = b"00" * 16 diff --git a/opendbc_repo/opendbc/car/tests/test_car_interfaces.py b/opendbc_repo/opendbc/car/tests/test_car_interfaces.py index ad7befd1e..2390cec64 100644 --- a/opendbc_repo/opendbc/car/tests/test_car_interfaces.py +++ b/opendbc_repo/opendbc/car/tests/test_car_interfaces.py @@ -8,9 +8,13 @@ from collections.abc import Callable from typing import Any from cereal import custom -from opendbc.car import DT_CTRL, CanData, structs +from opendbc.can import CANParser +from opendbc.car import Bus, DT_CTRL, CanData, structs from opendbc.car.car_helpers import _apply_disable_openpilot_long, interfaces +from opendbc.car.chrysler.carcontroller import CarController as ChryslerCarController from opendbc.car.chrysler.carstate import CarState as ChryslerCarState +from opendbc.car.chrysler.interface import CarInterface as ChryslerCarInterface +from opendbc.car.chrysler.values import CAR as CHRYSLER_CAR, DBC as CHRYSLER_DBC, ChryslerStarPilotFlags from opendbc.car.fingerprints import FW_VERSIONS from opendbc.car.fw_versions import FW_QUERY_CONFIGS from opendbc.car.hyundai.interface import CarInterface as HyundaiCarInterface @@ -161,6 +165,53 @@ class TestCarInterfaces: "Center_Stack_2": {"LKAS_Button": 1}, }, is_ram=True) + def test_chrysler_wd_mod_enables_steer_to_zero(self): + fingerprint = {bus: {} for bus in range(8)} + fingerprint[0][0x4FF] = 8 + toggles = get_test_starpilot_toggles() + + car_params = ChryslerCarInterface.get_params( + CHRYSLER_CAR.CHRYSLER_PACIFICA_2020, + fingerprint, + [], + alpha_long=False, + is_release=False, + docs=False, + starpilot_toggles=toggles, + ) + assert car_params.minSteerSpeed > 0. + + fp_car_params = ChryslerCarInterface.get_starpilot_params( + CHRYSLER_CAR.CHRYSLER_PACIFICA_2020, + fingerprint, + [], + car_params, + toggles, + ) + assert fp_car_params.flags & ChryslerStarPilotFlags.NO_MIN_STEERING_SPEED + assert car_params.minSteerSpeed == 0. + + controller = ChryslerCarController({Bus.pt: CHRYSLER_DBC[car_params.carFingerprint][Bus.pt]}, car_params) + controller.FPCP = fp_car_params + controller.frame = 202 + + CC = structs.CarControl() + CC.latActive = True + CC.actuators.torque = 0.1 + CC = CC.as_reader() + CS = SimpleNamespace( + out=SimpleNamespace(vEgo=0.0, steeringTorqueEps=0.0, gearShifter=structs.CarState.GearShifter.drive), + lkas_car_model=-1, + button_counter=0, + button_message="CRUISE_BUTTONS", + auto_high_beam=0, + ) + _, can_sends = controller.update(CC, CS, 0, toggles) + + lkas_parser = CANParser(CHRYSLER_DBC[car_params.carFingerprint][Bus.pt], [("LKAS_COMMAND", 50)], 0) + lkas_parser.update([0, can_sends]) + assert lkas_parser.vl["LKAS_COMMAND"]["LKAS_CONTROL_BIT"] == 1 + def test_gm_bolt_gen2_pedal_safety_flags(self): CarInterface = interfaces[GM_CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL]