f2292e4 Hyundai: added safety check for button spam 1a8c4c4 Hyundai safety: fwd option 5398abf Hyundai safety: added tests for cruise enable/disable too a91d7ef added hyundai regression test 487fcae Safety hyundai: fixed RT check 04270b8 Safety Hyundai: bug fixes d0c28b7 Hyndai safety: tuned ad1ba69 Hyundai safety: fixed wrong param 8a1dcbe Hyundai safety: added Santa Fe safety: need to be tested. Removed some unnecessary funcitons 4e9d08a Hyundai safety: controls_allowed ==1 by default for now f42d092 Hyundai all output for now 7927cab compiling the use of bitbang_gmlan only for panda 4fe2dcd build pedal image in CI 3d67294 keep pedal obj folder git-subtree-dir: panda git-subtree-split: f2292e420bd856b8cef6633af46e2641f401e84cpull/340/merge
							parent
							
								
									c812915765
								
							
						
					
					
						commit
						c4bba32347
					
				
				 16 changed files with 373 additions and 71 deletions
			
			
		| @ -0,0 +1,186 @@ | |||||||
|  | #!/usr/bin/env python2 | ||||||
|  | import unittest | ||||||
|  | import numpy as np | ||||||
|  | import libpandasafety_py | ||||||
|  | 
 | ||||||
|  | MAX_RATE_UP = 3 | ||||||
|  | MAX_RATE_DOWN = 7 | ||||||
|  | MAX_STEER = 250 | ||||||
|  | 
 | ||||||
|  | MAX_RT_DELTA = 112 | ||||||
|  | RT_INTERVAL = 250000 | ||||||
|  | 
 | ||||||
|  | DRIVER_TORQUE_ALLOWANCE = 50; | ||||||
|  | DRIVER_TORQUE_FACTOR = 2; | ||||||
|  | 
 | ||||||
|  | def twos_comp(val, bits): | ||||||
|  |   if val >= 0: | ||||||
|  |     return val | ||||||
|  |   else: | ||||||
|  |     return (2**bits) + val | ||||||
|  | 
 | ||||||
|  | def sign(a): | ||||||
|  |   if a > 0: | ||||||
|  |     return 1 | ||||||
|  |   else: | ||||||
|  |     return -1 | ||||||
|  | 
 | ||||||
|  | class TestHyundaiSafety(unittest.TestCase): | ||||||
|  |   @classmethod | ||||||
|  |   def setUp(cls): | ||||||
|  |     cls.safety = libpandasafety_py.libpandasafety | ||||||
|  |     cls.safety.nooutput_init(0) | ||||||
|  |     cls.safety.init_tests_hyundai() | ||||||
|  | 
 | ||||||
|  |   def _button_msg(self, buttons): | ||||||
|  |     to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') | ||||||
|  |     to_send[0].RIR = 1265 << 21 | ||||||
|  |     to_send[0].RDLR = buttons | ||||||
|  |     return to_send | ||||||
|  | 
 | ||||||
|  |   def _set_prev_torque(self, t): | ||||||
|  |     self.safety.set_hyundai_desired_torque_last(t) | ||||||
|  |     self.safety.set_hyundai_rt_torque_last(t) | ||||||
|  | 
 | ||||||
|  |   def _torque_driver_msg(self, torque): | ||||||
|  |     to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') | ||||||
|  |     to_send[0].RIR = 897 << 21 | ||||||
|  |     to_send[0].RDLR = (torque + 2048) << 11 | ||||||
|  |     return to_send | ||||||
|  | 
 | ||||||
|  |   def _torque_msg(self, torque): | ||||||
|  |     to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') | ||||||
|  |     to_send[0].RIR = 832 << 21 | ||||||
|  |     to_send[0].RDLR = (torque + 1024) << 16 | ||||||
|  |     return to_send | ||||||
|  | 
 | ||||||
|  |   def test_default_controls_not_allowed(self): | ||||||
|  |     self.assertFalse(self.safety.get_controls_allowed()) | ||||||
|  | 
 | ||||||
|  |   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.safety.hyundai_tx_hook(self._torque_msg(t))) | ||||||
|  |         else: | ||||||
|  |           self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(t))) | ||||||
|  | 
 | ||||||
|  |   def test_manually_enable_controls_allowed(self): | ||||||
|  |     self.safety.set_controls_allowed(1) | ||||||
|  |     self.assertTrue(self.safety.get_controls_allowed()) | ||||||
|  |     self.safety.set_controls_allowed(0) | ||||||
|  |     self.assertFalse(self.safety.get_controls_allowed()) | ||||||
|  | 
 | ||||||
|  |   def test_enable_control_allowed_from_cruise(self): | ||||||
|  |     to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') | ||||||
|  |     to_push[0].RIR = 1057 << 21 | ||||||
|  |     to_push[0].RDLR = 1 << 13 | ||||||
|  | 
 | ||||||
|  |     self.safety.hyundai_rx_hook(to_push) | ||||||
|  |     self.assertTrue(self.safety.get_controls_allowed()) | ||||||
|  | 
 | ||||||
|  |   def test_disable_control_allowed_from_cruise(self): | ||||||
|  |     to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') | ||||||
|  |     to_push[0].RIR = 1057 << 21 | ||||||
|  |     to_push[0].RDLR = 0 | ||||||
|  | 
 | ||||||
|  |     self.safety.set_controls_allowed(1) | ||||||
|  |     self.safety.hyundai_rx_hook(to_push) | ||||||
|  |     self.assertFalse(self.safety.get_controls_allowed()) | ||||||
|  | 
 | ||||||
|  |   def test_non_realtime_limit_up(self): | ||||||
|  |     self.safety.set_hyundai_torque_driver(0, 0) | ||||||
|  |     self.safety.set_controls_allowed(True) | ||||||
|  | 
 | ||||||
|  |     self._set_prev_torque(0) | ||||||
|  |     self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(MAX_RATE_UP))) | ||||||
|  |     self._set_prev_torque(0) | ||||||
|  |     self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(-MAX_RATE_UP))) | ||||||
|  | 
 | ||||||
|  |     self._set_prev_torque(0) | ||||||
|  |     self.assertFalse(self.safety.hyundai_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) | ||||||
|  |     self.safety.set_controls_allowed(True) | ||||||
|  |     self._set_prev_torque(0) | ||||||
|  |     self.assertFalse(self.safety.hyundai_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) | ||||||
|  | 
 | ||||||
|  |   def test_non_realtime_limit_down(self): | ||||||
|  |     self.safety.set_hyundai_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_hyundai_torque_driver(t, t) | ||||||
|  |         self._set_prev_torque(MAX_STEER * sign) | ||||||
|  |         self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(MAX_STEER * sign))) | ||||||
|  | 
 | ||||||
|  |       self.safety.set_hyundai_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1) | ||||||
|  |       self.assertFalse(self.safety.hyundai_tx_hook(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_hyundai_torque_driver(-driver_torque, -driver_torque) | ||||||
|  |       self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(torque_desired))) | ||||||
|  |       self._set_prev_torque(torque_desired + delta) | ||||||
|  |       self.safety.set_hyundai_torque_driver(-driver_torque, -driver_torque) | ||||||
|  |       self.assertFalse(self.safety.hyundai_tx_hook(self._torque_msg(torque_desired + delta))) | ||||||
|  | 
 | ||||||
|  |       self._set_prev_torque(MAX_STEER * sign) | ||||||
|  |       self.safety.set_hyundai_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) | ||||||
|  |       self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) | ||||||
|  |       self._set_prev_torque(MAX_STEER * sign) | ||||||
|  |       self.safety.set_hyundai_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) | ||||||
|  |       self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(0))) | ||||||
|  |       self._set_prev_torque(MAX_STEER * sign) | ||||||
|  |       self.safety.set_hyundai_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) | ||||||
|  |       self.assertFalse(self.safety.hyundai_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_hyundai() | ||||||
|  |       self._set_prev_torque(0) | ||||||
|  |       self.safety.set_hyundai_torque_driver(0, 0) | ||||||
|  |       for t in np.arange(0, MAX_RT_DELTA, 1): | ||||||
|  |         t *= sign | ||||||
|  |         self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(t))) | ||||||
|  |       self.assertFalse(self.safety.hyundai_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.hyundai_tx_hook(self._torque_msg(t))) | ||||||
|  | 
 | ||||||
|  |       # Increase timer to update rt_torque_last | ||||||
|  |       self.safety.set_timer(RT_INTERVAL + 1) | ||||||
|  |       self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) | ||||||
|  |       self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   def test_spam_cancel_safety_check(self): | ||||||
|  |     RESUME_BTN = 1 | ||||||
|  |     SET_BTN = 2 | ||||||
|  |     CANCEL_BTN = 4 | ||||||
|  |     BUTTON_MSG = 1265 | ||||||
|  |     self.safety.set_controls_allowed(0) | ||||||
|  |     self.assertTrue(self.safety.hyundai_tx_hook(self._button_msg(CANCEL_BTN))) | ||||||
|  |     self.assertFalse(self.safety.hyundai_tx_hook(self._button_msg(RESUME_BTN))) | ||||||
|  |     self.assertFalse(self.safety.hyundai_tx_hook(self._button_msg(SET_BTN))) | ||||||
|  |     # do not block resume if we are engaged already | ||||||
|  |     self.safety.set_controls_allowed(1) | ||||||
|  |     self.assertTrue(self.safety.hyundai_tx_hook(self._button_msg(RESUME_BTN))) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |   unittest.main() | ||||||
					Loading…
					
					
				
		Reference in new issue