diff --git a/board/health.h b/board/health.h index a1b7ed95..8745cb0e 100644 --- a/board/health.h +++ b/board/health.h @@ -1,6 +1,6 @@ // When changing these structs, python/__init__.py needs to be kept up to date! -#define HEALTH_PACKET_VERSION 14 +#define HEALTH_PACKET_VERSION 15 struct __attribute__((packed)) health_t { uint32_t uptime_pkt; uint32_t voltage_pkt; @@ -14,7 +14,6 @@ struct __attribute__((packed)) health_t { uint8_t ignition_line_pkt; uint8_t ignition_can_pkt; uint8_t controls_allowed_pkt; - uint8_t gas_interceptor_detected_pkt; uint8_t car_harness_status_pkt; uint8_t safety_mode_pkt; uint16_t safety_param_pkt; diff --git a/board/main_comms.h b/board/main_comms.h index df698fb1..e5ba719f 100644 --- a/board/main_comms.h +++ b/board/main_comms.h @@ -17,7 +17,6 @@ int get_health_pkt(void *dat) { health->ignition_can_pkt = (uint8_t)(ignition_can); health->controls_allowed_pkt = controls_allowed; - health->gas_interceptor_detected_pkt = gas_interceptor_detected; health->safety_tx_blocked_pkt = safety_tx_blocked; health->safety_rx_invalid_pkt = safety_rx_invalid; health->tx_buffer_overflow_pkt = tx_buffer_overflow; diff --git a/board/safety.h b/board/safety.h index 758223fb..4b6ebf94 100644 --- a/board/safety.h +++ b/board/safety.h @@ -332,7 +332,7 @@ int set_safety_hooks(uint16_t mode, uint16_t param) { // reset state set by safety mode safety_mode_cnt = 0U; relay_malfunction = false; - gas_interceptor_detected = false; + enable_gas_interceptor = false; gas_interceptor_prev = 0; gas_pressed = false; gas_pressed_prev = false; diff --git a/board/safety/safety_honda.h b/board/safety/safety_honda.h index 6bdc4005..8e75c8e9 100644 --- a/board/safety/safety_honda.h +++ b/board/safety/safety_honda.h @@ -1,4 +1,5 @@ -const CanMsg HONDA_N_TX_MSGS[] = {{0xE4, 0, 5}, {0x194, 0, 4}, {0x1FA, 0, 8}, {0x200, 0, 6}, {0x30C, 0, 8}, {0x33D, 0, 5}}; +const CanMsg HONDA_N_TX_MSGS[] = {{0xE4, 0, 5}, {0x194, 0, 4}, {0x1FA, 0, 8}, {0x30C, 0, 8}, {0x33D, 0, 5}}; +const CanMsg HONDA_N_INTERCEPTOR_TX_MSGS[] = {{0xE4, 0, 5}, {0x194, 0, 4}, {0x1FA, 0, 8}, {0x200, 0, 6}, {0x30C, 0, 8}, {0x33D, 0, 5}}; const CanMsg HONDA_BOSCH_TX_MSGS[] = {{0xE4, 0, 5}, {0xE5, 0, 8}, {0x296, 1, 4}, {0x33D, 0, 5}, {0x33DA, 0, 5}, {0x33DB, 0, 8}}; // Bosch const CanMsg HONDA_BOSCH_LONG_TX_MSGS[] = {{0xE4, 1, 5}, {0x1DF, 1, 8}, {0x1EF, 1, 8}, {0x1FA, 1, 8}, {0x30C, 1, 8}, {0x33D, 1, 5}, {0x33DA, 1, 5}, {0x33DB, 1, 8}, {0x39F, 1, 8}, {0x18DAB0F1, 1, 8}}; // Bosch w/ gas and brakes const CanMsg HONDA_RADARLESS_TX_MSGS[] = {{0xE4, 0, 5}, {0x296, 2, 4}, {0x33D, 0, 8}}; // Bosch radarless @@ -46,6 +47,11 @@ RxCheck honda_common_rx_checks[] = { HONDA_COMMON_RX_CHECKS(0) }; +RxCheck honda_common_interceptor_rx_checks[] = { + HONDA_COMMON_RX_CHECKS(0) + {.msg = {{0x201, 0, 6, .check_checksum = false, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, +}; + RxCheck honda_common_alt_brake_rx_checks[] = { HONDA_COMMON_RX_CHECKS(0) HONDA_ALT_BRAKE_ADDR_CHECK(0) @@ -56,6 +62,11 @@ RxCheck honda_nidec_alt_rx_checks[] = { HONDA_COMMON_NO_SCM_FEEDBACK_RX_CHECKS(0) }; +RxCheck honda_nidec_alt_interceptor_rx_checks[] = { + HONDA_COMMON_NO_SCM_FEEDBACK_RX_CHECKS(0) + {.msg = {{0x201, 0, 6, .check_checksum = false, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, +}; + // Bosch has pt on bus 1, verified 0x1A6 does not exist RxCheck honda_bosch_rx_checks[] = { HONDA_COMMON_RX_CHECKS(1) @@ -70,6 +81,7 @@ const uint16_t HONDA_PARAM_ALT_BRAKE = 1; const uint16_t HONDA_PARAM_BOSCH_LONG = 2; const uint16_t HONDA_PARAM_NIDEC_ALT = 4; const uint16_t HONDA_PARAM_RADARLESS = 8; +const uint16_t HONDA_PARAM_GAS_INTERCEPTOR = 16; enum { HONDA_BTN_NONE = 0, @@ -115,13 +127,22 @@ static uint32_t honda_compute_checksum(CANPacket_t *to_push) { } static uint8_t honda_get_counter(CANPacket_t *to_push) { - int counter_byte = GET_LEN(to_push) - 1U; - return ((uint8_t)(GET_BYTE(to_push, counter_byte)) >> 4U) & 0x3U; + int addr = GET_ADDR(to_push); + + uint8_t cnt = 0U; + if (addr == 0x201) { + // Signal: COUNTER_PEDAL + cnt = GET_BYTE(to_push, 4) & 0x0FU; + } else { + int counter_byte = GET_LEN(to_push) - 1U; + cnt = (GET_BYTE(to_push, counter_byte) >> 4U) & 0x3U; + } + return cnt; } static void honda_rx_hook(CANPacket_t *to_push) { const bool pcm_cruise = ((honda_hw == HONDA_BOSCH) && !honda_bosch_long) || \ - ((honda_hw == HONDA_NIDEC) && !gas_interceptor_detected); + ((honda_hw == HONDA_NIDEC) && !enable_gas_interceptor); int pt_bus = honda_get_pt_bus(); int addr = GET_ADDR(to_push); @@ -198,14 +219,13 @@ static void honda_rx_hook(CANPacket_t *to_push) { } // length check because bosch hardware also uses this id (0x201 w/ len = 8) - if ((addr == 0x201) && (len == 6)) { - gas_interceptor_detected = 1; + if ((addr == 0x201) && (len == 6) && enable_gas_interceptor) { int gas_interceptor = HONDA_GET_INTERCEPTOR(to_push); gas_pressed = gas_interceptor > HONDA_GAS_INTERCEPTOR_THRESHOLD; gas_interceptor_prev = gas_interceptor; } - if (!gas_interceptor_detected) { + if (!enable_gas_interceptor) { if (addr == 0x17C) { gas_pressed = GET_BYTE(to_push, 0) != 0U; } @@ -359,12 +379,21 @@ static safety_config honda_nidec_init(uint16_t param) { honda_alt_brake_msg = false; honda_bosch_long = false; honda_bosch_radarless = false; + enable_gas_interceptor = GET_FLAG(param, HONDA_PARAM_GAS_INTERCEPTOR); safety_config ret; if (GET_FLAG(param, HONDA_PARAM_NIDEC_ALT)) { - ret = BUILD_SAFETY_CFG(honda_nidec_alt_rx_checks, HONDA_N_TX_MSGS); + enable_gas_interceptor ? SET_RX_CHECKS(honda_nidec_alt_interceptor_rx_checks, ret) : \ + SET_RX_CHECKS(honda_nidec_alt_rx_checks, ret); } else { - ret= BUILD_SAFETY_CFG(honda_common_rx_checks, HONDA_N_TX_MSGS); + enable_gas_interceptor ? SET_RX_CHECKS(honda_common_interceptor_rx_checks, ret) : \ + SET_RX_CHECKS(honda_common_rx_checks, ret); + } + + if (enable_gas_interceptor) { + SET_TX_MSGS(HONDA_N_INTERCEPTOR_TX_MSGS, ret); + } else { + SET_TX_MSGS(HONDA_N_TX_MSGS, ret); } return ret; } diff --git a/board/safety/safety_toyota.h b/board/safety/safety_toyota.h index c1144e65..fc87c48f 100644 --- a/board/safety/safety_toyota.h +++ b/board/safety/safety_toyota.h @@ -43,10 +43,19 @@ const LongitudinalLimits TOYOTA_LONG_LIMITS = { const int TOYOTA_GAS_INTERCEPTOR_THRSLD = 805; #define TOYOTA_GET_INTERCEPTOR(msg) (((GET_BYTE((msg), 0) << 8) + GET_BYTE((msg), 1) + (GET_BYTE((msg), 2) << 8) + GET_BYTE((msg), 3)) / 2U) // avg between 2 tracks -const CanMsg TOYOTA_TX_MSGS[] = {{0x283, 0, 7}, {0x2E6, 0, 8}, {0x2E7, 0, 8}, {0x33E, 0, 7}, {0x344, 0, 8}, {0x365, 0, 7}, {0x366, 0, 7}, {0x4CB, 0, 8}, // DSU bus 0 - {0x128, 1, 6}, {0x141, 1, 4}, {0x160, 1, 8}, {0x161, 1, 7}, {0x470, 1, 4}, // DSU bus 1 - {0x2E4, 0, 5}, {0x191, 0, 8}, {0x411, 0, 8}, {0x412, 0, 8}, {0x343, 0, 8}, {0x1D2, 0, 8}, // LKAS + ACC - {0x200, 0, 6}}; // gas interceptor +#define TOYOTA_COMMON_TX_MSGS \ + {0x283, 0, 7}, {0x2E6, 0, 8}, {0x2E7, 0, 8}, {0x33E, 0, 7}, {0x344, 0, 8}, {0x365, 0, 7}, {0x366, 0, 7}, {0x4CB, 0, 8}, /* DSU bus 0 */ \ + {0x128, 1, 6}, {0x141, 1, 4}, {0x160, 1, 8}, {0x161, 1, 7}, {0x470, 1, 4}, /* DSU bus 1 */ \ + {0x2E4, 0, 5}, {0x191, 0, 8}, {0x411, 0, 8}, {0x412, 0, 8}, {0x343, 0, 8}, {0x1D2, 0, 8}, /* LKAS + ACC */ \ + +const CanMsg TOYOTA_TX_MSGS[] = { + TOYOTA_COMMON_TX_MSGS +}; + +const CanMsg TOYOTA_INTERCEPTOR_TX_MSGS[] = { + TOYOTA_COMMON_TX_MSGS + {0x200, 0, 6}, // gas interceptor +}; #define TOYOTA_COMMON_RX_CHECKS(lta) \ {.msg = {{ 0xaa, 0, 8, .check_checksum = false, .frequency = 83U}, { 0 }, { 0 }}}, \ @@ -59,11 +68,21 @@ RxCheck toyota_lka_rx_checks[] = { TOYOTA_COMMON_RX_CHECKS(false) }; +RxCheck toyota_lka_interceptor_rx_checks[] = { + TOYOTA_COMMON_RX_CHECKS(false) + {.msg = {{0x201, 0, 6, .check_checksum = false, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, +}; + +// Check the quality flag for angle measurement when using LTA, since it's not set on TSS-P cars RxCheck toyota_lta_rx_checks[] = { - // Check the quality flag for angle measurement when using LTA, since it's not set on TSS-P cars TOYOTA_COMMON_RX_CHECKS(true) }; +RxCheck toyota_lta_interceptor_rx_checks[] = { + TOYOTA_COMMON_RX_CHECKS(true) + {.msg = {{0x201, 0, 6, .check_checksum = false, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, +}; + // safety param flags // first byte is for EPS factor, second is for flags const uint32_t TOYOTA_PARAM_OFFSET = 8U; @@ -71,6 +90,7 @@ const uint32_t TOYOTA_EPS_FACTOR = (1U << TOYOTA_PARAM_OFFSET) - 1U; const uint32_t TOYOTA_PARAM_ALT_BRAKE = 1U << TOYOTA_PARAM_OFFSET; const uint32_t TOYOTA_PARAM_STOCK_LONGITUDINAL = 2U << TOYOTA_PARAM_OFFSET; const uint32_t TOYOTA_PARAM_LTA = 4U << TOYOTA_PARAM_OFFSET; +const uint32_t TOYOTA_PARAM_GAS_INTERCEPTOR = 8U << TOYOTA_PARAM_OFFSET; bool toyota_alt_brake = false; bool toyota_stock_longitudinal = false; @@ -92,6 +112,17 @@ static uint32_t toyota_get_checksum(CANPacket_t *to_push) { return (uint8_t)(GET_BYTE(to_push, checksum_byte)); } +static uint8_t toyota_get_counter(CANPacket_t *to_push) { + int addr = GET_ADDR(to_push); + + uint8_t cnt = 0U; + if (addr == 0x201) { + // Signal: COUNTER_PEDAL + cnt = GET_BYTE(to_push, 4) & 0x0FU; + } + return cnt; +} + static bool toyota_get_quality_flag_valid(CANPacket_t *to_push) { int addr = GET_ADDR(to_push); @@ -144,7 +175,7 @@ static void toyota_rx_hook(CANPacket_t *to_push) { pcm_cruise_check(cruise_engaged); // sample gas pedal - if (!gas_interceptor_detected) { + if (!enable_gas_interceptor) { gas_pressed = GET_BIT(to_push, 4U) == 0U; } } @@ -170,8 +201,7 @@ static void toyota_rx_hook(CANPacket_t *to_push) { } // sample gas interceptor - if (addr == 0x201) { - gas_interceptor_detected = 1; + if ((addr == 0x201) && enable_gas_interceptor) { int gas_interceptor = TOYOTA_GET_INTERCEPTOR(to_push); gas_pressed = gas_interceptor > TOYOTA_GAS_INTERCEPTOR_THRSLD; @@ -304,13 +334,21 @@ static safety_config toyota_init(uint16_t param) { toyota_alt_brake = GET_FLAG(param, TOYOTA_PARAM_ALT_BRAKE); toyota_stock_longitudinal = GET_FLAG(param, TOYOTA_PARAM_STOCK_LONGITUDINAL); toyota_lta = GET_FLAG(param, TOYOTA_PARAM_LTA); + enable_gas_interceptor = GET_FLAG(param, TOYOTA_PARAM_GAS_INTERCEPTOR); toyota_dbc_eps_torque_factor = param & TOYOTA_EPS_FACTOR; + // Gas interceptor should not be used if openpilot is not controlling longitudinal + if (toyota_stock_longitudinal) { + enable_gas_interceptor = false; + } + safety_config ret; if (toyota_lta) { - ret = BUILD_SAFETY_CFG(toyota_lta_rx_checks, TOYOTA_TX_MSGS); + ret = enable_gas_interceptor ? BUILD_SAFETY_CFG(toyota_lta_interceptor_rx_checks, TOYOTA_INTERCEPTOR_TX_MSGS) : \ + BUILD_SAFETY_CFG(toyota_lta_rx_checks, TOYOTA_TX_MSGS); } else { - ret = BUILD_SAFETY_CFG(toyota_lka_rx_checks, TOYOTA_TX_MSGS); + ret = enable_gas_interceptor ? BUILD_SAFETY_CFG(toyota_lka_interceptor_rx_checks, TOYOTA_INTERCEPTOR_TX_MSGS) : \ + BUILD_SAFETY_CFG(toyota_lka_rx_checks, TOYOTA_TX_MSGS); } return ret; } @@ -345,5 +383,6 @@ const safety_hooks toyota_hooks = { .fwd = toyota_fwd_hook, .get_checksum = toyota_get_checksum, .compute_checksum = toyota_compute_checksum, + .get_counter = toyota_get_counter, .get_quality_flag_valid = toyota_get_quality_flag_valid, }; diff --git a/board/safety_declarations.h b/board/safety_declarations.h index 7ac0a460..ec0e986a 100644 --- a/board/safety_declarations.h +++ b/board/safety_declarations.h @@ -212,7 +212,7 @@ void safety_tick(const safety_config *safety_config); // This can be set by the safety hooks bool controls_allowed = false; bool relay_malfunction = false; -bool gas_interceptor_detected = false; +bool enable_gas_interceptor = false; int gas_interceptor_prev = 0; bool gas_pressed = false; bool gas_pressed_prev = false; diff --git a/drivers/windows/panda_shared/panda.h b/drivers/windows/panda_shared/panda.h index cac3e6dc..a9c9b0e2 100644 --- a/drivers/windows/panda_shared/panda.h +++ b/drivers/windows/panda_shared/panda.h @@ -90,7 +90,6 @@ namespace panda { uint8_t ignition_line; uint8_t ignition_can; uint8_t controls_allowed; - uint8_t gas_interceptor_detected; uint8_t car_harness_status; uint8_t usb_power_mode; uint8_t safety_mode; diff --git a/python/__init__.py b/python/__init__.py index 274e7dbe..1c92c964 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -167,9 +167,9 @@ class Panda: HW_TYPE_TRES = b'\x09' CAN_PACKET_VERSION = 4 - HEALTH_PACKET_VERSION = 14 + HEALTH_PACKET_VERSION = 15 CAN_HEALTH_PACKET_VERSION = 5 - HEALTH_STRUCT = struct.Struct(" int: ... def set_relay_malfunction(self, c: bool) -> None: ... def get_relay_malfunction(self) -> bool: ... - def set_gas_interceptor_detected(self, c: bool) -> None: ... - def get_gas_interceptor_detected(self) -> bool: ... def get_gas_interceptor_prev(self) -> int: ... def get_gas_pressed_prev(self) -> bool: ... def get_brake_pressed_prev(self) -> bool: ... diff --git a/tests/safety/common.py b/tests/safety/common.py index 17c82071..8b70966a 100644 --- a/tests/safety/common.py +++ b/tests/safety/common.py @@ -129,7 +129,7 @@ class GasInterceptorSafetyTest(PandaSafetyTestBase): @classmethod def setUpClass(cls): - if cls.__name__ == "GasInterceptorSafetyTest": + if cls.__name__ == "GasInterceptorSafetyTest" or cls.__name__.endswith("Base"): cls.safety = None raise unittest.SkipTest @@ -147,6 +147,16 @@ class GasInterceptorSafetyTest(PandaSafetyTestBase): self.__class__.cnt_user_gas += 1 return self.packer.make_can_msg_panda("GAS_SENSOR", 0, values) + # Skip non-interceptor user gas tests + def test_prev_gas(self): + pass + + def test_disengage_on_gas(self): + pass + + def test_alternative_experience_no_disengage_on_gas(self): + pass + def test_prev_gas_interceptor(self): self._rx(self._interceptor_user_gas(0x0)) self.assertFalse(self.safety.get_gas_interceptor_prev()) diff --git a/tests/safety/test_honda.py b/tests/safety/test_honda.py index 5be2d399..08d069b5 100755 --- a/tests/safety/test_honda.py +++ b/tests/safety/test_honda.py @@ -8,6 +8,8 @@ from panda.tests.libpanda import libpanda_py import panda.tests.safety.common as common from panda.tests.safety.common import CANPackerPanda, MAX_WRONG_COUNTERS +HONDA_N_COMMON_TX_MSGS = [[0xE4, 0], [0x194, 0], [0x1FA, 0], [0x30C, 0], [0x33D, 0]] + class Btn: NONE = 0 MAIN = 1 @@ -21,10 +23,10 @@ HONDA_BOSCH = 1 # Honda safety has several different configurations tested here: # * Nidec -# * normal -# * alt SCM messages -# * gas interceptor -# * gas interceptor with alt SCM messages +# * normal (PCM-enable) +# * alt SCM messages (PCM-enable) +# * gas interceptor (button-enable) +# * gas interceptor with alt SCM messages (button-enable) # * Bosch # * Bosch with Longitudinal Support # * Bosch Radarless @@ -71,7 +73,7 @@ class HondaButtonEnableBase(common.PandaCarSafetyTest): btn_prev in (Btn.RESUME, Btn.SET) and btn_cur not in (Btn.CANCEL, Btn.MAIN)) - self._rx(self._button_msg(btn_cur)) + self._rx(self._button_msg(btn_cur, main_on=main_on)) self.assertEqual(should_enable, self.safety.get_controls_allowed(), msg=f"{main_on=} {btn_prev=} {btn_cur=}") def test_main_cancel_buttons(self): @@ -131,7 +133,7 @@ class HondaButtonEnableBase(common.PandaCarSafetyTest): # restore counters for future tests with a couple of good messages for _ in range(2): self.safety.set_controls_allowed(1) - self._rx(self._button_msg(Btn.SET)) + self._rx(self._button_msg(Btn.SET, main_on=True)) self._rx(self._speed_msg(0)) self._rx(self._user_gas_msg(0)) self._rx(self._button_msg(Btn.SET, main_on=True)) @@ -256,14 +258,13 @@ class HondaBase(common.PandaCarSafetyTest): class TestHondaNidecSafetyBase(HondaBase): - TX_MSGS = [[0xE4, 0], [0x194, 0], [0x1FA, 0], [0x200, 0], [0x30C, 0], [0x33D, 0]] + TX_MSGS = HONDA_N_COMMON_TX_MSGS FWD_BLACKLISTED_ADDRS = {2: [0xE4, 0x194, 0x33D, 0x30C]} PT_BUS = 0 STEER_BUS = 0 BUTTONS_BUS = 0 - INTERCEPTOR_THRESHOLD = 492 MAX_GAS = 198 def setUp(self): @@ -342,7 +343,7 @@ class TestHondaNidecSafetyBase(HondaBase): self.assertEqual(send, self._tx(self._send_brake_msg(brake))) -class TestHondaNidecSafety(HondaPcmEnableBase, TestHondaNidecSafetyBase): +class TestHondaNidecPcmSafety(HondaPcmEnableBase, TestHondaNidecSafetyBase): """ Covers the Honda Nidec safety mode """ @@ -352,13 +353,22 @@ class TestHondaNidecSafety(HondaPcmEnableBase, TestHondaNidecSafetyBase): pass -class TestHondaNidecGasInterceptorSafety(TestHondaNidecSafety, common.GasInterceptorSafetyTest): +class TestHondaNidecGasInterceptorSafety(common.GasInterceptorSafetyTest, HondaButtonEnableBase, TestHondaNidecSafetyBase): """ - Covers the Honda Nidec safety mode with a gas interceptor + Covers the Honda Nidec safety mode with a gas interceptor, switches to a button-enable car """ + TX_MSGS = HONDA_N_COMMON_TX_MSGS + [[0x200, 0]] + INTERCEPTOR_THRESHOLD = 492 -class TestHondaNidecAltSafety(TestHondaNidecSafety): + def setUp(self): + self.packer = CANPackerPanda("honda_civic_touring_2016_can_generated") + self.safety = libpanda_py.libpanda + self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC, Panda.FLAG_HONDA_GAS_INTERCEPTOR) + self.safety.init_tests() + + +class TestHondaNidecPcmAltSafety(TestHondaNidecPcmSafety): """ Covers the Honda Nidec safety mode with alt SCM messages """ @@ -380,14 +390,18 @@ class TestHondaNidecAltSafety(TestHondaNidecSafety): return self.packer.make_can_msg_panda("SCM_BUTTONS", bus, values) -class TestHondaNidecAltGasInterceptorSafety(TestHondaNidecSafety, common.GasInterceptorSafetyTest): +class TestHondaNidecAltGasInterceptorSafety(common.GasInterceptorSafetyTest, HondaButtonEnableBase, TestHondaNidecSafetyBase): """ - Covers the Honda Nidec safety mode with alt SCM messages and gas interceptor + Covers the Honda Nidec safety mode with alt SCM messages and gas interceptor, switches to a button-enable car """ + + TX_MSGS = HONDA_N_COMMON_TX_MSGS + [[0x200, 0]] + INTERCEPTOR_THRESHOLD = 492 + def setUp(self): self.packer = CANPackerPanda("acura_ilx_2016_can_generated") self.safety = libpanda_py.libpanda - self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC, Panda.FLAG_HONDA_NIDEC_ALT) + self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC, Panda.FLAG_HONDA_NIDEC_ALT | Panda.FLAG_HONDA_GAS_INTERCEPTOR) self.safety.init_tests() def _acc_state_msg(self, main_on): diff --git a/tests/safety/test_toyota.py b/tests/safety/test_toyota.py index 9f3a8d03..8ef07eea 100755 --- a/tests/safety/test_toyota.py +++ b/tests/safety/test_toyota.py @@ -10,18 +10,19 @@ import panda.tests.safety.common as common from panda.tests.safety.common import CANPackerPanda -class TestToyotaSafetyBase(common.PandaCarSafetyTest, common.GasInterceptorSafetyTest, - common.LongitudinalAccelSafetyTest): +TOYOTA_COMMON_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 + [0x2E4, 0], [0x191, 0], [0x411, 0], [0x412, 0], [0x343, 0], [0x1D2, 0], # LKAS + ACC + [0x750, 0]] # blindspot monitor - 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 - [0x2E4, 0], [0x191, 0], [0x411, 0], [0x412, 0], [0x343, 0], [0x1D2, 0], # LKAS + ACC - [0x200, 0], [0x750, 0]] # gas interceptor + blindspot monitor + +class TestToyotaSafetyBase(common.PandaCarSafetyTest, common.LongitudinalAccelSafetyTest): + + TX_MSGS = TOYOTA_COMMON_TX_MSGS STANDSTILL_THRESHOLD = 0 # kph RELAY_MALFUNCTION_ADDRS = {0: (0x2E4,)} FWD_BLACKLISTED_ADDRS = {2: [0x2E4, 0x412, 0x191, 0x343]} FWD_BUS_LOOKUP = {0: 2, 2: 0} - INTERCEPTOR_THRESHOLD = 805 EPS_SCALE = 73 packer: CANPackerPanda @@ -118,6 +119,32 @@ class TestToyotaSafetyBase(common.PandaCarSafetyTest, common.GasInterceptorSafet self.assertFalse(self.safety.get_controls_allowed()) +class TestToyotaSafetyGasInterceptorBase(common.GasInterceptorSafetyTest, TestToyotaSafetyBase): + + TX_MSGS = TOYOTA_COMMON_TX_MSGS + [[0x200, 0]] + INTERCEPTOR_THRESHOLD = 805 + + def setUp(self): + super().setUp() + self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, self.safety.get_current_safety_param() | + Panda.FLAG_TOYOTA_GAS_INTERCEPTOR) + self.safety.init_tests() + + def test_stock_longitudinal(self): + # If stock longitudinal is set, the gas interceptor safety param should not be respected + self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, self.safety.get_current_safety_param() | + Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL) + self.safety.init_tests() + + # Spot check a few gas interceptor tests: (1) reading interceptor, + # (2) behavior around interceptor, and (3) txing interceptor msgs + for test in (self.test_prev_gas_interceptor, self.test_disengage_on_gas_interceptor, + self.test_gas_interceptor_safety_check): + with self.subTest(test=test.__name__): + with self.assertRaises(AssertionError): + test() + + class TestToyotaSafetyTorque(TestToyotaSafetyBase, common.MotorTorqueSteeringSafetyTest, common.SteerRequestCutSafetyTest): MAX_RATE_UP = 15 @@ -140,6 +167,10 @@ class TestToyotaSafetyTorque(TestToyotaSafetyBase, common.MotorTorqueSteeringSaf self.safety.init_tests() +class TestToyotaSafetyTorqueGasInterceptor(TestToyotaSafetyGasInterceptorBase, TestToyotaSafetyTorque): + pass + + class TestToyotaSafetyAngle(TestToyotaSafetyBase, common.AngleSteeringSafetyTest): # Angle control limits @@ -253,6 +284,10 @@ class TestToyotaSafetyAngle(TestToyotaSafetyBase, common.AngleSteeringSafetyTest self.assertEqual(self.safety.get_angle_meas_max(), 0) +class TestToyotaSafetyAngleGasInterceptor(TestToyotaSafetyGasInterceptorBase, TestToyotaSafetyAngle): + pass + + class TestToyotaAltBrakeSafety(TestToyotaSafetyTorque): def setUp(self): @@ -270,6 +305,10 @@ class TestToyotaAltBrakeSafety(TestToyotaSafetyTorque): pass +class TestToyotaAltBrakeSafetyGasInterceptor(TestToyotaSafetyGasInterceptorBase, TestToyotaAltBrakeSafety): + pass + + class TestToyotaStockLongitudinalBase(TestToyotaSafetyBase): # Base fwd addresses minus ACC_CONTROL (0x343)