Skip to content

Commit

Permalink
VW MQB: Redundant brake pressed signals (commaai#1137)
Browse files Browse the repository at this point in the history
* VW MQB: Redundant brake pressed signals

* bump timer for safety tests in CI

* use nicer f-string syntax

* don't need that
  • Loading branch information
jyoung8607 committed Nov 22, 2022
1 parent c075050 commit e4c4253
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 9 deletions.
27 changes: 20 additions & 7 deletions board/safety/safety_volkswagen_mqb.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const int VOLKSWAGEN_MQB_MIN_ACCEL = -3500;
#define MSG_GRA_ACC_01 0x12B // TX by OP, ACC control buttons for cancel/resume
#define MSG_ACC_07 0x12E // TX by OP, ACC control instructions to the drivetrain coordinator
#define MSG_ACC_02 0x30C // TX by OP, ACC HUD data to the instrument cluster
#define MSG_MOTOR_14 0x3BE // RX from ECU, for brake switch status
#define MSG_LDW_02 0x397 // TX by OP, Lane line recognition and text alerts

// Transmit of GRA_ACC_01 is allowed on bus 0 and 2 to keep compatibility with gateway and camera integration
Expand All @@ -35,16 +36,19 @@ const CanMsg VOLKSWAGEN_MQB_LONG_TX_MSGS[] = {{MSG_HCA_01, 0, 8}, {MSG_LDW_02, 0
{MSG_ACC_02, 0, 8}, {MSG_ACC_06, 0, 8}, {MSG_ACC_07, 0, 8}};

AddrCheckStruct volkswagen_mqb_addr_checks[] = {
{.msg = {{MSG_ESP_19, 0, 8, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U}, { 0 }, { 0 }}},
{.msg = {{MSG_LH_EPS_03, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U}, { 0 }, { 0 }}},
{.msg = {{MSG_ESP_05, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}},
{.msg = {{MSG_TSK_06, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}},
{.msg = {{MSG_MOTOR_20, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}},
{.msg = {{MSG_ESP_19, 0, 8, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U}, { 0 }, { 0 }}},
{.msg = {{MSG_LH_EPS_03, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U}, { 0 }, { 0 }}},
{.msg = {{MSG_ESP_05, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}},
{.msg = {{MSG_TSK_06, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}},
{.msg = {{MSG_MOTOR_20, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}, { 0 }, { 0 }}},
{.msg = {{MSG_MOTOR_14, 0, 8, .check_checksum = false, .max_counter = 0U, .expected_timestep = 100000U}, { 0 }, { 0 }}},
};
#define VOLKSWAGEN_MQB_ADDR_CHECKS_LEN (sizeof(volkswagen_mqb_addr_checks) / sizeof(volkswagen_mqb_addr_checks[0]))
addr_checks volkswagen_mqb_rx_checks = {volkswagen_mqb_addr_checks, VOLKSWAGEN_MQB_ADDR_CHECKS_LEN};

uint8_t volkswagen_crc8_lut_8h2f[256]; // Static lookup table for CRC8 poly 0x2F, aka 8H2F/AUTOSAR
bool volkswagen_mqb_brake_pedal_switch = false;
bool volkswagen_mqb_brake_pressure_detected = false;

static uint32_t volkswagen_mqb_get_checksum(CANPacket_t *to_push) {
return (uint8_t)GET_BYTE(to_push, 0);
Expand Down Expand Up @@ -95,6 +99,8 @@ static const addr_checks* volkswagen_mqb_init(uint16_t param) {

volkswagen_set_button_prev = false;
volkswagen_resume_button_prev = false;
volkswagen_mqb_brake_pedal_switch = false;
volkswagen_mqb_brake_pressure_detected = false;

#ifdef ALLOW_DEBUG
volkswagen_longitudinal = GET_FLAG(param, FLAG_VOLKSWAGEN_LONG_CONTROL);
Expand Down Expand Up @@ -176,11 +182,18 @@ static int volkswagen_mqb_rx_hook(CANPacket_t *to_push) {
gas_pressed = ((GET_BYTES_04(to_push) >> 12) & 0xFFU) != 0U;
}

// Signal: ESP_05.ESP_Fahrer_bremst
// Signal: Motor_14.MO_Fahrer_bremst (ECU detected brake pedal switch F63)
if (addr == MSG_MOTOR_14) {
volkswagen_mqb_brake_pedal_switch = (GET_BYTE(to_push, 3) & 0x10U) >> 4;
}

// Signal: ESP_05.ESP_Fahrer_bremst (ESP detected driver brake pressure above platform specified threshold)
if (addr == MSG_ESP_05) {
brake_pressed = (GET_BYTE(to_push, 3) & 0x4U) >> 2;
volkswagen_mqb_brake_pressure_detected = (GET_BYTE(to_push, 3) & 0x4U) >> 2;
}

brake_pressed = volkswagen_mqb_brake_pedal_switch || volkswagen_mqb_brake_pressure_detected;

generic_rx_checks((addr == MSG_HCA_01));
}
return valid;
Expand Down
24 changes: 22 additions & 2 deletions tests/safety/test_volkswagen_mqb.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,19 @@ def _speed_msg(self, speed):
values = {"ESP_%s_Radgeschw_02" % s: speed for s in ["HL", "HR", "VL", "VR"]}
return self.packer.make_can_msg_panda("ESP_19", 0, values)

# Brake light switch _esp_05_msg
def _user_brake_msg(self, brake):
# Driver brake pressure over threshold
def _esp_05_msg(self, brake):
values = {"ESP_Fahrer_bremst": brake}
return self.packer.make_can_msg_panda("ESP_05", 0, values)

# Brake pedal switch
def _motor_14_msg(self, brake):
values = {"MO_Fahrer_bremst": brake}
return self.packer.make_can_msg_panda("Motor_14", 0, values)

def _user_brake_msg(self, brake):
return self._motor_14_msg(brake)

# Driver throttle input
def _user_gas_msg(self, gas):
values = {"MO_Fahrpedalrohwert_01": gas}
Expand Down Expand Up @@ -95,6 +103,18 @@ def _acc_07_msg(self, accel, secondary_accel=3.02):
values = {"ACC_Sollbeschleunigung_02": accel, "ACC_Folgebeschl": secondary_accel}
return self.packer.make_can_msg_panda("ACC_07", 0, values)

# Verify brake_pressed is true if either the switch or pressure threshold signals are true
def test_redundant_brake_signals(self):
test_combinations = [(True, True, True), (True, True, False), (True, False, True), (False, False, False)]
for brake_pressed, motor_14_signal, esp_05_signal in test_combinations:
self._rx(self._motor_14_msg(False))
self._rx(self._esp_05_msg(False))
self.assertFalse(self.safety.get_brake_pressed_prev())
self._rx(self._motor_14_msg(motor_14_signal))
self._rx(self._esp_05_msg(esp_05_signal))
self.assertEqual(brake_pressed, self.safety.get_brake_pressed_prev(),
f"expected {brake_pressed=} with {motor_14_signal=} and {esp_05_signal=}")

def test_torque_measurements(self):
# TODO: make this test work with all cars
self._rx(self._torque_driver_msg(50))
Expand Down

0 comments on commit e4c4253

Please sign in to comment.