Chrysler: Ram 1500 support (#969)

* RamInit

* Some fixes

* ram param

* cleanup steering

* invert

* couple fixups

* tests pass

* check that

* misra fixes

* same limits

* revert that

* remove those

Co-authored-by: Jonathan <jraycec@gmail.com>
Co-authored-by: Shane Smiskol <shane@smiskol.com>
This commit is contained in:
Adeeb Shihadeh
2022-07-06 22:50:29 -07:00
committed by GitHub
parent 6c0d0b43c2
commit fae3ee2e81
5 changed files with 131 additions and 38 deletions

View File

@@ -1,30 +1,77 @@
const int CHRYSLER_MAX_STEER = 261;
const int CHRYSLER_MAX_RT_DELTA = 112; // max delta torque allowed for real time checks
const int CHRYSLER_MAX_RT_DELTA = 112; // max delta torque allowed for real time checks
const uint32_t CHRYSLER_RT_INTERVAL = 250000; // 250ms between real time checks
const int CHRYSLER_MAX_RATE_UP = 3;
const int CHRYSLER_MAX_RATE_DOWN = 3;
const int CHRYSLER_MAX_TORQUE_ERROR = 80; // max torque cmd in excess of torque motor
const int CHRYSLER_STANDSTILL_THRSLD = 10; // about 1m/s
const CanMsg CHRYSLER_TX_MSGS[] = {{571, 0, 3}, {658, 0, 6}, {678, 0, 8}};
const int CHRYSLER_MAX_TORQUE_ERROR = 80; // max torque cmd in excess of torque motor
const int CHRYSLER_STANDSTILL_THRSLD = 10; // about 1m/s
const int CHRYSLER_RAM_STANDSTILL_THRSLD = 3; // about 1m/s changed from wheel rpm to km/h
// CAN messages for Chrysler/Jeep platforms
#define EPS_2 544 // EPS driver input torque
#define ESP_1 320 // Brake pedal and vehicle speed
#define ESP_8 284 // Brake pedal and vehicle speed
#define ECM_5 559 // Throttle position sensor
#define DAS_3 500 // ACC engagement states from DASM
#define DAS_6 678 // LKAS HUD and auto headlight control from DASM
#define LKAS_COMMAND 658 // LKAS controls from DASM
#define CRUISE_BUTTONS 571 // Cruise control buttons
// CAN messages for the 5h gen RAM DT platform
#define EPS_2_RAM 49 // EPS driver input torque
#define ESP_1_RAM 131 // Brake pedal and vehicle speed
#define ESP_8_RAM 121 // Brake pedal and vehicle speed
#define ECM_5_RAM 157 // Throttle position sensor
#define DAS_3_RAM 153 // ACC engagement states from DASM
#define DAS_6_RAM 250 // LKAS HUD and auto headlight control from DASM
#define LKAS_COMMAND_RAM 166 // LKAS controls from DASM
#define CRUISE_BUTTONS_RAM 177 // Cruise control buttons
const CanMsg CHRYSLER_TX_MSGS[] = {
{CRUISE_BUTTONS, 0, 3},
{LKAS_COMMAND, 0, 6},
{DAS_6, 0, 8},
};
const CanMsg CHRYSLER_RAM_TX_MSGS[] = {
{CRUISE_BUTTONS_RAM, 2, 3},
{LKAS_COMMAND_RAM, 0, 8},
{DAS_6_RAM, 0, 8},
};
AddrCheckStruct chrysler_addr_checks[] = {
{.msg = {{544, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U}, { 0 }, { 0 }}},
{.msg = {{EPS_2, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U}, { 0 }, { 0 }}}, // EPS module
{.msg = {{ESP_1, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}}, // brake pressed
//{.msg = {{ESP_8, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}}, // vehicle Speed
{.msg = {{514, 0, 8, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U}, { 0 }, { 0 }}},
{.msg = {{500, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}},
{.msg = {{559, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}},
{.msg = {{320, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}},
{.msg = {{ECM_5, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}}, // gas pedal
{.msg = {{DAS_3, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}}, // cruise state
};
#define CHRYSLER_ADDR_CHECK_LEN (sizeof(chrysler_addr_checks) / sizeof(chrysler_addr_checks[0]))
AddrCheckStruct chrysler_ram_addr_checks[] = {
{.msg = {{EPS_2_RAM, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U}, { 0 }, { 0 }}}, // EPS module
{.msg = {{ESP_1_RAM, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}}, // brake pressed
{.msg = {{ESP_8_RAM, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}}, // vehicle Speed
{.msg = {{ECM_5_RAM, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}}, // gas pedal
{.msg = {{DAS_3_RAM, 2, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}}, // cruise state
};
#define CHRYSLER_RAM_ADDR_CHECK_LEN (sizeof(chrysler_ram_addr_checks) / sizeof(chrysler_ram_addr_checks[0]))
addr_checks chrysler_rx_checks = {chrysler_addr_checks, CHRYSLER_ADDR_CHECK_LEN};
const uint32_t CHRYSLER_PARAM_RAM_DT = 1U; // set for Ram DT platform
bool chrysler_ram = false;
static uint32_t chrysler_get_checksum(CANPacket_t *to_push) {
int checksum_byte = GET_LEN(to_push) - 1U;
return (uint8_t)(GET_BYTE(to_push, checksum_byte));
}
static uint32_t chrysler_compute_checksum(CANPacket_t *to_push) {
/* This function does not want the checksum byte in the input data.
jeep chrysler canbus checksum from http://illmatics.com/Remote%20Car%20Hacking.pdf */
// TODO: clean this up
// http://illmatics.com/Remote%20Car%20Hacking.pdf
uint8_t checksum = 0xFFU;
int len = GET_LEN(to_push);
for (int j = 0; j < (len - 1); j++) {
@@ -56,7 +103,6 @@ static uint32_t chrysler_compute_checksum(CANPacket_t *to_push) {
}
static uint8_t chrysler_get_counter(CANPacket_t *to_push) {
// Well defined counter only for 8 bytes messages
return (uint8_t)(GET_BYTE(to_push, 6) >> 4);
}
@@ -66,19 +112,22 @@ static int chrysler_rx_hook(CANPacket_t *to_push) {
chrysler_get_checksum, chrysler_compute_checksum,
chrysler_get_counter);
if (valid && (GET_BUS(to_push) == 0U)) {
int addr = GET_ADDR(to_push);
const int bus = GET_BUS(to_push);
const int addr = GET_ADDR(to_push);
// Measured eps torque
if (addr == 544) {
if (valid) {
// Measured EPS torque
const int eps_2 = chrysler_ram ? EPS_2_RAM : EPS_2;
if ((bus == 0) && (addr == eps_2)) {
int torque_meas_new = ((GET_BYTE(to_push, 4) & 0x7U) << 8) + GET_BYTE(to_push, 5) - 1024U;
// update array of samples
update_sample(&torque_meas, torque_meas_new);
}
// enter controls on rising edge of ACC, exit controls on ACC off
if (addr == 500) {
const int das_3 = chrysler_ram ? DAS_3_RAM : DAS_3;
const int das_3_bus = chrysler_ram ? 2 : 0;
if ((bus == das_3_bus) && (addr == das_3)) {
int cruise_engaged = GET_BIT(to_push, 21U) == 1U;
if (cruise_engaged && !cruise_engaged_prev) {
controls_allowed = 1;
@@ -89,8 +138,13 @@ static int chrysler_rx_hook(CANPacket_t *to_push) {
cruise_engaged_prev = cruise_engaged;
}
// TODO: use the same message for both
// update speed
if (addr == 514) {
if (chrysler_ram && (bus == 0) && (addr == ESP_8_RAM)) {
vehicle_speed = (((GET_BYTE(to_push, 4) & 0x3U) << 8) + GET_BYTE(to_push, 5))*0.0078125;
vehicle_moving = (int)vehicle_speed > CHRYSLER_RAM_STANDSTILL_THRSLD;
}
if (!chrysler_ram && (bus == 0) && (addr == 514)) {
int speed_l = (GET_BYTE(to_push, 0) << 4) + (GET_BYTE(to_push, 1) >> 4);
int speed_r = (GET_BYTE(to_push, 2) << 4) + (GET_BYTE(to_push, 3) >> 4);
vehicle_speed = (speed_l + speed_r) / 2;
@@ -98,16 +152,19 @@ static int chrysler_rx_hook(CANPacket_t *to_push) {
}
// exit controls on rising edge of gas press
if (addr == 559) {
const int ecm_5 = chrysler_ram ? ECM_5_RAM : ECM_5;
if ((bus == 0) && (addr == ecm_5)) {
gas_pressed = GET_BYTE(to_push, 0U) != 0U;
}
// exit controls on rising edge of brake press
if (addr == 320) {
const int esp_1 = chrysler_ram ? ESP_1_RAM : ESP_1;
if ((bus == 0) && (addr == esp_1)) {
brake_pressed = ((GET_BYTE(to_push, 0U) & 0xFU) >> 2U) == 1U;
}
generic_rx_checks((addr == 0x292));
const int lkas_command = chrysler_ram ? LKAS_COMMAND_RAM : LKAS_COMMAND;
generic_rx_checks((bus == 0) && (addr == lkas_command));
}
return valid;
}
@@ -118,18 +175,23 @@ static int chrysler_tx_hook(CANPacket_t *to_send, bool longitudinal_allowed) {
int tx = 1;
int addr = GET_ADDR(to_send);
if (!msg_allowed(to_send, CHRYSLER_TX_MSGS, sizeof(CHRYSLER_TX_MSGS) / sizeof(CHRYSLER_TX_MSGS[0]))) {
tx = 0;
if (chrysler_ram) {
tx = msg_allowed(to_send, CHRYSLER_RAM_TX_MSGS, sizeof(CHRYSLER_RAM_TX_MSGS) / sizeof(CHRYSLER_RAM_TX_MSGS[0]));
} else {
tx = msg_allowed(to_send, CHRYSLER_TX_MSGS, sizeof(CHRYSLER_TX_MSGS) / sizeof(CHRYSLER_TX_MSGS[0]));
}
// LKA STEER
if (addr == 0x292) {
int desired_torque = ((GET_BYTE(to_send, 0) & 0x7U) << 8) + GET_BYTE(to_send, 1) - 1024U;
// STEERING
const int lkas_addr = chrysler_ram ? LKAS_COMMAND_RAM : LKAS_COMMAND;
if (tx && (addr == lkas_addr)) {
int start_byte = chrysler_ram ? 1 : 0;
int desired_torque = ((GET_BYTE(to_send, start_byte) & 0x7U) << 8) | GET_BYTE(to_send, start_byte + 1);
desired_torque -= 1024;
uint32_t ts = microsecond_timer_get();
bool violation = 0;
if (controls_allowed) {
// *** global torque limit check ***
violation |= max_limit_check(desired_torque, CHRYSLER_MAX_STEER, -CHRYSLER_MAX_STEER);
@@ -169,7 +231,7 @@ static int chrysler_tx_hook(CANPacket_t *to_send, bool longitudinal_allowed) {
}
// FORCE CANCEL: only the cancel button press is allowed
if (addr == 571) {
if ((addr == CRUISE_BUTTONS) || (addr == CRUISE_BUTTONS_RAM)) {
if ((GET_BYTE(to_send, 0) != 1U) || ((GET_BYTE(to_send, 1) & 1U) == 1U)) {
tx = 0;
}
@@ -179,17 +241,18 @@ static int chrysler_tx_hook(CANPacket_t *to_send, bool longitudinal_allowed) {
}
static int chrysler_fwd_hook(int bus_num, CANPacket_t *to_fwd) {
int bus_fwd = -1;
int addr = GET_ADDR(to_fwd);
// forward CAN 0 -> 2 so stock LKAS camera sees messages
// forward to camera
if (bus_num == 0) {
bus_fwd = 2;
}
// forward all messages from camera except LKAS_COMMAND and LKAS_HUD
if ((bus_num == 2) && (addr != 658) && (addr != 678)) {
// forward all messages from camera except LKAS messages
const bool is_lkas = (!chrysler_ram && ((addr == LKAS_COMMAND) || (addr == DAS_6))) ||
(chrysler_ram && ((addr == LKAS_COMMAND_RAM) || (addr == DAS_6_RAM)));
if ((bus_num == 2) && !is_lkas){
bus_fwd = 0;
}
@@ -197,7 +260,14 @@ static int chrysler_fwd_hook(int bus_num, CANPacket_t *to_fwd) {
}
static const addr_checks* chrysler_init(uint16_t param) {
UNUSED(param);
chrysler_ram = GET_FLAG(param, CHRYSLER_PARAM_RAM_DT);
if (chrysler_ram) {
chrysler_rx_checks = (addr_checks){chrysler_ram_addr_checks, CHRYSLER_RAM_ADDR_CHECK_LEN};
} else {
chrysler_rx_checks = (addr_checks){chrysler_addr_checks, CHRYSLER_ADDR_CHECK_LEN};
}
return &chrysler_rx_checks;
}

View File

@@ -198,6 +198,8 @@ class Panda:
FLAG_TESLA_POWERTRAIN = 1
FLAG_TESLA_LONG_CONTROL = 2
FLAG_CHRYSLER_RAM_DT = 1
def __init__(self, serial: Optional[str] = None, claim: bool = True):
self._serial = serial
self._handle = None

View File

@@ -570,7 +570,6 @@ class PandaSafetyTest(PandaSafetyTestBase):
# No point in comparing different Tesla safety modes
if 'Tesla' in attr and 'Tesla' in current_test:
continue
if {attr, current_test}.issubset({'TestToyotaSafety', 'TestToyotaAltBrakeSafety', 'TestToyotaStockLongitudinal'}):
continue

View File

@@ -21,6 +21,8 @@ class TestChryslerSafety(common.PandaSafetyTest, common.MotorTorqueSteeringSafet
RT_INTERVAL = 250000
MAX_TORQUE_ERROR = 80
DAS_BUS = 0
def setUp(self):
self.packer = CANPackerPanda("chrysler_pacifica_2017_hybrid_generated")
self.safety = libpandasafety_py.libpandasafety
@@ -29,11 +31,11 @@ class TestChryslerSafety(common.PandaSafetyTest, common.MotorTorqueSteeringSafet
def _button_msg(self, cancel):
values = {"ACC_Cancel": cancel}
return self.packer.make_can_msg_panda("CRUISE_BUTTONS", 0, values)
return self.packer.make_can_msg_panda("CRUISE_BUTTONS", self.DAS_BUS, values)
def _pcm_status_msg(self, enable):
values = {"ACC_ACTIVE": enable}
return self.packer.make_can_msg_panda("DAS_3", 0, values, counter=True)
return self.packer.make_can_msg_panda("DAS_3", self.DAS_BUS, values, counter=True)
def _speed_msg(self, speed):
values = {"SPEED_LEFT": speed, "SPEED_RIGHT": speed}
@@ -60,5 +62,25 @@ class TestChryslerSafety(common.PandaSafetyTest, common.MotorTorqueSteeringSafet
self.assertEqual(cancel, self._tx(self._button_msg(cancel)))
class TestChryslerRamSafety(TestChryslerSafety):
TX_MSGS = [[177, 2], [166, 0], [250, 0]]
STANDSTILL_THRESHOLD = 3
RELAY_MALFUNCTION_ADDR = 166
FWD_BLACKLISTED_ADDRS = {2: [166, 250]}
DAS_BUS = 2
def setUp(self):
self.packer = CANPackerPanda("chrysler_ram_dt_generated")
self.safety = libpandasafety_py.libpandasafety
self.safety.set_safety_hooks(Panda.SAFETY_CHRYSLER, Panda.FLAG_CHRYSLER_RAM_DT)
self.safety.init_tests()
def _speed_msg(self, speed):
values = {"Vehicle_Speed": speed}
return self.packer.make_can_msg_panda("ESP_8", 0, values, counter=True)
if __name__ == "__main__":
unittest.main()

View File

@@ -83,7 +83,7 @@ if __name__ == "__main__":
logs = r.log_paths()[s.segment_num:s.segment_num+1] if s.segment_num >= 0 else r.log_paths()
lr = MultiLogIterator(logs)
if None in (args.mode, args.param):
if None in (args.mode, args.param, args.alternative_experience):
for msg in lr:
if msg.which() == 'carParams':
if args.mode is None: