diff --git a/board/safety/safety_honda.h b/board/safety/safety_honda.h index 968608c..319053e 100644 --- a/board/safety/safety_honda.h +++ b/board/safety/safety_honda.h @@ -266,6 +266,7 @@ static void honda_nidec_init(int16_t param) { UNUSED(param); controls_allowed = false; relay_malfunction_reset(); + gas_interceptor_detected = 0; honda_hw = HONDA_N_HW; honda_alt_brake_msg = false; } diff --git a/tests/safety/common.py b/tests/safety/common.py index 4f56f96..620d547 100644 --- a/tests/safety/common.py +++ b/tests/safety/common.py @@ -1,6 +1,7 @@ import abc import struct import unittest +import numpy as np from opendbc.can.packer import CANPacker # pylint: disable=import-error from panda.tests.safety import libpandasafety_py @@ -54,6 +55,66 @@ class PandaSafetyTestBase(unittest.TestCase): def _tx(self, msg): return self.safety.safety_tx_hook(msg) +class InterceptorSafetyTest(PandaSafetyTestBase): + + INTERCEPTOR_THRESHOLD = 0 + + @classmethod + def setUpClass(cls): + if cls.__name__ == "InterceptorSafetyTest": + cls.safety = None + raise unittest.SkipTest + + @abc.abstractmethod + def _interceptor_msg(self, gas, addr): + pass + + def test_prev_gas_interceptor(self): + self._rx(self._interceptor_msg(0x0, 0x201)) + self.assertFalse(self.safety.get_gas_interceptor_prev()) + self._rx(self._interceptor_msg(0x1000, 0x201)) + self.assertTrue(self.safety.get_gas_interceptor_prev()) + self._rx(self._interceptor_msg(0x0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + + def test_disengage_on_gas_interceptor(self): + for g in range(0, 0x1000): + self._rx(self._interceptor_msg(0, 0x201)) + self.safety.set_controls_allowed(True) + self._rx(self._interceptor_msg(g, 0x201)) + remain_enabled = g <= self.INTERCEPTOR_THRESHOLD + self.assertEqual(remain_enabled, self.safety.get_controls_allowed()) + self._rx(self._interceptor_msg(0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + + def test_unsafe_mode_no_disengage_on_gas_interceptor(self): + self.safety.set_controls_allowed(True) + self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) + for g in range(0, 0x1000): + self._rx(self._interceptor_msg(g, 0x201)) + self.assertTrue(self.safety.get_controls_allowed()) + self._rx(self._interceptor_msg(0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + + def test_allow_engage_with_gas_interceptor_pressed(self): + self._rx(self._interceptor_msg(0x1000, 0x201)) + self.safety.set_controls_allowed(1) + self._rx(self._interceptor_msg(0x1000, 0x201)) + self.assertTrue(self.safety.get_controls_allowed()) + self._rx(self._interceptor_msg(0, 0x201)) + + def test_gas_interceptor_safety_check(self): + for gas in np.arange(0, 4000, 100): + for controls_allowed in [True, False]: + self.safety.set_controls_allowed(controls_allowed) + if controls_allowed: + send = True + else: + send = gas == 0 + self.assertEqual(send, self._tx(self._interceptor_msg(gas, 0x200))) + + class PandaSafetyTest(PandaSafetyTestBase): TX_MSGS = None STANDSTILL_THRESHOLD = None diff --git a/tests/safety/test_honda.py b/tests/safety/test_honda.py index 761dd53..68fb374 100755 --- a/tests/safety/test_honda.py +++ b/tests/safety/test_honda.py @@ -9,8 +9,6 @@ from panda.tests.safety.common import CANPackerPanda, make_msg, \ MAX_BRAKE = 255 -INTERCEPTOR_THRESHOLD = 344 - class Btn: CANCEL = 2 SET = 3 @@ -20,14 +18,6 @@ HONDA_N_HW = 0 HONDA_BG_HW = 1 HONDA_BH_HW = 2 -# Honda gas gains are the different -def honda_interceptor_msg(gas, addr): - to_send = make_msg(0, addr, 6) - gas2 = gas * 2 - to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \ - ((gas2 & 0xff) << 24) | ((gas2 & 0xff00) << 8) - return to_send - class TestHondaSafety(common.PandaSafetyTest): cnt_speed = 0 @@ -102,43 +92,6 @@ class TestHondaSafety(common.PandaSafetyTest): self._rx(self._brake_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) - def test_prev_gas_interceptor(self): - self._rx(honda_interceptor_msg(0x0, 0x201)) - self.assertFalse(self.safety.get_gas_interceptor_prev()) - self._rx(honda_interceptor_msg(0x1000, 0x201)) - self.assertTrue(self.safety.get_gas_interceptor_prev()) - self._rx(honda_interceptor_msg(0x0, 0x201)) - self.safety.set_gas_interceptor_detected(False) - - def test_disengage_on_gas_interceptor(self): - for g in range(0, 0x1000): - self._rx(honda_interceptor_msg(0, 0x201)) - self.safety.set_controls_allowed(True) - self._rx(honda_interceptor_msg(g, 0x201)) - remain_enabled = g <= INTERCEPTOR_THRESHOLD - self.assertEqual(remain_enabled, self.safety.get_controls_allowed()) - self._rx(honda_interceptor_msg(0, 0x201)) - self.safety.set_gas_interceptor_detected(False) - - def test_unsafe_mode_no_disengage_on_gas_interceptor(self): - self.safety.set_controls_allowed(True) - self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) - for g in range(0, 0x1000): - self._rx(honda_interceptor_msg(g, 0x201)) - self.assertTrue(self.safety.get_controls_allowed()) - self._rx(honda_interceptor_msg(0, 0x201)) - self.safety.set_gas_interceptor_detected(False) - self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) - self.safety.set_controls_allowed(False) - - def test_allow_engage_with_gas_interceptor_pressed(self): - self._rx(honda_interceptor_msg(0x1000, 0x201)) - self.safety.set_controls_allowed(1) - self._rx(honda_interceptor_msg(0x1000, 0x201)) - self.assertTrue(self.safety.get_controls_allowed()) - self._rx(honda_interceptor_msg(0, 0x201)) - self.safety.set_gas_interceptor_detected(False) - def test_steer_safety_check(self): self.safety.set_controls_allowed(0) self.assertTrue(self._tx(self._send_steer_msg(0x0000))) @@ -223,7 +176,7 @@ class TestHondaSafety(common.PandaSafetyTest): self._rx(self._gas_msg(0)) -class TestHondaNidecSafety(TestHondaSafety): +class TestHondaNidecSafety(TestHondaSafety, common.InterceptorSafetyTest): TX_MSGS = [[0xE4, 0], [0x194, 0], [0x1FA, 0], [0x200, 0], [0x30C, 0], [0x33D, 0]] STANDSTILL_THRESHOLD = 0 @@ -232,12 +185,22 @@ class TestHondaNidecSafety(TestHondaSafety): FWD_BLACKLISTED_ADDRS = {2: [0xE4, 0x194, 0x33D, 0x30C]} FWD_BUS_LOOKUP = {0: 2, 2: 0} + INTERCEPTOR_THRESHOLD = 344 + def setUp(self): self.packer = CANPackerPanda("honda_civic_touring_2016_can_generated") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC, 0) self.safety.init_tests_honda() + # Honda gas gains are the different + def _interceptor_msg(self, gas, addr): + to_send = make_msg(0, addr, 6) + gas2 = gas * 2 + to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \ + ((gas2 & 0xff) << 24) | ((gas2 & 0xff00) << 8) + return to_send + def test_fwd_hook(self): # normal operation, not forwarding AEB self.FWD_BLACKLISTED_ADDRS[2].append(0x1FA) @@ -265,28 +228,18 @@ class TestHondaNidecSafety(TestHondaSafety): self.assertEqual(send, self._tx(self._send_brake_msg(brake))) self.safety.set_honda_fwd_brake(False) - def test_gas_interceptor_safety_check(self): - for gas in np.arange(0, 4000, 100): - for controls_allowed in [True, False]: - self.safety.set_controls_allowed(controls_allowed) - if controls_allowed: - send = True - else: - send = gas == 0 - self.assertEqual(send, self._tx(honda_interceptor_msg(gas, 0x200))) - def test_tx_hook_on_interceptor_pressed(self): for mode in [UNSAFE_MODE.DEFAULT, UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS]: self.safety.set_unsafe_mode(mode) # gas_interceptor_prev > INTERCEPTOR_THRESHOLD - self._rx(honda_interceptor_msg(INTERCEPTOR_THRESHOLD+1, 0x201)) - self._rx(honda_interceptor_msg(INTERCEPTOR_THRESHOLD+1, 0x201)) + self._rx(self._interceptor_msg(self.INTERCEPTOR_THRESHOLD+1, 0x201)) + self._rx(self._interceptor_msg(self.INTERCEPTOR_THRESHOLD+1, 0x201)) allow_ctrl = mode == UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS self.safety.set_controls_allowed(1) self.safety.set_honda_fwd_brake(False) self.assertEqual(allow_ctrl, self._tx(self._send_brake_msg(MAX_BRAKE))) - self.assertEqual(allow_ctrl, self._tx(honda_interceptor_msg(INTERCEPTOR_THRESHOLD, 0x200))) + self.assertEqual(allow_ctrl, self._tx(self._interceptor_msg(self.INTERCEPTOR_THRESHOLD, 0x200))) self.assertEqual(allow_ctrl, self._tx(self._send_steer_msg(0x1000))) # reset status @@ -294,7 +247,7 @@ class TestHondaNidecSafety(TestHondaSafety): self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) self._tx(self._send_brake_msg(0)) self._tx(self._send_steer_msg(0)) - self._tx(honda_interceptor_msg(0, 0x200)) + self._tx(self._interceptor_msg(0, 0x200)) self.safety.set_gas_interceptor_detected(False) diff --git a/tests/safety/test_toyota.py b/tests/safety/test_toyota.py index 29d06f5..027565e 100755 --- a/tests/safety/test_toyota.py +++ b/tests/safety/test_toyota.py @@ -20,16 +20,8 @@ MAX_RT_DELTA = 375 RT_INTERVAL = 250000 MAX_TORQUE_ERROR = 350 -INTERCEPTOR_THRESHOLD = 845 -# Toyota gas gains are the same -def toyota_interceptor_msg(gas, addr): - to_send = make_msg(0, addr, 6) - to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \ - ((gas & 0xff) << 24) | ((gas & 0xff00) << 8) - return to_send - -class TestToyotaSafety(common.PandaSafetyTest): +class TestToyotaSafety(common.PandaSafetyTest, common.InterceptorSafetyTest): TX_MSGS = [[0x283, 0], [0x2E6, 0], [0x2E7, 0], [0x33E, 0], [0x344, 0], [0x365, 0], [0x366, 0], [0x4CB, 0], # DSU bus 0 [0x128, 1], [0x141, 1], [0x160, 1], [0x161, 1], [0x470, 1], # DSU bus 1 @@ -40,6 +32,7 @@ class TestToyotaSafety(common.PandaSafetyTest): RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS = {2: [0x2E4, 0x412, 0x191, 0x343]} FWD_BUS_LOOKUP = {0: 2, 2: 0} + INTERCEPTOR_THRESHOLD = 845 @classmethod def setUp(self): @@ -83,39 +76,12 @@ class TestToyotaSafety(common.PandaSafetyTest): values["CHECKSUM"] = 1 return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values) - def test_prev_gas_interceptor(self): - self._rx(toyota_interceptor_msg(0x0, 0x201)) - self.assertFalse(self.safety.get_gas_interceptor_prev()) - self._rx(toyota_interceptor_msg(0x1000, 0x201)) - self.assertTrue(self.safety.get_gas_interceptor_prev()) - self._rx(toyota_interceptor_msg(0x0, 0x201)) - - def test_disengage_on_gas_interceptor(self): - for g in range(0, 0x1000): - self._rx(toyota_interceptor_msg(0, 0x201)) - self.safety.set_controls_allowed(True) - self._rx(toyota_interceptor_msg(g, 0x201)) - remain_enabled = g <= INTERCEPTOR_THRESHOLD - self.assertEqual(remain_enabled, self.safety.get_controls_allowed()) - self._rx(toyota_interceptor_msg(0, 0x201)) - self.safety.set_gas_interceptor_detected(False) - - def test_unsafe_mode_no_disengage_on_gas_interceptor(self): - self.safety.set_controls_allowed(True) - self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) - for g in range(0, 0x1000): - self._rx(toyota_interceptor_msg(g, 0x201)) - self.assertTrue(self.safety.get_controls_allowed()) - self._rx(toyota_interceptor_msg(0, 0x201)) - self.safety.set_gas_interceptor_detected(False) - self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) - - def test_allow_engage_with_gas_interceptor_pressed(self): - self._rx(toyota_interceptor_msg(0x1000, 0x201)) - self.safety.set_controls_allowed(1) - self._rx(toyota_interceptor_msg(0x1000, 0x201)) - self.assertTrue(self.safety.get_controls_allowed()) - self._rx(toyota_interceptor_msg(0, 0x201)) + # Toyota gas gains are the same + def _interceptor_msg(self, gas, addr): + to_send = make_msg(0, addr, 6) + to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \ + ((gas & 0xff) << 24) | ((gas & 0xff00) << 8) + return to_send def test_accel_actuation_limits(self): limits = ((MIN_ACCEL, MAX_ACCEL, UNSAFE_MODE.DEFAULT), @@ -219,13 +185,6 @@ class TestToyotaSafety(common.PandaSafetyTest): self.assertEqual(1, self.safety.get_toyota_torque_meas_max()) self.assertEqual(-1, self.safety.get_toyota_torque_meas_min()) - def test_gas_interceptor_safety_check(self): - self.safety.set_controls_allowed(0) - self.assertTrue(self._tx(toyota_interceptor_msg(0, 0x200))) - self.assertFalse(self._tx(toyota_interceptor_msg(0x1000, 0x200))) - self.safety.set_controls_allowed(1) - self.assertTrue(self._tx(toyota_interceptor_msg(0x1000, 0x200))) - def test_rx_hook(self): # checksum checks for msg in ["trq", "pcm"]: