diff --git a/RELEASES.md b/RELEASES.md index 5b71fc3375..fedff5dbff 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -19,6 +19,7 @@ Version 0.8.15 (2022-07-XX) * Honda Civic 2022 support * Hyundai Tucson 2021 support thanks to bluesforte! * Lexus NX Hybrid 2020 support thanks to AlexandreSato! +* Ram 1500 2019-21 support thanks to realfast! Version 0.8.14 (2022-06-01) ======================== diff --git a/docs/CARS.md b/docs/CARS.md index 0cf384df18..a1e89efe12 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -144,7 +144,7 @@ How We Rate The Cars |Volkswagen|Passat 2015-19[6](#footnotes)|Driver Assistance|||||| |Volkswagen|Polo 2020|Driver Assistance|||||| -# Bronze - 79 cars +# Bronze - 80 cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| |---|---|---|:---:|:---:|:---:|:---:|:---:| @@ -198,6 +198,7 @@ How We Rate The Cars |Lexus|RX Hybrid 2016-19|All|[3](#footnotes)||||| |Mazda|CX-5 2022|All|||||| |Mazda|CX-9 2021|All|||||| +|Ram|1500 2019-21|Adaptive Cruise|||||| |Subaru|Crosstrek 2018-19|EyeSight|||||| |Subaru|Impreza 2017-19|EyeSight|||||| |Subaru|XV 2018-19|EyeSight|||||| diff --git a/panda b/panda index 6c0d0b43c2..fae3ee2e81 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 6c0d0b43c239b89baa83b4a1885d0ce21ab2335e +Subproject commit fae3ee2e8161d34a7c1939503e583db9b85e5402 diff --git a/release/files_common b/release/files_common index b46266fa91..260e37e29a 100644 --- a/release/files_common +++ b/release/files_common @@ -474,6 +474,7 @@ opendbc/can/parser_pyx.pyx opendbc/comma_body.dbc +opendbc/chrysler_ram_dt_generated.dbc opendbc/chrysler_pacifica_2017_hybrid_generated.dbc opendbc/chrysler_pacifica_2017_hybrid_private_fusion.dbc diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 49525646ca..606cb51176 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -1,8 +1,7 @@ -from cereal import car from opendbc.can.packer import CANPacker from selfdrive.car import apply_toyota_steer_torque_limits from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, create_cruise_buttons -from selfdrive.car.chrysler.values import CAR, CarControllerParams +from selfdrive.car.chrysler.values import RAM_CARS, CarControllerParams class CarController: @@ -10,61 +9,51 @@ class CarController: self.CP = CP self.apply_steer_last = 0 self.frame = 0 - self.prev_lkas_frame = -1 - self.hud_count = 0 - self.car_fingerprint = CP.carFingerprint - self.gone_fast_yet = False self.steer_rate_limited = False - self.packer = CANPacker(dbc_name) - - def update(self, CC, CS): - # this seems needed to avoid steering faults and to force the sync with the EPS counter - if self.prev_lkas_frame == CS.lkas_counter: - return car.CarControl.Actuators.new_message(), [] - - actuators = CC.actuators - - # steer torque - new_steer = int(round(actuators.steer * CarControllerParams.STEER_MAX)) - apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, - CS.out.steeringTorqueEps, CarControllerParams) - self.steer_rate_limited = new_steer != apply_steer - - moving_fast = CS.out.vEgo > self.CP.minSteerSpeed # for status message - if CS.out.vEgo > (self.CP.minSteerSpeed - 0.5): # for command high bit - self.gone_fast_yet = True - elif self.car_fingerprint in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE_2019): - if CS.out.vEgo < (self.CP.minSteerSpeed - 3.0): - self.gone_fast_yet = False # < 14.5m/s stock turns off this bit, but fine down to 13.5 - lkas_active = moving_fast and CC.enabled - - if not lkas_active: - apply_steer = 0 + self.hud_count = 0 + self.last_lkas_falling_edge = 0 + self.lkas_active_prev = False - self.apply_steer_last = apply_steer + self.packer = CANPacker(dbc_name) + def update(self, CC, CS, low_speed_alert): can_sends = [] + # EPS faults if LKAS re-enables too quickly + lkas_active = CC.latActive and not low_speed_alert and (self.frame - self.last_lkas_falling_edge > 200) + # *** control msgs *** if CC.cruiseControl.cancel: - can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, cancel=True)) + bus = 2 if self.CP.carFingerprint in RAM_CARS else 0 + can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, bus, cancel=True)) - # LKAS_HEARTBIT is forwarded by Panda so no need to send it here. - # frame is 100Hz (0.01s period) - if self.frame % 25 == 0: # 0.25s period + # HUD alerts + if self.frame % 25 == 0: if CS.lkas_car_model != -1: - can_sends.append(create_lkas_hud(self.packer, CS.out.gearShifter, lkas_active, - CC.hudControl.visualAlert, self.hud_count, CS.lkas_car_model)) + can_sends.append(create_lkas_hud(self.packer, self.CP, lkas_active, CC.hudControl.visualAlert, self.hud_count, CS.lkas_car_model, CS.auto_high_beam)) self.hud_count += 1 - can_sends.append(create_lkas_command(self.packer, int(apply_steer), self.gone_fast_yet, CS.lkas_counter)) + # steering + if self.frame % 2 == 0: + # steer torque + new_steer = int(round(CC.actuators.steer * CarControllerParams.STEER_MAX)) + apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorqueEps, CarControllerParams) + if not lkas_active: + apply_steer = 0 + self.steer_rate_limited = new_steer != apply_steer + self.apply_steer_last = apply_steer + + idx = self.frame // 2 + can_sends.append(create_lkas_command(self.packer, self.CP, int(apply_steer), lkas_active, idx)) self.frame += 1 - self.prev_lkas_frame = CS.lkas_counter + if not lkas_active and self.lkas_active_prev: + self.last_lkas_falling_edge = self.frame + self.lkas_active_prev = lkas_active - new_actuators = actuators.copy() - new_actuators.steer = apply_steer / CarControllerParams.STEER_MAX + new_actuators = CC.actuators.copy() + new_actuators.steer = self.apply_steer_last / CarControllerParams.STEER_MAX return new_actuators, can_sends diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index 61fe1f7ec6..71b7e34623 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -3,21 +3,29 @@ from common.conversions import Conversions as CV from opendbc.can.parser import CANParser from opendbc.can.can_define import CANDefine from selfdrive.car.interfaces import CarStateBase -from selfdrive.car.chrysler.values import DBC, STEER_THRESHOLD +from selfdrive.car.chrysler.values import DBC, STEER_THRESHOLD, RAM_CARS class CarState(CarStateBase): def __init__(self, CP): super().__init__(CP) + self.CP = CP can_define = CANDefine(DBC[CP.carFingerprint]["pt"]) - self.shifter_values = can_define.dv["GEAR"]["PRNDL"] + + self.auto_high_beam = 0 + self.button_counter = 0 + self.lkas_car_model = -1 + + if CP.carFingerprint in RAM_CARS: + self.shifter_values = can_define.dv["Transmission_Status"]["Gear_State"] + else: + self.shifter_values = can_define.dv["GEAR"]["PRNDL"] def update(self, cp, cp_cam): ret = car.CarState.new_message() - self.frame = int(cp.vl["EPS_2"]["COUNTER"]) - + # lock info ret.doorOpen = any([cp.vl["BCM_1"]["DOOR_OPEN_FL"], cp.vl["BCM_1"]["DOOR_OPEN_FR"], cp.vl["BCM_1"]["DOOR_OPEN_RL"], @@ -32,8 +40,15 @@ class CarState(CarStateBase): ret.gas = cp.vl["ECM_5"]["Accelerator_Position"] ret.gasPressed = ret.gas > 1e-5 - ret.espDisabled = (cp.vl["TRACTION_BUTTON"]["TRACTION_OFF"] == 1) - + # car speed + if self.CP.carFingerprint in RAM_CARS: + ret.vEgoRaw = cp.vl["ESP_8"]["Vehicle_Speed"] * CV.KPH_TO_MS + ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(cp.vl["Transmission_Status"]["Gear_State"], None)) + else: + ret.vEgoRaw = (cp.vl["SPEED_1"]["SPEED_LEFT"] + cp.vl["SPEED_1"]["SPEED_RIGHT"]) / 2. + ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(cp.vl["GEAR"]["PRNDL"], None)) + ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) + ret.standstill = not ret.vEgoRaw > 0.001 ret.wheelSpeeds = self.get_wheel_speeds( cp.vl["ESP_6"]["WHEEL_SPEED_FL"], cp.vl["ESP_6"]["WHEEL_SPEED_FR"], @@ -41,55 +56,73 @@ class CarState(CarStateBase): cp.vl["ESP_6"]["WHEEL_SPEED_RR"], unit=1, ) - ret.vEgoRaw = (cp.vl["SPEED_1"]["SPEED_LEFT"] + cp.vl["SPEED_1"]["SPEED_RIGHT"]) / 2. - ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) - ret.standstill = not ret.vEgoRaw > 0.001 + # button presses ret.leftBlinker = cp.vl["STEERING_LEVERS"]["TURN_SIGNALS"] == 1 ret.rightBlinker = cp.vl["STEERING_LEVERS"]["TURN_SIGNALS"] == 2 - ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(cp.vl["GEAR"]["PRNDL"], None)) - - ret.cruiseState.available = cp.vl["DAS_3"]["ACC_AVAILABLE"] == 1 # ACC is white - ret.cruiseState.enabled = cp.vl["DAS_3"]["ACC_ACTIVE"] == 1 # ACC is green - ret.cruiseState.speed = cp.vl["DAS_4"]["ACC_SET_SPEED_KPH"] * CV.KPH_TO_MS - # CRUISE_STATE is a three bit msg, 0 is off, 1 and 2 are Non-ACC mode, 3 and 4 are ACC mode, find if there are other states too - ret.cruiseState.nonAdaptive = cp.vl["DAS_4"]["ACC_STATE"] in (1, 2) - ret.accFaulted = cp.vl["DAS_3"]["ACC_FAULTED"] != 0 + ret.genericToggle = cp.vl["STEERING_LEVERS"]["HIGH_BEAM_PRESSED"] == 1 + # steering wheel ret.steeringAngleDeg = cp.vl["STEERING"]["STEER_ANGLE"] ret.steeringRateDeg = cp.vl["STEERING"]["STEERING_RATE"] ret.steeringTorque = cp.vl["EPS_2"]["COLUMN_TORQUE"] ret.steeringTorqueEps = cp.vl["EPS_2"]["EPS_TORQUE_MOTOR"] ret.steeringPressed = abs(ret.steeringTorque) > STEER_THRESHOLD - steer_state = cp.vl["EPS_2"]["LKAS_STATE"] - ret.steerFaultPermanent = steer_state == 4 or (steer_state == 0 and ret.vEgo > self.CP.minSteerSpeed) - ret.genericToggle = bool(cp.vl["STEERING_LEVERS"]["HIGH_BEAM_PRESSED"]) + # cruise state + cp_cruise = cp_cam if self.CP.carFingerprint in RAM_CARS else cp + + ret.cruiseState.available = cp_cruise.vl["DAS_3"]["ACC_AVAILABLE"] == 1 + ret.cruiseState.enabled = cp_cruise.vl["DAS_3"]["ACC_ACTIVE"] == 1 + ret.cruiseState.speed = cp_cruise.vl["DAS_4"]["ACC_SET_SPEED_KPH"] * CV.KPH_TO_MS + ret.cruiseState.nonAdaptive = cp_cruise.vl["DAS_4"]["ACC_STATE"] in (1, 2) # 1 NormalCCOn and 2 NormalCCSet + ret.cruiseState.standstill = cp_cruise.vl["DAS_3"]["ACC_STANDSTILL"] == 1 + ret.accFaulted = cp_cruise.vl["DAS_3"]["ACC_FAULTED"] != 0 + + if self.CP.carFingerprint in RAM_CARS: + self.auto_high_beam = cp_cam.vl["DAS_6"]['AUTO_HIGH_BEAM_ON'] # Auto High Beam isn't Located in this message on chrysler or jeep currently located in 729 message + ret.steerFaultTemporary = cp.vl["EPS_3"]["DASM_FAULT"] == 1 + else: + steer_state = cp.vl["EPS_2"]["LKAS_STATE"] + ret.steerFaultPermanent = steer_state == 4 or (steer_state == 0 and ret.vEgo > self.CP.minSteerSpeed) + # blindspot sensors if self.CP.enableBsm: ret.leftBlindspot = cp.vl["BSM_1"]["LEFT_STATUS"] == 1 ret.rightBlindspot = cp.vl["BSM_1"]["RIGHT_STATUS"] == 1 - self.lkas_counter = cp_cam.vl["LKAS_COMMAND"]["COUNTER"] self.lkas_car_model = cp_cam.vl["DAS_6"]["CAR_MODEL"] - self.lkas_status_ok = cp_cam.vl["LKAS_HEARTBIT"]["LKAS_STATUS_OK"] self.button_counter = cp.vl["CRUISE_BUTTONS"]["COUNTER"] return ret + @staticmethod + def get_cruise_signals(): + signals = [ + ("ACC_AVAILABLE", "DAS_3"), + ("ACC_ACTIVE", "DAS_3"), + ("ACC_FAULTED", "DAS_3"), + ("ACC_STANDSTILL", "DAS_3"), + ("COUNTER", "DAS_3"), + ("ACC_SET_SPEED_KPH", "DAS_4"), + ("ACC_STATE", "DAS_4"), + ] + checks = [ + ("DAS_3", 50), + ("DAS_4", 50), + ] + return signals, checks + @staticmethod def get_can_parser(CP): signals = [ # sig_name, sig_address - ("PRNDL", "GEAR"), ("DOOR_OPEN_FL", "BCM_1"), ("DOOR_OPEN_FR", "BCM_1"), ("DOOR_OPEN_RL", "BCM_1"), ("DOOR_OPEN_RR", "BCM_1"), ("Brake_Pedal_State", "ESP_1"), ("Accelerator_Position", "ECM_5"), - ("SPEED_LEFT", "SPEED_1"), - ("SPEED_RIGHT", "SPEED_1"), ("WHEEL_SPEED_FL", "ESP_6"), ("WHEEL_SPEED_RR", "ESP_6"), ("WHEEL_SPEED_RL", "ESP_6"), @@ -97,18 +130,12 @@ class CarState(CarStateBase): ("STEER_ANGLE", "STEERING"), ("STEERING_RATE", "STEERING"), ("TURN_SIGNALS", "STEERING_LEVERS"), - ("ACC_AVAILABLE", "DAS_3"), - ("ACC_ACTIVE", "DAS_3"), - ("ACC_FAULTED", "DAS_3"), ("HIGH_BEAM_PRESSED", "STEERING_LEVERS"), - ("ACC_SET_SPEED_KPH", "DAS_4"), - ("ACC_STATE", "DAS_4"), + ("SEATBELT_DRIVER_UNLATCHED", "ORC_1"), + ("COUNTER", "EPS_2",), ("COLUMN_TORQUE", "EPS_2"), ("EPS_TORQUE_MOTOR", "EPS_2"), ("LKAS_STATE", "EPS_2"), - ("COUNTER", "EPS_2",), - ("TRACTION_OFF", "TRACTION_BUTTON"), - ("SEATBELT_DRIVER_UNLATCHED", "ORC_1"), ("COUNTER", "CRUISE_BUTTONS"), ] @@ -116,18 +143,13 @@ class CarState(CarStateBase): # sig_address, frequency ("ESP_1", 50), ("EPS_2", 100), - ("SPEED_1", 100), ("ESP_6", 50), ("STEERING", 100), - ("DAS_3", 50), - ("GEAR", 50), ("ECM_5", 50), ("CRUISE_BUTTONS", 50), - ("DAS_4", 15), ("STEERING_LEVERS", 10), ("ORC_1", 2), ("BCM_1", 1), - ("TRACTION_BUTTON", 1), ] if CP.enableBsm: @@ -137,20 +159,47 @@ class CarState(CarStateBase): ] checks.append(("BSM_1", 2)) + if CP.carFingerprint in RAM_CARS: + signals += [ + ("DASM_FAULT", "EPS_3"), + ("Vehicle_Speed", "ESP_8"), + ("Gear_State", "Transmission_Status"), + ] + checks += [ + ("ESP_8", 50), + ("EPS_3", 50), + ("Transmission_Status", 50), + ] + else: + signals += [ + ("PRNDL", "GEAR"), + ("SPEED_LEFT", "SPEED_1"), + ("SPEED_RIGHT", "SPEED_1"), + ] + checks += [ + ("GEAR", 50), + ("SPEED_1", 100), + ] + signals += CarState.get_cruise_signals()[0] + checks += CarState.get_cruise_signals()[1] + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 0) @staticmethod def get_cam_can_parser(CP): signals = [ - # sig_name, sig_address - ("COUNTER", "LKAS_COMMAND"), + # sig_name, sig_address, default ("CAR_MODEL", "DAS_6"), - ("LKAS_STATUS_OK", "LKAS_HEARTBIT") ] checks = [ - ("LKAS_COMMAND", 100), - ("LKAS_HEARTBIT", 10), ("DAS_6", 4), ] + if CP.carFingerprint in RAM_CARS: + signals += [ + ("AUTO_HIGH_BEAM_ON", "DAS_6"), + ] + signals += CarState.get_cruise_signals()[0] + checks += CarState.get_cruise_signals()[1] + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2) diff --git a/selfdrive/car/chrysler/chryslercan.py b/selfdrive/car/chrysler/chryslercan.py index adcd411d31..e17e5d5b2a 100644 --- a/selfdrive/car/chrysler/chryslercan.py +++ b/selfdrive/car/chrysler/chryslercan.py @@ -1,56 +1,69 @@ from cereal import car -from selfdrive.car import make_can_msg - +from selfdrive.car.chrysler.values import RAM_CARS GearShifter = car.CarState.GearShifter VisualAlert = car.CarControl.HUDControl.VisualAlert -def create_lkas_hud(packer, gear, lkas_active, hud_alert, hud_count, lkas_car_model): - # LKAS_HUD 0x2a6 (678) Controls what lane-keeping icon is displayed. +def create_lkas_hud(packer, CP, lkas_active, hud_alert, hud_count, car_model, auto_high_beam): + # LKAS_HUD - Controls what lane-keeping icon is displayed + + # == Color == + # 0 hidden? + # 1 white + # 2 green + # 3 ldw + + # == Lines == + # 03 white Lines + # 04 grey lines + # 09 left lane close + # 0A right lane close + # 0B left Lane very close + # 0C right Lane very close + # 0D left cross cross + # 0E right lane cross - if hud_alert in (VisualAlert.steerRequired, VisualAlert.ldw): - msg = b'\x00\x00\x00\x03\x00\x00\x00\x00' - return make_can_msg(0x2a6, msg, 0) + # == Alerts == + # 7 Normal + # 6 lane departure place hands on wheel - color = 1 # default values are for park or neutral in 2017 are 0 0, but trying 1 1 for 2019 - lines = 1 - alerts = 0 + color = 2 if lkas_active else 1 + lines = 3 if lkas_active else 0 + alerts = 7 if lkas_active else 0 if hud_count < (1 * 4): # first 3 seconds, 4Hz alerts = 1 - # CAR.PACIFICA_2018_HYBRID and CAR.PACIFICA_2019_HYBRID - # had color = 1 and lines = 1 but trying 2017 hybrid style for now. - if gear in (GearShifter.drive, GearShifter.reverse, GearShifter.low): - if lkas_active: - color = 2 # control active, display green. - lines = 6 - else: - color = 1 # control off, display white. - lines = 1 + + if hud_alert in (VisualAlert.ldw, VisualAlert.steerRequired): + color = 4 + lines = 0 + alerts = 6 values = { - "LKAS_ICON_COLOR": color, # byte 0, last 2 bits - "CAR_MODEL": lkas_car_model, # byte 1 - "LKAS_LANE_LINES": lines, # byte 2, last 4 bits - "LKAS_ALERTS": alerts, # byte 3, last 4 bits - } + "LKAS_ICON_COLOR": color, + "CAR_MODEL": car_model, + "LKAS_LANE_LINES": lines, + "LKAS_ALERTS": alerts, + } + + if CP.carFingerprint in RAM_CARS: + values['AUTO_HIGH_BEAM_ON'] = auto_high_beam - return packer.make_can_msg("DAS_6", 0, values) # 0x2a6 + return packer.make_can_msg("DAS_6", 0, values) -def create_lkas_command(packer, apply_steer, moving_fast, frame): - # LKAS_COMMAND 0x292 (658) Lane-keeping signal to turn the wheel. +def create_lkas_command(packer, CP, apply_steer, lat_active, frame): + # LKAS_COMMAND Lane-keeping signal to turn the wheel + enabled_val = 2 if CP.carFingerprint in RAM_CARS else 1 values = { "STEERING_TORQUE": apply_steer, - "LKAS_CONTROL_BIT": int(moving_fast), - "COUNTER": frame % 0x10, + "LKAS_CONTROL_BIT": enabled_val if lat_active else 0, } - return packer.make_can_msg("LKAS_COMMAND", 0, values) + return packer.make_can_msg("LKAS_COMMAND", 0, values, frame % 0x10) -def create_cruise_buttons(packer, frame, cancel=False): +def create_cruise_buttons(packer, frame, bus, cancel=False): values = { "ACC_Cancel": cancel, - "COUNTER": frame % 0x10, } - return packer.make_can_msg("CRUISE_BUTTONS", 0, values) + return packer.make_can_msg("CRUISE_BUTTONS", bus, values, frame % 0x10) diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 8ebcb6b126..af202cdc46 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 from cereal import car -from selfdrive.car.chrysler.values import CAR +from panda import Panda from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config +from selfdrive.car.chrysler.values import CAR, RAM_CARS from selfdrive.car.interfaces import CarInterfaceBase @@ -10,7 +11,9 @@ class CarInterface(CarInterfaceBase): def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disable_radar=False): ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "chrysler" - ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.chrysler)] + + param = Panda.FLAG_CHRYSLER_RAM_DT if candidate in RAM_CARS else None + ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.chrysler, param)] ret.steerActuatorDelay = 0.1 ret.steerLimitTimer = 0.4 @@ -39,6 +42,15 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.15, 0.30], [0.03, 0.05]] ret.lateralTuning.pid.kf = 0.00006 + # Ram + elif candidate == CAR.RAM_1500: + ret.wheelbase = 3.88 + ret.steerRatio = 16.3 + ret.mass = 2493. + STD_CARGO_KG + ret.maxLateralAccel = 2.4 + ret.minSteerSpeed = 14.5 + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + else: raise ValueError(f"Unsupported car: {candidate}") @@ -64,9 +76,9 @@ class CarInterface(CarInterfaceBase): events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.low]) # Low speed steer alert hysteresis logic - if self.CP.minSteerSpeed > 0. and ret.vEgo < (self.CP.minSteerSpeed + 1.): + if self.CP.minSteerSpeed > 0. and ret.vEgo < (self.CP.minSteerSpeed + 0.5): self.low_speed_alert = True - elif ret.vEgo > (self.CP.minSteerSpeed + 2.): + elif ret.vEgo > (self.CP.minSteerSpeed + 1.): self.low_speed_alert = False if self.low_speed_alert: events.add(car.CarEvent.EventName.belowSteerSpeed) @@ -76,4 +88,4 @@ class CarInterface(CarInterfaceBase): return ret def apply(self, c): - return self.CC.update(c, self.CS) + return self.CC.update(c, self.CS, self.low_speed_alert) diff --git a/selfdrive/car/chrysler/radar_interface.py b/selfdrive/car/chrysler/radar_interface.py index 8882dc2d91..348e3c3632 100755 --- a/selfdrive/car/chrysler/radar_interface.py +++ b/selfdrive/car/chrysler/radar_interface.py @@ -10,6 +10,10 @@ LAST_MSG = max(RADAR_MSGS_C + RADAR_MSGS_D) NUMBER_MSGS = len(RADAR_MSGS_C) + len(RADAR_MSGS_D) def _create_radar_can_parser(car_fingerprint): + dbc = DBC[car_fingerprint]['radar'] + if dbc is None: + return None + msg_n = len(RADAR_MSGS_C) # list of [(signal name, message name or number), (...)] # [('RADAR_STATE', 1024), @@ -46,6 +50,9 @@ class RadarInterface(RadarInterfaceBase): self.trigger_msg = LAST_MSG def update(self, can_strings): + if self.rcp is None: + return super().update(None) + vls = self.rcp.update_strings(can_strings) self.updated_messages.update(vls) @@ -81,4 +88,4 @@ class RadarInterface(RadarInterfaceBase): ret.points = [x for x in self.pts.values() if x.dRel != 0] self.updated_messages.clear() - return ret + return ret \ No newline at end of file diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 5537b383d3..40210e68e6 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -2,19 +2,12 @@ from dataclasses import dataclass from enum import Enum from typing import Dict, List, Optional, Union +from cereal import car from selfdrive.car import dbc_dict from selfdrive.car.docs_definitions import CarInfo, Harness -from cereal import car Ecu = car.CarParams.Ecu -class CarControllerParams: - STEER_MAX = 261 # 262 faults - STEER_DELTA_UP = 3 # 3 is stock. 100 is fine. 200 is too much it seems - STEER_DELTA_DOWN = 3 # no faults on the way down it seems - STEER_ERROR_MAX = 80 - - class CAR: # Chrysler PACIFICA_2017_HYBRID = "CHRYSLER PACIFICA HYBRID 2017" @@ -24,16 +17,28 @@ class CAR: PACIFICA_2020 = "CHRYSLER PACIFICA 2020" # Jeep - JEEP_CHEROKEE = "JEEP GRAND CHEROKEE V6 2018" # includes 2017 Trailhawk - JEEP_CHEROKEE_2019 = "JEEP GRAND CHEROKEE 2019" # includes 2020 Trailhawk + JEEP_CHEROKEE = "JEEP GRAND CHEROKEE V6 2018" # includes 2017 Trailhawk + JEEP_CHEROKEE_2019 = "JEEP GRAND CHEROKEE 2019" # includes 2020 Trailhawk + + # Ram + RAM_1500 = "RAM 1500 5TH GEN" + +class CarControllerParams: + STEER_MAX = 261 # higher than this faults the EPS on Chrysler/Jeep. Ram DT allows more + STEER_DELTA_UP = 3 + STEER_DELTA_DOWN = 3 + STEER_ERROR_MAX = 80 + +STEER_THRESHOLD = 120 + +RAM_CARS = {CAR.RAM_1500, } @dataclass class ChryslerCarInfo(CarInfo): package: str = "Adaptive Cruise" harness: Enum = Harness.fca - CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = { CAR.PACIFICA_2017_HYBRID: ChryslerCarInfo("Chrysler Pacifica Hybrid 2017-18"), CAR.PACIFICA_2018_HYBRID: None, # same platforms @@ -42,6 +47,7 @@ CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = { CAR.PACIFICA_2020: ChryslerCarInfo("Chrysler Pacifica 2019-20"), CAR.JEEP_CHEROKEE: ChryslerCarInfo("Jeep Grand Cherokee 2016-18", video_link="https://www.youtube.com/watch?v=eLR9o2JkuRk"), CAR.JEEP_CHEROKEE_2019: ChryslerCarInfo("Jeep Grand Cherokee 2019-20", video_link="https://www.youtube.com/watch?v=jBe4lWnRSu4"), + CAR.RAM_1500: ChryslerCarInfo("Ram 1500 2019-21"), } # Unique CAN messages: @@ -97,6 +103,11 @@ FINGERPRINTS = { # Jeep Grand Cherokee 2019, including most 2020 models 55: 8, 168: 8, 179: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 341: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 530: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 640: 1, 656: 4, 658: 6, 660: 8, 671: 8, 672: 8, 676: 8, 678: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 785: 8, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 840: 8, 844: 5, 847: 1, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 960: 4, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 976: 8, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1223: 8, 1225: 8, 1227: 8, 1235: 8, 1242: 8, 1250: 8, 1251: 8, 1252: 8, 1254: 8, 1264: 8, 1284: 8, 1536: 8, 1537: 8, 1543: 8, 1545: 8, 1562: 8, 1568: 8, 1570: 8, 1572: 8, 1593: 8, 1856: 8, 1858: 8, 1860: 8, 1863: 8, 1865: 8, 1867: 8, 1875: 8, 1882: 8, 1890: 8, 1891: 8, 1892: 8, 1894: 8, 1896: 8, 1904: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8 }], + CAR.RAM_1500: [ + {35: 8, 37: 8, 39: 8, 41: 8, 43: 8, 47: 8, 49: 8, 53: 8, 55: 8, 113: 8, 119: 2, 121: 8, 123: 7, 125: 6, 127: 8, 129: 8, 131: 8, 133: 8, 135: 8, 137: 8, 139: 8, 141: 8, 145: 8, 147: 8, 149: 7, 153: 8, 155: 8, 157: 8, 163: 8, 164: 8, 166: 8, 167: 8, 169: 8, 171: 8, 173: 5, 177: 3, 179: 8, 181: 8, 213: 3, 221: 8, 232: 8, 250: 8, 278: 8, 289: 5, 293: 3, 295: 8, 296: 8, 297: 4, 298: 8, 299: 8, 305: 8, 307: 8, 311: 8, 315: 8, 317: 8, 319: 8, 323: 8, 333: 8, 334: 8, 341: 8, 343: 8, 345: 8, 347: 8, 409: 6, 421: 8, 448: 6, 456: 4, 464: 8, 489: 8, 491: 8, 502: 8, 503: 8, 505: 8, 507: 5, 516: 7, 517: 7, 524: 8, 526: 6, 557: 8, 560: 8, 584: 8, 601: 8, 605: 8, 607: 8, 609: 8, 611: 8, 613: 8, 623: 8, 631: 8, 633: 8, 634: 8, 635: 8, 637: 8, 641: 8, 643: 8, 645: 2, 649: 8, 650: 8, 651: 8, 656: 4, 657: 8, 659: 5, 663: 8, 664: 8, 673: 8, 676: 8, 679: 8, 685: 8, 687: 8, 689: 5, 706: 8, 709: 8, 710: 8, 711: 8, 720: 6, 752: 2, 754: 8, 773: 8, 788: 3, 792: 8, 808: 8, 818: 8, 819: 8, 822: 8, 823: 8, 825: 2, 838: 2, 840: 8, 848: 8, 856: 4, 860: 6, 862: 8, 875: 2, 897: 8, 906: 8, 910: 8, 926: 3, 929: 8, 930: 8, 931: 8, 932: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 956: 8, 961: 8, 962: 8, 969: 4, 971: 8, 972: 8, 973: 8, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8}, + {35: 8, 37: 8, 39: 8, 43: 8, 47: 8, 49: 8, 53: 8, 55: 8, 113: 8, 119: 2, 121: 8, 123: 7, 125: 6, 127: 8, 129: 8, 131: 8, 133: 8, 135: 8, 137: 8, 139: 8, 141: 8, 145: 8, 147: 8, 149: 7, 153: 8, 155: 8, 157: 8, 163: 8, 164: 8, 166: 8, 167: 8, 169: 8, 171: 8, 173: 5, 177: 3, 179: 8, 181: 8, 213: 3, 221: 8, 232: 8, 250: 8, 276: 8, 277: 8, 278: 8, 289: 5, 293: 3, 295: 8, 296: 8, 297: 4, 299: 8, 301: 8, 302: 8, 305: 8, 307: 8, 311: 8, 317: 8, 319: 8, 323: 8, 327: 8, 333: 8, 334: 8, 341: 8, 343: 8, 345: 8, 347: 8, 421: 8, 448: 6, 456: 4, 457: 8, 464: 8, 489: 8, 491: 8, 502: 8, 503: 8, 507: 5, 516: 7, 517: 7, 524: 8, 526: 6, 557: 8, 560: 8, 584: 8, 601: 8, 605: 8, 607: 8, 609: 8, 613: 8, 623: 8, 631: 8, 633: 8, 634: 8, 635: 8, 637: 8, 641: 8, 643: 8, 645: 2, 649: 8, 650: 8, 651: 8, 656: 4, 657: 8, 663: 8, 673: 8, 676: 8, 679: 8, 685: 8, 687: 8, 689: 5, 706: 8, 709: 8, 710: 8, 711: 8, 720: 6, 738: 8, 752: 2, 754: 8, 773: 8, 792: 8, 808: 8, 812: 8, 813: 8, 814: 8, 818: 8, 819: 8, 821: 8, 822: 8, 823: 8, 825: 2, 838: 2, 840: 8, 847: 1, 848: 8, 856: 4, 860: 6, 862: 8, 874: 2, 876: 8, 897: 8, 906: 8, 910: 8, 926: 3, 929: 8, 930: 8, 931: 8, 932: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 961: 8, 962: 8, 969: 4, 971: 8, 972: 8, 973: 8, 975: 8, 976: 8, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1030: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1098: 8, 1100: 8}, + {35: 8, 37: 8, 39: 8, 43: 8, 47: 8, 49: 8, 53: 8, 55: 8, 113: 8, 119: 2, 121: 8, 123: 7, 125: 6, 127: 8, 129: 8, 131: 8, 133: 8, 135: 8, 137: 8, 139: 8, 141: 8, 145: 8, 147: 8, 149: 7, 153: 8, 155: 8, 157: 8, 163: 8, 164: 8, 166: 8, 167: 8, 169: 8, 171: 8, 173: 5, 177: 3, 179: 8, 181: 8, 213: 3, 221: 8, 232: 8, 250: 8, 289: 5, 293: 3, 295: 8, 296: 8, 297: 4, 299: 8, 301: 8, 302: 8, 305: 8, 307: 8, 311: 8, 317: 8, 319: 8, 323: 8, 334: 8, 337: 8, 343: 8, 347: 8, 409: 6, 421: 8, 448: 6, 456: 4, 464: 8, 489: 8, 491: 8, 502: 8, 503: 8, 507: 5, 516: 7, 517: 7, 524: 8, 526: 6, 557: 8, 560: 8, 584: 8, 601: 8, 605: 8, 607: 8, 609: 8, 613: 8, 623: 8, 631: 8, 633: 8, 634: 8, 635: 8, 637: 8, 641: 8, 643: 8, 645: 2, 649: 8, 650: 8, 651: 8, 656: 4, 657: 8, 659: 5, 663: 8, 664: 8, 673: 8, 676: 8, 679: 8, 685: 8, 687: 8, 689: 5, 706: 8, 709: 8, 710: 8, 711: 8, 720: 6, 752: 2, 754: 8, 773: 8, 788: 3, 792: 8, 808: 8, 812: 8, 813: 8, 814: 8, 818: 8, 819: 8, 821: 8, 822: 8, 825: 2, 838: 2, 840: 8, 847: 1, 848: 8, 856: 4, 860: 6, 862: 8, 876: 8, 897: 8, 906: 8, 910: 8, 926: 3, 929: 8, 930: 8, 931: 8, 932: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 956: 8, 961: 8, 962: 8, 969: 4, 971: 8, 972: 8, 973: 8, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1030: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, + ], } @@ -108,6 +119,5 @@ DBC = { CAR.PACIFICA_2019_HYBRID: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), CAR.JEEP_CHEROKEE: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), CAR.JEEP_CHEROKEE_2019: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), + CAR.RAM_1500: dbc_dict('chrysler_ram_dt_generated', None), } - -STEER_THRESHOLD = 120 diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 19b1a05c23..96eb5f67b9 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -38,6 +38,7 @@ routes = [ TestRoute("378472f830ee7395|2021-05-28--07-38-43", CHRYSLER.PACIFICA_2018_HYBRID), TestRoute("8190c7275a24557b|2020-01-29--08-33-58", CHRYSLER.PACIFICA_2019_HYBRID), TestRoute("3d84727705fecd04|2021-05-25--08-38-56", CHRYSLER.PACIFICA_2020), + TestRoute("221c253375af4ee9|2022-06-15--18-38-24", CHRYSLER.RAM_1500), #TestRoute("f1b4c567731f4a1b|2018-04-30--10-15-35", FORD.FUSION), diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index a2200926c0..be81af2606 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -19,8 +19,9 @@ FORD FOCUS 4TH GEN: [.nan, 1.5, .nan] # No steering wheel COMMA BODY: [.nan, 1000, .nan] -# Totally new car +# Totally new cars KIA EV6 2022: [3.0, 2.5, 0.0] +RAM 1500 5TH GEN: [2.0, 2.0, 0.05] # Dashcam or fallback configured as ideal car mock: [10.0, 10, 0.0] diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 0eeae1e3e3..b0136da88e 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -b904e52e9de4ff7b2bd7f6af8b19abaf4957e6cc \ No newline at end of file +ebe7f1285ec60f522179606d483a198535c0e83a \ No newline at end of file