diff --git a/board/safety/safety_chrysler.h b/board/safety/safety_chrysler.h index 0bcffd636..4f5edd0da 100644 --- a/board/safety/safety_chrysler.h +++ b/board/safety/safety_chrysler.h @@ -74,6 +74,8 @@ static int chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { chrysler_get_checksum, chrysler_compute_checksum, chrysler_get_counter); + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; + if (valid && (GET_BUS(to_push) == 0)) { int addr = GET_ADDR(to_push); @@ -107,7 +109,7 @@ static int chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // exit controls on rising edge of gas press if (addr == 308) { bool gas_pressed = (GET_BYTE(to_push, 5) & 0x7F) != 0; - if (gas_pressed && !gas_pressed_prev && (chrysler_speed > CHRYSLER_GAS_THRSLD)) { + if (!unsafe_allow_gas && gas_pressed && !gas_pressed_prev && (chrysler_speed > CHRYSLER_GAS_THRSLD)) { controls_allowed = 0; } gas_pressed_prev = gas_pressed; diff --git a/board/safety/safety_ford.h b/board/safety/safety_ford.h index 067ed1cad..562c8d2a4 100644 --- a/board/safety/safety_ford.h +++ b/board/safety/safety_ford.h @@ -13,6 +13,7 @@ static int ford_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { int addr = GET_ADDR(to_push); int bus = GET_BUS(to_push); + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; if (addr == 0x217) { // wheel speeds are 14 bits every 16 @@ -47,7 +48,7 @@ static int ford_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // exit controls on rising edge of gas press if (addr == 0x204) { bool gas_pressed = ((GET_BYTE(to_push, 0) & 0x03) | GET_BYTE(to_push, 1)) != 0; - if (gas_pressed && !gas_pressed_prev) { + if (!unsafe_allow_gas && gas_pressed && !gas_pressed_prev) { controls_allowed = 0; } gas_pressed_prev = gas_pressed; @@ -72,7 +73,11 @@ static int ford_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { // disallow actuator commands if gas or brake (with vehicle moving) are pressed // and the the latching controls_allowed flag is True - int pedal_pressed = gas_pressed_prev || (brake_pressed_prev && ford_moving); + int pedal_pressed = brake_pressed_prev && ford_moving; + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; + if (!unsafe_allow_gas) { + pedal_pressed = pedal_pressed || gas_pressed_prev; + } bool current_controls_allowed = controls_allowed && !(pedal_pressed); if (relay_malfunction) { diff --git a/board/safety/safety_gm.h b/board/safety/safety_gm.h index 8672cc267..43e412af9 100644 --- a/board/safety/safety_gm.h +++ b/board/safety/safety_gm.h @@ -44,6 +44,8 @@ static int gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { bool valid = addr_safety_check(to_push, gm_rx_checks, GM_RX_CHECK_LEN, NULL, NULL, NULL); + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; + if (valid && (GET_BUS(to_push) == 0)) { int addr = GET_ADDR(to_push); @@ -91,7 +93,7 @@ static int gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // exit controls on rising edge of gas press if (addr == 417) { bool gas_pressed = GET_BYTE(to_push, 6) != 0; - if (gas_pressed && !gas_pressed_prev) { + if (!unsafe_allow_gas && gas_pressed && !gas_pressed_prev) { controls_allowed = 0; } gas_pressed_prev = gas_pressed; @@ -138,7 +140,11 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { // disallow actuator commands if gas or brake (with vehicle moving) are pressed // and the the latching controls_allowed flag is True - int pedal_pressed = gas_pressed_prev || (brake_pressed_prev && gm_moving); + int pedal_pressed = brake_pressed_prev && gm_moving; + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; + if (!unsafe_allow_gas) { + pedal_pressed = pedal_pressed || gas_pressed_prev; + } bool current_controls_allowed = controls_allowed && !pedal_pressed; // BRAKE: safety check diff --git a/board/safety/safety_honda.h b/board/safety/safety_honda.h index 40d93a82e..7a0117757 100644 --- a/board/safety/safety_honda.h +++ b/board/safety/safety_honda.h @@ -72,6 +72,8 @@ static int honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { honda_get_checksum, honda_compute_checksum, honda_get_counter); } + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; + if (valid) { int addr = GET_ADDR(to_push); int len = GET_LEN(to_push); @@ -121,7 +123,7 @@ static int honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { if ((addr == 0x201) && (len == 6)) { gas_interceptor_detected = 1; int gas_interceptor = GET_INTERCEPTOR(to_push); - if ((gas_interceptor > HONDA_GAS_INTERCEPTOR_THRESHOLD) && + if (!unsafe_allow_gas && (gas_interceptor > HONDA_GAS_INTERCEPTOR_THRESHOLD) && (gas_interceptor_prev <= HONDA_GAS_INTERCEPTOR_THRESHOLD)) { controls_allowed = 0; } @@ -132,13 +134,13 @@ static int honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { if (!gas_interceptor_detected) { if (addr == 0x17C) { bool gas_pressed = GET_BYTE(to_push, 0) != 0; - if (gas_pressed && !gas_pressed_prev) { + if (!unsafe_allow_gas && gas_pressed && !gas_pressed_prev) { controls_allowed = 0; } gas_pressed_prev = gas_pressed; } } - + // disable stock Honda AEB in unsafe mode if ( !(unsafe_mode & UNSAFE_DISABLE_STOCK_AEB) ) { if ((bus == 2) && (addr == 0x1FA)) { @@ -196,8 +198,11 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { // disallow actuator commands if gas or brake (with vehicle moving) are pressed // and the the latching controls_allowed flag is True - int pedal_pressed = gas_pressed_prev || (gas_interceptor_prev > HONDA_GAS_INTERCEPTOR_THRESHOLD) || - (brake_pressed_prev && honda_moving); + int pedal_pressed = brake_pressed_prev && honda_moving; + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; + if (!unsafe_allow_gas) { + pedal_pressed = pedal_pressed || gas_pressed_prev || (gas_interceptor_prev > HONDA_GAS_INTERCEPTOR_THRESHOLD); + } bool current_controls_allowed = controls_allowed && !(pedal_pressed); // BRAKE: safety check diff --git a/board/safety/safety_hyundai.h b/board/safety/safety_hyundai.h index 1b5b656ff..66ec5e7b8 100644 --- a/board/safety/safety_hyundai.h +++ b/board/safety/safety_hyundai.h @@ -30,6 +30,8 @@ static int hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { bool valid = addr_safety_check(to_push, hyundai_rx_checks, HYUNDAI_RX_CHECK_LEN, NULL, NULL, NULL); + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; + if (valid && GET_BUS(to_push) == 0) { int addr = GET_ADDR(to_push); @@ -55,7 +57,7 @@ static int hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // exit controls on rising edge of gas press if (addr == 608) { bool gas_pressed = (GET_BYTE(to_push, 7) >> 6) != 0; - if (gas_pressed && !gas_pressed_prev) { + if (!unsafe_allow_gas && gas_pressed && !gas_pressed_prev) { controls_allowed = 0; } gas_pressed_prev = gas_pressed; diff --git a/board/safety/safety_nissan.h b/board/safety/safety_nissan.h index bf02925ae..cb647ee39 100644 --- a/board/safety/safety_nissan.h +++ b/board/safety/safety_nissan.h @@ -36,6 +36,8 @@ static int nissan_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { bool valid = addr_safety_check(to_push, nissan_rx_checks, NISSAN_RX_CHECK_LEN, NULL, NULL, NULL); + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; + if (valid) { int bus = GET_BUS(to_push); int addr = GET_ADDR(to_push); @@ -68,7 +70,7 @@ static int nissan_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { gas_pressed = GET_BYTE(to_push, 0) > 3; } - if (gas_pressed && !gas_pressed_prev) { + if (!unsafe_allow_gas && gas_pressed && !gas_pressed_prev) { controls_allowed = 0; } gas_pressed_prev = gas_pressed; diff --git a/board/safety/safety_subaru.h b/board/safety/safety_subaru.h index 9b7665f2b..052713775 100644 --- a/board/safety/safety_subaru.h +++ b/board/safety/safety_subaru.h @@ -67,6 +67,8 @@ static int subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { NULL, NULL, NULL); } + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; + if (valid && (GET_BUS(to_push) == 0)) { int addr = GET_ADDR(to_push); if (((addr == 0x119) && subaru_global) || @@ -116,7 +118,7 @@ static int subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { ((addr == 0x140) && !subaru_global)) { int byte = subaru_global ? 4 : 0; bool gas_pressed = GET_BYTE(to_push, byte) != 0; - if (gas_pressed && !gas_pressed_prev) { + if (!unsafe_allow_gas && gas_pressed && !gas_pressed_prev) { controls_allowed = 0; } gas_pressed_prev = gas_pressed; diff --git a/board/safety/safety_toyota.h b/board/safety/safety_toyota.h index 4f18ee678..979cb19bd 100644 --- a/board/safety/safety_toyota.h +++ b/board/safety/safety_toyota.h @@ -14,7 +14,10 @@ const uint32_t TOYOTA_RT_INTERVAL = 250000; // 250ms between real time checks // longitudinal limits const int TOYOTA_MAX_ACCEL = 1500; // 1.5 m/s2 -const int TOYOTA_MIN_ACCEL = -3000; // 3.0 m/s2 +const int TOYOTA_MIN_ACCEL = -3000; // -3.0 m/s2 + +const int TOYOTA_ISO_MAX_ACCEL = 2000; // 2.0 m/s2 +const int TOYOTA_ISO_MIN_ACCEL = -3500; // -3.5 m/s2 const int TOYOTA_STANDSTILL_THRSLD = 100; // 1kph const int TOYOTA_GAS_INTERCEPTOR_THRSLD = 475; // ratio between offset and gain from dbc file @@ -63,6 +66,8 @@ static int toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { bool valid = addr_safety_check(to_push, toyota_rx_checks, TOYOTA_RX_CHECKS_LEN, toyota_get_checksum, toyota_compute_checksum, NULL); + bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS; + if (valid && (GET_BUS(to_push) == 0)) { int addr = GET_ADDR(to_push); @@ -121,7 +126,7 @@ static int toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { if (addr == 0x201) { gas_interceptor_detected = 1; int gas_interceptor = GET_INTERCEPTOR(to_push); - if ((gas_interceptor > TOYOTA_GAS_INTERCEPTOR_THRSLD) && + if (!unsafe_allow_gas && (gas_interceptor > TOYOTA_GAS_INTERCEPTOR_THRSLD) && (gas_interceptor_prev <= TOYOTA_GAS_INTERCEPTOR_THRSLD)) { controls_allowed = 0; } @@ -131,7 +136,7 @@ static int toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // exit controls on rising edge of gas press if (addr == 0x2C1) { bool gas_pressed = GET_BYTE(to_push, 6) != 0; - if (gas_pressed && !gas_pressed_prev && !gas_interceptor_detected) { + if (!unsafe_allow_gas && gas_pressed && !gas_pressed_prev && !gas_interceptor_detected) { controls_allowed = 0; } gas_pressed_prev = gas_pressed; @@ -180,7 +185,10 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { tx = 0; } } - bool violation = max_limit_check(desired_accel, TOYOTA_MAX_ACCEL, TOYOTA_MIN_ACCEL); + bool violation = (unsafe_mode & UNSAFE_RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX)? + max_limit_check(desired_accel, TOYOTA_ISO_MAX_ACCEL, TOYOTA_ISO_MIN_ACCEL) : + max_limit_check(desired_accel, TOYOTA_MAX_ACCEL, TOYOTA_MIN_ACCEL); + if (violation) { tx = 0; } diff --git a/tests/safety/test_chrysler.py b/tests/safety/test_chrysler.py index c66b90b6b..71ca8b0a3 100755 --- a/tests/safety/test_chrysler.py +++ b/tests/safety/test_chrysler.py @@ -3,7 +3,7 @@ import unittest import numpy as np from panda import Panda from panda.tests.safety import libpandasafety_py -from panda.tests.safety.common import StdTest, make_msg +from panda.tests.safety.common import StdTest, make_msg, UNSAFE_MODE MAX_RATE_UP = 3 MAX_RATE_DOWN = 3 @@ -149,6 +149,14 @@ class TestChryslerSafety(unittest.TestCase): self.safety.safety_rx_hook(self._gas_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) + def test_unsafe_mode_no_disengage_on_gas(self): + self.safety.safety_rx_hook(self._gas_msg(0)) + self.safety.set_controls_allowed(1) + self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) + self.safety.safety_rx_hook(self._gas_msg(1)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + def test_brake_disengage(self): StdTest.test_allow_brake_at_zero_speed(self) StdTest.test_not_allow_brake_when_moving(self, 0) diff --git a/tests/safety/test_gm.py b/tests/safety/test_gm.py index 34d92357c..7ed0d5cf4 100644 --- a/tests/safety/test_gm.py +++ b/tests/safety/test_gm.py @@ -3,7 +3,7 @@ import unittest import numpy as np from panda import Panda from panda.tests.safety import libpandasafety_py -from panda.tests.safety.common import StdTest, make_msg +from panda.tests.safety.common import StdTest, make_msg, UNSAFE_MODE MAX_RATE_UP = 7 MAX_RATE_DOWN = 17 @@ -126,6 +126,14 @@ class TestGmSafety(unittest.TestCase): self.assertFalse(self.safety.get_controls_allowed()) self.safety.safety_rx_hook(self._gas_msg(False)) + def test_unsafe_mode_no_disengage_on_gas(self): + self.safety.safety_rx_hook(self._gas_msg(False)) + self.safety.set_controls_allowed(1) + self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) + self.safety.safety_rx_hook(self._gas_msg(True)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + def test_allow_engage_with_gas_pressed(self): self.safety.safety_rx_hook(self._gas_msg(True)) self.safety.set_controls_allowed(1) @@ -252,6 +260,59 @@ class TestGmSafety(unittest.TestCase): # assume len 8 self.assertEqual(-1, self.safety.safety_fwd_hook(b, make_msg(b, m, 8))) + def test_tx_hook_on_pedal_pressed(self): + for pedal in ['brake', 'gas']: + if pedal == 'brake': + # brake_pressed_prev and honda_moving + self.safety.safety_rx_hook(self._speed_msg(100)) + self.safety.safety_rx_hook(self._brake_msg(MAX_BRAKE)) + elif pedal == 'gas': + # gas_pressed_prev + self.safety.safety_rx_hook(self._gas_msg(MAX_GAS)) + + self.safety.set_controls_allowed(1) + self.assertFalse(self.safety.safety_tx_hook(self._send_brake_msg(MAX_BRAKE))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP))) + self.assertFalse(self.safety.safety_tx_hook(self._send_gas_msg(MAX_GAS))) + + # reset status + self.safety.set_controls_allowed(0) + self.safety.safety_tx_hook(self._send_brake_msg(0)) + self.safety.safety_tx_hook(self._torque_msg(0)) + if pedal == 'brake': + self.safety.safety_rx_hook(self._speed_msg(0)) + self.safety.safety_rx_hook(self._brake_msg(0)) + elif pedal == 'gas': + self.safety.safety_rx_hook(self._gas_msg(0)) + + def test_tx_hook_on_pedal_pressed_on_unsafe_gas_mode(self): + for pedal in ['brake', 'gas']: + self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) + if pedal == 'brake': + # brake_pressed_prev and honda_moving + self.safety.safety_rx_hook(self._speed_msg(100)) + self.safety.safety_rx_hook(self._brake_msg(MAX_BRAKE)) + allow_ctrl = False + elif pedal == 'gas': + # gas_pressed_prev + self.safety.safety_rx_hook(self._gas_msg(MAX_GAS)) + allow_ctrl = True + + self.safety.set_controls_allowed(1) + self.assertEqual(allow_ctrl, self.safety.safety_tx_hook(self._send_brake_msg(MAX_BRAKE))) + self.assertEqual(allow_ctrl, self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP))) + self.assertEqual(allow_ctrl, self.safety.safety_tx_hook(self._send_gas_msg(MAX_GAS))) + + # reset status + self.safety.set_controls_allowed(0) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + self.safety.safety_tx_hook(self._send_brake_msg(0)) + self.safety.safety_tx_hook(self._torque_msg(0)) + if pedal == 'brake': + self.safety.safety_rx_hook(self._speed_msg(0)) + self.safety.safety_rx_hook(self._brake_msg(0)) + elif pedal == 'gas': + self.safety.safety_rx_hook(self._gas_msg(0)) if __name__ == "__main__": unittest.main() diff --git a/tests/safety/test_honda.py b/tests/safety/test_honda.py index adf02fd5c..3b3827f76 100755 --- a/tests/safety/test_honda.py +++ b/tests/safety/test_honda.py @@ -3,7 +3,7 @@ import unittest import numpy as np from panda import Panda from panda.tests.safety import libpandasafety_py -from panda.tests.safety.common import StdTest, make_msg, MAX_WRONG_COUNTERS +from panda.tests.safety.common import StdTest, make_msg, MAX_WRONG_COUNTERS, UNSAFE_MODE MAX_BRAKE = 255 @@ -189,6 +189,14 @@ class TestHondaSafety(unittest.TestCase): self.safety.safety_rx_hook(self._gas_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) + def test_unsafe_mode_no_disengage_on_gas(self): + self.safety.safety_rx_hook(self._gas_msg(0)) + self.safety.set_controls_allowed(1) + self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) + self.safety.safety_rx_hook(self._gas_msg(1)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + def test_allow_engage_with_gas_pressed(self): self.safety.safety_rx_hook(self._gas_msg(1)) self.safety.set_controls_allowed(1) @@ -205,6 +213,17 @@ class TestHondaSafety(unittest.TestCase): self.safety.safety_rx_hook(self._send_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.safety.safety_rx_hook(self._send_interceptor_msg(g, 0x201)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._send_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.safety.safety_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) self.safety.set_controls_allowed(1) @@ -335,6 +354,79 @@ class TestHondaSafety(unittest.TestCase): self.safety.set_honda_fwd_brake(False) + def test_tx_hook_on_pedal_pressed(self): + for pedal in ['brake', 'gas', 'interceptor']: + if pedal == 'brake': + # brake_pressed_prev and honda_moving + self.safety.safety_rx_hook(self._speed_msg(100)) + self.safety.safety_rx_hook(self._brake_msg(1)) + elif pedal == 'gas': + # gas_pressed_prev + self.safety.safety_rx_hook(self._gas_msg(1)) + elif pedal == 'interceptor': + # gas_interceptor_prev > INTERCEPTOR_THRESHOLD + self.safety.safety_rx_hook(self._send_interceptor_msg(INTERCEPTOR_THRESHOLD+1, 0x201)) + self.safety.safety_rx_hook(self._send_interceptor_msg(INTERCEPTOR_THRESHOLD+1, 0x201)) + + self.safety.set_controls_allowed(1) + hw = self.safety.get_honda_hw() + if hw == HONDA_N_HW: + self.safety.set_honda_fwd_brake(False) + self.assertFalse(self.safety.safety_tx_hook(self._send_brake_msg(MAX_BRAKE))) + self.assertFalse(self.safety.safety_tx_hook(self._send_interceptor_msg(INTERCEPTOR_THRESHOLD, 0x200))) + self.assertFalse(self.safety.safety_tx_hook(self._send_steer_msg(0x1000))) + + # reset status + self.safety.set_controls_allowed(0) + self.safety.safety_tx_hook(self._send_brake_msg(0)) + self.safety.safety_tx_hook(self._send_steer_msg(0)) + self.safety.safety_tx_hook(self._send_interceptor_msg(0, 0x200)) + if pedal == 'brake': + self.safety.safety_rx_hook(self._speed_msg(0)) + self.safety.safety_rx_hook(self._brake_msg(0)) + elif pedal == 'gas': + self.safety.safety_rx_hook(self._gas_msg(0)) + elif pedal == 'interceptor': + self.safety.set_gas_interceptor_detected(False) + + def test_tx_hook_on_pedal_pressed_on_unsafe_gas_mode(self): + for pedal in ['brake', 'gas', 'interceptor']: + self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) + if pedal == 'brake': + # brake_pressed_prev and honda_moving + self.safety.safety_rx_hook(self._speed_msg(100)) + self.safety.safety_rx_hook(self._brake_msg(1)) + allow_ctrl = False + elif pedal == 'gas': + # gas_pressed_prev + self.safety.safety_rx_hook(self._gas_msg(1)) + allow_ctrl = True + elif pedal == 'interceptor': + # gas_interceptor_prev > INTERCEPTOR_THRESHOLD + self.safety.safety_rx_hook(self._send_interceptor_msg(INTERCEPTOR_THRESHOLD+1, 0x201)) + self.safety.safety_rx_hook(self._send_interceptor_msg(INTERCEPTOR_THRESHOLD+1, 0x201)) + allow_ctrl = True + + self.safety.set_controls_allowed(1) + hw = self.safety.get_honda_hw() + if hw == HONDA_N_HW: + self.safety.set_honda_fwd_brake(False) + self.assertEqual(allow_ctrl, self.safety.safety_tx_hook(self._send_brake_msg(MAX_BRAKE))) + self.assertEqual(allow_ctrl, self.safety.safety_tx_hook(self._send_interceptor_msg(INTERCEPTOR_THRESHOLD, 0x200))) + self.assertEqual(allow_ctrl, self.safety.safety_tx_hook(self._send_steer_msg(0x1000))) + # reset status + self.safety.set_controls_allowed(0) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + self.safety.safety_tx_hook(self._send_brake_msg(0)) + self.safety.safety_tx_hook(self._send_steer_msg(0)) + self.safety.safety_tx_hook(self._send_interceptor_msg(0, 0x200)) + if pedal == 'brake': + self.safety.safety_rx_hook(self._speed_msg(0)) + self.safety.safety_rx_hook(self._brake_msg(0)) + elif pedal == 'gas': + self.safety.safety_rx_hook(self._gas_msg(0)) + elif pedal == 'interceptor': + self.safety.set_gas_interceptor_detected(False) class TestHondaBoschGiraffeSafety(TestHondaSafety): @classmethod diff --git a/tests/safety/test_hyundai.py b/tests/safety/test_hyundai.py index 2d022759e..29fa64d91 100644 --- a/tests/safety/test_hyundai.py +++ b/tests/safety/test_hyundai.py @@ -3,7 +3,7 @@ import unittest import numpy as np from panda import Panda from panda.tests.safety import libpandasafety_py -from panda.tests.safety.common import StdTest, make_msg +from panda.tests.safety.common import StdTest, make_msg, UNSAFE_MODE MAX_RATE_UP = 3 MAX_RATE_DOWN = 7 @@ -114,6 +114,14 @@ class TestHyundaiSafety(unittest.TestCase): self.safety.safety_rx_hook(self._gas_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) + def test_unsafe_mode_no_disengage_on_gas(self): + self.safety.safety_rx_hook(self._gas_msg(0)) + self.safety.set_controls_allowed(True) + self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) + self.safety.safety_rx_hook(self._gas_msg(1)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + def test_brake_disengage(self): StdTest.test_allow_brake_at_zero_speed(self) StdTest.test_not_allow_brake_when_moving(self, SPEED_THRESHOLD) diff --git a/tests/safety/test_nissan.py b/tests/safety/test_nissan.py index dc41b3d35..bce0eabb6 100644 --- a/tests/safety/test_nissan.py +++ b/tests/safety/test_nissan.py @@ -3,7 +3,7 @@ import unittest import numpy as np from panda import Panda from panda.tests.safety import libpandasafety_py -from panda.tests.safety.common import StdTest, make_msg +from panda.tests.safety.common import StdTest, make_msg, UNSAFE_MODE ANGLE_DELTA_BP = [0., 5., 15.] ANGLE_DELTA_V = [5., .8, .15] # windup limit @@ -154,6 +154,14 @@ class TestNissanSafety(unittest.TestCase): self.safety.safety_rx_hook(self._send_gas_cmd(100)) self.assertFalse(self.safety.get_controls_allowed()) + def test_unsafe_mode_no_disengage_on_gas(self): + self.safety.safety_rx_hook(self._send_gas_cmd(0)) + self.safety.set_controls_allowed(True) + self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) + self.safety.safety_rx_hook(self._send_gas_cmd(100)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + def test_acc_buttons(self): self.safety.set_controls_allowed(1) self.safety.safety_tx_hook(self._acc_button_cmd(0x2)) # Cancel button diff --git a/tests/safety/test_subaru.py b/tests/safety/test_subaru.py index d68090d19..9f1f5c45a 100644 --- a/tests/safety/test_subaru.py +++ b/tests/safety/test_subaru.py @@ -3,7 +3,7 @@ import unittest import numpy as np from panda import Panda from panda.tests.safety import libpandasafety_py -from panda.tests.safety.common import StdTest, make_msg +from panda.tests.safety.common import StdTest, make_msg, UNSAFE_MODE MAX_RATE_UP = 50 MAX_RATE_DOWN = 70 @@ -155,6 +155,14 @@ class TestSubaruSafety(unittest.TestCase): self.safety.safety_rx_hook(self._gas_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) + def test_unsafe_mode_no_disengage_on_gas(self): + self.safety.safety_rx_hook(self._gas_msg(0)) + self.safety.set_controls_allowed(True) + self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) + self.safety.safety_rx_hook(self._gas_msg(1)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + def test_brake_disengage(self): if (self.safety.get_subaru_global()): StdTest.test_allow_brake_at_zero_speed(self) diff --git a/tests/safety/test_toyota.py b/tests/safety/test_toyota.py index bc0795595..76786e2e6 100644 --- a/tests/safety/test_toyota.py +++ b/tests/safety/test_toyota.py @@ -3,7 +3,7 @@ import unittest import numpy as np from panda import Panda from panda.tests.safety import libpandasafety_py -from panda.tests.safety.common import StdTest, make_msg +from panda.tests.safety.common import StdTest, make_msg, UNSAFE_MODE MAX_RATE_UP = 10 MAX_RATE_DOWN = 25 @@ -12,6 +12,9 @@ MAX_TORQUE = 1500 MAX_ACCEL = 1500 MIN_ACCEL = -3000 +ISO_MAX_ACCEL = 2000 +ISO_MIN_ACCEL = -3500 + MAX_RT_DELTA = 375 RT_INTERVAL = 250000 @@ -154,6 +157,14 @@ class TestToyotaSafety(unittest.TestCase): self.safety.safety_rx_hook(self._send_gas_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) + def test_unsafe_mode_no_disengage_on_gas(self): + self.safety.safety_rx_hook(self._send_gas_msg(0)) + self.safety.set_controls_allowed(True) + self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS) + self.safety.safety_rx_hook(self._send_gas_msg(1)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + def test_allow_engage_with_gas_pressed(self): self.safety.safety_rx_hook(self._send_gas_msg(1)) self.safety.set_controls_allowed(True) @@ -172,6 +183,17 @@ class TestToyotaSafety(unittest.TestCase): self.safety.safety_rx_hook(self._send_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.safety.safety_rx_hook(self._send_interceptor_msg(g, 0x201)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._send_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_brake_disengage(self): StdTest.test_allow_brake_at_zero_speed(self) StdTest.test_not_allow_brake_when_moving(self, STANDSTILL_THRESHOLD) @@ -194,6 +216,18 @@ class TestToyotaSafety(unittest.TestCase): send = accel == 0 self.assertEqual(send, self.safety.safety_tx_hook(self._accel_msg(accel))) + def test_unsafe_iso_accel_actuation_limits(self): + for accel in np.arange(ISO_MIN_ACCEL - 1000, ISO_MAX_ACCEL + 1000, 100): + for controls_allowed in [True, False]: + self.safety.set_controls_allowed(controls_allowed) + self.safety.set_unsafe_mode(UNSAFE_MODE.RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX) + if controls_allowed: + send = ISO_MIN_ACCEL <= accel <= ISO_MAX_ACCEL + else: + send = accel == 0 + self.assertEqual(send, self.safety.safety_tx_hook(self._accel_msg(accel))) + self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) + def test_torque_absolute_limits(self): for controls_allowed in [True, False]: for torque in np.arange(-MAX_TORQUE - 1000, MAX_TORQUE + 1000, MAX_RATE_UP):