Skip to content

Commit

Permalink
Volkswagen safety updates: Phase 3 (commaai#462)
Browse files Browse the repository at this point in the history
* Torque limit bump, change signal for ACC state tracking
  • Loading branch information
jyoung8607 committed Mar 6, 2020
1 parent 4368748 commit c7d0d5f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 31 deletions.
20 changes: 10 additions & 10 deletions board/safety/safety_volkswagen.h
@@ -1,5 +1,5 @@
// Safety-relevant steering constants for Volkswagen
const int VOLKSWAGEN_MAX_STEER = 250; // 2.5 Nm (EPS side max of 3.0Nm with fault if violated)
const int VOLKSWAGEN_MAX_STEER = 300; // 3.0 Nm (EPS side max of 3.0Nm with fault if violated)
const int VOLKSWAGEN_MAX_RT_DELTA = 75; // 4 max rate up * 50Hz send rate * 250000 RT interval / 1000000 = 50 ; 50 * 1.5 for safety pad = 75
const uint32_t VOLKSWAGEN_RT_INTERVAL = 250000; // 250ms between real time checks
const int VOLKSWAGEN_MAX_RATE_UP = 4; // 2.0 Nm/s RoC limit (EPS rack has own soft-limit of 5.0 Nm/s)
Expand All @@ -11,8 +11,8 @@ const int VOLKSWAGEN_DRIVER_TORQUE_FACTOR = 3;
#define MSG_ESP_19 0x0B2 // RX from ABS, for wheel speeds
#define MSG_EPS_01 0x09F // RX from EPS, for driver steering torque
#define MSG_ESP_05 0x106 // RX from ABS, for brake switch state
#define MSG_TSK_06 0x120 // RX from ECU, for ACC status from drivetrain coordinator
#define MSG_MOTOR_20 0x121 // RX from ECU, for driver throttle input
#define MSG_ACC_06 0x122 // RX from ACC radar, for status and engagement
#define MSG_HCA_01 0x126 // TX by OP, Heading Control Assist steering torque
#define MSG_GRA_ACC_01 0x12B // TX by OP, ACC control buttons for cancel/resume
#define MSG_LDW_02 0x397 // TX by OP, Lane line recognition and text alerts
Expand All @@ -25,8 +25,8 @@ AddrCheckStruct volkswagen_mqb_rx_checks[] = {
{.addr = {MSG_ESP_19}, .bus = 0, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U},
{.addr = {MSG_EPS_01}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U},
{.addr = {MSG_ESP_05}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
{.addr = {MSG_TSK_06}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
{.addr = {MSG_MOTOR_20}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
{.addr = {MSG_ACC_06}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
};
const int VOLKSWAGEN_MQB_RX_CHECKS_LEN = sizeof(volkswagen_mqb_rx_checks) / sizeof(volkswagen_mqb_rx_checks[0]);

Expand Down Expand Up @@ -72,12 +72,12 @@ static uint8_t volkswagen_mqb_compute_crc(CAN_FIFOMailBox_TypeDef *to_push) {
case MSG_ESP_05:
crc ^= (uint8_t[]){0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}[counter];
break;
case MSG_TSK_06:
crc ^= (uint8_t[]){0xC4,0xE2,0x4F,0xE4,0xF8,0x2F,0x56,0x81,0x9F,0xE5,0x83,0x44,0x05,0x3F,0x97,0xDF}[counter];
break;
case MSG_MOTOR_20:
crc ^= (uint8_t[]){0xE9,0x65,0xAE,0x6B,0x7B,0x35,0xE5,0x5F,0x4E,0xC7,0x86,0xA2,0xBB,0xDD,0xEB,0xB4}[counter];
break;
case MSG_ACC_06:
crc ^= (uint8_t[]){0x37,0x7D,0xF3,0xA9,0x18,0x46,0x6D,0x4D,0x3D,0x71,0x92,0x9C,0xE5,0x32,0x10,0xB9}[counter];
break;
default: // Undefined CAN message, CRC check expected to fail
break;
}
Expand Down Expand Up @@ -128,10 +128,10 @@ static int volkswagen_mqb_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
update_sample(&volkswagen_torque_driver, torque_driver_new);
}

// Update ACC status from radar for controls-allowed state
// Signal: ACC_06.ACC_Status_ACC
if ((bus == 0) && (addr == MSG_ACC_06)) {
int acc_status = (GET_BYTE(to_push, 7) & 0x70) >> 4;
// Update ACC status from drivetrain coordinator for controls-allowed state
// Signal: TSK_06.TSK_Status
if ((bus == 0) && (addr == MSG_TSK_06)) {
int acc_status = (GET_BYTE(to_push, 3) & 0x7);
controls_allowed = ((acc_status == 3) || (acc_status == 4) || (acc_status == 5)) ? 1 : 0;
}

Expand Down
40 changes: 20 additions & 20 deletions tests/safety/test_volkswagen_mqb.py
Expand Up @@ -9,7 +9,7 @@

MAX_RATE_UP = 4
MAX_RATE_DOWN = 10
MAX_STEER = 250
MAX_STEER = 300
MAX_RT_DELTA = 75
RT_INTERVAL = 250000

Expand All @@ -19,8 +19,8 @@
MSG_ESP_19 = 0xB2 # RX from ABS, for wheel speeds
MSG_EPS_01 = 0x9F # RX from EPS, for driver steering torque
MSG_ESP_05 = 0x106 # RX from ABS, for brake light state
MSG_TSK_06 = 0x120 # RX from ECU, for ACC status from drivetrain coordinator
MSG_MOTOR_20 = 0x121 # RX from ECU, for driver throttle input
MSG_ACC_06 = 0x122 # RX from ACC radar, for status and engagement
MSG_HCA_01 = 0x126 # TX by OP, Heading Control Assist steering torque
MSG_GRA_ACC_01 = 0x12B # TX by OP, ACC control buttons for cancel/resume
MSG_LDW_02 = 0x397 # TX by OP, Lane line recognition and text alerts
Expand Down Expand Up @@ -48,10 +48,10 @@ def volkswagen_mqb_crc(msg, addr, len_msg):
magic_pad = b'\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5'[counter]
elif addr == MSG_ESP_05:
magic_pad = b'\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07'[counter]
elif addr == MSG_TSK_06:
magic_pad = b'\xC4\xE2\x4F\xE4\xF8\x2F\x56\x81\x9F\xE5\x83\x44\x05\x3F\x97\xDF'[counter]
elif addr == MSG_MOTOR_20:
magic_pad = b'\xE9\x65\xAE\x6B\x7B\x35\xE5\x5F\x4E\xC7\x86\xA2\xBB\xDD\xEB\xB4'[counter]
elif addr == MSG_ACC_06:
magic_pad = b'\x37\x7D\xF3\xA9\x18\x46\x6D\x4D\x3D\x71\x92\x9C\xE5\x32\x10\xB9'[counter]
elif addr == MSG_HCA_01:
magic_pad = b'\xDA\xDA\xDA\xDA\xDA\xDA\xDA\xDA\xDA\xDA\xDA\xDA\xDA\xDA\xDA\xDA'[counter]
elif addr == MSG_GRA_ACC_01:
Expand All @@ -63,8 +63,8 @@ def volkswagen_mqb_crc(msg, addr, len_msg):
class TestVolkswagenMqbSafety(unittest.TestCase):
cnt_eps_01 = 0
cnt_esp_05 = 0
cnt_tsk_06 = 0
cnt_motor_20 = 0
cnt_acc_06 = 0
cnt_hca_01 = 0
cnt_gra_acc_01 = 0

Expand Down Expand Up @@ -120,12 +120,12 @@ def _hca_01_msg(self, torque):
return to_send

# ACC engagement status
def _acc_06_msg(self, status):
to_send = make_msg(0, MSG_ACC_06)
to_send[0].RDHR = (status & 0x7) << 28
to_send[0].RDLR |= (self.cnt_acc_06 % 16) << 8
to_send[0].RDLR |= volkswagen_mqb_crc(to_send[0], MSG_ACC_06, 8)
self.__class__.cnt_acc_06 += 1
def _tsk_06_msg(self, status):
to_send = make_msg(0, MSG_TSK_06)
to_send[0].RDLR = (status & 0x7) << 24
to_send[0].RDLR |= (self.cnt_tsk_06 % 16) << 8
to_send[0].RDLR |= volkswagen_mqb_crc(to_send[0], MSG_TSK_06, 8)
self.__class__.cnt_tsk_06 += 1
return to_send

# Driver throttle input
Expand Down Expand Up @@ -162,12 +162,12 @@ def test_default_controls_not_allowed(self):

def test_enable_control_allowed_from_cruise(self):
self.safety.set_controls_allowed(0)
self.safety.safety_rx_hook(self._acc_06_msg(3))
self.safety.safety_rx_hook(self._tsk_06_msg(3))
self.assertTrue(self.safety.get_controls_allowed())

def test_disable_control_allowed_from_cruise(self):
self.safety.set_controls_allowed(1)
self.safety.safety_rx_hook(self._acc_06_msg(1))
self.safety.safety_rx_hook(self._tsk_06_msg(1))
self.assertFalse(self.safety.get_controls_allowed())

def test_sample_speed(self):
Expand Down Expand Up @@ -351,16 +351,16 @@ def test_rx_hook(self):
# TODO: Would be ideal to check ESP_19 as well, but it has no checksum
# or counter, and I'm not sure if we can easily validate Panda's simple
# temporal reception-rate check here.
for msg in [MSG_EPS_01, MSG_ESP_05, MSG_MOTOR_20, MSG_ACC_06]:
for msg in [MSG_EPS_01, MSG_ESP_05, MSG_TSK_06, MSG_MOTOR_20]:
self.safety.set_controls_allowed(1)
if msg == MSG_EPS_01:
to_push = self._eps_01_msg(0)
if msg == MSG_ESP_05:
to_push = self._esp_05_msg(False)
if msg == MSG_TSK_06:
to_push = self._tsk_06_msg(3)
if msg == MSG_MOTOR_20:
to_push = self._motor_20_msg(0)
if msg == MSG_ACC_06:
to_push = self._acc_06_msg(3)
self.assertTrue(self.safety.safety_rx_hook(to_push))
to_push[0].RDHR ^= 0xFF
self.assertFalse(self.safety.safety_rx_hook(to_push))
Expand All @@ -371,28 +371,28 @@ def test_rx_hook(self):
for i in range(MAX_WRONG_COUNTERS + 1):
self.__class__.cnt_eps_01 += 1
self.__class__.cnt_esp_05 += 1
self.__class__.cnt_tsk_06 += 1
self.__class__.cnt_motor_20 += 1
self.__class__.cnt_acc_06 += 1
if i < MAX_WRONG_COUNTERS:
self.safety.set_controls_allowed(1)
self.safety.safety_rx_hook(self._eps_01_msg(0))
self.safety.safety_rx_hook(self._esp_05_msg(False))
self.safety.safety_rx_hook(self._tsk_06_msg(3))
self.safety.safety_rx_hook(self._motor_20_msg(0))
self.safety.safety_rx_hook(self._acc_06_msg(3))
else:
self.assertFalse(self.safety.safety_rx_hook(self._eps_01_msg(0)))
self.assertFalse(self.safety.safety_rx_hook(self._esp_05_msg(False)))
self.assertFalse(self.safety.safety_rx_hook(self._tsk_06_msg(3)))
self.assertFalse(self.safety.safety_rx_hook(self._motor_20_msg(0)))
self.assertFalse(self.safety.safety_rx_hook(self._acc_06_msg(3)))
self.assertFalse(self.safety.get_controls_allowed())

# restore counters for future tests with a couple of good messages
for i in range(2):
self.safety.set_controls_allowed(1)
self.safety.safety_rx_hook(self._eps_01_msg(0))
self.safety.safety_rx_hook(self._esp_05_msg(False))
self.safety.safety_rx_hook(self._tsk_06_msg(3))
self.safety.safety_rx_hook(self._motor_20_msg(0))
self.safety.safety_rx_hook(self._acc_06_msg(3))
self.assertTrue(self.safety.get_controls_allowed())

def test_fwd_hook(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/safety_replay/test_safety_replay.py
Expand Up @@ -18,7 +18,7 @@
("02ec6bea180a4d36|2019-04-17--11-21-35.bz2", Panda.SAFETY_HYUNDAI, 0), # HYUNDAI.SANTA_FE
("6fb4948a7ebe670e|2019-11-12--00-35-53.bz2", Panda.SAFETY_CHRYSLER, 0), # CHRYSLER.PACIFICA_2018_HYBRID
("791340bc01ed993d|2019-04-08--10-26-00.bz2", Panda.SAFETY_SUBARU, 0), # SUBARU.IMPREZA
("b0c9d2329ad1606b|2019-11-17--17-06-13.bz2", Panda.SAFETY_VOLKSWAGEN_MQB, 0), # VOLKSWAGEN.GOLF
("76b83eb0245de90e|2020-03-05--19-16-05.bz2", Panda.SAFETY_VOLKSWAGEN_MQB, 0), # VOLKSWAGEN.GOLF
("fbbfa6af821552b9|2020-03-03--08-09-43.bz2", Panda.SAFETY_NISSAN, 0), # NISSAN.XTRAIL
]

Expand Down

0 comments on commit c7d0d5f

Please sign in to comment.