class TestHondaNidecAltInterceptorSafety(TestHondaNidecSafety, common.InterceptorSafetyTest): """ Covers the Honda Nidec safety mode with alt SCM messages and gas interceptor """ def setUp(self): self.packer = CANPackerPanda("acura_ilx_2016_can_generated") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC, Panda.FLAG_HONDA_NIDEC_ALT) self.safety.init_tests_honda() def _acc_state_msg(self, main_on): values = {"MAIN_ON": main_on, "COUNTER": self.cnt_acc_state % 4} self.__class__.cnt_acc_state += 1 return self.packer.make_can_msg_panda("SCM_BUTTONS", self.PT_BUS, values) def _button_msg(self, buttons, main_on=False): values = { "CRUISE_BUTTONS": buttons, "MAIN_ON": main_on, "COUNTER": self.cnt_button % 4 } self.__class__.cnt_button += 1 return self.packer.make_can_msg_panda("SCM_BUTTONS", self.PT_BUS, values)
def setUp(self): self.packer = CANPackerPanda("acura_ilx_2016_can_generated") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC, Panda.FLAG_HONDA_NIDEC_ALT) self.safety.init_tests_honda() common.InterceptorSafetyTest.setUpClass()
def setUp(self): self.packer = CANPackerPanda("tesla_powertrain") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks( Panda.SAFETY_TESLA, Panda.FLAG_TESLA_LONG_CONTROL | Panda.FLAG_TESLA_POWERTRAIN) self.safety.init_tests()
class TestSubaruLegacySafety(TestSubaruSafety): TX_MSGS = [[0x164, 0], [0x221, 0], [0x322, 0]] RELAY_MALFUNCTION_ADDR = 0x164 RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS = {2: [356, 545, 802]} FWD_BUS_LOOKUP = {0: 2, 2: 0} def setUp(self): self.packer = CANPackerPanda("subaru_outback_2015_eyesight") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_SUBARU_LEGACY, 0) self.safety.init_tests() # subaru legacy safety doesn't have brake checks def test_prev_brake(self): pass def test_not_allow_brake_when_moving(self): pass def test_allow_brake_at_zero_speed(self): pass # doesn't have speed checks either def test_sample_speed(self): pass def _torque_driver_msg(self, torque): # TODO: figure out if this scaling factor from the DBC is right. # if it is, remove the scaling from here and put it in the safety code values = {"Steer_Torque_Sensor": torque * 8} return self.packer.make_can_msg_panda("Steering_Torque", 0, values) def _torque_msg(self, torque): values = {"LKAS_Command": torque} return self.packer.make_can_msg_panda("ES_LKAS", 0, values) def _gas_msg(self, gas): values = {"Throttle_Pedal": gas} return self.packer.make_can_msg_panda("Throttle", 0, values) def _pcm_status_msg(self, enable): values = {"Cruise_Activated": enable} return self.packer.make_can_msg_panda("CruiseControl", 0, values)
class TestNissanLeafSafety(TestNissanSafety): def setUp(self): self.packer = CANPackerPanda("nissan_leaf_2018") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_NISSAN, 0) self.safety.init_tests() def _user_brake_msg(self, brake): values = {"USER_BRAKE_PRESSED": brake} return self.packer.make_can_msg_panda("CRUISE_THROTTLE", 0, values) def _user_gas_msg(self, gas): values = {"GAS_PEDAL": gas} return self.packer.make_can_msg_panda("CRUISE_THROTTLE", 0, values) # TODO: leaf should use its own safety param def test_acc_buttons(self): pass
class TestHyundaiLegacySafetyHEV(TestHyundaiSafety): def setUp(self): self.packer = CANPackerPanda("hyundai_kia_generic") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI_LEGACY, 2) self.safety.init_tests() def _gas_msg(self, gas): values = {"CR_Vcu_AccPedDep_Pos": gas} return self.packer.make_can_msg_panda("E_EMS11", 0, values, fix_checksum=checksum)
class TestHondaBoschSafetyBase(TestHondaSafetyBase): PT_BUS = 1 STEER_BUS = 0 TX_MSGS = [[0xE4, 0], [0xE5, 0], [0x296, 1], [0x33D, 0], [0x33DA, 0], [0x33DB, 0]] FWD_BLACKLISTED_ADDRS = {2: [0xE4, 0xE5, 0x33D, 0x33DA, 0x33DB]} @classmethod def setUpClass(cls): if cls.__name__ == "TestHondaBoschSafetyBase": cls.packer = None cls.safety = None raise unittest.SkipTest def setUp(self): self.packer = CANPackerPanda("honda_accord_2018_can_generated") self.safety = libpandasafety_py.libpandasafety def _alt_brake_msg(self, brake): values = {"BRAKE_PRESSED": brake, "COUNTER": self.cnt_brake % 4} self.__class__.cnt_brake += 1 return self.packer.make_can_msg_panda("BRAKE_MODULE", self.PT_BUS, values) def _send_brake_msg(self, brake): pass # TODO: add back in once alternative brake checksum/counter validation is added # def test_alt_brake_rx_hook(self): # self.safety.set_honda_alt_brake_msg(1) # self.safety.set_controls_allowed(1) # to_push = self._alt_brake_msg(0) # self.assertTrue(self._rx(to_push)) # to_push[0].RDLR = to_push[0].RDLR & 0xFFF0FFFF # invalidate checksum # self.assertFalse(self._rx(to_push)) # self.assertFalse(self.safety.get_controls_allowed()) def test_alt_disengage_on_brake(self): self.safety.set_honda_alt_brake_msg(1) self.safety.set_controls_allowed(1) self._rx(self._alt_brake_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) self.safety.set_honda_alt_brake_msg(0) self.safety.set_controls_allowed(1) self._rx(self._alt_brake_msg(1)) self.assertTrue(self.safety.get_controls_allowed())
class TestHondaBoschSafety(TestHondaSafety): STANDSTILL_THRESHOLD = 0 RELAY_MALFUNCTION_ADDR = 0xE4 @classmethod def setUpClass(cls): if cls.__name__ == "TestHondaBoschSafety": cls.packer = None cls.safety = None raise unittest.SkipTest def setUp(self): self.packer = CANPackerPanda("honda_accord_s2t_2018_can_generated") self.safety = libpandasafety_py.libpandasafety def _alt_brake_msg(self, brake): values = {"BRAKE_PRESSED": brake, "COUNTER": self.cnt_brake % 4} self.__class__.cnt_brake += 1 return self.packer.make_can_msg_panda("BRAKE_MODULE", self.PT_BUS, values) def _send_brake_msg(self, brake): pass # TODO: add back in once alternative brake checksum/counter validation is added # def test_alt_brake_rx_hook(self): # self.safety.set_honda_alt_brake_msg(1) # self.safety.set_controls_allowed(1) # to_push = self._alt_brake_msg(0) # self.assertTrue(self._rx(to_push)) # to_push[0].RDLR = to_push[0].RDLR & 0xFFF0FFFF # invalidate checksum # self.assertFalse(self._rx(to_push)) # self.assertFalse(self.safety.get_controls_allowed()) def test_alt_disengage_on_brake(self): self.safety.set_honda_alt_brake_msg(1) self.safety.set_controls_allowed(1) self._rx(self._alt_brake_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) self.safety.set_honda_alt_brake_msg(0) self.safety.set_controls_allowed(1) self._rx(self._alt_brake_msg(1)) self.assertTrue(self.safety.get_controls_allowed())
def setUp(self): self.packer = CANPackerPanda("chrysler_pacifica_2017_hybrid") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_CHRYSLER, 0) self.safety.init_tests()
def setUp(self): self.packer = CANPackerPanda("honda_accord_s2t_2018_can_generated") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_HONDA_BOSCH_HARNESS, 0) self.safety.init_tests_honda()
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()
def setUp(self): self.packer = CANPackerPanda("toyota_prius_2017_pt_generated") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, 66) self.safety.init_tests()
def setUp(self): self.packer = CANPackerPanda("nissan_x_trail_2017") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_NISSAN, 0) self.safety.init_tests()
def setUp(self): self.packer = CANPackerPanda("subaru_outback_2015_eyesight") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_SUBARU_LEGACY, 0) self.safety.init_tests_subaru()
class TestToyotaSafety(common.PandaSafetyTest, common.InterceptorSafetyTest, common.TorqueSteeringSafetyTest): 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] ] # interceptor + blindspot monitor STANDSTILL_THRESHOLD = 1 # 1kph RELAY_MALFUNCTION_ADDR = 0x2E4 RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS = {2: [0x2E4, 0x412, 0x191, 0x343]} FWD_BUS_LOOKUP = {0: 2, 2: 0} INTERCEPTOR_THRESHOLD = 845 MAX_RATE_UP = 15 MAX_RATE_DOWN = 25 MAX_TORQUE = 1500 MAX_RT_DELTA = 450 RT_INTERVAL = 250000 MAX_TORQUE_ERROR = 350 TORQUE_MEAS_TOLERANCE = 1 # toyota safety adds one to be conversative for rounding EPS_SCALE = 0.73 def setUp(self): self.packer = CANPackerPanda("toyota_nodsu_pt_generated") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, 73) self.safety.init_tests() def _torque_meas_msg(self, torque): values = {"STEER_TORQUE_EPS": (torque / self.EPS_SCALE)} return self.packer.make_can_msg_panda("STEER_TORQUE_SENSOR", 0, values) def _torque_msg(self, torque): values = {"STEER_TORQUE_CMD": torque} return self.packer.make_can_msg_panda("STEERING_LKA", 0, values) def _lta_msg(self, req, req2, angle_cmd): values = { "STEER_REQUEST": req, "STEER_REQUEST_2": req2, "STEER_ANGLE_CMD": angle_cmd } return self.packer.make_can_msg_panda("STEERING_LTA", 0, values) def _accel_msg(self, accel): values = {"ACCEL_CMD": accel} return self.packer.make_can_msg_panda("ACC_CONTROL", 0, values) def _speed_msg(self, speed): values = {("WHEEL_SPEED_%s" % n): speed for n in ["FR", "FL", "RR", "RL"]} return self.packer.make_can_msg_panda("WHEEL_SPEEDS", 0, values) def _user_brake_msg(self, brake): values = {"BRAKE_PRESSED": brake} return self.packer.make_can_msg_panda("BRAKE_MODULE", 0, values) def _user_gas_msg(self, gas): cruise_active = self.safety.get_controls_allowed() values = {"GAS_RELEASED": not gas, "CRUISE_ACTIVE": cruise_active} return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values) def _pcm_status_msg(self, enable): values = {"CRUISE_ACTIVE": enable} return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values) def _interceptor_gas_cmd(self, gas): return interceptor_msg(gas, 0x200) def _interceptor_user_gas(self, gas): return interceptor_msg(gas, 0x201) def test_block_aeb(self): for controls_allowed in (True, False): for bad in (True, False): for _ in range(10): self.safety.set_controls_allowed(controls_allowed) dat = [random.randint(1, 255) for _ in range(7)] if not bad: dat = [0] * 6 + dat[-1:] msg = common.package_can_msg([0x283, 0, bytes(dat), 0]) self.assertEqual(not bad, self._tx(msg)) def test_accel_actuation_limits(self): limits = ((MIN_ACCEL, MAX_ACCEL, ALTERNATIVE_EXPERIENCE.DEFAULT), ( MIN_ACCEL, MAX_ACCEL, ALTERNATIVE_EXPERIENCE.RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX)) for min_accel, max_accel, alternative_experience in limits: for accel in np.arange(min_accel - 1, max_accel + 1, 0.1): for controls_allowed in [True, False]: self.safety.set_controls_allowed(controls_allowed) self.safety.set_alternative_experience( alternative_experience) if controls_allowed: should_tx = int(min_accel * 1000) <= int( accel * 1000) <= int(max_accel * 1000) else: should_tx = np.isclose(accel, 0, atol=0.0001) self.assertEqual(should_tx, self._tx(self._accel_msg(accel))) # Only allow LTA msgs with no actuation def test_lta_steer_cmd(self): for engaged in [True, False]: self.safety.set_controls_allowed(engaged) # good msg self.assertTrue(self._tx(self._lta_msg(0, 0, 0))) # bad msgs self.assertFalse(self._tx(self._lta_msg(1, 0, 0))) self.assertFalse(self._tx(self._lta_msg(0, 1, 0))) self.assertFalse(self._tx(self._lta_msg(0, 0, 1))) for _ in range(20): req = random.choice([0, 1]) req2 = random.choice([0, 1]) angle = random.randint(-50, 50) should_tx = not req and not req2 and angle == 0 self.assertEqual(should_tx, self._tx(self._lta_msg(req, req2, angle))) def test_rx_hook(self): # checksum checks for msg in ["trq", "pcm"]: self.safety.set_controls_allowed(1) if msg == "trq": to_push = self._torque_meas_msg(0) if msg == "pcm": to_push = self._pcm_status_msg(True) self.assertTrue(self._rx(to_push)) to_push[0].data[4] = 0 to_push[0].data[5] = 0 to_push[0].data[6] = 0 to_push[0].data[7] = 0 self.assertFalse(self._rx(to_push)) self.assertFalse(self.safety.get_controls_allowed())
def setUp(self): self.packer = CANPackerPanda("vw_mqb_2010") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_VOLKSWAGEN_MQB, 0) self.safety.init_tests_volkswagen()
class TestVolkswagenMqbSafety(common.PandaSafetyTest): cnt_eps_01 = 0 cnt_esp_05 = 0 cnt_tsk_06 = 0 cnt_motor_20 = 0 cnt_hca_01 = 0 cnt_gra_acc_01 = 0 # Transmit of GRA_ACC_01 is allowed on bus 0 and 2 to keep # compatibility with gateway and camera integration TX_MSGS = [[MSG_HCA_01, 0], [MSG_GRA_ACC_01, 0], [MSG_GRA_ACC_01, 2], [MSG_LDW_02, 0]] STANDSTILL_THRESHOLD = 1 RELAY_MALFUNCTION_ADDR = MSG_HCA_01 RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS = {2: [MSG_HCA_01, MSG_LDW_02]} FWD_BUS_LOOKUP = {0: 2, 2: 0} @classmethod def setUp(self): self.packer = CANPackerPanda("vw_mqb_2010") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_VOLKSWAGEN_MQB, 0) self.safety.init_tests_volkswagen() # override these inherited tests from PandaSafetyTest def test_cruise_engaged_prev(self): pass def _set_prev_torque(self, t): self.safety.set_volkswagen_desired_torque_last(t) self.safety.set_volkswagen_rt_torque_last(t) # Wheel speeds _esp_19_msg 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 _brake_msg(self, brake): values = {"ESP_Fahrer_bremst": brake, "COUNTER": self.cnt_esp_05 % 16} self.__class__.cnt_esp_05 += 1 return self.packer.make_can_msg_panda("ESP_05", 0, values) # Driver throttle input def _gas_msg(self, gas): values = {"MO_Fahrpedalrohwert_01": gas, "COUNTER": self.cnt_motor_20 % 16} self.__class__.cnt_motor_20 += 1 return self.packer.make_can_msg_panda("Motor_20", 0, values) # ACC engagement status def _pcm_status_msg(self, enable): values = {"TSK_Status": 3 if enable else 1, "COUNTER": self.cnt_tsk_06 % 16} self.__class__.cnt_tsk_06 += 1 return self.packer.make_can_msg_panda("TSK_06", 0, values) # Driver steering input torque def _eps_01_msg(self, torque): values = {"Driver_Strain": abs(torque), "Driver_Strain_VZ": torque < 0, "COUNTER": self.cnt_eps_01 % 16} self.__class__.cnt_eps_01 += 1 return self.packer.make_can_msg_panda("EPS_01", 0, values) # openpilot steering output torque def _hca_01_msg(self, torque): values = {"Assist_Torque": abs(torque), "Assist_VZ": torque < 0, "COUNTER": self.cnt_hca_01 % 16} self.__class__.cnt_hca_01 += 1 return self.packer.make_can_msg_panda("HCA_01", 0, values) # Cruise control buttons def _gra_acc_01_msg(self, cancel=0, resume=0, _set=0): values = {"GRA_Abbrechen": cancel, "GRA_Tip_Setzen": _set, "GRA_Tip_Wiederaufnahme": resume, "COUNTER": self.cnt_gra_acc_01 % 16} self.__class__.cnt_gra_acc_01 += 1 return self.packer.make_can_msg_panda("GRA_ACC_01", 0, values) def test_enable_control_allowed_from_cruise(self): self.safety.set_controls_allowed(0) self._rx(self._pcm_status_msg(True)) self.assertTrue(self.safety.get_controls_allowed()) def test_disable_control_allowed_from_cruise(self): self.safety.set_controls_allowed(1) self._rx(self._pcm_status_msg(False)) self.assertFalse(self.safety.get_controls_allowed()) def test_steer_safety_check(self): for enabled in [0, 1]: for t in range(-500, 500): self.safety.set_controls_allowed(enabled) self._set_prev_torque(t) if abs(t) > MAX_STEER or (not enabled and abs(t) > 0): self.assertFalse(self._tx(self._hca_01_msg(t))) else: self.assertTrue(self._tx(self._hca_01_msg(t))) def test_spam_cancel_safety_check(self): self.safety.set_controls_allowed(0) self.assertTrue(self._tx(self._gra_acc_01_msg(cancel=1))) self.assertFalse(self._tx(self._gra_acc_01_msg(resume=1))) self.assertFalse(self._tx(self._gra_acc_01_msg(_set=1))) # do not block resume if we are engaged already self.safety.set_controls_allowed(1) self.assertTrue(self._tx(self._gra_acc_01_msg(resume=1))) def test_non_realtime_limit_up(self): self.safety.set_volkswagen_torque_driver(0, 0) self.safety.set_controls_allowed(True) self._set_prev_torque(0) self.assertTrue(self._tx(self._hca_01_msg(MAX_RATE_UP))) self._set_prev_torque(0) self.assertTrue(self._tx(self._hca_01_msg(-MAX_RATE_UP))) self._set_prev_torque(0) self.assertFalse(self._tx(self._hca_01_msg(MAX_RATE_UP + 1))) self.safety.set_controls_allowed(True) self._set_prev_torque(0) self.assertFalse(self._tx(self._hca_01_msg(-MAX_RATE_UP - 1))) def test_non_realtime_limit_down(self): self.safety.set_volkswagen_torque_driver(0, 0) self.safety.set_controls_allowed(True) def test_against_torque_driver(self): self.safety.set_controls_allowed(True) for sign in [-1, 1]: for t in np.arange(0, DRIVER_TORQUE_ALLOWANCE + 1, 1): t *= -sign self.safety.set_volkswagen_torque_driver(t, t) self._set_prev_torque(MAX_STEER * sign) self.assertTrue(self._tx(self._hca_01_msg(MAX_STEER * sign))) self.safety.set_volkswagen_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1) self.assertFalse(self._tx(self._hca_01_msg(-MAX_STEER))) # spot check some individual cases for sign in [-1, 1]: driver_torque = (DRIVER_TORQUE_ALLOWANCE + 10) * sign torque_desired = (MAX_STEER - 10 * DRIVER_TORQUE_FACTOR) * sign delta = 1 * sign self._set_prev_torque(torque_desired) self.safety.set_volkswagen_torque_driver(-driver_torque, -driver_torque) self.assertTrue(self._tx(self._hca_01_msg(torque_desired))) self._set_prev_torque(torque_desired + delta) self.safety.set_volkswagen_torque_driver(-driver_torque, -driver_torque) self.assertFalse(self._tx(self._hca_01_msg(torque_desired + delta))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) self.assertTrue(self._tx(self._hca_01_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) self.assertTrue(self._tx(self._hca_01_msg(0))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) self.assertFalse(self._tx(self._hca_01_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) def test_realtime_limits(self): self.safety.set_controls_allowed(True) for sign in [-1, 1]: self.safety.init_tests_volkswagen() self._set_prev_torque(0) self.safety.set_volkswagen_torque_driver(0, 0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign self.assertTrue(self._tx(self._hca_01_msg(t))) self.assertFalse(self._tx(self._hca_01_msg(sign * (MAX_RT_DELTA + 1)))) self._set_prev_torque(0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign self.assertTrue(self._tx(self._hca_01_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) self.assertTrue(self._tx(self._hca_01_msg(sign * (MAX_RT_DELTA - 1)))) self.assertTrue(self._tx(self._hca_01_msg(sign * (MAX_RT_DELTA + 1)))) def test_torque_measurements(self): self._rx(self._eps_01_msg(50)) self._rx(self._eps_01_msg(-50)) self._rx(self._eps_01_msg(0)) self._rx(self._eps_01_msg(0)) self._rx(self._eps_01_msg(0)) self._rx(self._eps_01_msg(0)) self.assertEqual(-50, self.safety.get_volkswagen_torque_driver_min()) self.assertEqual(50, self.safety.get_volkswagen_torque_driver_max()) self._rx(self._eps_01_msg(0)) self.assertEqual(0, self.safety.get_volkswagen_torque_driver_max()) self.assertEqual(-50, self.safety.get_volkswagen_torque_driver_min()) self._rx(self._eps_01_msg(0)) self.assertEqual(0, self.safety.get_volkswagen_torque_driver_max()) self.assertEqual(0, self.safety.get_volkswagen_torque_driver_min()) def test_rx_hook(self): # checksum checks # 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_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._brake_msg(False) if msg == MSG_TSK_06: to_push = self._pcm_status_msg(True) if msg == MSG_MOTOR_20: to_push = self._gas_msg(0) self.assertTrue(self._rx(to_push)) to_push[0].RDHR ^= 0xFF self.assertFalse(self._rx(to_push)) self.assertFalse(self.safety.get_controls_allowed()) # counter # reset wrong_counters to zero by sending valid messages 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 if i < MAX_WRONG_COUNTERS: self.safety.set_controls_allowed(1) self._rx(self._eps_01_msg(0)) self._rx(self._brake_msg(False)) self._rx(self._pcm_status_msg(True)) self._rx(self._gas_msg(0)) else: self.assertFalse(self._rx(self._eps_01_msg(0))) self.assertFalse(self._rx(self._brake_msg(False))) self.assertFalse(self._rx(self._pcm_status_msg(True))) self.assertFalse(self._rx(self._gas_msg(0))) 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._rx(self._eps_01_msg(0)) self._rx(self._brake_msg(False)) self._rx(self._pcm_status_msg(True)) self._rx(self._gas_msg(0)) self.assertTrue(self.safety.get_controls_allowed())
def setUp(self): self.packer = CANPackerPanda("tesla_can") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_TESLA, 0) self.safety.init_tests()
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 [0x2E4, 0], [0x411, 0], [0x412, 0], [0x343, 0], [0x1D2, 0], # LKAS + ACC [0x200, 0], [0x750, 0] ] # interceptor + blindspot monitor STANDSTILL_THRESHOLD = 1 # 1kph RELAY_MALFUNCTION_ADDR = 0x2E4 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): self.packer = CANPackerPanda("toyota_prius_2017_pt_generated") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, 66) self.safety.init_tests_toyota() def _set_prev_torque(self, t): self.safety.set_toyota_desired_torque_last(t) self.safety.set_toyota_rt_torque_last(t) self.safety.set_toyota_torque_meas(t, t) def _torque_meas_msg(self, torque): values = {"STEER_TORQUE_EPS": torque} return self.packer.make_can_msg_panda("STEER_TORQUE_SENSOR", 0, values) def _torque_msg(self, torque): values = {"STEER_TORQUE_CMD": torque} return self.packer.make_can_msg_panda("STEERING_LKA", 0, values) def _accel_msg(self, accel): values = {"ACCEL_CMD": accel} return self.packer.make_can_msg_panda("ACC_CONTROL", 0, values) def _speed_msg(self, s): values = {("WHEEL_SPEED_%s" % n): s for n in ["FR", "FL", "RR", "RL"]} return self.packer.make_can_msg_panda("WHEEL_SPEEDS", 0, values) def _brake_msg(self, pressed): values = {"BRAKE_PRESSED": pressed} return self.packer.make_can_msg_panda("BRAKE_MODULE", 0, values) def _gas_msg(self, pressed): cruise_active = self.safety.get_controls_allowed() values = {"GAS_RELEASED": not pressed, "CRUISE_ACTIVE": cruise_active} return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values) def _pcm_status_msg(self, cruise_on): values = {"CRUISE_ACTIVE": cruise_on} values["CHECKSUM"] = 1 return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values) # 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), (ISO_MIN_ACCEL, ISO_MAX_ACCEL, UNSAFE_MODE.RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX)) for min_accel, max_accel, unsafe_mode in limits: for accel in np.arange(min_accel - 1, max_accel + 1, 0.1): for controls_allowed in [True, False]: self.safety.set_controls_allowed(controls_allowed) self.safety.set_unsafe_mode(unsafe_mode) if controls_allowed: should_tx = int(min_accel * 1000) <= int( accel * 1000) <= int(max_accel * 1000) else: should_tx = np.isclose(accel, 0, atol=0.0001) self.assertEqual(should_tx, self._tx(self._accel_msg(accel))) 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): self.safety.set_controls_allowed(controls_allowed) self.safety.set_toyota_rt_torque_last(torque) self.safety.set_toyota_torque_meas(torque, torque) self.safety.set_toyota_desired_torque_last(torque - MAX_RATE_UP) if controls_allowed: send = (-MAX_TORQUE <= torque <= MAX_TORQUE) else: send = torque == 0 self.assertEqual(send, self._tx(self._torque_msg(torque))) def test_non_realtime_limit_up(self): self.safety.set_controls_allowed(True) self._set_prev_torque(0) self.assertTrue(self._tx(self._torque_msg(MAX_RATE_UP))) self._set_prev_torque(0) self.assertFalse(self._tx(self._torque_msg(MAX_RATE_UP + 1))) def test_non_realtime_limit_down(self): self.safety.set_controls_allowed(True) self.safety.set_toyota_rt_torque_last(1000) self.safety.set_toyota_torque_meas(500, 500) self.safety.set_toyota_desired_torque_last(1000) self.assertTrue(self._tx(self._torque_msg(1000 - MAX_RATE_DOWN))) self.safety.set_toyota_rt_torque_last(1000) self.safety.set_toyota_torque_meas(500, 500) self.safety.set_toyota_desired_torque_last(1000) self.assertFalse(self._tx(self._torque_msg(1000 - MAX_RATE_DOWN + 1))) def test_exceed_torque_sensor(self): self.safety.set_controls_allowed(True) for sign in [-1, 1]: self._set_prev_torque(0) for t in np.arange(0, MAX_TORQUE_ERROR + 10, 10): t *= sign self.assertTrue(self._tx(self._torque_msg(t))) self.assertFalse( self._tx(self._torque_msg(sign * (MAX_TORQUE_ERROR + 10)))) def test_realtime_limit_up(self): self.safety.set_controls_allowed(True) for sign in [-1, 1]: self.safety.init_tests_toyota() self._set_prev_torque(0) for t in np.arange(0, 380, 10): t *= sign self.safety.set_toyota_torque_meas(t, t) self.assertTrue(self._tx(self._torque_msg(t))) self.assertFalse(self._tx(self._torque_msg(sign * 380))) self._set_prev_torque(0) for t in np.arange(0, 370, 10): t *= sign self.safety.set_toyota_torque_meas(t, t) self.assertTrue(self._tx(self._torque_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) self.assertTrue(self._tx(self._torque_msg(sign * 370))) self.assertTrue(self._tx(self._torque_msg(sign * 380))) def test_torque_measurements(self): for trq in [50, -50, 0, 0, 0, 0]: self._rx(self._torque_meas_msg(trq)) # toyota safety adds one to be conservative on rounding self.assertEqual(-51, self.safety.get_toyota_torque_meas_min()) self.assertEqual(51, self.safety.get_toyota_torque_meas_max()) self._rx(self._torque_meas_msg(0)) self.assertEqual(1, self.safety.get_toyota_torque_meas_max()) self.assertEqual(-51, self.safety.get_toyota_torque_meas_min()) self._rx(self._torque_meas_msg(0)) self.assertEqual(1, self.safety.get_toyota_torque_meas_max()) self.assertEqual(-1, self.safety.get_toyota_torque_meas_min()) def test_rx_hook(self): # checksum checks for msg in ["trq", "pcm"]: self.safety.set_controls_allowed(1) if msg == "trq": to_push = self._torque_meas_msg(0) if msg == "pcm": to_push = self._pcm_status_msg(True) self.assertTrue(self._rx(to_push)) to_push[0].RDHR = 0 self.assertFalse(self._rx(to_push)) self.assertFalse(self.safety.get_controls_allowed())
class TestChryslerSafety(common.PandaSafetyTest, common.TorqueSteeringSafetyTest): TX_MSGS = [[571, 0], [658, 0], [678, 0]] STANDSTILL_THRESHOLD = 0 RELAY_MALFUNCTION_ADDR = 0x292 RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS = {2: [658, 678]} FWD_BUS_LOOKUP = {0: 2, 2: 0} MAX_RATE_UP = 3 MAX_RATE_DOWN = 3 MAX_TORQUE = 261 MAX_RT_DELTA = 112 RT_INTERVAL = 250000 MAX_TORQUE_ERROR = 80 cnt_torque_meas = 0 cnt_gas = 0 cnt_cruise = 0 cnt_brake = 0 def setUp(self): self.packer = CANPackerPanda("chrysler_pacifica_2017_hybrid") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_CHRYSLER, 0) self.safety.init_tests() def _button_msg(self, cancel): values = {"ACC_CANCEL": cancel} return self.packer.make_can_msg_panda("WHEEL_BUTTONS", 0, values) def _pcm_status_msg(self, enable): values = { "ACC_STATUS_2": 0x7 if enable else 0, "COUNTER": self.cnt_cruise % 16 } self.__class__.cnt_cruise += 1 return self.packer.make_can_msg_panda("ACC_2", 0, values) def _speed_msg(self, speed): values = {"SPEED_LEFT": speed, "SPEED_RIGHT": speed} return self.packer.make_can_msg_panda("SPEED_1", 0, values) def _gas_msg(self, gas): values = {"ACCEL_134": gas, "COUNTER": self.cnt_gas % 16} self.__class__.cnt_gas += 1 return self.packer.make_can_msg_panda("ACCEL_GAS_134", 0, values) def _brake_msg(self, brake): values = { "BRAKE_PRESSED_2": 5 if brake else 0, "COUNTER": self.cnt_brake % 16 } self.__class__.cnt_brake += 1 return self.packer.make_can_msg_panda("BRAKE_2", 0, values) def _torque_meas_msg(self, torque): values = {"TORQUE_MOTOR": torque, "COUNTER": self.cnt_torque_meas % 16} self.__class__.cnt_torque_meas += 1 return self.packer.make_can_msg_panda("EPS_STATUS", 0, values) def _torque_msg(self, torque): values = {"LKAS_STEERING_TORQUE": torque} return self.packer.make_can_msg_panda("LKAS_COMMAND", 0, values) def test_disengage_on_gas(self): self.safety.set_controls_allowed(1) self._rx(self._speed_msg(2.1)) self._rx(self._gas_msg(1)) self.assertTrue(self.safety.get_controls_allowed()) self._rx(self._gas_msg(0)) self._rx(self._speed_msg(2.2)) self._rx(self._gas_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) def test_cancel_button(self): for cancel in [True, False]: self.assertEqual(cancel, self._tx(self._button_msg(cancel)))
class TestNissanSafety(common.PandaSafetyTest): TX_MSGS = [[0x169, 0], [0x2b1, 0], [0x4cc, 0], [0x20b, 2], [0x280, 2]] STANDSTILL_THRESHOLD = 0 GAS_PRESSED_THRESHOLD = 3 RELAY_MALFUNCTION_ADDR = 0x169 RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS = {0: [0x280], 2: [0x169, 0x2b1, 0x4cc]} FWD_BUS_LOOKUP = {0: 2, 2: 0} def setUp(self): self.packer = CANPackerPanda("nissan_x_trail_2017") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_NISSAN, 0) self.safety.init_tests() def _angle_meas_msg(self, angle): values = {"STEER_ANGLE": angle} return self.packer.make_can_msg_panda("STEER_ANGLE_SENSOR", 0, values) def _set_prev_angle(self, t): t = int(t * -100) self.safety.set_desired_angle_last(t) def _angle_meas_msg_array(self, angle): for _ in range(6): self._rx(self._angle_meas_msg(angle)) def _pcm_status_msg(self, enable): values = {"CRUISE_ENABLED": enable} return self.packer.make_can_msg_panda("CRUISE_STATE", 2, values) def _lkas_control_msg(self, angle, state): values = {"DESIRED_ANGLE": angle, "LKA_ACTIVE": state} return self.packer.make_can_msg_panda("LKAS", 0, values) def _speed_msg(self, speed): # TODO: why the 3.6? m/s to kph? not in dbc values = {"WHEEL_SPEED_%s" % s: speed * 3.6 for s in ["RR", "RL"]} return self.packer.make_can_msg_panda("WHEEL_SPEEDS_REAR", 0, values) def _brake_msg(self, brake): values = {"USER_BRAKE_PRESSED": brake} return self.packer.make_can_msg_panda("DOORS_LIGHTS", 1, values) def _gas_msg(self, gas): values = {"GAS_PEDAL": gas} return self.packer.make_can_msg_panda("GAS_PEDAL", 0, values) def _acc_button_cmd(self, cancel=0, propilot=0, flw_dist=0, _set=0, res=0): no_button = not any([cancel, propilot, flw_dist, _set, res]) values = { "CANCEL_BUTTON": cancel, "PROPILOT_BUTTON": propilot, "FOLLOW_DISTANCE_BUTTON": flw_dist, "SET_BUTTON": _set, "RES_BUTTON": res, "NO_BUTTON_PRESSED": no_button } return self.packer.make_can_msg_panda("CRUISE_THROTTLE", 2, values) def test_angle_cmd_when_enabled(self): # when controls are allowed, angle cmd rate limit is enforced speeds = [0., 1., 5., 10., 15., 50.] angles = [-300, -100, -10, 0, 10, 100, 300] for a in angles: for s in speeds: max_delta_up = np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_V) max_delta_down = np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_VU) # first test against false positives self._angle_meas_msg_array(a) self._rx(self._speed_msg(s)) self._set_prev_angle(a) self.safety.set_controls_allowed(1) # Stay within limits # Up self.assertEqual( True, self._tx( self._lkas_control_msg(a + sign(a) * max_delta_up, 1))) self.assertTrue(self.safety.get_controls_allowed()) # Don't change self.assertEqual(True, self._tx(self._lkas_control_msg(a, 1))) self.assertTrue(self.safety.get_controls_allowed()) # Down self.assertEqual( True, self._tx( self._lkas_control_msg(a - sign(a) * max_delta_down, 1))) self.assertTrue(self.safety.get_controls_allowed()) # Inject too high rates # Up self.assertEqual( False, self._tx( self._lkas_control_msg( a + sign(a) * (max_delta_up + 1), 1))) self.assertFalse(self.safety.get_controls_allowed()) # Don't change self.safety.set_controls_allowed(1) self._set_prev_angle(a) self.assertTrue(self.safety.get_controls_allowed()) self.assertEqual(True, self._tx(self._lkas_control_msg(a, 1))) self.assertTrue(self.safety.get_controls_allowed()) # Down self.assertEqual( False, self._tx( self._lkas_control_msg( a - sign(a) * (max_delta_down + 1), 1))) self.assertFalse(self.safety.get_controls_allowed()) # Check desired steer should be the same as steer angle when controls are off self.safety.set_controls_allowed(0) self.assertEqual(True, self._tx(self._lkas_control_msg(a, 0))) def test_angle_cmd_when_disabled(self): self.safety.set_controls_allowed(0) self._set_prev_angle(0) self.assertFalse(self._tx(self._lkas_control_msg(0, 1))) self.assertFalse(self.safety.get_controls_allowed()) def test_acc_buttons(self): self.safety.set_controls_allowed(1) self._tx(self._acc_button_cmd(cancel=1)) self.assertTrue(self.safety.get_controls_allowed()) self._tx(self._acc_button_cmd(propilot=1)) self.assertFalse(self.safety.get_controls_allowed()) self.safety.set_controls_allowed(1) self._tx(self._acc_button_cmd(flw_dist=1)) self.assertFalse(self.safety.get_controls_allowed()) self.safety.set_controls_allowed(1) self._tx(self._acc_button_cmd(_set=1)) self.assertFalse(self.safety.get_controls_allowed()) self.safety.set_controls_allowed(1) self._tx(self._acc_button_cmd(res=1)) self.assertFalse(self.safety.get_controls_allowed()) self.safety.set_controls_allowed(1) self._tx(self._acc_button_cmd()) self.assertFalse(self.safety.get_controls_allowed())
class TestHyundaiSafety(common.PandaSafetyTest): TX_MSGS = [[832, 0], [1265, 0], [1157, 0]] STANDSTILL_THRESHOLD = 30 # ~1kph RELAY_MALFUNCTION_ADDR = 832 RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS = {2: [832, 1157]} FWD_BUS_LOOKUP = {0: 2, 2: 0} cnt_gas = 0 cnt_speed = 0 cnt_brake = 0 cnt_cruise = 0 def setUp(self): self.packer = CANPackerPanda("hyundai_kia_generic") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI, 0) self.safety.init_tests() def _button_msg(self, buttons): values = {"CF_Clu_CruiseSwState": buttons} return self.packer.make_can_msg_panda("CLU11", 0, values) def _gas_msg(self, gas): values = {"CF_Ems_AclAct": gas, "AliveCounter": self.cnt_gas % 4} self.__class__.cnt_gas += 1 return self.packer.make_can_msg_panda("EMS16", 0, values, fix_checksum=checksum) def _brake_msg(self, brake): values = {"DriverBraking": brake, "AliveCounterTCS": self.cnt_brake % 8} self.__class__.cnt_brake += 1 return self.packer.make_can_msg_panda("TCS13", 0, values, fix_checksum=checksum) def _speed_msg(self, speed): # panda safety doesn't scale, so undo the scaling values = {"WHL_SPD_%s" % s: speed * 0.03125 for s in ["FL", "FR", "RL", "RR"]} values["WHL_SPD_AliveCounter_LSB"] = (self.cnt_speed % 16) & 0x3 values["WHL_SPD_AliveCounter_MSB"] = (self.cnt_speed % 16) >> 2 self.__class__.cnt_speed += 1 return self.packer.make_can_msg_panda("WHL_SPD11", 0, values) def _pcm_status_msg(self, enable): values = {"ACCMode": enable, "CR_VSM_Alive": self.cnt_cruise % 16} self.__class__.cnt_cruise += 1 return self.packer.make_can_msg_panda("SCC12", 0, values, fix_checksum=checksum) def _set_prev_torque(self, t): self.safety.set_desired_torque_last(t) self.safety.set_rt_torque_last(t) # TODO: this is unused def _torque_driver_msg(self, torque): values = {"CR_Mdps_StrColTq": torque} return self.packer.make_can_msg_panda("MDPS12", 0, values) def _torque_msg(self, torque): values = {"CR_Lkas_StrToqReq": torque} return self.packer.make_can_msg_panda("LKAS11", 0, values) def test_steer_safety_check(self): for enabled in [0, 1]: for t in range(-0x200, 0x200): self.safety.set_controls_allowed(enabled) self._set_prev_torque(t) if abs(t) > MAX_STEER or (not enabled and abs(t) > 0): self.assertFalse(self._tx(self._torque_msg(t))) else: self.assertTrue(self._tx(self._torque_msg(t))) def test_non_realtime_limit_up(self): self.safety.set_torque_driver(0, 0) self.safety.set_controls_allowed(True) self._set_prev_torque(0) self.assertTrue(self._tx(self._torque_msg(MAX_RATE_UP))) self._set_prev_torque(0) self.assertTrue(self._tx(self._torque_msg(-MAX_RATE_UP))) self._set_prev_torque(0) self.assertFalse(self._tx(self._torque_msg(MAX_RATE_UP + 1))) self.safety.set_controls_allowed(True) self._set_prev_torque(0) self.assertFalse(self._tx(self._torque_msg(-MAX_RATE_UP - 1))) def test_non_realtime_limit_down(self): self.safety.set_torque_driver(0, 0) self.safety.set_controls_allowed(True) def test_against_torque_driver(self): self.safety.set_controls_allowed(True) for sign in [-1, 1]: for t in np.arange(0, DRIVER_TORQUE_ALLOWANCE + 1, 1): t *= -sign self.safety.set_torque_driver(t, t) self._set_prev_torque(MAX_STEER * sign) self.assertTrue(self._tx(self._torque_msg(MAX_STEER * sign))) self.safety.set_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1) self.assertFalse(self._tx(self._torque_msg(-MAX_STEER))) # spot check some individual cases for sign in [-1, 1]: driver_torque = (DRIVER_TORQUE_ALLOWANCE + 10) * sign torque_desired = (MAX_STEER - 10 * DRIVER_TORQUE_FACTOR) * sign delta = 1 * sign self._set_prev_torque(torque_desired) self.safety.set_torque_driver(-driver_torque, -driver_torque) self.assertTrue(self._tx(self._torque_msg(torque_desired))) self._set_prev_torque(torque_desired + delta) self.safety.set_torque_driver(-driver_torque, -driver_torque) self.assertFalse(self._tx(self._torque_msg(torque_desired + delta))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) self.assertTrue(self._tx(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) self.assertTrue(self._tx(self._torque_msg(0))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) self.assertFalse(self._tx(self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) def test_realtime_limits(self): self.safety.set_controls_allowed(True) for sign in [-1, 1]: self.safety.init_tests() self._set_prev_torque(0) self.safety.set_torque_driver(0, 0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign self.assertTrue(self._tx(self._torque_msg(t))) self.assertFalse(self._tx(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) self._set_prev_torque(0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign self.assertTrue(self._tx(self._torque_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) self.assertTrue(self._tx(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) self.assertTrue(self._tx(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) def test_spam_cancel_safety_check(self): RESUME_BTN = 1 SET_BTN = 2 CANCEL_BTN = 4 self.safety.set_controls_allowed(0) self.assertTrue(self._tx(self._button_msg(CANCEL_BTN))) self.assertFalse(self._tx(self._button_msg(RESUME_BTN))) self.assertFalse(self._tx(self._button_msg(SET_BTN))) # do not block resume if we are engaged already self.safety.set_controls_allowed(1) self.assertTrue(self._tx(self._button_msg(RESUME_BTN)))
class TestSubaruSafety(common.PandaSafetyTest): cnt_gas = 0 cnt_torque_driver = 0 cnt_cruise = 0 cnt_speed = 0 cnt_brake = 0 TX_MSGS = [[0x122, 0], [0x221, 0], [0x322, 0]] STANDSTILL_THRESHOLD = 20 # 1kph (see dbc file) RELAY_MALFUNCTION_ADDR = 0x122 RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS = {2: [290, 545, 802]} FWD_BUS_LOOKUP = {0: 2, 2: 0} def setUp(self): self.packer = CANPackerPanda("subaru_global_2017") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_SUBARU, 0) self.safety.init_tests_subaru() def _set_prev_torque(self, t): self.safety.set_subaru_desired_torque_last(t) self.safety.set_subaru_rt_torque_last(t) def _torque_driver_msg(self, torque): values = { "Steer_Torque_Sensor": -torque, "counter": self.cnt_torque_driver % 4 } self.__class__.cnt_torque_driver += 1 return self.packer.make_can_msg_panda("Steering_Torque", 0, values) def _speed_msg(self, speed): # subaru safety doesn't use the scaled value, so undo the scaling values = {s: speed * 0.057 for s in ["FR", "FL", "RR", "RL"]} values["Counter"] = self.cnt_speed % 4 self.__class__.cnt_speed += 1 return self.packer.make_can_msg_panda("Wheel_Speeds", 0, values) def _brake_msg(self, brake): values = {"Brake_Pedal": brake, "Counter": self.cnt_brake % 4} self.__class__.cnt_brake += 1 return self.packer.make_can_msg_panda("Brake_Pedal", 0, values) def _torque_msg(self, torque): values = {"LKAS_Output": -torque} return self.packer.make_can_msg_panda("ES_LKAS", 0, values) def _gas_msg(self, gas): values = {"Throttle_Pedal": gas, "Counter": self.cnt_gas % 4} self.__class__.cnt_gas += 1 return self.packer.make_can_msg_panda("Throttle", 0, values) def _pcm_status_msg(self, cruise): values = {"Cruise_Activated": cruise, "Counter": self.cnt_cruise % 4} self.__class__.cnt_cruise += 1 return self.packer.make_can_msg_panda("CruiseControl", 0, values) def _set_torque_driver(self, min_t, max_t): for i in range(0, 5): self.safety.safety_rx_hook(self._torque_driver_msg(min_t)) self.safety.safety_rx_hook(self._torque_driver_msg(max_t)) def test_steer_safety_check(self): for enabled in [0, 1]: for t in range(-3000, 3000): self.safety.set_controls_allowed(enabled) self._set_prev_torque(t) block = abs(t) > MAX_STEER or (not enabled and abs(t) > 0) self.assertEqual( not block, self.safety.safety_tx_hook(self._torque_msg(t))) def test_non_realtime_limit_up(self): self._set_torque_driver(0, 0) self.safety.set_controls_allowed(True) self._set_prev_torque(0) self.assertTrue( self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP))) self._set_prev_torque(0) self.assertTrue( self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP))) self._set_prev_torque(0) self.assertFalse( self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) self.safety.set_controls_allowed(True) self._set_prev_torque(0) self.assertFalse( self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) def test_non_realtime_limit_down(self): self._set_torque_driver(0, 0) self.safety.set_controls_allowed(True) def test_against_torque_driver(self): self.safety.set_controls_allowed(True) for sign in [-1, 1]: for t in np.arange(0, DRIVER_TORQUE_ALLOWANCE + 1, 1): t *= -sign self._set_torque_driver(t, t) self._set_prev_torque(MAX_STEER * sign) self.assertTrue( self.safety.safety_tx_hook( self._torque_msg(MAX_STEER * sign))) self._set_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1) self.assertFalse( self.safety.safety_tx_hook(self._torque_msg(-MAX_STEER))) # arbitrary high driver torque to ensure max steer torque is allowed max_driver_torque = int(MAX_STEER / DRIVER_TORQUE_FACTOR + DRIVER_TORQUE_ALLOWANCE + 1) # spot check some individual cases for sign in [-1, 1]: driver_torque = (DRIVER_TORQUE_ALLOWANCE + 10) * sign torque_desired = (MAX_STEER - 10 * DRIVER_TORQUE_FACTOR) * sign delta = 1 * sign self._set_prev_torque(torque_desired) self._set_torque_driver(-driver_torque, -driver_torque) self.assertTrue( self.safety.safety_tx_hook(self._torque_msg(torque_desired))) self._set_prev_torque(torque_desired + delta) self._set_torque_driver(-driver_torque, -driver_torque) self.assertFalse( self.safety.safety_tx_hook( self._torque_msg(torque_desired + delta))) self._set_prev_torque(MAX_STEER * sign) self._set_torque_driver(-max_driver_torque * sign, -max_driver_torque * sign) self.assertTrue( self.safety.safety_tx_hook( self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) self._set_prev_torque(MAX_STEER * sign) self._set_torque_driver(-max_driver_torque * sign, -max_driver_torque * sign) self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(0))) self._set_prev_torque(MAX_STEER * sign) self._set_torque_driver(-max_driver_torque * sign, -max_driver_torque * sign) self.assertFalse( self.safety.safety_tx_hook( self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) def test_realtime_limits(self): self.safety.set_controls_allowed(True) for sign in [-1, 1]: self.safety.init_tests_subaru() self._set_prev_torque(0) self._set_torque_driver(0, 0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign self.assertTrue(self.safety.safety_tx_hook( self._torque_msg(t))) self.assertFalse( self.safety.safety_tx_hook( self._torque_msg(sign * (MAX_RT_DELTA + 1)))) self._set_prev_torque(0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign self.assertTrue(self.safety.safety_tx_hook( self._torque_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) self.assertTrue( self.safety.safety_tx_hook( self._torque_msg(sign * (MAX_RT_DELTA - 1)))) self.assertTrue( self.safety.safety_tx_hook( self._torque_msg(sign * (MAX_RT_DELTA + 1))))
class TestGmSafety(common.PandaSafetyTest): TX_MSGS = [ [384, 0], [1033, 0], [1034, 0], [715, 0], [880, 0], # pt bus [161, 1], [774, 1], [776, 1], [784, 1], # obs bus [789, 2], # ch bus [0x104c006c, 3], [0x10400060, 3] ] # gmlan STANDSTILL_THRESHOLD = 0 RELAY_MALFUNCTION_ADDR = 384 RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS: Dict[int, List[int]] = {} FWD_BUS_LOOKUP: Dict[int, int] = {} def setUp(self): self.packer = CANPackerPanda("gm_global_a_powertrain") self.packer_chassis = CANPackerPanda("gm_global_a_chassis") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_GM, 0) self.safety.init_tests() # override these tests from PandaSafetyTest, GM uses button enable def test_disable_control_allowed_from_cruise(self): pass def test_enable_control_allowed_from_cruise(self): pass def test_cruise_engaged_prev(self): pass def _pcm_status_msg(self, enable): raise NotImplementedError def _speed_msg(self, speed): values = {"%sWheelSpd" % s: speed for s in ["RL", "RR"]} return self.packer.make_can_msg_panda("EBCMWheelSpdRear", 0, values) def _button_msg(self, buttons): values = {"ACCButtons": buttons} return self.packer.make_can_msg_panda("ASCMSteeringButton", 0, values) def _brake_msg(self, brake): # GM safety has a brake threshold of 10 values = {"BrakePedalPosition": 10 if brake else 0} return self.packer.make_can_msg_panda("EBCMBrakePedalPosition", 0, values) def _gas_msg(self, gas): values = {"AcceleratorPedal": 1 if gas else 0} return self.packer.make_can_msg_panda("AcceleratorPedal", 0, values) def _send_brake_msg(self, brake): values = {"FrictionBrakeCmd": -brake} return self.packer_chassis.make_can_msg_panda("EBCMFrictionBrakeCmd", 2, values) def _send_gas_msg(self, gas): values = {"GasRegenCmd": gas} return self.packer.make_can_msg_panda("ASCMGasRegenCmd", 0, values) def _set_prev_torque(self, t): self.safety.set_desired_torque_last(t) self.safety.set_rt_torque_last(t) def _torque_driver_msg(self, torque): values = {"LKADriverAppldTrq": torque} return self.packer.make_can_msg_panda("PSCMStatus", 0, values) def _torque_msg(self, torque): values = {"LKASteeringCmd": torque} return self.packer.make_can_msg_panda("ASCMLKASteeringCmd", 0, values) def test_resume_button(self): RESUME_BTN = 2 self.safety.set_controls_allowed(0) self._rx(self._button_msg(RESUME_BTN)) self.assertTrue(self.safety.get_controls_allowed()) def test_set_button(self): SET_BTN = 3 self.safety.set_controls_allowed(0) self._rx(self._button_msg(SET_BTN)) self.assertTrue(self.safety.get_controls_allowed()) def test_cancel_button(self): CANCEL_BTN = 6 self.safety.set_controls_allowed(1) self._rx(self._button_msg(CANCEL_BTN)) self.assertFalse(self.safety.get_controls_allowed()) def test_brake_safety_check(self): for enabled in [0, 1]: for b in range(0, 500): self.safety.set_controls_allowed(enabled) if abs(b) > MAX_BRAKE or (not enabled and b != 0): self.assertFalse(self._tx(self._send_brake_msg(b))) else: self.assertTrue(self._tx(self._send_brake_msg(b))) def test_gas_safety_check(self): for enabled in [0, 1]: for g in range(0, 2**12 - 1): self.safety.set_controls_allowed(enabled) if abs(g) > MAX_GAS or (not enabled and g != MAX_REGEN): self.assertFalse(self._tx(self._send_gas_msg(g))) else: self.assertTrue(self._tx(self._send_gas_msg(g))) def test_steer_safety_check(self): for enabled in [0, 1]: for t in range(-0x200, 0x200): self.safety.set_controls_allowed(enabled) self._set_prev_torque(t) if abs(t) > MAX_STEER or (not enabled and abs(t) > 0): self.assertFalse(self._tx(self._torque_msg(t))) else: self.assertTrue(self._tx(self._torque_msg(t))) def test_non_realtime_limit_up(self): self.safety.set_torque_driver(0, 0) self.safety.set_controls_allowed(True) self._set_prev_torque(0) self.assertTrue(self._tx(self._torque_msg(MAX_RATE_UP))) self._set_prev_torque(0) self.assertTrue(self._tx(self._torque_msg(-MAX_RATE_UP))) self._set_prev_torque(0) self.assertFalse(self._tx(self._torque_msg(MAX_RATE_UP + 1))) self.safety.set_controls_allowed(True) self._set_prev_torque(0) self.assertFalse(self._tx(self._torque_msg(-MAX_RATE_UP - 1))) def test_non_realtime_limit_down(self): self.safety.set_torque_driver(0, 0) self.safety.set_controls_allowed(True) def test_against_torque_driver(self): self.safety.set_controls_allowed(True) for sign in [-1, 1]: for t in np.arange(0, DRIVER_TORQUE_ALLOWANCE + 1, 1): t *= -sign self.safety.set_torque_driver(t, t) self._set_prev_torque(MAX_STEER * sign) self.assertTrue(self._tx(self._torque_msg(MAX_STEER * sign))) self.safety.set_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1) self.assertFalse(self._tx(self._torque_msg(-MAX_STEER))) # spot check some individual cases for sign in [-1, 1]: driver_torque = (DRIVER_TORQUE_ALLOWANCE + 10) * sign torque_desired = (MAX_STEER - 10 * DRIVER_TORQUE_FACTOR) * sign delta = 1 * sign self._set_prev_torque(torque_desired) self.safety.set_torque_driver(-driver_torque, -driver_torque) self.assertTrue(self._tx(self._torque_msg(torque_desired))) self._set_prev_torque(torque_desired + delta) self.safety.set_torque_driver(-driver_torque, -driver_torque) self.assertFalse(self._tx(self._torque_msg(torque_desired + delta))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) self.assertTrue( self._tx(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) self.assertTrue(self._tx(self._torque_msg(0))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) self.assertFalse( self._tx( self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) def test_realtime_limits(self): self.safety.set_controls_allowed(True) for sign in [-1, 1]: self.safety.init_tests() self._set_prev_torque(0) self.safety.set_torque_driver(0, 0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign self.assertTrue(self._tx(self._torque_msg(t))) self.assertFalse( self._tx(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) self._set_prev_torque(0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign self.assertTrue(self._tx(self._torque_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) self.assertTrue( self._tx(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) self.assertTrue( self._tx(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) def test_tx_hook_on_pedal_pressed(self): for pedal in ['brake', 'gas']: if pedal == 'brake': # brake_pressed_prev and vehicle_moving self._rx(self._speed_msg(100)) self._rx(self._brake_msg(MAX_BRAKE)) elif pedal == 'gas': # gas_pressed_prev self._rx(self._gas_msg(MAX_GAS)) self.safety.set_controls_allowed(1) self.assertFalse(self._tx(self._send_brake_msg(MAX_BRAKE))) self.assertFalse(self._tx(self._torque_msg(MAX_RATE_UP))) self.assertFalse(self._tx(self._send_gas_msg(MAX_GAS))) # reset status self.safety.set_controls_allowed(0) self._tx(self._send_brake_msg(0)) self._tx(self._torque_msg(0)) if pedal == 'brake': self._rx(self._speed_msg(0)) self._rx(self._brake_msg(0)) elif pedal == 'gas': self._rx(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 vehicle_moving self._rx(self._speed_msg(100)) self._rx(self._brake_msg(MAX_BRAKE)) allow_ctrl = False elif pedal == 'gas': # gas_pressed_prev self._rx(self._gas_msg(MAX_GAS)) allow_ctrl = True self.safety.set_controls_allowed(1) self.assertEqual(allow_ctrl, self._tx(self._send_brake_msg(MAX_BRAKE))) self.assertEqual(allow_ctrl, self._tx(self._torque_msg(MAX_RATE_UP))) self.assertEqual(allow_ctrl, self._tx(self._send_gas_msg(MAX_GAS))) # reset status self.safety.set_controls_allowed(0) self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT) self._tx(self._send_brake_msg(0)) self._tx(self._torque_msg(0)) if pedal == 'brake': self._rx(self._speed_msg(0)) self._rx(self._brake_msg(0)) elif pedal == 'gas': self._rx(self._gas_msg(0))
def setUp(self): self.packer = CANPackerPanda("subaru_global_2017") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_SUBARU, 0) self.safety.init_tests_subaru()
class TestMazdaSafety(common.PandaSafetyTest): TX_MSGS = [[0x243, 0], [0x09d, 0]] STANDSTILL_THRESHOLD = .1 RELAY_MALFUNCTION_ADDR = 0x243 RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS = {2: [0x243]} FWD_BUS_LOOKUP = {0: 2, 2: 0} LKAS_ENABLE_SPEED = 52 LKAS_DISABLE_SPEED = 45 def setUp(self): self.packer = CANPackerPanda("mazda_cx5_gt_2017") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_MAZDA, 0) self.safety.init_tests() def _torque_meas_msg(self, torque): values = {"STEER_TORQUE_MOTOR": torque} return self.packer.make_can_msg_panda("STEER_TORQUE", 0, values) # def _torque_driver_msg(self, torque): # values = {"STEER_TORQUE_DRIVER": torque} # return self.packer.make_can_msg_panda("STEER_TORQUE", 0, values) def _torque_msg(self, torque): values = {"LKAS_REQUEST": torque} return self.packer.make_can_msg_panda("CAM_LKAS", 0, values) def _speed_msg(self, s): values = {"SPEED": s} return self.packer.make_can_msg_panda("ENGINE_DATA", 0, values) def _brake_msg(self, pressed): values = {"BRAKE_ON": pressed} return self.packer.make_can_msg_panda("PEDALS", 0, values) def _gas_msg(self, pressed): values = {"PEDAL_GAS": pressed} return self.packer.make_can_msg_panda("ENGINE_DATA", 0, values) def _pcm_status_msg(self, cruise_on): values = {"CRZ_ACTIVE": cruise_on} return self.packer.make_can_msg_panda("CRZ_CTRL", 0, values) def test_enable_control_allowed_from_cruise(self): self._rx(self._pcm_status_msg(False)) self.assertFalse(self.safety.get_controls_allowed()) self._rx(self._speed_msg(self.LKAS_DISABLE_SPEED - 1)) self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1)) self._rx(self._pcm_status_msg(True)) self.assertFalse(self.safety.get_controls_allowed()) self._rx(self._pcm_status_msg(False)) self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED + 1)) self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1)) self._rx(self._pcm_status_msg(True)) self.assertTrue(self.safety.get_controls_allowed()) self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED + 1)) self._rx(self._pcm_status_msg(True)) self.assertTrue(self.safety.get_controls_allowed()) self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1)) self.assertTrue(self.safety.get_controls_allowed()) # Enabled going down self._rx(self._speed_msg(self.LKAS_DISABLE_SPEED - 1)) self.assertTrue(self.safety.get_controls_allowed()) self._rx(self._pcm_status_msg(False)) # Disabled going up self._rx(self._speed_msg(self.LKAS_DISABLE_SPEED + 1)) self._rx(self._pcm_status_msg(True)) self.assertFalse(self.safety.get_controls_allowed()) def test_cruise_engaged_prev(self): self._rx(self._pcm_status_msg(False)) self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1)) self._rx(self._pcm_status_msg(True)) self.assertFalse(self.safety.get_cruise_engaged_prev()) self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED + 1)) for engaged in [True, False]: self._rx(self._pcm_status_msg(engaged)) self.assertEqual(engaged, self.safety.get_cruise_engaged_prev()) self._rx(self._pcm_status_msg(not engaged)) self.assertEqual(not engaged, self.safety.get_cruise_engaged_prev())
def setUp(self): self.packer = CANPackerPanda("hyundai_kia_generic") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI, 0) self.safety.init_tests()
def setUp(self): self.packer = CANPackerPanda("mazda_cx5_gt_2017") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_MAZDA, 0) self.safety.init_tests()
def setUp(self): self.packer = CANPackerPanda("gm_global_a_powertrain") self.packer_chassis = CANPackerPanda("gm_global_a_chassis") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_GM, 0) self.safety.init_tests()
class TestToyotaSafety(common.PandaSafetyTest, common.InterceptorSafetyTest, \ common.TorqueSteeringSafetyTest): 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], [0x411, 0], [0x412, 0], [0x343, 0], [0x1D2, 0], # LKAS + ACC [0x200, 0], [0x750, 0] ] # interceptor + blindspot monitor STANDSTILL_THRESHOLD = 1 # 1kph RELAY_MALFUNCTION_ADDR = 0x2E4 RELAY_MALFUNCTION_BUS = 0 FWD_BLACKLISTED_ADDRS = {2: [0x2E4, 0x412, 0x191, 0x343]} FWD_BUS_LOOKUP = {0: 2, 2: 0} INTERCEPTOR_THRESHOLD = 845 MAX_RATE_UP = 10 MAX_RATE_DOWN = 25 MAX_TORQUE = 1500 MAX_RT_DELTA = 375 RT_INTERVAL = 250000 MAX_TORQUE_ERROR = 350 TORQUE_MEAS_TOLERANCE = 1 # toyota safety adds one to be conversative for rounding def setUp(self): self.packer = CANPackerPanda("toyota_prius_2017_pt_generated") self.safety = libpandasafety_py.libpandasafety self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, 66) self.safety.init_tests() def _torque_meas_msg(self, torque): values = {"STEER_TORQUE_EPS": torque} return self.packer.make_can_msg_panda("STEER_TORQUE_SENSOR", 0, values) def _torque_msg(self, torque): values = {"STEER_TORQUE_CMD": torque} return self.packer.make_can_msg_panda("STEERING_LKA", 0, values) def _accel_msg(self, accel): values = {"ACCEL_CMD": accel} return self.packer.make_can_msg_panda("ACC_CONTROL", 0, values) def _speed_msg(self, s): values = {("WHEEL_SPEED_%s" % n): s for n in ["FR", "FL", "RR", "RL"]} return self.packer.make_can_msg_panda("WHEEL_SPEEDS", 0, values) def _brake_msg(self, pressed): values = {"BRAKE_PRESSED": pressed} return self.packer.make_can_msg_panda("BRAKE_MODULE", 0, values) def _gas_msg(self, pressed): cruise_active = self.safety.get_controls_allowed() values = {"GAS_RELEASED": not pressed, "CRUISE_ACTIVE": cruise_active} return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values) def _pcm_status_msg(self, cruise_on): values = {"CRUISE_ACTIVE": cruise_on} return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values) # 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), (ISO_MIN_ACCEL, ISO_MAX_ACCEL, UNSAFE_MODE.RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX)) for min_accel, max_accel, unsafe_mode in limits: for accel in np.arange(min_accel - 1, max_accel + 1, 0.1): for controls_allowed in [True, False]: self.safety.set_controls_allowed(controls_allowed) self.safety.set_unsafe_mode(unsafe_mode) if controls_allowed: should_tx = int(min_accel * 1000) <= int( accel * 1000) <= int(max_accel * 1000) else: should_tx = np.isclose(accel, 0, atol=0.0001) self.assertEqual(should_tx, self._tx(self._accel_msg(accel))) def test_rx_hook(self): # checksum checks for msg in ["trq", "pcm"]: self.safety.set_controls_allowed(1) if msg == "trq": to_push = self._torque_meas_msg(0) if msg == "pcm": to_push = self._pcm_status_msg(True) self.assertTrue(self._rx(to_push)) to_push[0].RDHR = 0 self.assertFalse(self._rx(to_push)) self.assertFalse(self.safety.get_controls_allowed())