Skip to content

Commit e5a586e

Browse files
Abstract gas interceptor tests (#517)
* abstract interceptor tests * honda
1 parent 1dbed65 commit e5a586e

File tree

4 files changed

+85
-111
lines changed

4 files changed

+85
-111
lines changed

board/safety/safety_honda.h

+1
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ static void honda_nidec_init(int16_t param) {
266266
UNUSED(param);
267267
controls_allowed = false;
268268
relay_malfunction_reset();
269+
gas_interceptor_detected = 0;
269270
honda_hw = HONDA_N_HW;
270271
honda_alt_brake_msg = false;
271272
}

tests/safety/common.py

+61
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import abc
22
import struct
33
import unittest
4+
import numpy as np
45
from opendbc.can.packer import CANPacker # pylint: disable=import-error
56
from panda.tests.safety import libpandasafety_py
67

@@ -54,6 +55,66 @@ def _rx(self, msg):
5455
def _tx(self, msg):
5556
return self.safety.safety_tx_hook(msg)
5657

58+
class InterceptorSafetyTest(PandaSafetyTestBase):
59+
60+
INTERCEPTOR_THRESHOLD = 0
61+
62+
@classmethod
63+
def setUpClass(cls):
64+
if cls.__name__ == "InterceptorSafetyTest":
65+
cls.safety = None
66+
raise unittest.SkipTest
67+
68+
@abc.abstractmethod
69+
def _interceptor_msg(self, gas, addr):
70+
pass
71+
72+
def test_prev_gas_interceptor(self):
73+
self._rx(self._interceptor_msg(0x0, 0x201))
74+
self.assertFalse(self.safety.get_gas_interceptor_prev())
75+
self._rx(self._interceptor_msg(0x1000, 0x201))
76+
self.assertTrue(self.safety.get_gas_interceptor_prev())
77+
self._rx(self._interceptor_msg(0x0, 0x201))
78+
self.safety.set_gas_interceptor_detected(False)
79+
80+
def test_disengage_on_gas_interceptor(self):
81+
for g in range(0, 0x1000):
82+
self._rx(self._interceptor_msg(0, 0x201))
83+
self.safety.set_controls_allowed(True)
84+
self._rx(self._interceptor_msg(g, 0x201))
85+
remain_enabled = g <= self.INTERCEPTOR_THRESHOLD
86+
self.assertEqual(remain_enabled, self.safety.get_controls_allowed())
87+
self._rx(self._interceptor_msg(0, 0x201))
88+
self.safety.set_gas_interceptor_detected(False)
89+
90+
def test_unsafe_mode_no_disengage_on_gas_interceptor(self):
91+
self.safety.set_controls_allowed(True)
92+
self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS)
93+
for g in range(0, 0x1000):
94+
self._rx(self._interceptor_msg(g, 0x201))
95+
self.assertTrue(self.safety.get_controls_allowed())
96+
self._rx(self._interceptor_msg(0, 0x201))
97+
self.safety.set_gas_interceptor_detected(False)
98+
self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT)
99+
100+
def test_allow_engage_with_gas_interceptor_pressed(self):
101+
self._rx(self._interceptor_msg(0x1000, 0x201))
102+
self.safety.set_controls_allowed(1)
103+
self._rx(self._interceptor_msg(0x1000, 0x201))
104+
self.assertTrue(self.safety.get_controls_allowed())
105+
self._rx(self._interceptor_msg(0, 0x201))
106+
107+
def test_gas_interceptor_safety_check(self):
108+
for gas in np.arange(0, 4000, 100):
109+
for controls_allowed in [True, False]:
110+
self.safety.set_controls_allowed(controls_allowed)
111+
if controls_allowed:
112+
send = True
113+
else:
114+
send = gas == 0
115+
self.assertEqual(send, self._tx(self._interceptor_msg(gas, 0x200)))
116+
117+
57118
class PandaSafetyTest(PandaSafetyTestBase):
58119
TX_MSGS = None
59120
STANDSTILL_THRESHOLD = None

tests/safety/test_honda.py

+15-62
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
MAX_BRAKE = 255
1111

12-
INTERCEPTOR_THRESHOLD = 344
13-
1412
class Btn:
1513
CANCEL = 2
1614
SET = 3
@@ -20,14 +18,6 @@ class Btn:
2018
HONDA_BG_HW = 1
2119
HONDA_BH_HW = 2
2220

23-
# Honda gas gains are the different
24-
def honda_interceptor_msg(gas, addr):
25-
to_send = make_msg(0, addr, 6)
26-
gas2 = gas * 2
27-
to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \
28-
((gas2 & 0xff) << 24) | ((gas2 & 0xff00) << 8)
29-
return to_send
30-
3121

3222
class TestHondaSafety(common.PandaSafetyTest):
3323
cnt_speed = 0
@@ -102,43 +92,6 @@ def test_disengage_on_brake(self):
10292
self._rx(self._brake_msg(1))
10393
self.assertFalse(self.safety.get_controls_allowed())
10494

105-
def test_prev_gas_interceptor(self):
106-
self._rx(honda_interceptor_msg(0x0, 0x201))
107-
self.assertFalse(self.safety.get_gas_interceptor_prev())
108-
self._rx(honda_interceptor_msg(0x1000, 0x201))
109-
self.assertTrue(self.safety.get_gas_interceptor_prev())
110-
self._rx(honda_interceptor_msg(0x0, 0x201))
111-
self.safety.set_gas_interceptor_detected(False)
112-
113-
def test_disengage_on_gas_interceptor(self):
114-
for g in range(0, 0x1000):
115-
self._rx(honda_interceptor_msg(0, 0x201))
116-
self.safety.set_controls_allowed(True)
117-
self._rx(honda_interceptor_msg(g, 0x201))
118-
remain_enabled = g <= INTERCEPTOR_THRESHOLD
119-
self.assertEqual(remain_enabled, self.safety.get_controls_allowed())
120-
self._rx(honda_interceptor_msg(0, 0x201))
121-
self.safety.set_gas_interceptor_detected(False)
122-
123-
def test_unsafe_mode_no_disengage_on_gas_interceptor(self):
124-
self.safety.set_controls_allowed(True)
125-
self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS)
126-
for g in range(0, 0x1000):
127-
self._rx(honda_interceptor_msg(g, 0x201))
128-
self.assertTrue(self.safety.get_controls_allowed())
129-
self._rx(honda_interceptor_msg(0, 0x201))
130-
self.safety.set_gas_interceptor_detected(False)
131-
self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT)
132-
self.safety.set_controls_allowed(False)
133-
134-
def test_allow_engage_with_gas_interceptor_pressed(self):
135-
self._rx(honda_interceptor_msg(0x1000, 0x201))
136-
self.safety.set_controls_allowed(1)
137-
self._rx(honda_interceptor_msg(0x1000, 0x201))
138-
self.assertTrue(self.safety.get_controls_allowed())
139-
self._rx(honda_interceptor_msg(0, 0x201))
140-
self.safety.set_gas_interceptor_detected(False)
141-
14295
def test_steer_safety_check(self):
14396
self.safety.set_controls_allowed(0)
14497
self.assertTrue(self._tx(self._send_steer_msg(0x0000)))
@@ -223,7 +176,7 @@ def test_tx_hook_on_pedal_pressed(self):
223176
self._rx(self._gas_msg(0))
224177

225178

226-
class TestHondaNidecSafety(TestHondaSafety):
179+
class TestHondaNidecSafety(TestHondaSafety, common.InterceptorSafetyTest):
227180

228181
TX_MSGS = [[0xE4, 0], [0x194, 0], [0x1FA, 0], [0x200, 0], [0x30C, 0], [0x33D, 0]]
229182
STANDSTILL_THRESHOLD = 0
@@ -232,12 +185,22 @@ class TestHondaNidecSafety(TestHondaSafety):
232185
FWD_BLACKLISTED_ADDRS = {2: [0xE4, 0x194, 0x33D, 0x30C]}
233186
FWD_BUS_LOOKUP = {0: 2, 2: 0}
234187

188+
INTERCEPTOR_THRESHOLD = 344
189+
235190
def setUp(self):
236191
self.packer = CANPackerPanda("honda_civic_touring_2016_can_generated")
237192
self.safety = libpandasafety_py.libpandasafety
238193
self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC, 0)
239194
self.safety.init_tests_honda()
240195

196+
# Honda gas gains are the different
197+
def _interceptor_msg(self, gas, addr):
198+
to_send = make_msg(0, addr, 6)
199+
gas2 = gas * 2
200+
to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \
201+
((gas2 & 0xff) << 24) | ((gas2 & 0xff00) << 8)
202+
return to_send
203+
241204
def test_fwd_hook(self):
242205
# normal operation, not forwarding AEB
243206
self.FWD_BLACKLISTED_ADDRS[2].append(0x1FA)
@@ -265,36 +228,26 @@ def test_brake_safety_check(self):
265228
self.assertEqual(send, self._tx(self._send_brake_msg(brake)))
266229
self.safety.set_honda_fwd_brake(False)
267230

268-
def test_gas_interceptor_safety_check(self):
269-
for gas in np.arange(0, 4000, 100):
270-
for controls_allowed in [True, False]:
271-
self.safety.set_controls_allowed(controls_allowed)
272-
if controls_allowed:
273-
send = True
274-
else:
275-
send = gas == 0
276-
self.assertEqual(send, self._tx(honda_interceptor_msg(gas, 0x200)))
277-
278231
def test_tx_hook_on_interceptor_pressed(self):
279232
for mode in [UNSAFE_MODE.DEFAULT, UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS]:
280233
self.safety.set_unsafe_mode(mode)
281234
# gas_interceptor_prev > INTERCEPTOR_THRESHOLD
282-
self._rx(honda_interceptor_msg(INTERCEPTOR_THRESHOLD+1, 0x201))
283-
self._rx(honda_interceptor_msg(INTERCEPTOR_THRESHOLD+1, 0x201))
235+
self._rx(self._interceptor_msg(self.INTERCEPTOR_THRESHOLD+1, 0x201))
236+
self._rx(self._interceptor_msg(self.INTERCEPTOR_THRESHOLD+1, 0x201))
284237
allow_ctrl = mode == UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS
285238

286239
self.safety.set_controls_allowed(1)
287240
self.safety.set_honda_fwd_brake(False)
288241
self.assertEqual(allow_ctrl, self._tx(self._send_brake_msg(MAX_BRAKE)))
289-
self.assertEqual(allow_ctrl, self._tx(honda_interceptor_msg(INTERCEPTOR_THRESHOLD, 0x200)))
242+
self.assertEqual(allow_ctrl, self._tx(self._interceptor_msg(self.INTERCEPTOR_THRESHOLD, 0x200)))
290243
self.assertEqual(allow_ctrl, self._tx(self._send_steer_msg(0x1000)))
291244

292245
# reset status
293246
self.safety.set_controls_allowed(0)
294247
self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT)
295248
self._tx(self._send_brake_msg(0))
296249
self._tx(self._send_steer_msg(0))
297-
self._tx(honda_interceptor_msg(0, 0x200))
250+
self._tx(self._interceptor_msg(0, 0x200))
298251
self.safety.set_gas_interceptor_detected(False)
299252

300253

tests/safety/test_toyota.py

+8-49
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,8 @@
2020
RT_INTERVAL = 250000
2121

2222
MAX_TORQUE_ERROR = 350
23-
INTERCEPTOR_THRESHOLD = 845
2423

25-
# Toyota gas gains are the same
26-
def toyota_interceptor_msg(gas, addr):
27-
to_send = make_msg(0, addr, 6)
28-
to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \
29-
((gas & 0xff) << 24) | ((gas & 0xff00) << 8)
30-
return to_send
31-
32-
class TestToyotaSafety(common.PandaSafetyTest):
24+
class TestToyotaSafety(common.PandaSafetyTest, common.InterceptorSafetyTest):
3325

3426
TX_MSGS = [[0x283, 0], [0x2E6, 0], [0x2E7, 0], [0x33E, 0], [0x344, 0], [0x365, 0], [0x366, 0], [0x4CB, 0], # DSU bus 0
3527
[0x128, 1], [0x141, 1], [0x160, 1], [0x161, 1], [0x470, 1], # DSU bus 1
@@ -40,6 +32,7 @@ class TestToyotaSafety(common.PandaSafetyTest):
4032
RELAY_MALFUNCTION_BUS = 0
4133
FWD_BLACKLISTED_ADDRS = {2: [0x2E4, 0x412, 0x191, 0x343]}
4234
FWD_BUS_LOOKUP = {0: 2, 2: 0}
35+
INTERCEPTOR_THRESHOLD = 845
4336

4437
@classmethod
4538
def setUp(self):
@@ -83,39 +76,12 @@ def _pcm_status_msg(self, cruise_on):
8376
values["CHECKSUM"] = 1
8477
return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values)
8578

86-
def test_prev_gas_interceptor(self):
87-
self._rx(toyota_interceptor_msg(0x0, 0x201))
88-
self.assertFalse(self.safety.get_gas_interceptor_prev())
89-
self._rx(toyota_interceptor_msg(0x1000, 0x201))
90-
self.assertTrue(self.safety.get_gas_interceptor_prev())
91-
self._rx(toyota_interceptor_msg(0x0, 0x201))
92-
93-
def test_disengage_on_gas_interceptor(self):
94-
for g in range(0, 0x1000):
95-
self._rx(toyota_interceptor_msg(0, 0x201))
96-
self.safety.set_controls_allowed(True)
97-
self._rx(toyota_interceptor_msg(g, 0x201))
98-
remain_enabled = g <= INTERCEPTOR_THRESHOLD
99-
self.assertEqual(remain_enabled, self.safety.get_controls_allowed())
100-
self._rx(toyota_interceptor_msg(0, 0x201))
101-
self.safety.set_gas_interceptor_detected(False)
102-
103-
def test_unsafe_mode_no_disengage_on_gas_interceptor(self):
104-
self.safety.set_controls_allowed(True)
105-
self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS)
106-
for g in range(0, 0x1000):
107-
self._rx(toyota_interceptor_msg(g, 0x201))
108-
self.assertTrue(self.safety.get_controls_allowed())
109-
self._rx(toyota_interceptor_msg(0, 0x201))
110-
self.safety.set_gas_interceptor_detected(False)
111-
self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT)
112-
113-
def test_allow_engage_with_gas_interceptor_pressed(self):
114-
self._rx(toyota_interceptor_msg(0x1000, 0x201))
115-
self.safety.set_controls_allowed(1)
116-
self._rx(toyota_interceptor_msg(0x1000, 0x201))
117-
self.assertTrue(self.safety.get_controls_allowed())
118-
self._rx(toyota_interceptor_msg(0, 0x201))
79+
# Toyota gas gains are the same
80+
def _interceptor_msg(self, gas, addr):
81+
to_send = make_msg(0, addr, 6)
82+
to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \
83+
((gas & 0xff) << 24) | ((gas & 0xff00) << 8)
84+
return to_send
11985

12086
def test_accel_actuation_limits(self):
12187
limits = ((MIN_ACCEL, MAX_ACCEL, UNSAFE_MODE.DEFAULT),
@@ -219,13 +185,6 @@ def test_torque_measurements(self):
219185
self.assertEqual(1, self.safety.get_toyota_torque_meas_max())
220186
self.assertEqual(-1, self.safety.get_toyota_torque_meas_min())
221187

222-
def test_gas_interceptor_safety_check(self):
223-
self.safety.set_controls_allowed(0)
224-
self.assertTrue(self._tx(toyota_interceptor_msg(0, 0x200)))
225-
self.assertFalse(self._tx(toyota_interceptor_msg(0x1000, 0x200)))
226-
self.safety.set_controls_allowed(1)
227-
self.assertTrue(self._tx(toyota_interceptor_msg(0x1000, 0x200)))
228-
229188
def test_rx_hook(self):
230189
# checksum checks
231190
for msg in ["trq", "pcm"]:

0 commit comments

Comments
 (0)