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