Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HKG: HDA2 ALT_BUTTON support #2117

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions board/safety/safety_hyundai_canfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,16 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *to_send) {
}

// cruise buttons check
if (addr == 0x1cf) {
int button = GET_BYTE(to_send, 2) & 0x7U;
bool is_cancel = (button == HYUNDAI_BTN_CANCEL);
bool is_resume = (button == HYUNDAI_BTN_RESUME);
const int button_addr = hyundai_canfd_alt_buttons ? 0x1aa : 0x1cf;
if (addr == button_addr) {
int cruise_button = 0;
if (addr == 0x1cf) {
cruise_button = GET_BYTE(to_send, 2) & 0x7U;
} else {
cruise_button = (GET_BYTE(to_send, 4) >> 4) & 0x7U;
}
bool is_cancel = (cruise_button == HYUNDAI_BTN_CANCEL);
bool is_resume = (cruise_button == HYUNDAI_BTN_RESUME);

bool allowed = (is_cancel && cruise_engaged_prev) || (is_resume && controls_allowed);
if (!allowed) {
Expand Down Expand Up @@ -231,12 +237,16 @@ static safety_config hyundai_canfd_init(uint16_t param) {
static const CanMsg HYUNDAI_CANFD_HDA2_TX_MSGS[] = {
{0x50, 0, 16}, // LKAS
{0x1CF, 1, 8}, // CRUISE_BUTTON
{0x1AA, 1, 16}, // CRUISE_BUTTONS_ALT
{0x2A4, 0, 24}, // CAM_0x2A4
};

static const CanMsg HYUNDAI_CANFD_HDA2_ALT_STEERING_TX_MSGS[] = {
{0x110, 0, 32}, // LKAS_ALT
{0x1CF, 1, 8}, // CRUISE_BUTTON
{0x1AA, 1, 16}, // CRUISE_BUTTONS_ALT
// Needed for cruise control in case of ALT_BUTTONS.
{0x1A0, 1, 32}, // CRUISE_INFO
{0x362, 0, 32}, // CAM_0x362
};

Expand All @@ -260,6 +270,7 @@ static safety_config hyundai_canfd_init(uint16_t param) {
{0x12A, 0, 16}, // LFA
{0x1A0, 0, 32}, // CRUISE_INFO
{0x1CF, 2, 8}, // CRUISE_BUTTON
{0x1AA, 2, 16}, // CRUISE_BUTTONS_ALT
{0x1E0, 0, 16}, // LFAHDA_CLUSTER
};

Expand Down Expand Up @@ -303,15 +314,23 @@ static safety_config hyundai_canfd_init(uint16_t param) {
if (hyundai_canfd_hda2) {
// *** HDA2 checks ***
// E-CAN is on bus 1, ADAS unit sends SCC messages on HDA2.
// Does not use the alt buttons message
static RxCheck hyundai_canfd_hda2_rx_checks[] = {
HYUNDAI_CANFD_COMMON_RX_CHECKS(1)
HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(1)
HYUNDAI_CANFD_SCC_ADDR_CHECK(1)
};

ret = hyundai_canfd_hda2_alt_steering ? BUILD_SAFETY_CFG(hyundai_canfd_hda2_rx_checks, HYUNDAI_CANFD_HDA2_ALT_STEERING_TX_MSGS) : \
BUILD_SAFETY_CFG(hyundai_canfd_hda2_rx_checks, HYUNDAI_CANFD_HDA2_TX_MSGS);
if (hyundai_canfd_alt_buttons) {
static RxCheck hyundai_canfd_hda2_alt_buttons_rx_checks[] = {
HYUNDAI_CANFD_COMMON_RX_CHECKS(1)
HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(1)
HYUNDAI_CANFD_SCC_ADDR_CHECK(1)
};
ret = hyundai_canfd_hda2_alt_steering ? BUILD_SAFETY_CFG(hyundai_canfd_hda2_alt_buttons_rx_checks, HYUNDAI_CANFD_HDA2_ALT_STEERING_TX_MSGS) : \
BUILD_SAFETY_CFG(hyundai_canfd_hda2_alt_buttons_rx_checks, HYUNDAI_CANFD_HDA2_TX_MSGS);
} else {
static RxCheck hyundai_canfd_hda2_rx_checks[] = {
HYUNDAI_CANFD_COMMON_RX_CHECKS(1)
HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(1)
HYUNDAI_CANFD_SCC_ADDR_CHECK(1)
};
ret = hyundai_canfd_hda2_alt_steering ? BUILD_SAFETY_CFG(hyundai_canfd_hda2_rx_checks, HYUNDAI_CANFD_HDA2_ALT_STEERING_TX_MSGS) : \
BUILD_SAFETY_CFG(hyundai_canfd_hda2_rx_checks, HYUNDAI_CANFD_HDA2_TX_MSGS);
}
} else if (!hyundai_camera_scc) {
static RxCheck hyundai_canfd_radar_scc_alt_buttons_rx_checks[] = {
HYUNDAI_CANFD_COMMON_RX_CHECKS(0)
Expand Down
129 changes: 55 additions & 74 deletions tests/safety/test_hyundai_canfd.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@


class TestHyundaiCanfdBase(HyundaiButtonBase, common.PandaCarSafetyTest, common.DriverTorqueSteeringSafetyTest, common.SteerRequestCutSafetyTest):

TX_MSGS = [[0x50, 0], [0x1CF, 1], [0x2A4, 0]]
SAFETY_PARAM = 0
TX_MSGS = [[0x50, 0], [0x1CF, 1], [0x1AA, 1], [0x2A4, 0]]
STANDSTILL_THRESHOLD = 12 # 0.375 kph
FWD_BLACKLISTED_ADDRS = {2: [0x50, 0x2a4]}
FWD_BUS_LOOKUP = {0: 2, 2: 0}
Expand Down Expand Up @@ -45,6 +45,12 @@ def setUpClass(cls):
cls.safety = None
raise unittest.SkipTest

def setUp(self):
self.packer = CANPackerPanda("hyundai_canfd")
self.safety = libpanda_py.libpanda
self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI_CANFD, self.SAFETY_PARAM)
self.safety.init_tests()

def _torque_driver_msg(self, torque):
values = {"STEERING_COL_TORQUE": torque}
return self.packer.make_can_msg_panda("MDPS", self.PT_BUS, values)
Expand Down Expand Up @@ -79,16 +85,32 @@ def _button_msg(self, buttons, main_button=0, bus=None):
return self.packer.make_can_msg_panda("CRUISE_BUTTONS", bus, values)


class HyundaiCanfdAltButtonsMixin:
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.SAFETY_PARAM |= Panda.FLAG_HYUNDAI_CANFD_ALT_BUTTONS

def _button_msg(self, buttons, main_button=0, bus=None):
if bus is None:
bus = self.PT_BUS
values = {
"CRUISE_BUTTONS": buttons,
"ADAPTIVE_CRUISE_MAIN_BTN": main_button,
}
msg = self.packer.make_can_msg_panda("CRUISE_BUTTONS_ALT", bus, values)
return msg


class TestHyundaiCanfdHDA1Base(TestHyundaiCanfdBase):

TX_MSGS = [[0x12A, 0], [0x1A0, 1], [0x1CF, 0], [0x1E0, 0]]
TX_MSGS = [[0x12A, 0], [0x1A0, 1], [0x1CF, 2], [0x1AA, 2], [0x1E0, 0]]
RELAY_MALFUNCTION_ADDRS = {0: (0x12A,)} # LFA
FWD_BLACKLISTED_ADDRS = {2: [0x12A, 0x1E0]}
FWD_BUS_LOOKUP = {0: 2, 2: 0}

STEER_MSG = "LFA"
BUTTONS_TX_BUS = 2
SAFETY_PARAM: int

@classmethod
def setUpClass(cls):
Expand All @@ -98,12 +120,6 @@ def setUpClass(cls):
cls.safety = None
raise unittest.SkipTest

def setUp(self):
self.packer = CANPackerPanda("hyundai_canfd")
self.safety = libpanda_py.libpanda
self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI_CANFD, self.SAFETY_PARAM)
self.safety.init_tests()


@parameterized_class([
# Radar SCC, test with long flag to ensure flag is not respected until it is supported
Expand All @@ -129,76 +145,50 @@ class TestHyundaiCanfdHDA1(TestHyundaiCanfdHDA1Base):
{"GAS_MSG": ("ACCELERATOR", "ACCELERATOR_PEDAL"), "SCC_BUS": 2, "SAFETY_PARAM": Panda.FLAG_HYUNDAI_EV_GAS | Panda.FLAG_HYUNDAI_CAMERA_SCC},
{"GAS_MSG": ("ACCELERATOR_ALT", "ACCELERATOR_PEDAL"), "SCC_BUS": 2, "SAFETY_PARAM": Panda.FLAG_HYUNDAI_HYBRID_GAS | Panda.FLAG_HYUNDAI_CAMERA_SCC},
])
class TestHyundaiCanfdHDA1AltButtons(TestHyundaiCanfdHDA1Base):

SAFETY_PARAM: int

def setUp(self):
self.packer = CANPackerPanda("hyundai_canfd")
self.safety = libpanda_py.libpanda
self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI_CANFD, Panda.FLAG_HYUNDAI_CANFD_ALT_BUTTONS | self.SAFETY_PARAM)
self.safety.init_tests()

def _button_msg(self, buttons, main_button=0, bus=1):
values = {
"CRUISE_BUTTONS": buttons,
"ADAPTIVE_CRUISE_MAIN_BTN": main_button,
}
return self.packer.make_can_msg_panda("CRUISE_BUTTONS_ALT", self.PT_BUS, values)

def test_button_sends(self):
"""
No button send allowed with alt buttons.
"""
for enabled in (True, False):
for btn in range(8):
self.safety.set_controls_allowed(enabled)
self.assertFalse(self._tx(self._button_msg(btn)))
class TestHyundaiCanfdHDA1AltButtons(HyundaiCanfdAltButtonsMixin, TestHyundaiCanfdHDA1Base):
pass


class TestHyundaiCanfdHDA2EV(TestHyundaiCanfdBase):
# ********************* HDA2 **********************

TX_MSGS = [[0x50, 0], [0x1CF, 1], [0x2A4, 0]]
RELAY_MALFUNCTION_ADDRS = {0: (0x50,)} # LKAS
FWD_BLACKLISTED_ADDRS = {2: [0x50, 0x2a4]}
FWD_BUS_LOOKUP = {0: 2, 2: 0}

# TODO: Handle ICE and HEV configurations.
class TestHyundaiCanfdHDA2EVBase(TestHyundaiCanfdBase):
PT_BUS = 1
SCC_BUS = 1
STEER_MSG = "LKAS"
GAS_MSG = ("ACCELERATOR", "ACCELERATOR_PEDAL")
FWD_BUS_LOOKUP = {0: 2, 2: 0}

def setUp(self):
self.packer = CANPackerPanda("hyundai_canfd")
self.safety = libpanda_py.libpanda
self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI_CANFD, Panda.FLAG_HYUNDAI_CANFD_HDA2 | Panda.FLAG_HYUNDAI_EV_GAS)
self.safety.init_tests()

class TestHyundaiCanfdHDA2EV(TestHyundaiCanfdHDA2EVBase):
TX_MSGS = [[0x50, 0], [0x1CF, 1], [0x1AA, 1], [0x2A4, 0]]
RELAY_MALFUNCTION_ADDRS = {0: (0x50,)}
FWD_BLACKLISTED_ADDRS = {2: [0x50, 0x2a4]}
STEER_MSG = "LKAS"
SAFETY_PARAM = Panda.FLAG_HYUNDAI_CANFD_HDA2 | Panda.FLAG_HYUNDAI_EV_GAS

# TODO: Handle ICE and HEV configurations once we see cars that use the new messages
class TestHyundaiCanfdHDA2EVAltSteering(TestHyundaiCanfdBase):

TX_MSGS = [[0x110, 0], [0x1CF, 1], [0x362, 0]]
RELAY_MALFUNCTION_ADDRS = {0: (0x110,)} # LKAS_ALT
class TestHyundaiCanfdHDA2EVAltSteering(TestHyundaiCanfdHDA2EVBase):
TX_MSGS = [[0x110, 0], [0x1CF, 1], [0x1AA, 1], [0x362, 0]]
RELAY_MALFUNCTION_ADDRS = {0: (0x110,)}
FWD_BLACKLISTED_ADDRS = {2: [0x110, 0x362]}
FWD_BUS_LOOKUP = {0: 2, 2: 0}

PT_BUS = 1
SCC_BUS = 1
STEER_MSG = "LKAS_ALT"
GAS_MSG = ("ACCELERATOR", "ACCELERATOR_PEDAL")
SAFETY_PARAM = Panda.FLAG_HYUNDAI_CANFD_HDA2 | Panda.FLAG_HYUNDAI_EV_GAS | Panda.FLAG_HYUNDAI_CANFD_HDA2_ALT_STEERING

def setUp(self):
self.packer = CANPackerPanda("hyundai_canfd")
self.safety = libpanda_py.libpanda
self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI_CANFD, Panda.FLAG_HYUNDAI_CANFD_HDA2 | Panda.FLAG_HYUNDAI_EV_GAS |
Panda.FLAG_HYUNDAI_CANFD_HDA2_ALT_STEERING)
self.safety.init_tests()

class TestHyundaiCanfdHDA2EVAltButtons(HyundaiCanfdAltButtonsMixin, TestHyundaiCanfdHDA2EV):
pass

class TestHyundaiCanfdHDA2EVAltSteeringAltButtons(HyundaiCanfdAltButtonsMixin, TestHyundaiCanfdHDA2EVAltSteering):
pass


# ********************* LONG **********************


class TestHyundaiCanfdHDA2LongEV(HyundaiLongitudinalBase, TestHyundaiCanfdHDA2EV):

TX_MSGS = [[0x50, 0], [0x1CF, 1], [0x2A4, 0], [0x51, 0], [0x730, 1], [0x12a, 1], [0x160, 1],
TX_MSGS = [[0x50, 0], [0x1CF, 1], [0x1AA, 1], [0x2A4, 0], [0x51, 0], [0x730, 1], [0x12a, 1], [0x160, 1],
[0x1e0, 1], [0x1a0, 1], [0x1ea, 1], [0x200, 1], [0x345, 1], [0x1da, 1]]

RELAY_MALFUNCTION_ADDRS = {0: (0x50,), 1: (0x1a0,)} # LKAS, SCC_CONTROL
Expand All @@ -209,12 +199,7 @@ class TestHyundaiCanfdHDA2LongEV(HyundaiLongitudinalBase, TestHyundaiCanfdHDA2EV
STEER_MSG = "LFA"
GAS_MSG = ("ACCELERATOR", "ACCELERATOR_PEDAL")
STEER_BUS = 1

def setUp(self):
self.packer = CANPackerPanda("hyundai_canfd")
self.safety = libpanda_py.libpanda
self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI_CANFD, Panda.FLAG_HYUNDAI_CANFD_HDA2 | Panda.FLAG_HYUNDAI_LONG | Panda.FLAG_HYUNDAI_EV_GAS)
self.safety.init_tests()
SAFETY_PARAM = Panda.FLAG_HYUNDAI_CANFD_HDA2 | Panda.FLAG_HYUNDAI_LONG | Panda.FLAG_HYUNDAI_EV_GAS

def _accel_msg(self, accel, aeb_req=False, aeb_decel=0):
values = {
Expand Down Expand Up @@ -246,16 +231,12 @@ class TestHyundaiCanfdHDA1Long(HyundaiLongitudinalBase, TestHyundaiCanfdHDA1Base

@classmethod
def setUpClass(cls):
super().setUpClass()
cls.SAFETY_PARAM |= Panda.FLAG_HYUNDAI_CAMERA_SCC
if cls.__name__ == "TestHyundaiCanfdHDA1Long":
cls.safety = None
raise unittest.SkipTest

def setUp(self):
self.packer = CANPackerPanda("hyundai_canfd")
self.safety = libpanda_py.libpanda
self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI_CANFD, Panda.FLAG_HYUNDAI_CAMERA_SCC | self.SAFETY_PARAM)
self.safety.init_tests()

def _accel_msg(self, accel, aeb_req=False, aeb_decel=0):
values = {
"aReqRaw": accel,
Expand Down
Loading