safety tests: add common longitudinal accel class (#1298)

* add longitudinal safety test class

* rename to accel_cmd_msg

* line

* do hyundai

* set default min and max accel

* revert

* thanks pylint
This commit is contained in:
Shane Smiskol
2023-03-21 12:24:33 -07:00
committed by GitHub
parent d70fa4e120
commit 2136e2e45b
4 changed files with 48 additions and 48 deletions

View File

@@ -131,6 +131,40 @@ class InterceptorSafetyTest(PandaSafetyTestBase):
self.assertEqual(send, self._tx(self._interceptor_gas_cmd(gas)))
class LongitudinalAccelSafetyTest(PandaSafetyTestBase, abc.ABC):
MIN_ACCEL: float = 2.0
MAX_ACCEL: float = -3.5
INACTIVE_ACCEL: float = 0.0
@classmethod
def setUpClass(cls):
if cls.__name__ == "LongitudinalAccelSafetyTest":
cls.safety = None
raise unittest.SkipTest
@abc.abstractmethod
def _accel_msg(self, accel: float):
pass
def test_accel_actuation_limits(self, stock_longitudinal=False):
limits = ((self.MIN_ACCEL, self.MAX_ACCEL, ALTERNATIVE_EXPERIENCE.DEFAULT),
(self.MIN_ACCEL, self.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.05):
for controls_allowed in [True, False]:
self.safety.set_controls_allowed(controls_allowed)
self.safety.set_alternative_experience(alternative_experience)
if stock_longitudinal:
should_tx = False
elif controls_allowed:
should_tx = int(min_accel * 1000) <= int(accel * 1000) <= int(max_accel * 1000)
else:
should_tx = np.isclose(accel, self.INACTIVE_ACCEL, atol=0.0001)
self.assertEqual(should_tx, self._tx(self._accel_msg(accel)))
class TorqueSteeringSafetyTestBase(PandaSafetyTestBase, abc.ABC):
MAX_RATE_UP = 0

View File

@@ -1,6 +1,7 @@
import numpy as np
from typing import Tuple
import unittest
import panda.tests.safety.common as common
from panda.tests.libpanda import libpanda_py
from panda.tests.safety.common import make_msg
@@ -12,8 +13,6 @@ class Buttons:
CANCEL = 4
MAX_ACCEL = 2.0
MIN_ACCEL = -3.5
PREV_BUTTON_SAMPLES = 8
ENABLE_BUTTONS = (Buttons.RESUME, Buttons.SET, Buttons.CANCEL)
@@ -75,12 +74,18 @@ class HyundaiButtonBase:
self._rx(self._button_msg(Buttons.NONE))
class HyundaiLongitudinalBase:
class HyundaiLongitudinalBase(common.LongitudinalAccelSafetyTest):
# pylint: disable=no-member,abstract-method
DISABLED_ECU_UDS_MSG: Tuple[int, int]
DISABLED_ECU_ACTUATION_MSG: Tuple[int, int]
@classmethod
def setUpClass(cls):
if cls.__name__ == "HyundaiLongitudinalBase":
cls.safety = None
raise unittest.SkipTest
# override these tests from PandaSafetyTest, hyundai longitudinal uses button enable
def test_disable_control_allowed_from_cruise(self):
pass
@@ -128,14 +133,6 @@ class HyundaiLongitudinalBase:
self._rx(self._button_msg(Buttons.CANCEL))
self.assertFalse(self.safety.get_controls_allowed())
def test_accel_safety_check(self):
for controls_allowed in [True, False]:
for accel in np.arange(MIN_ACCEL - 1, MAX_ACCEL + 1, 0.01):
accel = round(accel, 2) # floats might not hit exact boundary conditions without rounding
self.safety.set_controls_allowed(controls_allowed)
send = MIN_ACCEL <= accel <= MAX_ACCEL if controls_allowed else accel == 0
self.assertEqual(send, self._tx(self._accel_msg(accel)), (controls_allowed, accel))
def test_tester_present_allowed(self):
"""
Ensure tester present diagnostic message is allowed to keep ECU knocked out

View File

@@ -7,10 +7,7 @@ import itertools
from panda import Panda
from panda.tests.libpanda import libpanda_py
import panda.tests.safety.common as common
from panda.tests.safety.common import CANPackerPanda, make_msg, ALTERNATIVE_EXPERIENCE
MAX_ACCEL = 2.0
MIN_ACCEL = -3.5
from panda.tests.safety.common import CANPackerPanda, make_msg
def interceptor_msg(gas, addr):
@@ -22,7 +19,8 @@ def interceptor_msg(gas, addr):
return to_send
class TestToyotaSafetyBase(common.PandaSafetyTest, common.InterceptorSafetyTest):
class TestToyotaSafetyBase(common.PandaSafetyTest, common.InterceptorSafetyTest,
common.LongitudinalAccelSafetyTest):
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
@@ -94,23 +92,6 @@ class TestToyotaSafetyBase(common.PandaSafetyTest, common.InterceptorSafetyTest)
msg = libpanda_py.make_CANPacket(0x283, 0, bytes(dat))
self.assertEqual(not bad, self._tx(msg))
def test_accel_actuation_limits(self, stock_longitudinal=False):
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 stock_longitudinal:
should_tx = False
elif 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, req, req2, setme_x64, angle in itertools.product([True, False],
@@ -211,7 +192,7 @@ class TestToyotaStockLongitudinalBase(TestToyotaSafetyBase):
"""
for controls_allowed in [True, False]:
self.safety.set_controls_allowed(controls_allowed)
for accel in np.arange(MIN_ACCEL - 1, MAX_ACCEL + 1, 0.1):
for accel in np.arange(self.MIN_ACCEL - 1, self.MAX_ACCEL + 1, 0.1):
self.assertFalse(self._tx(self._accel_msg(accel)))
should_tx = np.isclose(accel, 0, atol=0.0001)
self.assertEqual(should_tx, self._tx(self._accel_msg(accel, cancel_req=1)))

View File

@@ -1,5 +1,4 @@
#!/usr/bin/env python3
import numpy as np
import unittest
from panda import Panda
from panda.tests.libpanda import libpanda_py
@@ -17,8 +16,6 @@ MSG_MOTOR_5 = 0x480 # RX from ECU, for ACC main switch state
MSG_ACC_GRA_ANZEIGE = 0x56A # TX by OP, ACC HUD
MSG_LDW_1 = 0x5BE # TX by OP, Lane line recognition and text alerts
MAX_ACCEL = 2.0
MIN_ACCEL = -3.5
class TestVolkswagenPqSafety(common.PandaSafetyTest, common.DriverTorqueSteeringSafetyTest):
cruise_engaged = False
@@ -142,7 +139,7 @@ class TestVolkswagenPqStockSafety(TestVolkswagenPqSafety):
self.assertTrue(self._tx(self._button_msg(resume=True)))
class TestVolkswagenPqLongSafety(TestVolkswagenPqSafety):
class TestVolkswagenPqLongSafety(TestVolkswagenPqSafety, common.LongitudinalAccelSafetyTest):
TX_MSGS = [[MSG_HCA_1, 0], [MSG_LDW_1, 0], [MSG_ACC_SYSTEM, 0], [MSG_ACC_GRA_ANZEIGE, 0]]
FWD_BLACKLISTED_ADDRS = {2: [MSG_HCA_1, MSG_LDW_1, MSG_ACC_SYSTEM, MSG_ACC_GRA_ANZEIGE]}
FWD_BUS_LOOKUP = {0: 2, 2: 0}
@@ -192,15 +189,6 @@ class TestVolkswagenPqLongSafety(TestVolkswagenPqSafety):
self._rx(self._motor_5_msg(main_switch=False))
self.assertFalse(self.safety.get_controls_allowed(), "controls allowed after ACC main switch off")
def test_accel_safety_check(self):
for controls_allowed in [True, False]:
for accel in np.arange(MIN_ACCEL - 2, MAX_ACCEL + 2, 0.005):
accel = round(accel, 2) # floats might not hit exact boundary conditions without rounding
send = MIN_ACCEL <= accel <= MAX_ACCEL if controls_allowed else accel == self.INACTIVE_ACCEL
self.safety.set_controls_allowed(controls_allowed)
# primary accel request used by ECU
self.assertEqual(send, self._tx(self._accel_msg(accel)), (controls_allowed, accel))
if __name__ == "__main__":
unittest.main()