Skip to content

Commit

Permalink
chrysler longitudinal
Browse files Browse the repository at this point in the history
  • Loading branch information
gregjhogan committed Dec 6, 2023
1 parent fa2b8c0 commit 055b09e
Show file tree
Hide file tree
Showing 4 changed files with 308 additions and 45 deletions.
213 changes: 172 additions & 41 deletions board/safety/safety_chrysler.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,38 @@ const SteeringLimits CHRYSLER_RAM_HD_STEERING_LIMITS = {
.type = TorqueMotorLimited,
};

const LongitudinalLimits CHRYSLER_LONG_LIMITS = {
// acceleration cmd limits (used for brakes)
// Signal: ACC_DECEL
.max_accel = 3685, // 3685 x 0.004885 - 16 = 2.0 m/s^2
.min_accel = 2558, // 2558 x 0.004885 - 16 = -3.5 m/s^2
.inactive_accel = 4094, // 4094 x 0.004885 - 16 = 4.0 m/s^2

// gas cmd limits
// Signal: ENGINE_TORQUE_REQUEST
.max_gas = 4000, // 4000 x .25 - 500 = 500.0 Nm
.min_gas = 0, // 0 x .25 - 500 = -500.0 Nm
.inactive_gas = 2000, // 2000 x .25 - 500 = 0.0 Nm
};

enum {
CHRYSLER_BTN_NONE = 0,
CHRYSLER_BTN_CANCEL = 1,
CHRYSLER_BTN_ACCEL = 4,
CHRYSLER_BTN_DECEL = 8,
CHRYSLER_BTN_RESUME = 16,
};

bool chrysler_longitudinal = false;

typedef struct {
const int EPS_2;
const int ESP_1;
const int ESP_8;
const int ECM_5;
const int DAS_3;
const int DAS_4;
const int DAS_5;
const int DAS_6;
const int LKAS_COMMAND;
const int CRUISE_BUTTONS;
Expand All @@ -45,7 +71,9 @@ const ChryslerAddrs CHRYSLER_ADDRS = {
.ESP_1 = 0x140, // Brake pedal and vehicle speed
.ESP_8 = 0x11C, // Brake pedal and vehicle speed
.ECM_5 = 0x22F, // Throttle position sensor
.DAS_3 = 0x1F4, // ACC engagement states from DASM
.DAS_3 = 0x1F4, // ACC state and control from DASM
.DAS_4 = 0x1F5, // ACC and FCW dispaly and config from DASM
.DAS_5 = 0x271, // ACC and FCW dispaly and config from DASM
.DAS_6 = 0x2A6, // LKAS HUD and auto headlight control from DASM
.LKAS_COMMAND = 0x292, // LKAS controls from DASM
.CRUISE_BUTTONS = 0x23B, // Cruise control buttons
Expand All @@ -57,7 +85,9 @@ const ChryslerAddrs CHRYSLER_RAM_DT_ADDRS = {
.ESP_1 = 0x83, // Brake pedal and vehicle speed
.ESP_8 = 0x79, // Brake pedal and vehicle speed
.ECM_5 = 0x9D, // Throttle position sensor
.DAS_3 = 0x99, // ACC engagement states from DASM
.DAS_3 = 0x99, // ACC state and control from DASM
.DAS_4 = 0xE8, // ACC and FCW dispaly and config from DASM
.DAS_5 = 0xA3, // ACC and FCW dispaly and config from DASM
.DAS_6 = 0xFA, // LKAS HUD and auto headlight control from DASM
.LKAS_COMMAND = 0xA6, // LKAS controls from DASM
.CRUISE_BUTTONS = 0xB1, // Cruise control buttons
Expand All @@ -69,59 +99,108 @@ const ChryslerAddrs CHRYSLER_RAM_HD_ADDRS = {
.ESP_1 = 0x140, // Brake pedal and vehicle speed
.ESP_8 = 0x11C, // Brake pedal and vehicle speed
.ECM_5 = 0x22F, // Throttle position sensor
.DAS_3 = 0x1F4, // ACC engagement states from DASM
.DAS_3 = 0x1F4, // ACC state and control from DASM
.DAS_4 = 0x1F5, // ACC and FCW dispaly and config from DASM
.DAS_5 = 0x271, // ACC and FCW dispaly and config from DASM
.DAS_6 = 0x275, // LKAS HUD and auto headlight control from DASM
.LKAS_COMMAND = 0x276, // LKAS controls from DASM
.CRUISE_BUTTONS = 0x23A, // Cruise control buttons
};

#define CHRYSLER_COMMON_TX_MSGS(addrs, cruise_buttons_bus, lkas_cmd_len) \
{(addrs).CRUISE_BUTTONS, (cruise_buttons_bus), 3}, \
{(addrs).LKAS_COMMAND, 0, (lkas_cmd_len)}, \
{(addrs).DAS_6, 0, 8}, \

#define CHRYSLER_COMMON_LONG_TX_MSGS(addrs) \
{(addrs).DAS_3, 0, 8}, \
{(addrs).DAS_4, 0, 8}, \
{(addrs).DAS_5, 0, 8}, \

const CanMsg CHRYSLER_TX_MSGS[] = {
{CHRYSLER_ADDRS.CRUISE_BUTTONS, 0, 3},
{CHRYSLER_ADDRS.LKAS_COMMAND, 0, 6},
{CHRYSLER_ADDRS.DAS_6, 0, 8},
CHRYSLER_COMMON_TX_MSGS(CHRYSLER_ADDRS, 0, 6)
};

const CanMsg CHRYSLER_LONG_TX_MSGS[] = {
CHRYSLER_COMMON_TX_MSGS(CHRYSLER_ADDRS, 0, 6)
CHRYSLER_COMMON_LONG_TX_MSGS(CHRYSLER_ADDRS)
};

const CanMsg CHRYSLER_RAM_DT_TX_MSGS[] = {
{CHRYSLER_RAM_DT_ADDRS.CRUISE_BUTTONS, 2, 3},
{CHRYSLER_RAM_DT_ADDRS.LKAS_COMMAND, 0, 8},
{CHRYSLER_RAM_DT_ADDRS.DAS_6, 0, 8},
CHRYSLER_COMMON_TX_MSGS(CHRYSLER_RAM_DT_ADDRS, 2, 8)
};

const CanMsg CHRYSLER_RAM_DT_LONG_TX_MSGS[] = {
CHRYSLER_COMMON_TX_MSGS(CHRYSLER_RAM_DT_ADDRS, 2, 8)
CHRYSLER_COMMON_LONG_TX_MSGS(CHRYSLER_RAM_DT_ADDRS)
};

const CanMsg CHRYSLER_RAM_HD_TX_MSGS[] = {
{CHRYSLER_RAM_HD_ADDRS.CRUISE_BUTTONS, 2, 3},
{CHRYSLER_RAM_HD_ADDRS.LKAS_COMMAND, 0, 8},
{CHRYSLER_RAM_HD_ADDRS.DAS_6, 0, 8},
CHRYSLER_COMMON_TX_MSGS(CHRYSLER_RAM_HD_ADDRS, 2, 8)
};

const CanMsg CHRYSLER_RAM_HD_LONG_TX_MSGS[] = {
CHRYSLER_COMMON_TX_MSGS(CHRYSLER_RAM_HD_ADDRS, 2, 8)
CHRYSLER_COMMON_LONG_TX_MSGS(CHRYSLER_RAM_HD_ADDRS)
};

#define CHRYSLER_COMMON_RX_CHECKS(addrs) \
{.msg = {{(addrs).EPS_2, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 100U}, { 0 }, { 0 }}}, \
{.msg = {{(addrs).ESP_1, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, \
{.msg = {{(addrs).ECM_5, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, \

// TODO: use the same message for both (see vehicle_moving below)
#define CHRYSLER_COMMON_ALT_RX_CHECKS() \
{.msg = {{514, 0, 8, .check_checksum = false, .max_counter = 0U, .frequency = 100U}, { 0 }, { 0 }}}, \

#define CHRYSLER_COMMON_RAM_RX_CHECKS(addrs) \
{.msg = {{(addrs).ESP_8, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, \

#define CHRYSLER_COMMON_ACC_RX_CHECKS(addrs, das_3_bus) \
{.msg = {{(addrs).DAS_3, (das_3_bus), 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, \

#define CHRYSLER_COMMON_BUTTONS_RX_CHECKS(addrs) \
{.msg = {{(addrs).CRUISE_BUTTONS, 0, 3, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, \

RxCheck chrysler_rx_checks[] = {
{.msg = {{CHRYSLER_ADDRS.EPS_2, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 100U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_ADDRS.ESP_1, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
//{.msg = {{ESP_8, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}}},
{.msg = {{514, 0, 8, .check_checksum = false, .max_counter = 0U, .frequency = 100U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_ADDRS.ECM_5, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_ADDRS.DAS_3, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
CHRYSLER_COMMON_RX_CHECKS(CHRYSLER_ADDRS)
CHRYSLER_COMMON_ALT_RX_CHECKS()
CHRYSLER_COMMON_ACC_RX_CHECKS(CHRYSLER_ADDRS, 0)
};

RxCheck chrysler_long_rx_checks[] = {
CHRYSLER_COMMON_RX_CHECKS(CHRYSLER_ADDRS)
CHRYSLER_COMMON_ALT_RX_CHECKS()
CHRYSLER_COMMON_BUTTONS_RX_CHECKS(CHRYSLER_ADDRS)
};

RxCheck chrysler_ram_dt_rx_checks[] = {
{.msg = {{CHRYSLER_RAM_DT_ADDRS.EPS_2, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 100U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_RAM_DT_ADDRS.ESP_1, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_RAM_DT_ADDRS.ESP_8, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_RAM_DT_ADDRS.ECM_5, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_RAM_DT_ADDRS.DAS_3, 2, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
CHRYSLER_COMMON_RX_CHECKS(CHRYSLER_RAM_DT_ADDRS)
CHRYSLER_COMMON_RAM_RX_CHECKS(CHRYSLER_RAM_DT_ADDRS)
CHRYSLER_COMMON_ACC_RX_CHECKS(CHRYSLER_RAM_DT_ADDRS, 2)
};

RxCheck chrysler_ram_hd_rx_checks[] = {
{.msg = {{CHRYSLER_RAM_HD_ADDRS.EPS_2, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 100U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_RAM_HD_ADDRS.ESP_1, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_RAM_HD_ADDRS.ESP_8, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_RAM_HD_ADDRS.ECM_5, 0, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
{.msg = {{CHRYSLER_RAM_HD_ADDRS.DAS_3, 2, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}},
RxCheck chrysler_ram_dt_long_rx_checks[] = {
CHRYSLER_COMMON_RX_CHECKS(CHRYSLER_RAM_DT_ADDRS)
CHRYSLER_COMMON_RAM_RX_CHECKS(CHRYSLER_RAM_DT_ADDRS)
CHRYSLER_COMMON_BUTTONS_RX_CHECKS(CHRYSLER_RAM_DT_ADDRS)
};

RxCheck chrysler_ram_hd_rx_checks[] = {
CHRYSLER_COMMON_RX_CHECKS(CHRYSLER_RAM_HD_ADDRS)
CHRYSLER_COMMON_RAM_RX_CHECKS(CHRYSLER_RAM_HD_ADDRS)
CHRYSLER_COMMON_ACC_RX_CHECKS(CHRYSLER_RAM_HD_ADDRS, 2)
};

RxCheck chrysler_ram_hd_long_rx_checks[] = {
CHRYSLER_COMMON_RX_CHECKS(CHRYSLER_RAM_HD_ADDRS)
CHRYSLER_COMMON_RAM_RX_CHECKS(CHRYSLER_RAM_HD_ADDRS)
CHRYSLER_COMMON_BUTTONS_RX_CHECKS(CHRYSLER_RAM_HD_ADDRS)
};

const uint32_t CHRYSLER_PARAM_RAM_DT = 1U; // set for Ram DT platform
const uint32_t CHRYSLER_PARAM_RAM_HD = 2U; // set for Ram HD platform
const uint32_t CHRYSLER_PARAM_LONGITUDINAL = 4U;

enum {
CHRYSLER_RAM_DT,
Expand Down Expand Up @@ -169,24 +248,52 @@ static uint32_t chrysler_compute_checksum(CANPacket_t *to_push) {
}

static uint8_t chrysler_get_counter(CANPacket_t *to_push) {
return (uint8_t)(GET_BYTE(to_push, 6) >> 4);
int counter_byte = GET_LEN(to_push) - 2U;
return (uint8_t)(GET_BYTE(to_push, counter_byte) >> 4);
}

static void chrysler_rx_hook(CANPacket_t *to_push) {
const int bus = GET_BUS(to_push);
const int addr = GET_ADDR(to_push);

if ((bus == 0) && (addr == chrysler_addrs->CRUISE_BUTTONS) && chrysler_longitudinal) {
int cruise_button = GET_BIT(to_push, 0U); // cancel button
// ensure cancel overrides any multi-button pressed state
if (!cruise_button) {
cruise_button |= GET_BIT(to_push, 2U) << 2U; // accel button
cruise_button |= GET_BIT(to_push, 3U) << 3U; // decel button
cruise_button |= GET_BIT(to_push, 4U) << 4U; // resume button
}

// enter controls on falling edge of accel/decel/resume
bool accel = (cruise_button != CHRYSLER_BTN_ACCEL) && (cruise_button_prev == CHRYSLER_BTN_ACCEL);
bool decel = (cruise_button != CHRYSLER_BTN_DECEL) && (cruise_button_prev == CHRYSLER_BTN_DECEL);
bool resume = (cruise_button != CHRYSLER_BTN_RESUME) && (cruise_button_prev == CHRYSLER_BTN_RESUME);
if (accel || decel || resume) {
controls_allowed = true;
}

// exit controls on cancel press
if (cruise_button == CHRYSLER_BTN_CANCEL) {
controls_allowed = false;
}

cruise_button_prev = cruise_button;
}

// Measured EPS torque
if ((bus == 0) && (addr == chrysler_addrs->EPS_2)) {
int torque_meas_new = ((GET_BYTE(to_push, 4) & 0x7U) << 8) + GET_BYTE(to_push, 5) - 1024U;
update_sample(&torque_meas, torque_meas_new);
}

// enter controls on rising edge of ACC, exit controls on ACC off
const int das_3_bus = (chrysler_platform == CHRYSLER_PACIFICA) ? 0 : 2;
if ((bus == das_3_bus) && (addr == chrysler_addrs->DAS_3)) {
bool cruise_engaged = GET_BIT(to_push, 21U) == 1U;
pcm_cruise_check(cruise_engaged);
if (!chrysler_longitudinal) {
// enter controls on rising edge of ACC, exit controls on ACC off
const int das_3_bus = (chrysler_platform == CHRYSLER_PACIFICA) ? 0 : 2;
if ((bus == das_3_bus) && (addr == chrysler_addrs->DAS_3)) {
bool cruise_engaged = GET_BIT(to_push, 21U) == 1U;
pcm_cruise_check(cruise_engaged);
}
}

// TODO: use the same message for both
Expand Down Expand Up @@ -232,8 +339,24 @@ static bool chrysler_tx_hook(CANPacket_t *to_send) {
}
}

// ACCEL
if (tx && (addr == chrysler_addrs->DAS_3)) {
// Signal: ENGINE_TORQUE_REQUEST
int gas = (((GET_BYTE(to_send, 0) & 0x1FU) << 8) | GET_BYTE(to_send, 1));
// Signal: ACC_DECEL
int accel = (((GET_BYTE(to_send, 2) & 0xFU) << 8) | GET_BYTE(to_send, 3));

bool violation = false;
violation |= longitudinal_accel_checks(accel, CHRYSLER_LONG_LIMITS);
violation |= longitudinal_gas_checks(gas, CHRYSLER_LONG_LIMITS);

if (violation) {
tx = 0;
}
}

// FORCE CANCEL: only the cancel button press is allowed
if (addr == chrysler_addrs->CRUISE_BUTTONS) {
if ((addr == chrysler_addrs->CRUISE_BUTTONS) && !chrysler_longitudinal) {
const bool is_cancel = GET_BYTE(to_send, 0) == 1U;
const bool is_resume = GET_BYTE(to_send, 0) == 0x10U;
const bool allowed = is_cancel || (is_resume && controls_allowed);
Expand All @@ -249,35 +372,43 @@ static int chrysler_fwd_hook(int bus_num, int addr) {
int bus_fwd = -1;

// forward to camera
if (bus_num == 0) {
const bool is_buttons = (addr == chrysler_addrs->CRUISE_BUTTONS);
if ((bus_num == 0) && (!chrysler_longitudinal || !is_buttons)) {
bus_fwd = 2;
}

// forward all messages from camera except LKAS messages
const bool is_lkas = ((addr == chrysler_addrs->LKAS_COMMAND) || (addr == chrysler_addrs->DAS_6));
if ((bus_num == 2) && !is_lkas){
const bool is_acc = ((addr == chrysler_addrs->DAS_3) || (addr == chrysler_addrs->DAS_4) || (addr == chrysler_addrs->DAS_5));
if ((bus_num == 2) && !is_lkas && (!chrysler_longitudinal || !is_acc)){
bus_fwd = 0;
}

return bus_fwd;
}

static safety_config chrysler_init(uint16_t param) {
#ifdef ALLOW_DEBUG
chrysler_longitudinal = GET_FLAG(param, CHRYSLER_PARAM_LONGITUDINAL);
#else
chrysler_longitudinal = false;
#endif

safety_config ret;
if (GET_FLAG(param, CHRYSLER_PARAM_RAM_DT)) {
chrysler_platform = CHRYSLER_RAM_DT;
chrysler_addrs = &CHRYSLER_RAM_DT_ADDRS;
ret = BUILD_SAFETY_CFG(chrysler_ram_dt_rx_checks, CHRYSLER_RAM_DT_TX_MSGS);
ret = chrysler_longitudinal ? BUILD_SAFETY_CFG(chrysler_ram_dt_long_rx_checks, CHRYSLER_RAM_DT_LONG_TX_MSGS) : BUILD_SAFETY_CFG(chrysler_ram_dt_rx_checks, CHRYSLER_RAM_DT_TX_MSGS);
#ifdef ALLOW_DEBUG
} else if (GET_FLAG(param, CHRYSLER_PARAM_RAM_HD)) {
chrysler_platform = CHRYSLER_RAM_HD;
chrysler_addrs = &CHRYSLER_RAM_HD_ADDRS;
ret = BUILD_SAFETY_CFG(chrysler_ram_hd_rx_checks, CHRYSLER_RAM_HD_TX_MSGS);
ret = chrysler_longitudinal ? BUILD_SAFETY_CFG(chrysler_ram_hd_long_rx_checks, CHRYSLER_RAM_HD_LONG_TX_MSGS) : BUILD_SAFETY_CFG(chrysler_ram_hd_rx_checks, CHRYSLER_RAM_HD_TX_MSGS);
#endif
} else {
chrysler_platform = CHRYSLER_PACIFICA;
chrysler_addrs = &CHRYSLER_ADDRS;
ret = BUILD_SAFETY_CFG(chrysler_rx_checks, CHRYSLER_TX_MSGS);
ret = chrysler_longitudinal ? BUILD_SAFETY_CFG(chrysler_long_rx_checks, CHRYSLER_LONG_TX_MSGS) : BUILD_SAFETY_CFG(chrysler_rx_checks, CHRYSLER_TX_MSGS);
}
return ret;
}
Expand Down
1 change: 1 addition & 0 deletions python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ class Panda:

FLAG_CHRYSLER_RAM_DT = 1
FLAG_CHRYSLER_RAM_HD = 2
FLAG_CHRYSLER_LONG = 4

FLAG_SUBARU_GEN2 = 1
FLAG_SUBARU_LONG = 2
Expand Down
5 changes: 5 additions & 0 deletions tests/safety/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,11 @@ def test_tx_hook_on_wrong_safety_mode(self):
continue
if {attr, current_test}.issubset({'TestVolkswagenMqbSafety', 'TestVolkswagenMqbStockSafety', 'TestVolkswagenMqbLongSafety'}):
continue
if attr.startswith('TestChryslerRamDT') and current_test.startswith('TestChryslerRamDT'):
continue
if {attr, current_test}.issubset({'TestChryslerSafety', 'TestChryslerLongitudinalSafety',
'TestChryslerRamHDSafety', 'TestChryslerRamHDLongitudinalSafety'}):
continue

# overlapping TX addrs, but they're not actuating messages for either car
if attr == 'TestHyundaiCanfdHDA2LongEV' and current_test.startswith('TestToyota'):
Expand Down
Loading

0 comments on commit 055b09e

Please sign in to comment.