570 lines
21 KiB
Python
Executable File
570 lines
21 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from parameterized import parameterized_class
|
|
import random
|
|
import unittest
|
|
|
|
from opendbc.car.hyundai.values import HyundaiSafetyFlags
|
|
from opendbc.car.structs import CarParams
|
|
from opendbc.safety.tests.libsafety import libsafety_py
|
|
import opendbc.safety.tests.common as common
|
|
from opendbc.safety.tests.common import CANPackerSafety
|
|
from opendbc.safety.tests.hyundai_common import HyundaiButtonBase, HyundaiLongitudinalBase
|
|
|
|
from opendbc.iqpilot.car.hyundai.values import HyundaiSafetyFlagsIQ
|
|
|
|
# LDA button availability
|
|
LDA_BUTTON = [
|
|
{"SAFETY_PARAM_IQ": HyundaiSafetyFlagsIQ.DEFAULT},
|
|
{"SAFETY_PARAM_IQ": HyundaiSafetyFlagsIQ.HAS_LDA_BUTTON},
|
|
]
|
|
|
|
# All combinations of non-SCC HEV/PHEV/EV cars
|
|
_ALL_NON_SCC_HEV_EV_COMBOS = [
|
|
# Hybrid
|
|
{"PCM_STATUS_MSG": ("E_CRUISE_CONTROL", "CRUISE_LAMP_S"),
|
|
"ACC_STATE_MSG": ("E_CRUISE_CONTROL", "CRUISE_LAMP_M"),
|
|
"GAS_MSG": ("E_EMS11", "CR_Vcu_AccPedDep_Pos"),
|
|
"SAFETY_PARAM": HyundaiSafetyFlags.HYBRID_GAS},
|
|
# EV
|
|
{"PCM_STATUS_MSG": ("LABEL11", "CC_ACT"),
|
|
"ACC_STATE_MSG": ("LABEL11", "CC_React"),
|
|
"GAS_MSG": ("E_EMS11", "Accel_Pedal_Pos"),
|
|
"SAFETY_PARAM": HyundaiSafetyFlags.EV_GAS},
|
|
]
|
|
ALL_NON_SCC_HEV_EV_COMBOS = [{**p, **lda} for lda in LDA_BUTTON for p in _ALL_NON_SCC_HEV_EV_COMBOS]
|
|
|
|
|
|
# 4 bit checkusm used in some hyundai messages
|
|
# lives outside the can packer because we never send this msg
|
|
def checksum(msg):
|
|
addr, dat, bus = msg
|
|
|
|
chksum = 0
|
|
if addr == 0x386:
|
|
for i, b in enumerate(dat):
|
|
for j in range(8):
|
|
# exclude checksum and counter bits
|
|
if (i != 1 or j < 6) and (i != 3 or j < 6) and (i != 5 or j < 6) and (i != 7 or j < 6):
|
|
bit = (b >> j) & 1
|
|
else:
|
|
bit = 0
|
|
chksum += bit
|
|
chksum = (chksum ^ 9) & 0xF
|
|
ret = bytearray(dat)
|
|
ret[5] |= (chksum & 0x3) << 6
|
|
ret[7] |= (chksum & 0xc) << 4
|
|
else:
|
|
for i, b in enumerate(dat):
|
|
if addr in [0x260, 0x421] and i == 7:
|
|
b &= 0x0F if addr == 0x421 else 0xF0
|
|
elif addr == 0x394 and i == 6:
|
|
b &= 0xF0
|
|
elif addr == 0x394 and i == 7:
|
|
continue
|
|
chksum += sum(divmod(b, 16))
|
|
chksum = (16 - chksum) % 16
|
|
ret = bytearray(dat)
|
|
ret[6 if addr == 0x394 else 7] |= chksum << (4 if addr == 0x421 else 0)
|
|
|
|
return addr, ret, bus
|
|
|
|
|
|
@parameterized_class(LDA_BUTTON)
|
|
class TestHyundaiSafety(HyundaiButtonBase, common.CarSafetyTest, common.DriverTorqueSteeringSafetyTest, common.SteerRequestCutSafetyTest):
|
|
TX_MSGS = [[0x340, 0], [0x4F1, 0], [0x485, 0]]
|
|
STANDSTILL_THRESHOLD = 12 # 0.375 kph
|
|
RELAY_MALFUNCTION_ADDRS = {0: (0x340, 0x485)} # LKAS11
|
|
FWD_BLACKLISTED_ADDRS = {2: [0x340, 0x485]}
|
|
|
|
MAX_RATE_UP = 3
|
|
MAX_RATE_DOWN = 7
|
|
MAX_TORQUE_LOOKUP = [0], [384]
|
|
MAX_RT_DELTA = 112
|
|
DRIVER_TORQUE_ALLOWANCE = 50
|
|
DRIVER_TORQUE_FACTOR = 2
|
|
|
|
# Safety around steering req bit
|
|
MIN_VALID_STEERING_FRAMES = 89
|
|
MAX_INVALID_STEERING_FRAMES = 2
|
|
|
|
cnt_gas = 0
|
|
cnt_speed = 0
|
|
cnt_brake = 0
|
|
cnt_cruise = 0
|
|
cnt_button = 0
|
|
|
|
SAFETY_PARAM_IQ: int = 0
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
if cls.__name__ == "TestHyundaiSafety":
|
|
cls.safety = None
|
|
raise unittest.SkipTest
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, 0)
|
|
self.safety.init_tests()
|
|
|
|
def _button_msg(self, buttons, main_button=0, bus=0):
|
|
values = {"CF_Clu_CruiseSwState": buttons, "CF_Clu_CruiseSwMain": main_button, "CF_Clu_AliveCnt1": self.cnt_button}
|
|
self.__class__.cnt_button += 1
|
|
return self.packer.make_can_msg_safety("CLU11", bus, values)
|
|
|
|
def _user_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_safety("EMS16", 0, values, fix_checksum=checksum)
|
|
|
|
def _user_brake_msg(self, brake):
|
|
values = {"DriverOverride": 2 if brake else random.choice((0, 1, 3)),
|
|
"AliveCounterTCS": self.cnt_brake % 8}
|
|
self.__class__.cnt_brake += 1
|
|
return self.packer.make_can_msg_safety("TCS13", 0, values, fix_checksum=checksum)
|
|
|
|
def _speed_msg(self, speed):
|
|
# 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_safety("WHL_SPD11", 0, values, fix_checksum=checksum)
|
|
|
|
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_safety("SCC12", self.SCC_BUS, values, fix_checksum=checksum)
|
|
|
|
def _torque_driver_msg(self, torque):
|
|
values = {"CR_Mdps_StrColTq": torque}
|
|
return self.packer.make_can_msg_safety("MDPS12", 0, values)
|
|
|
|
def _torque_cmd_msg(self, torque, steer_req=1):
|
|
values = {"CR_Lkas_StrToqReq": torque, "CF_Lkas_ActToi": steer_req}
|
|
return self.packer.make_can_msg_safety("LKAS11", 0, values)
|
|
|
|
def _acc_state_msg(self, enable):
|
|
values = {"MainMode_ACC": enable}
|
|
return self.packer.make_can_msg_safety("SCC11", self.SCC_BUS, values)
|
|
|
|
def _lkas_button_msg(self, enabled):
|
|
if self.SAFETY_PARAM_IQ & HyundaiSafetyFlagsIQ.HAS_LDA_BUTTON:
|
|
values = {"LDA_BTN": enabled}
|
|
return self.packer.make_can_msg_safety("BCM_PO_11", 0, values)
|
|
else:
|
|
raise NotImplementedError
|
|
|
|
def _main_cruise_button_msg(self, enabled):
|
|
return self._button_msg(0, enabled)
|
|
|
|
def test_pcm_main_cruise_state_availability(self):
|
|
"""Test that ACC main state is correctly set when receiving 0x420 message, toggling HYUNDAI_LONG flag"""
|
|
prior_safety_mode = self.safety.get_current_safety_mode()
|
|
prior_safety_param = self.safety.get_current_safety_param()
|
|
|
|
for hyundai_longitudinal in (True, False):
|
|
with self.subTest("hyundai_longitudinal", hyundai_longitudinal=hyundai_longitudinal):
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, 0 if hyundai_longitudinal else HyundaiSafetyFlags.LONG)
|
|
for should_turn_acc_main_on in (True, False):
|
|
with self.subTest("acc_main_on", should_turn_acc_main_on=should_turn_acc_main_on):
|
|
self._rx(self._acc_state_msg(should_turn_acc_main_on)) # Send the ACC state message
|
|
expected_acc_main = should_turn_acc_main_on and hyundai_longitudinal # ACC main should only be set if hyundai_longitudinal is True
|
|
self.assertEqual(expected_acc_main, self.safety.get_acc_main_on())
|
|
self.safety.set_safety_hooks(prior_safety_mode, prior_safety_param)
|
|
|
|
def test_enable_control_allowed_with_aol_button(self):
|
|
default_safety_mode = self.safety.get_current_safety_mode()
|
|
default_safety_param = self.safety.get_current_safety_param()
|
|
default_safety_param_iq = self.safety.get_current_safety_param_iq()
|
|
"""Toggle AOL with AOL button"""
|
|
try:
|
|
self._lkas_button_msg(False)
|
|
except NotImplementedError as err:
|
|
raise unittest.SkipTest("Skipping test because LDA button is not supported") from err
|
|
|
|
try:
|
|
for enable_aol in (True, False):
|
|
with self.subTest("enable_aol", aol_enabled=enable_aol):
|
|
for has_lda_button_param in (True, False):
|
|
with self.subTest("has_lda_button", has_lda_button_param=has_lda_button_param):
|
|
has_lda_button = HyundaiSafetyFlagsIQ.HAS_LDA_BUTTON if has_lda_button_param else 0
|
|
self.safety.set_current_safety_param_iq(has_lda_button)
|
|
self.safety.set_safety_hooks(default_safety_mode, default_safety_param)
|
|
|
|
self.safety.set_aol_params(enable_aol, False, False)
|
|
self.assertEqual(enable_aol, self.safety.get_enable_aol())
|
|
|
|
self._rx(self._lkas_button_msg(True))
|
|
self._rx(self._speed_msg(0))
|
|
self._rx(self._lkas_button_msg(False))
|
|
self._rx(self._speed_msg(0))
|
|
self.assertEqual(enable_aol and has_lda_button_param, self.safety.get_controls_allowed_lat())
|
|
finally:
|
|
self.safety.set_current_safety_param_iq(default_safety_param_iq)
|
|
|
|
|
|
@parameterized_class(LDA_BUTTON)
|
|
class TestHyundaiSafetyAltLimits(TestHyundaiSafety):
|
|
MAX_RATE_UP = 2
|
|
MAX_RATE_DOWN = 3
|
|
MAX_TORQUE_LOOKUP = [0], [270]
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
if cls.__name__ == "TestHyundaiSafetyAltLimits":
|
|
cls.safety = None
|
|
raise unittest.SkipTest
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.ALT_LIMITS)
|
|
self.safety.init_tests()
|
|
|
|
|
|
@parameterized_class(LDA_BUTTON)
|
|
class TestHyundaiSafetyAltLimits2(TestHyundaiSafety):
|
|
MAX_RATE_UP = 2
|
|
MAX_RATE_DOWN = 3
|
|
MAX_TORQUE_LOOKUP = [0], [170]
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
if cls.__name__ == "TestHyundaiSafetyAltLimits2":
|
|
cls.safety = None
|
|
raise unittest.SkipTest
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.ALT_LIMITS_2)
|
|
self.safety.init_tests()
|
|
|
|
|
|
@parameterized_class(LDA_BUTTON)
|
|
class TestHyundaiSafetyCameraSCC(TestHyundaiSafety):
|
|
BUTTONS_TX_BUS = 2 # tx on 2, rx on 0
|
|
SCC_BUS = 2 # rx on 2
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
if cls.__name__ == "TestHyundaiSafetyCameraSCC":
|
|
cls.safety = None
|
|
raise unittest.SkipTest
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.CAMERA_SCC)
|
|
self.safety.init_tests()
|
|
|
|
def test_pcm_main_cruise_state_availability(self):
|
|
"""
|
|
Test that ACC main state is correctly set when receiving 0x420 message.
|
|
For camera SCC, ACC main should always be on when receiving 0x420 message
|
|
"""
|
|
|
|
for should_turn_acc_main_on in (True, False):
|
|
with self.subTest("acc_main_on", should_turn_acc_main_on=should_turn_acc_main_on):
|
|
self._rx(self._acc_state_msg(should_turn_acc_main_on))
|
|
self.assertEqual(should_turn_acc_main_on, self.safety.get_acc_main_on())
|
|
|
|
|
|
@parameterized_class(LDA_BUTTON)
|
|
class TestHyundaiSafetyFCEV(TestHyundaiSafety):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
if cls.__name__ == "TestHyundaiSafetyFCEV":
|
|
cls.safety = None
|
|
raise unittest.SkipTest
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.FCEV_GAS)
|
|
self.safety.init_tests()
|
|
|
|
def _user_gas_msg(self, gas):
|
|
values = {"ACCELERATOR_PEDAL": gas}
|
|
return self.packer.make_can_msg_safety("FCEV_ACCELERATOR", 0, values)
|
|
|
|
|
|
class TestHyundaiLegacySafety(TestHyundaiSafety):
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiLegacy, 0)
|
|
self.safety.init_tests()
|
|
|
|
|
|
class TestHyundaiLegacySafetyEV(TestHyundaiSafety):
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiLegacy, HyundaiSafetyFlags.EV_GAS)
|
|
self.safety.init_tests()
|
|
|
|
def _user_gas_msg(self, gas):
|
|
values = {"Accel_Pedal_Pos": gas}
|
|
return self.packer.make_can_msg_safety("E_EMS11", 0, values, fix_checksum=checksum)
|
|
|
|
|
|
class TestHyundaiLegacySafetyHEV(TestHyundaiSafety):
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiLegacy, HyundaiSafetyFlags.HYBRID_GAS)
|
|
self.safety.init_tests()
|
|
|
|
def _user_gas_msg(self, gas):
|
|
values = {"CR_Vcu_AccPedDep_Pos": gas}
|
|
return self.packer.make_can_msg_safety("E_EMS11", 0, values, fix_checksum=checksum)
|
|
|
|
|
|
@parameterized_class(LDA_BUTTON)
|
|
class TestHyundaiLongitudinalSafety(HyundaiLongitudinalBase, TestHyundaiSafety):
|
|
TX_MSGS = [[0x340, 0], [0x4F1, 0], [0x485, 0], [0x420, 0], [0x421, 0], [0x50A, 0], [0x389, 0], [0x4A2, 0], [0x38D, 0], [0x483, 0], [0x7D0, 0]]
|
|
|
|
FWD_BLACKLISTED_ADDRS = {2: [0x340, 0x485, 0x421, 0x420, 0x50A, 0x389]}
|
|
|
|
RELAY_MALFUNCTION_ADDRS = {0: (0x340, 0x485, 0x421, 0x420, 0x50A, 0x389)} # LKAS11, LFAHDA_MFC, SCC12, SCC11, SCC13, SCC14
|
|
|
|
DISABLED_ECU_UDS_MSG = (0x7D0, 0)
|
|
DISABLED_ECU_ACTUATION_MSG = (0x421, 0)
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
if cls.__name__ == "TestHyundaiLongitudinalSafety":
|
|
cls.safety = None
|
|
raise unittest.SkipTest
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.LONG)
|
|
self.safety.init_tests()
|
|
|
|
def _accel_msg(self, accel, aeb_req=False, aeb_decel=0):
|
|
values = {
|
|
"aReqRaw": accel,
|
|
"aReqValue": accel,
|
|
"AEB_CmdAct": int(aeb_req),
|
|
"CR_VSM_DecCmd": aeb_decel,
|
|
}
|
|
return self.packer.make_can_msg_safety("SCC12", self.SCC_BUS, values)
|
|
|
|
def _fca11_msg(self, idx=0, vsm_aeb_req=False, fca_aeb_req=False, aeb_decel=0):
|
|
values = {
|
|
"CR_FCA_Alive": idx % 0xF,
|
|
"FCA_Status": 2,
|
|
"CR_VSM_DecCmd": aeb_decel,
|
|
"CF_VSM_DecCmdAct": int(vsm_aeb_req),
|
|
"FCA_CmdAct": int(fca_aeb_req),
|
|
}
|
|
return self.packer.make_can_msg_safety("FCA11", 0, values)
|
|
|
|
def _tx_acc_state_msg(self, enable):
|
|
values = {"MainMode_ACC": enable}
|
|
return self.packer.make_can_msg_safety("SCC11", 0, values)
|
|
|
|
def test_no_aeb_fca11(self):
|
|
self.assertTrue(self._tx(self._fca11_msg()))
|
|
self.assertFalse(self._tx(self._fca11_msg(vsm_aeb_req=True)))
|
|
self.assertFalse(self._tx(self._fca11_msg(fca_aeb_req=True)))
|
|
self.assertFalse(self._tx(self._fca11_msg(aeb_decel=1.0)))
|
|
|
|
def test_no_aeb_scc12(self):
|
|
self.assertTrue(self._tx(self._accel_msg(0)))
|
|
self.assertFalse(self._tx(self._accel_msg(0, aeb_req=True)))
|
|
self.assertFalse(self._tx(self._accel_msg(0, aeb_decel=1.0)))
|
|
|
|
|
|
class TestHyundaiLongitudinalSafetyCameraSCC(HyundaiLongitudinalBase, TestHyundaiSafety):
|
|
TX_MSGS = [[0x340, 0], [0x4F1, 2], [0x485, 0], [0x420, 0], [0x421, 0], [0x50A, 0], [0x389, 0], [0x4A2, 0]]
|
|
|
|
FWD_BLACKLISTED_ADDRS = {2: [0x340, 0x485, 0x420, 0x421, 0x50A, 0x389]}
|
|
RELAY_MALFUNCTION_ADDRS = {0: (0x340, 0x485, 0x421, 0x420, 0x50A, 0x389)} # LKAS11, LFAHDA_MFC, SCC12, SCC11, SCC13, SCC14
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(HyundaiSafetyFlagsIQ.HAS_LDA_BUTTON)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.LONG | HyundaiSafetyFlags.CAMERA_SCC)
|
|
self.safety.init_tests()
|
|
|
|
def _accel_msg(self, accel, aeb_req=False, aeb_decel=0):
|
|
values = {
|
|
"aReqRaw": accel,
|
|
"aReqValue": accel,
|
|
"AEB_CmdAct": int(aeb_req),
|
|
"CR_VSM_DecCmd": aeb_decel,
|
|
}
|
|
return self.packer.make_can_msg_safety("SCC12", self.SCC_BUS, values)
|
|
|
|
def _tx_acc_state_msg(self, enable):
|
|
values = {"MainMode_ACC": enable}
|
|
return self.packer.make_can_msg_safety("SCC11", self.SCC_BUS, values)
|
|
|
|
def test_no_aeb_scc12(self):
|
|
self.assertTrue(self._tx(self._accel_msg(0)))
|
|
self.assertFalse(self._tx(self._accel_msg(0, aeb_req=True)))
|
|
self.assertFalse(self._tx(self._accel_msg(0, aeb_decel=1.0)))
|
|
|
|
def test_tester_present_allowed(self):
|
|
pass
|
|
|
|
def test_disabled_ecu_alive(self):
|
|
pass
|
|
|
|
|
|
@parameterized_class(LDA_BUTTON)
|
|
class TestHyundaiSafetyFCEVLong(TestHyundaiLongitudinalSafety, TestHyundaiSafetyFCEV):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
if cls.__name__ == "TestHyundaiSafetyFCEVLong":
|
|
cls.safety = None
|
|
raise unittest.SkipTest
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.FCEV_GAS | HyundaiSafetyFlags.LONG)
|
|
self.safety.init_tests()
|
|
|
|
|
|
@parameterized_class(LDA_BUTTON)
|
|
class TestHyundaiLongitudinalESCCSafety(HyundaiLongitudinalBase, TestHyundaiSafety):
|
|
TX_MSGS = [[0x340, 0], [0x4F1, 0], [0x485, 0], [0x420, 0], [0x421, 0], [0x50A, 0], [0x389, 0]]
|
|
|
|
FWD_BLACKLISTED_ADDRS = {2: [0x340, 0x485, 0x420, 0x421, 0x50A, 0x389]}
|
|
RELAY_MALFUNCTION_ADDRS = {0: (0x340, 0x485, 0x420, 0x421, 0x50A, 0x389)} # LKAS11, LFAHDA_MFC, SCC12, SCC11, SCC13, SCC14
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
if cls.__name__ == "TestHyundaiLongitudinalESCCSafety":
|
|
cls.safety = None
|
|
raise unittest.SkipTest
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(HyundaiSafetyFlagsIQ.ESCC | self.SAFETY_PARAM_IQ)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.LONG)
|
|
self.safety.init_tests()
|
|
|
|
def _accel_msg(self, accel, aeb_req=False, aeb_decel=0):
|
|
values = {
|
|
"aReqRaw": accel,
|
|
"aReqValue": accel,
|
|
}
|
|
return self.packer.make_can_msg_safety("SCC12", self.SCC_BUS, values)
|
|
|
|
def _tx_acc_state_msg(self, enable):
|
|
values = {"MainMode_ACC": enable}
|
|
return self.packer.make_can_msg_safety("SCC11", 0, values)
|
|
|
|
def test_tester_present_allowed(self):
|
|
pass
|
|
|
|
def test_disabled_ecu_alive(self):
|
|
pass
|
|
|
|
|
|
@parameterized_class(LDA_BUTTON)
|
|
class TestHyundaiNonSCCSafety(TestHyundaiSafety):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
if cls.__name__ == "TestHyundaiNonSCCSafety":
|
|
cls.safety = None
|
|
raise unittest.SkipTest
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(HyundaiSafetyFlagsIQ.NON_SCC | self.SAFETY_PARAM_IQ)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, 0)
|
|
self.safety.init_tests()
|
|
|
|
def _pcm_status_msg(self, enable):
|
|
values = {"CRUISE_LAMP_S": enable, "AliveCounter": self.cnt_gas % 4}
|
|
self.__class__.cnt_gas += 1
|
|
return self.packer.make_can_msg_safety("EMS16", 0, values, fix_checksum=checksum)
|
|
|
|
def _acc_state_msg(self, enable):
|
|
values = {"CRUISE_LAMP_M": enable, "AliveCounter": self.cnt_gas % 4}
|
|
self.__class__.cnt_gas += 1
|
|
return self.packer.make_can_msg_safety("EMS16", 0, values, fix_checksum=checksum)
|
|
|
|
def _user_gas_msg(self, gas: float, controls_allowed: bool = True):
|
|
values = {"CF_Ems_AclAct": gas, "CRUISE_LAMP_M": 1, "CRUISE_LAMP_S": controls_allowed, "AliveCounter": self.cnt_gas % 4}
|
|
self.__class__.cnt_gas += 1
|
|
return self.packer.make_can_msg_safety("EMS16", 0, values, fix_checksum=checksum)
|
|
|
|
def test_allow_engage_with_gas_pressed(self):
|
|
self._rx(self._user_gas_msg(1, self.safety.get_controls_allowed()))
|
|
self.safety.set_controls_allowed(True)
|
|
self._rx(self._user_gas_msg(1, self.safety.get_controls_allowed()))
|
|
self.assertTrue(self.safety.get_controls_allowed())
|
|
self._rx(self._user_gas_msg(1, self.safety.get_controls_allowed()))
|
|
self.assertTrue(self.safety.get_controls_allowed())
|
|
|
|
def test_no_disengage_on_gas(self):
|
|
self._rx(self._user_gas_msg(0, self.safety.get_controls_allowed()))
|
|
self.safety.set_controls_allowed(True)
|
|
self._rx(self._user_gas_msg(self.GAS_PRESSED_THRESHOLD + 1, self.safety.get_controls_allowed()))
|
|
# Test we allow lateral, but not longitudinal
|
|
self.assertTrue(self.safety.get_controls_allowed())
|
|
self.assertFalse(self.safety.get_longitudinal_brake_allowed())
|
|
self.assertTrue(self.safety.get_longitudinal_gas_allowed())
|
|
# Make sure we can re-gain longitudinal actuation
|
|
self._rx(self._user_gas_msg(0, self.safety.get_controls_allowed()))
|
|
self.assertTrue(self.safety.get_longitudinal_brake_allowed())
|
|
self.assertTrue(self.safety.get_longitudinal_gas_allowed())
|
|
|
|
|
|
@parameterized_class(ALL_NON_SCC_HEV_EV_COMBOS)
|
|
class TestHyundaiNonSCCSafety_HEV_EV(TestHyundaiSafety):
|
|
|
|
PCM_STATUS_MSG = ("", "")
|
|
ACC_STATE_MSG = ("", "")
|
|
GAS_MSG = ("", "")
|
|
SAFETY_PARAM = 0
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
if cls.__name__ == "TestHyundaiNonSCCSafety_HEV_EV":
|
|
cls.safety = None
|
|
raise unittest.SkipTest
|
|
|
|
def setUp(self):
|
|
self.packer = CANPackerSafety("hyundai_kia_generic")
|
|
self.safety = libsafety_py.libsafety
|
|
self.safety.set_current_safety_param_iq(HyundaiSafetyFlagsIQ.NON_SCC | self.SAFETY_PARAM_IQ)
|
|
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, self.SAFETY_PARAM)
|
|
self.safety.init_tests()
|
|
|
|
def _pcm_status_msg(self, enable):
|
|
values = {self.PCM_STATUS_MSG[1]: enable}
|
|
return self.packer.make_can_msg_safety(self.PCM_STATUS_MSG[0], 0, values)
|
|
|
|
def _acc_state_msg(self, enable):
|
|
values = {self.ACC_STATE_MSG[1]: enable}
|
|
return self.packer.make_can_msg_safety(self.ACC_STATE_MSG[0], 0, values)
|
|
|
|
def _user_gas_msg(self, gas):
|
|
values = {self.GAS_MSG[1]: gas}
|
|
return self.packer.make_can_msg_safety(self.GAS_MSG[0], 0, values, fix_checksum=checksum)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|