mirror of
https://github.com/MoreTore/openpilot.git
synced 2026-07-27 04:42:05 +08:00
RIP iPedal
This commit is contained in:
@@ -159,7 +159,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"AlertVolumeControl", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
{"AlwaysOnLateral", {PERSISTENT, BOOL, "1", "0", 0}},
|
||||
{"AlwaysOnLateralLKAS", {PERSISTENT, BOOL, "1", "0", 2}},
|
||||
{"AlwaysIPedal", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
{"ApiCache_DriveStats", {PERSISTENT, JSON, "{}", "{}"}},
|
||||
{"AutomaticallyDownloadModels", {PERSISTENT, BOOL, "1", "0", 1}},
|
||||
{"AutomaticUpdates", {PERSISTENT, BOOL, "1", "1", 0}},
|
||||
|
||||
@@ -57,17 +57,6 @@ IONIQ_6_STOP_RELEASE_JERK_BP = [0.0, 0.15, 0.5]
|
||||
IONIQ_6_STOP_RELEASE_JERK_V = [3.6 * IONIQ_6_RESPONSE_MULTIPLIER,
|
||||
4.2 * IONIQ_6_RESPONSE_MULTIPLIER,
|
||||
4.8 * IONIQ_6_RESPONSE_MULTIPLIER]
|
||||
IONIQ_6_IPEDAL_PRESS_SEND_COUNT = 6
|
||||
IONIQ_6_IPEDAL_LATCH_PRESS_SEND_COUNT = 6
|
||||
IONIQ_6_IPEDAL_PADDLE_BURST_COUNT = 3
|
||||
IONIQ_6_MAX_REGEN_STATE = 0x3C
|
||||
IONIQ_6_MAX_REGEN_STATE_2 = 0x01
|
||||
IONIQ_6_IPEDAL_REGEN_STATE = 0x50
|
||||
IONIQ_6_IPEDAL_REGEN_STATE_2_PENDING = 0x01
|
||||
IONIQ_6_IPEDAL_PROGRESS_RETRY_WAIT_FRAMES = 10
|
||||
IONIQ_6_IPEDAL_RETRY_WAIT_FRAMES = 30
|
||||
|
||||
|
||||
def get_canfd_lead_distance_setting(lead_distance: float | None, default_setting: int) -> int:
|
||||
default = int(np.clip(default_setting, 0, 3))
|
||||
if lead_distance is None or lead_distance <= CANFD_LEAD_MIN_DISTANCE:
|
||||
@@ -253,17 +242,6 @@ class CarController(CarControllerBase):
|
||||
self._ioniq_6_lane_change_ui_side = None
|
||||
self._ioniq_6_lane_change_ui_trigger_frames = 0
|
||||
self._ioniq_6_long_tuning = Ioniq6LongitudinalTuningState()
|
||||
self._ioniq_6_always_ipedal_pending = False
|
||||
self._ioniq_6_always_ipedal_press_remaining = 0
|
||||
self._ioniq_6_always_ipedal_retry_frame = 0
|
||||
self._ioniq_6_always_ipedal_startup_park_done = False
|
||||
self._ioniq_6_last_ipedal_regen_state = 0
|
||||
self._ioniq_6_last_ipedal_regen_state_2 = 0
|
||||
self._ioniq_6_last_buttons_counter = 0
|
||||
self._ioniq_6_last_regen_control_counter = -1
|
||||
self._ioniq_6_regen_request_sent = False
|
||||
self._ioniq_6_ipedal_latch_counter = -1
|
||||
self._ioniq_6_last_gear = structs.CarState.GearShifter.unknown
|
||||
self._genesis_g90_long_tuning = GenesisG90LongitudinalTuningState()
|
||||
self._dash_lat_disengage_blink_frame = 0
|
||||
self._dash_lat_disengage_init = False
|
||||
@@ -306,126 +284,6 @@ class CarController(CarControllerBase):
|
||||
|
||||
return False, 0.0, 0.0, default_distance_setting
|
||||
|
||||
def _reset_ioniq_6_always_ipedal(self) -> None:
|
||||
self._ioniq_6_always_ipedal_pending = False
|
||||
self._ioniq_6_always_ipedal_press_remaining = 0
|
||||
self._ioniq_6_always_ipedal_retry_frame = 0
|
||||
self._ioniq_6_regen_request_sent = False
|
||||
self._ioniq_6_ipedal_latch_counter = -1
|
||||
|
||||
def _arm_ioniq_6_always_ipedal(self) -> None:
|
||||
self._ioniq_6_always_ipedal_pending = True
|
||||
self._ioniq_6_always_ipedal_press_remaining = 0
|
||||
self._ioniq_6_always_ipedal_retry_frame = self.frame
|
||||
self._ioniq_6_regen_request_sent = False
|
||||
self._ioniq_6_ipedal_latch_counter = -1
|
||||
|
||||
def _update_ioniq_6_always_ipedal(self, CC, CS, starpilot_toggles):
|
||||
can_sends = []
|
||||
|
||||
if self.CP.carFingerprint != CAR.HYUNDAI_IONIQ_6 or not getattr(starpilot_toggles, "always_ipedal", False):
|
||||
self._reset_ioniq_6_always_ipedal()
|
||||
self._ioniq_6_always_ipedal_startup_park_done = False
|
||||
self._ioniq_6_last_ipedal_regen_state = int(getattr(CS, "ipedal_regen_state", 0))
|
||||
self._ioniq_6_last_ipedal_regen_state_2 = int(getattr(CS, "ipedal_regen_state_2", 0))
|
||||
self._ioniq_6_last_buttons_counter = int(getattr(CS, "buttons_counter", 0))
|
||||
self._ioniq_6_last_regen_control_counter = int(getattr(CS, "ioniq_6_regen_control_msg", {}).get("COUNTER", -1))
|
||||
self._ioniq_6_last_gear = CS.out.gearShifter
|
||||
return can_sends
|
||||
|
||||
gear = CS.out.gearShifter
|
||||
regen_state = int(getattr(CS, "ipedal_regen_state", 0))
|
||||
regen_state_2 = int(getattr(CS, "ipedal_regen_state_2", 0))
|
||||
buttons_counter = int(getattr(CS, "buttons_counter", 0))
|
||||
regen_control_msg = getattr(CS, "ioniq_6_regen_control_msg", {})
|
||||
regen_control_counter = int(regen_control_msg.get("COUNTER", -1))
|
||||
has_regen_control_msg = bool(regen_control_msg) and getattr(CS, "ioniq_6_regen_control_ts", 0) > 0
|
||||
regen_state_changed = regen_state != self._ioniq_6_last_ipedal_regen_state or regen_state_2 != self._ioniq_6_last_ipedal_regen_state_2
|
||||
buttons_counter_changed = buttons_counter != self._ioniq_6_last_buttons_counter
|
||||
regen_control_counter_changed = regen_control_counter != self._ioniq_6_last_regen_control_counter
|
||||
max_regen_state = regen_state == IONIQ_6_MAX_REGEN_STATE and regen_state_2 == IONIQ_6_MAX_REGEN_STATE_2
|
||||
ipedal_latch_pending = regen_state == IONIQ_6_IPEDAL_REGEN_STATE and regen_state_2 == IONIQ_6_IPEDAL_REGEN_STATE_2_PENDING
|
||||
was_max_regen_state = self._ioniq_6_last_ipedal_regen_state == IONIQ_6_MAX_REGEN_STATE and \
|
||||
self._ioniq_6_last_ipedal_regen_state_2 == IONIQ_6_MAX_REGEN_STATE_2
|
||||
was_ipedal_latch_pending = self._ioniq_6_last_ipedal_regen_state == IONIQ_6_IPEDAL_REGEN_STATE and \
|
||||
self._ioniq_6_last_ipedal_regen_state_2 == IONIQ_6_IPEDAL_REGEN_STATE_2_PENDING
|
||||
entered_latch_stage = (max_regen_state and not was_max_regen_state) or \
|
||||
(ipedal_latch_pending and not was_ipedal_latch_pending)
|
||||
drive = gear == structs.CarState.GearShifter.drive
|
||||
park = gear == structs.CarState.GearShifter.park
|
||||
drive_edge = drive and self._ioniq_6_last_gear != structs.CarState.GearShifter.drive
|
||||
startup_park = park and not self._ioniq_6_always_ipedal_startup_park_done
|
||||
startup_park_edge = startup_park and self._ioniq_6_last_gear != structs.CarState.GearShifter.park
|
||||
target_gear = drive or startup_park
|
||||
|
||||
if gear == structs.CarState.GearShifter.unknown:
|
||||
self._ioniq_6_always_ipedal_startup_park_done = False
|
||||
elif not park and not self._ioniq_6_always_ipedal_startup_park_done:
|
||||
self._ioniq_6_always_ipedal_startup_park_done = True
|
||||
|
||||
if (startup_park_edge or drive_edge) and not CS.ipedal_active:
|
||||
self._arm_ioniq_6_always_ipedal()
|
||||
elif not target_gear or CS.ipedal_active:
|
||||
self._reset_ioniq_6_always_ipedal()
|
||||
elif CC.enabled:
|
||||
self._ioniq_6_always_ipedal_pending = False
|
||||
self._ioniq_6_always_ipedal_press_remaining = 0
|
||||
|
||||
if entered_latch_stage:
|
||||
self._ioniq_6_always_ipedal_press_remaining = 0
|
||||
self._ioniq_6_always_ipedal_retry_frame = self.frame
|
||||
self._ioniq_6_regen_request_sent = False
|
||||
self._ioniq_6_ipedal_latch_counter = -1
|
||||
|
||||
if target_gear and self._ioniq_6_always_ipedal_pending and not CS.ipedal_active and not CC.enabled:
|
||||
if self._ioniq_6_always_ipedal_press_remaining == 0 and self.frame >= self._ioniq_6_always_ipedal_retry_frame:
|
||||
self._ioniq_6_always_ipedal_press_remaining = IONIQ_6_IPEDAL_LATCH_PRESS_SEND_COUNT if (max_regen_state or ipedal_latch_pending) \
|
||||
else IONIQ_6_IPEDAL_PRESS_SEND_COUNT
|
||||
self._ioniq_6_regen_request_sent = False
|
||||
if max_regen_state or ipedal_latch_pending:
|
||||
self._ioniq_6_ipedal_latch_counter = buttons_counter if 0 <= buttons_counter < hyundaicanfd.IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX else -1
|
||||
else:
|
||||
self._ioniq_6_ipedal_latch_counter = -1
|
||||
|
||||
if self._ioniq_6_always_ipedal_press_remaining > 0:
|
||||
if max_regen_state or ipedal_latch_pending:
|
||||
if self._ioniq_6_ipedal_latch_counter < 0 and 0 <= buttons_counter < hyundaicanfd.IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX:
|
||||
self._ioniq_6_ipedal_latch_counter = buttons_counter
|
||||
|
||||
if 0 <= self._ioniq_6_ipedal_latch_counter < hyundaicanfd.IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX:
|
||||
# A real successful i-Pedal pull is a short held press followed by release, not a continuous hold.
|
||||
# Mirror that with a stock-like six-counter sequence, then stop transmitting to give the car a release window.
|
||||
paddle_msg = hyundaicanfd.create_ioniq_6_paddle_buttons(self.packer, self.CP, self.CAN,
|
||||
self._ioniq_6_ipedal_latch_counter, left_paddle=True)
|
||||
can_sends.append(paddle_msg)
|
||||
self._ioniq_6_ipedal_latch_counter = hyundaicanfd.get_ioniq_6_cruise_buttons_next_counter(self._ioniq_6_ipedal_latch_counter)
|
||||
self._ioniq_6_always_ipedal_press_remaining -= 1
|
||||
elif buttons_counter_changed and 0 <= buttons_counter < hyundaicanfd.IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX:
|
||||
paddle_msg = hyundaicanfd.create_ioniq_6_paddle_buttons(self.packer, self.CP, self.CAN,
|
||||
buttons_counter, left_paddle=True)
|
||||
can_sends.extend([paddle_msg] * IONIQ_6_IPEDAL_PADDLE_BURST_COUNT)
|
||||
self._ioniq_6_always_ipedal_press_remaining -= 1
|
||||
|
||||
if self._ioniq_6_always_ipedal_press_remaining == 0:
|
||||
retry_wait_frames = IONIQ_6_IPEDAL_PROGRESS_RETRY_WAIT_FRAMES if regen_state_changed else IONIQ_6_IPEDAL_RETRY_WAIT_FRAMES
|
||||
self._ioniq_6_always_ipedal_retry_frame = self.frame + retry_wait_frames
|
||||
self._ioniq_6_ipedal_latch_counter = -1
|
||||
|
||||
# The drivetrain latch uses a second HKG CAN-FD request path in addition to the left paddle bit.
|
||||
# Mirror the next stock 0x25A frame once per retry burst instead of spamming it continuously.
|
||||
if max_regen_state and has_regen_control_msg and regen_control_counter_changed and not self._ioniq_6_regen_request_sent:
|
||||
request_tail = hyundaicanfd.get_ioniq_6_regen_control_request_tail(regen_control_msg)
|
||||
if request_tail is not None:
|
||||
can_sends.append(hyundaicanfd.create_ioniq_6_regen_control(self.packer, self.CP, self.CAN, regen_control_msg))
|
||||
self._ioniq_6_regen_request_sent = True
|
||||
|
||||
self._ioniq_6_last_ipedal_regen_state = regen_state
|
||||
self._ioniq_6_last_ipedal_regen_state_2 = regen_state_2
|
||||
self._ioniq_6_last_buttons_counter = buttons_counter
|
||||
self._ioniq_6_last_regen_control_counter = regen_control_counter
|
||||
self._ioniq_6_last_gear = gear
|
||||
return can_sends
|
||||
|
||||
def update(self, CC, CS, now_nanos, starpilot_toggles):
|
||||
actuators = CC.actuators
|
||||
hud_control = CC.hudControl
|
||||
@@ -678,8 +536,6 @@ class CarController(CarControllerBase):
|
||||
if self._ioniq_6_lane_change_ui_trigger_frames > 0:
|
||||
self._ioniq_6_lane_change_ui_trigger_frames -= 1
|
||||
|
||||
can_sends.extend(self._update_ioniq_6_always_ipedal(CC, CS, starpilot_toggles))
|
||||
|
||||
if self.long_active_ecu:
|
||||
if lka_steering:
|
||||
can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame))
|
||||
|
||||
@@ -24,12 +24,6 @@ BUTTONS_DICT = {Buttons.RES_ACCEL: ButtonType.accelCruise, Buttons.SET_DECEL: Bu
|
||||
|
||||
IONIQ_6_BLINDSPOT_RIGHT_MASK = 0x08
|
||||
IONIQ_6_BLINDSPOT_LEFT_MASK = 0x10
|
||||
IONIQ_6_MAX_REGEN_STATE = 0x3C
|
||||
IONIQ_6_MAX_REGEN_STATE_2 = 0x01
|
||||
IONIQ_6_IPEDAL_INTERMEDIATE_REGEN_STATE = 0x50
|
||||
IONIQ_6_IPEDAL_INTERMEDIATE_REGEN_STATE_2 = 0x01
|
||||
IONIQ_6_IPEDAL_REGEN_STATE = 0x50
|
||||
IONIQ_6_IPEDAL_REGEN_STATE_2 = 0x03
|
||||
CANFD_CAMERA_LEAD_MIN_DISTANCE = 0.1
|
||||
|
||||
|
||||
@@ -50,18 +44,6 @@ def decode_ioniq_6_blindspot_radar_state(state: int) -> tuple[bool, bool]:
|
||||
return bool(state_int & IONIQ_6_BLINDSPOT_LEFT_MASK), bool(state_int & IONIQ_6_BLINDSPOT_RIGHT_MASK)
|
||||
|
||||
|
||||
def decode_ioniq_6_ipedal_state(regen_state: int, regen_state_2: int) -> bool:
|
||||
return int(regen_state) == IONIQ_6_IPEDAL_REGEN_STATE and int(regen_state_2) == IONIQ_6_IPEDAL_REGEN_STATE_2
|
||||
|
||||
|
||||
def decode_ioniq_6_max_regen_state(regen_state: int, regen_state_2: int) -> bool:
|
||||
return int(regen_state) == IONIQ_6_MAX_REGEN_STATE and int(regen_state_2) == IONIQ_6_MAX_REGEN_STATE_2
|
||||
|
||||
|
||||
def decode_ioniq_6_ipedal_intermediate_state(regen_state: int, regen_state_2: int) -> bool:
|
||||
return int(regen_state) == IONIQ_6_IPEDAL_INTERMEDIATE_REGEN_STATE and int(regen_state_2) == IONIQ_6_IPEDAL_INTERMEDIATE_REGEN_STATE_2
|
||||
|
||||
|
||||
def decode_canfd_camera_lead(distance: float, rel_speed: float) -> tuple[bool, float, float]:
|
||||
lead_distance = float(distance)
|
||||
lead_visible = lead_distance > CANFD_CAMERA_LEAD_MIN_DISTANCE
|
||||
@@ -89,11 +71,6 @@ class CarState(CarStateBase):
|
||||
self.custom_button = 0
|
||||
self.cancel_button_enable_in_progress = False
|
||||
self.cruise_buttons_msg = {}
|
||||
self.ipedal_active = False
|
||||
self.ipedal_regen_state = 0
|
||||
self.ipedal_regen_state_2 = 0
|
||||
self.ioniq_6_regen_control_msg = {}
|
||||
self.ioniq_6_regen_control_ts = 0
|
||||
|
||||
self.gear_msg_canfd = "ACCELERATOR" if CP.flags & HyundaiFlags.EV else \
|
||||
"GEAR_ALT" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS else \
|
||||
@@ -346,7 +323,6 @@ class CarState(CarStateBase):
|
||||
|
||||
self.is_metric = cp.vl["CRUISE_BUTTONS_ALT"]["DISTANCE_UNIT"] != 1
|
||||
speed_factor = CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS
|
||||
self.ipedal_active = False
|
||||
|
||||
if self.CP.flags & (HyundaiFlags.EV | HyundaiFlags.HYBRID):
|
||||
ret.gasPressed = cp.vl[self.accelerator_msg_canfd]["ACCELERATOR_PEDAL"] > 1e-5
|
||||
@@ -424,15 +400,6 @@ class CarState(CarStateBase):
|
||||
# TODO: find this message on ICE & HYBRID cars + cruise control signals (if exists)
|
||||
if self.CP.flags & HyundaiFlags.EV:
|
||||
ret.cruiseState.nonAdaptive = cp.vl["MANUAL_SPEED_LIMIT_ASSIST"]["MSLA_ENABLED"] == 1
|
||||
if self.CP.carFingerprint == CAR.HYUNDAI_IONIQ_6:
|
||||
msla = cp.vl["MANUAL_SPEED_LIMIT_ASSIST"]
|
||||
self.ipedal_regen_state = int(msla.get("EV_REGEN_STATE", 0))
|
||||
self.ipedal_regen_state_2 = int(msla.get("EV_REGEN_STATE_2", 0))
|
||||
self.ipedal_active = decode_ioniq_6_ipedal_state(self.ipedal_regen_state, self.ipedal_regen_state_2)
|
||||
if cp.ts_nanos["IONIQ_6_REGEN_CONTROL"]["CHECKSUM"] > 0:
|
||||
self.ioniq_6_regen_control_msg = copy.copy(cp.vl["IONIQ_6_REGEN_CONTROL"])
|
||||
self.ioniq_6_regen_control_ts = cp.ts_nanos["IONIQ_6_REGEN_CONTROL"]["CHECKSUM"]
|
||||
|
||||
prev_cruise_buttons = self.cruise_buttons[-1]
|
||||
prev_main_buttons = self.main_buttons[-1]
|
||||
prev_lda_button = self.lda_button
|
||||
@@ -517,8 +484,6 @@ class CarState(CarStateBase):
|
||||
if CP.flags & HyundaiFlags.EV:
|
||||
msgs.append(("DRIVE_MODE_EV", 0)) # optional: not all CAN-FD EV variants publish drive mode
|
||||
msgs.append(("MANUAL_SPEED_LIMIT_ASSIST", 0)) # optional: used for non-adaptive cruise state and Ioniq 6 i-Pedal latch detection
|
||||
if CP.carFingerprint == CAR.HYUNDAI_IONIQ_6:
|
||||
msgs.append(("IONIQ_6_REGEN_CONTROL", 0))
|
||||
msgs.append(("STEERING_WHEEL_MEDIA_BUTTONS", 0)) # optional: absent or slower on some CAN-FD variants
|
||||
cam_msgs.append(("ADAS_0x380", 0)) # optional: dashboard stop-sign signal, only on ADAS-equipped HKG CANFD
|
||||
return {
|
||||
|
||||
@@ -162,77 +162,6 @@ def create_suppress_lfa(packer, CAN, lfa_block_msg, lka_steering_alt):
|
||||
return packer.make_can_msg(suppress_msg, CAN.ACAN, values)
|
||||
|
||||
|
||||
IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX = 15
|
||||
IONIQ_6_CRUISE_BUTTONS_BASE_CHECKSUMS = (
|
||||
0x56, 0xEF, 0x39, 0x80, 0x88,
|
||||
0x31, 0xE7, 0x5E, 0xF7, 0x4E,
|
||||
0x98, 0x21, 0x29, 0x90, 0x46,
|
||||
)
|
||||
IONIQ_6_CRUISE_BUTTONS_LEFT_PADDLE_CHECKSUM_XOR = 0x77
|
||||
IONIQ_6_CRUISE_BUTTONS_RIGHT_PADDLE_CHECKSUM_XOR = 0xD4
|
||||
IONIQ_6_REGEN_CONTROL_REQUEST_TAILS = {
|
||||
(0xA8, 0x0C, 0x12, 0x0E): (0xC0, 0x0C, 0x12, 0x00),
|
||||
(0xA8, 0x0E, 0x07, 0x0E): (0x85, 0x0E, 0x07, 0x0C),
|
||||
(0x18, 0x10, 0x07, 0x02): (0xB5, 0x10, 0x07, 0x00),
|
||||
(0xA8, 0x10, 0x07, 0x0E): (0xB5, 0x10, 0x07, 0x00),
|
||||
}
|
||||
|
||||
|
||||
def get_ioniq_6_cruise_buttons_next_counter(counter: int) -> int:
|
||||
return (int(counter) + 1) % IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX
|
||||
|
||||
|
||||
def create_ioniq_6_paddle_buttons(packer, CP, CAN, cnt, left_paddle=False, right_paddle=False):
|
||||
if left_paddle and right_paddle:
|
||||
raise ValueError("Ioniq 6 paddle spoof only supports one paddle at a time")
|
||||
if cnt < 0 or cnt >= IONIQ_6_CRUISE_BUTTONS_COUNTER_MAX:
|
||||
raise ValueError(f"Invalid Ioniq 6 cruise buttons counter: {cnt}")
|
||||
|
||||
values = {
|
||||
"COUNTER": cnt,
|
||||
"SET_ME_1": 1,
|
||||
"CRUISE_BUTTONS": 0,
|
||||
"ADAPTIVE_CRUISE_MAIN_BTN": 0,
|
||||
"NORMAL_CRUISE_MAIN_BTN": 0,
|
||||
"LDA_BTN": 0,
|
||||
"LEFT_PADDLE": int(left_paddle),
|
||||
"RIGHT_PADDLE": int(right_paddle),
|
||||
}
|
||||
|
||||
address = packer.dbc.name_to_msg["CRUISE_BUTTONS"].address
|
||||
dat = packer.pack(address, values)
|
||||
checksum = IONIQ_6_CRUISE_BUTTONS_BASE_CHECKSUMS[cnt]
|
||||
if left_paddle:
|
||||
checksum ^= IONIQ_6_CRUISE_BUTTONS_LEFT_PADDLE_CHECKSUM_XOR
|
||||
if right_paddle:
|
||||
checksum ^= IONIQ_6_CRUISE_BUTTONS_RIGHT_PADDLE_CHECKSUM_XOR
|
||||
dat[0] = checksum
|
||||
|
||||
bus = CAN.ECAN if CP.flags & HyundaiFlags.CANFD_LKA_STEERING else CAN.CAM
|
||||
return address, bytes(dat), bus
|
||||
|
||||
|
||||
def get_ioniq_6_regen_control_request_tail(base_values):
|
||||
base_tail = tuple(int(base_values.get(f"BYTE{i}", 0)) for i in range(24, 28))
|
||||
return IONIQ_6_REGEN_CONTROL_REQUEST_TAILS.get(base_tail)
|
||||
|
||||
|
||||
def create_ioniq_6_regen_control(packer, CP, CAN, base_values):
|
||||
request_tail = get_ioniq_6_regen_control_request_tail(base_values)
|
||||
if request_tail is None:
|
||||
raise ValueError(f"Unsupported Ioniq 6 regen control tail: {tuple(int(base_values.get(f'BYTE{i}', 0)) for i in range(24, 28))}")
|
||||
|
||||
values = {k: v for k, v in base_values.items() if k != "CHECKSUM"}
|
||||
address = packer.dbc.name_to_msg["IONIQ_6_REGEN_CONTROL"].address
|
||||
dat = bytearray(packer.pack(address, values))
|
||||
dat[24:28] = bytes(request_tail)
|
||||
|
||||
checksum = hkg_can_fd_checksum(address, None, dat)
|
||||
dat[0] = checksum & 0xFF
|
||||
dat[1] = (checksum >> 8) & 0xFF
|
||||
return address, bytes(dat), CAN.ECAN
|
||||
|
||||
|
||||
def create_buttons(packer, CP, CAN, cnt, btn=0, base_values=None, left_paddle=False, right_paddle=False):
|
||||
values = {k: v for k, v in base_values.items() if k not in ("_CHECKSUM", "COUNTER")} if base_values else {}
|
||||
values.update({
|
||||
|
||||
@@ -9,11 +9,9 @@ from opendbc.car.structs import CarControl, CarParams
|
||||
from opendbc.car.fw_versions import build_fw_dict, match_fw_to_car
|
||||
from opendbc.car.hyundai.carcontroller import CarController, Ioniq6LongitudinalTuningState, GenesisG90LongitudinalTuningState, \
|
||||
get_canfd_lead_distance_setting, \
|
||||
IONIQ_6_IPEDAL_PADDLE_BURST_COUNT, \
|
||||
update_ioniq_6_longitudinal_tuning, \
|
||||
update_genesis_g90_longitudinal_tuning
|
||||
from opendbc.car.hyundai.carstate import CarState, decode_canfd_camera_lead, decode_ioniq_6_blindspot_radar_state, decode_ioniq_6_ipedal_intermediate_state, \
|
||||
decode_ioniq_6_ipedal_state, decode_ioniq_6_max_regen_state
|
||||
from opendbc.car.hyundai.carstate import CarState, decode_canfd_camera_lead, decode_ioniq_6_blindspot_radar_state
|
||||
from opendbc.car.hyundai.interface import CarInterface
|
||||
from opendbc.car.hyundai import hyundaican, hyundaicanfd
|
||||
from opendbc.car.hyundai.hyundaicanfd import CanBus
|
||||
@@ -57,7 +55,7 @@ CANFD_EXPECTED_ECUS = {Ecu.fwdCamera, Ecu.fwdRadar}
|
||||
|
||||
|
||||
def get_test_toggles() -> SimpleNamespace:
|
||||
return SimpleNamespace(always_ipedal=False, always_on_lateral_lkas=False, force_torque_controller=False, nnff=False, nnff_lite=False)
|
||||
return SimpleNamespace(always_on_lateral_lkas=False, force_torque_controller=False, nnff=False, nnff_lite=False)
|
||||
|
||||
|
||||
class TestHyundaiFingerprint:
|
||||
@@ -316,258 +314,6 @@ class TestHyundaiFingerprint:
|
||||
ret = update(0, 3)
|
||||
assert any(be.type == ButtonType.altButton2 and not be.pressed for be in ret.buttonEvents)
|
||||
|
||||
def test_ioniq_6_ipedal_state_decode(self):
|
||||
assert decode_ioniq_6_max_regen_state(0x3C, 0x01)
|
||||
assert not decode_ioniq_6_ipedal_state(0x3C, 0x01)
|
||||
assert not decode_ioniq_6_ipedal_state(0x50, 0x01)
|
||||
assert decode_ioniq_6_ipedal_intermediate_state(0x50, 0x01)
|
||||
assert decode_ioniq_6_ipedal_state(0x50, 0x03)
|
||||
|
||||
def test_ioniq_6_msla_regen_signals_decode(self):
|
||||
CP = CarParams.new_message()
|
||||
CP.carFingerprint = CAR.HYUNDAI_IONIQ_6
|
||||
CP.flags = int(HyundaiFlags.CANFD | HyundaiFlags.CANFD_LKA_STEERING)
|
||||
|
||||
packer = CANPacker(DBC[CP.carFingerprint][Bus.pt])
|
||||
can_bus = CanBus(CP)
|
||||
parser = CANParser(DBC[CP.carFingerprint][Bus.pt], [("MANUAL_SPEED_LIMIT_ASSIST", 0)], can_bus.ECAN)
|
||||
|
||||
msg = packer.make_can_msg("MANUAL_SPEED_LIMIT_ASSIST", can_bus.ECAN, {
|
||||
"MSLA_STATUS": 0,
|
||||
"MSLA_ENABLED": 0,
|
||||
"MAX_SPEED": 0,
|
||||
"MAX_SPEED_COPY": 0,
|
||||
"EV_REGEN_STATE": 0x50,
|
||||
"EV_REGEN_STATE_2": 0x03,
|
||||
})
|
||||
parser.update([(1, [msg])])
|
||||
|
||||
assert parser.can_valid
|
||||
assert parser.vl["MANUAL_SPEED_LIMIT_ASSIST"]["EV_REGEN_STATE"] == 0x50
|
||||
assert parser.vl["MANUAL_SPEED_LIMIT_ASSIST"]["EV_REGEN_STATE_2"] == 0x03
|
||||
|
||||
@pytest.mark.parametrize(("counter", "expected_hex"), [
|
||||
(0, "2100002800000000"),
|
||||
(7, "2970002800000000"),
|
||||
(14, "31e0002800000000"),
|
||||
])
|
||||
def test_ioniq_6_left_paddle_message_matches_stock(self, counter, expected_hex):
|
||||
CP = CarParams.new_message()
|
||||
CP.carFingerprint = CAR.HYUNDAI_IONIQ_6
|
||||
CP.flags = int(HyundaiFlags.CANFD | HyundaiFlags.CANFD_LKA_STEERING)
|
||||
|
||||
msg = hyundaicanfd.create_ioniq_6_paddle_buttons(CANPacker(DBC[CP.carFingerprint][Bus.pt]), CP, CanBus(CP),
|
||||
counter, left_paddle=True)
|
||||
assert msg[1].hex() == expected_hex
|
||||
|
||||
def test_ioniq_6_buttons_counter_wraps_like_stock(self):
|
||||
assert hyundaicanfd.get_ioniq_6_cruise_buttons_next_counter(13) == 14
|
||||
assert hyundaicanfd.get_ioniq_6_cruise_buttons_next_counter(14) == 0
|
||||
|
||||
@pytest.mark.parametrize(("stock_hex", "expected_tail"), [
|
||||
("45421440801f000000000000a865170000a000000080c071a80c120e00000000", bytes.fromhex("c00c1200")),
|
||||
("47745840801f0000000005006e5e0e0000a000000080c071a80e070e00000000", bytes.fromhex("850e070c")),
|
||||
("7aea8140801f000000000000b965140000a000000080c0711810070200000000", bytes.fromhex("b5100700")),
|
||||
("32438340801f000000000000b965140000a000000080c071a810070e00000000", bytes.fromhex("b5100700")),
|
||||
])
|
||||
def test_ioniq_6_regen_control_message_preserves_stock_frame_and_flips_only_ipedal_request_bytes(self, stock_hex, expected_tail):
|
||||
CP = CarParams.new_message()
|
||||
CP.carFingerprint = CAR.HYUNDAI_IONIQ_6
|
||||
CP.flags = int(HyundaiFlags.CANFD | HyundaiFlags.CANFD_LKA_STEERING)
|
||||
|
||||
packer = CANPacker(DBC[CP.carFingerprint][Bus.pt])
|
||||
can_bus = CanBus(CP)
|
||||
parser = CANParser(DBC[CP.carFingerprint][Bus.pt], [("IONIQ_6_REGEN_CONTROL", 0)], can_bus.ECAN)
|
||||
stock_dat = bytes.fromhex(stock_hex)
|
||||
parser.update([(1, [(0x25A, stock_dat, can_bus.ECAN)])])
|
||||
|
||||
msg = hyundaicanfd.create_ioniq_6_regen_control(packer, CP, can_bus, parser.vl["IONIQ_6_REGEN_CONTROL"])
|
||||
assert msg[1][2:24] == stock_dat[2:24]
|
||||
assert msg[1][24:28] == expected_tail
|
||||
assert msg[1][28:] == stock_dat[28:]
|
||||
checksum = hyundaicanfd.hkg_can_fd_checksum(msg[0], None, bytearray(msg[1]))
|
||||
assert msg[1][0] | (msg[1][1] << 8) == checksum
|
||||
|
||||
def test_ioniq_6_always_ipedal_spoofs_left_paddle_in_startup_park_and_drive_until_latched(self):
|
||||
toggles = get_test_toggles()
|
||||
toggles.always_ipedal = True
|
||||
CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, gen_empty_fingerprint(), [], True, False, False, toggles)
|
||||
|
||||
controller = CarController(DBC[CP.carFingerprint], CP)
|
||||
can_bus = CanBus(CP)
|
||||
parser_bus = can_bus.ECAN if CP.flags & HyundaiFlags.CANFD_LKA_STEERING else can_bus.CAM
|
||||
parser = CANParser(DBC[CP.carFingerprint][Bus.pt], [("CRUISE_BUTTONS", 0)], parser_bus)
|
||||
|
||||
cs = SimpleNamespace(
|
||||
out=SimpleNamespace(gearShifter=structs.CarState.GearShifter.park),
|
||||
ipedal_active=False,
|
||||
buttons_counter=5,
|
||||
cruise_buttons_msg={
|
||||
"_CHECKSUM": 0,
|
||||
"COUNTER": 5,
|
||||
"CRUISE_BUTTONS": 0,
|
||||
"ADAPTIVE_CRUISE_MAIN_BTN": 0,
|
||||
"NORMAL_CRUISE_MAIN_BTN": 0,
|
||||
"LDA_BTN": 0,
|
||||
"RIGHT_PADDLE": 0,
|
||||
"LEFT_PADDLE": 0,
|
||||
"SET_ME_1": 1,
|
||||
},
|
||||
ioniq_6_regen_control_msg={},
|
||||
ioniq_6_regen_control_ts=0,
|
||||
)
|
||||
cc = SimpleNamespace(enabled=False)
|
||||
|
||||
sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles)
|
||||
parser.update([(1, sends)])
|
||||
|
||||
assert sends
|
||||
assert len([msg for msg in sends if msg[0] == 0x1CF]) == IONIQ_6_IPEDAL_PADDLE_BURST_COUNT
|
||||
assert sends[0][1].hex() == "4650002800000000"
|
||||
assert parser.vl["CRUISE_BUTTONS"]["LEFT_PADDLE"] == 1
|
||||
assert parser.vl["CRUISE_BUTTONS"]["COUNTER"] == 5
|
||||
assert controller._ioniq_6_always_ipedal_pending
|
||||
assert not controller._ioniq_6_always_ipedal_startup_park_done
|
||||
|
||||
controller.frame = 1
|
||||
sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles)
|
||||
|
||||
assert sends == []
|
||||
|
||||
controller.frame = 2
|
||||
cs.out.gearShifter = structs.CarState.GearShifter.drive
|
||||
cs.buttons_counter = 6
|
||||
sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles)
|
||||
|
||||
assert sends
|
||||
assert len([msg for msg in sends if msg[0] == 0x1CF]) == IONIQ_6_IPEDAL_PADDLE_BURST_COUNT
|
||||
assert sends[0][1].hex() == "9060002800000000"
|
||||
assert controller._ioniq_6_always_ipedal_pending
|
||||
assert controller._ioniq_6_always_ipedal_startup_park_done
|
||||
|
||||
controller.frame = 4
|
||||
cs.ipedal_active = True
|
||||
sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles)
|
||||
|
||||
assert sends == []
|
||||
assert not controller._ioniq_6_always_ipedal_pending
|
||||
assert controller._ioniq_6_always_ipedal_press_remaining == 0
|
||||
|
||||
def test_ioniq_6_always_ipedal_uses_stronger_followup_pull_for_intermediate_latch_state(self):
|
||||
toggles = get_test_toggles()
|
||||
toggles.always_ipedal = True
|
||||
CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, gen_empty_fingerprint(), [], True, False, False, toggles)
|
||||
|
||||
controller = CarController(DBC[CP.carFingerprint], CP)
|
||||
cs = SimpleNamespace(
|
||||
out=SimpleNamespace(gearShifter=structs.CarState.GearShifter.drive),
|
||||
ipedal_active=False,
|
||||
ipedal_regen_state=0x50,
|
||||
ipedal_regen_state_2=0x01,
|
||||
buttons_counter=5,
|
||||
cruise_buttons_msg={
|
||||
"_CHECKSUM": 0,
|
||||
"COUNTER": 5,
|
||||
"CRUISE_BUTTONS": 0,
|
||||
"ADAPTIVE_CRUISE_MAIN_BTN": 0,
|
||||
"NORMAL_CRUISE_MAIN_BTN": 0,
|
||||
"LDA_BTN": 0,
|
||||
"RIGHT_PADDLE": 0,
|
||||
"LEFT_PADDLE": 0,
|
||||
"SET_ME_1": 1,
|
||||
},
|
||||
ioniq_6_regen_control_msg={},
|
||||
ioniq_6_regen_control_ts=0,
|
||||
)
|
||||
cc = SimpleNamespace(enabled=False)
|
||||
|
||||
controller._ioniq_6_last_gear = structs.CarState.GearShifter.reverse
|
||||
sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles)
|
||||
|
||||
assert sends
|
||||
assert [msg[1].hex() for msg in sends if msg[0] == 0x1CF] == ["4650002800000000"]
|
||||
assert controller._ioniq_6_always_ipedal_press_remaining == 5
|
||||
|
||||
def test_ioniq_6_always_ipedal_sends_regen_control_companion_once_max_regen_is_shown(self):
|
||||
toggles = get_test_toggles()
|
||||
toggles.always_ipedal = True
|
||||
CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, gen_empty_fingerprint(), [], True, False, False, toggles)
|
||||
|
||||
controller = CarController(DBC[CP.carFingerprint], CP)
|
||||
cs = SimpleNamespace(
|
||||
out=SimpleNamespace(gearShifter=structs.CarState.GearShifter.drive),
|
||||
ipedal_active=False,
|
||||
ipedal_regen_state=0x3C,
|
||||
ipedal_regen_state_2=0x01,
|
||||
buttons_counter=5,
|
||||
cruise_buttons_msg={
|
||||
"_CHECKSUM": 0,
|
||||
"COUNTER": 5,
|
||||
"CRUISE_BUTTONS": 0,
|
||||
"ADAPTIVE_CRUISE_MAIN_BTN": 0,
|
||||
"NORMAL_CRUISE_MAIN_BTN": 0,
|
||||
"LDA_BTN": 0,
|
||||
"RIGHT_PADDLE": 0,
|
||||
"LEFT_PADDLE": 0,
|
||||
"SET_ME_1": 1,
|
||||
},
|
||||
ioniq_6_regen_control_msg={
|
||||
"COUNTER": 0x14,
|
||||
"BYTE3": 0x40,
|
||||
"BYTE4": 0x80,
|
||||
"BYTE5": 0x1F,
|
||||
"BYTE6": 0x00,
|
||||
"BYTE7": 0x00,
|
||||
"BYTE8": 0x00,
|
||||
"BYTE9": 0x00,
|
||||
"BYTE10": 0x00,
|
||||
"BYTE11": 0x00,
|
||||
"BYTE12": 0xA8,
|
||||
"BYTE13": 0x65,
|
||||
"BYTE14": 0x17,
|
||||
"BYTE15": 0x00,
|
||||
"BYTE16": 0x00,
|
||||
"BYTE17": 0xA0,
|
||||
"BYTE18": 0x00,
|
||||
"BYTE19": 0x00,
|
||||
"BYTE20": 0x00,
|
||||
"BYTE21": 0x80,
|
||||
"BYTE22": 0xC0,
|
||||
"BYTE23": 0x71,
|
||||
"BYTE24": 0xA8,
|
||||
"BYTE25": 0x0C,
|
||||
"BYTE26": 0x12,
|
||||
"BYTE27": 0x0E,
|
||||
"BYTE28": 0x00,
|
||||
"BYTE29": 0x00,
|
||||
"BYTE30": 0x00,
|
||||
"BYTE31": 0x00,
|
||||
},
|
||||
ioniq_6_regen_control_ts=1,
|
||||
)
|
||||
cc = SimpleNamespace(enabled=False)
|
||||
|
||||
controller._ioniq_6_last_gear = structs.CarState.GearShifter.reverse
|
||||
controller._ioniq_6_last_regen_control_counter = 0x13
|
||||
sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles)
|
||||
|
||||
paddle_msgs = [msg for msg in sends if msg[0] == 0x1CF]
|
||||
assert [msg[1].hex() for msg in paddle_msgs] == ["4650002800000000"]
|
||||
regen_cmd = next(msg for msg in sends if msg[0] == 0x25A)
|
||||
assert regen_cmd[1][24:28] == bytes.fromhex("c00c1200")
|
||||
checksum = hyundaicanfd.hkg_can_fd_checksum(regen_cmd[0], None, bytearray(regen_cmd[1]))
|
||||
assert regen_cmd[1][0] | (regen_cmd[1][1] << 8) == checksum
|
||||
assert controller._ioniq_6_always_ipedal_press_remaining == 5
|
||||
|
||||
controller.frame = 1
|
||||
cs.buttons_counter = 6
|
||||
cs.ioniq_6_regen_control_msg = dict(cs.ioniq_6_regen_control_msg, COUNTER=0x15)
|
||||
sends = controller._update_ioniq_6_always_ipedal(cc, cs, toggles)
|
||||
|
||||
paddle_msgs = [msg for msg in sends if msg[0] == 0x1CF]
|
||||
assert [msg[1].hex() for msg in paddle_msgs] == ["9060002800000000"]
|
||||
assert not any(msg[0] == 0x25A for msg in sends)
|
||||
|
||||
def test_ioniq_6_longitudinal_params_match_canfd_tune(self):
|
||||
toggles = get_test_toggles()
|
||||
CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, gen_empty_fingerprint(), [], True, False, False, toggles)
|
||||
|
||||
@@ -125,7 +125,6 @@ class HyundaiSafetyFlags(IntFlag):
|
||||
class HyundaiStarPilotSafetyFlags(IntFlag):
|
||||
HAS_LDA_BUTTON = 1024
|
||||
AOL_LKAS_ON_ENGAGE = 2048
|
||||
ALLOW_IPEDAL_PADDLE = 32768
|
||||
|
||||
|
||||
class HyundaiStarPilotFlags(IntFlag):
|
||||
|
||||
@@ -232,9 +232,6 @@ class CarInterfaceBase(ABC):
|
||||
fp_ret.safetyConfigs[-1].safetyParam |= HyundaiStarPilotSafetyFlags.HAS_LDA_BUTTON.value
|
||||
if starpilot_toggles.always_on_lateral_lkas:
|
||||
fp_ret.safetyConfigs[-1].safetyParam |= HyundaiStarPilotSafetyFlags.AOL_LKAS_ON_ENGAGE.value
|
||||
if candidate == HYUNDAI.HYUNDAI_IONIQ_6 and getattr(starpilot_toggles, "always_ipedal", False):
|
||||
fp_ret.safetyConfigs[-1].safetyParam |= HyundaiStarPilotSafetyFlags.ALLOW_IPEDAL_PADDLE.value
|
||||
|
||||
elif platform in TOYOTA:
|
||||
fp_ret.canUsePedal = not CP.autoResumeSng
|
||||
fp_ret.canUseSDSU = candidate not in UNSUPPORTED_DSU_CAR and candidate not in TSS2_CAR
|
||||
|
||||
@@ -64,7 +64,6 @@ class DummyCarInterface(CarInterfaceBase):
|
||||
|
||||
def get_test_starpilot_toggles() -> SimpleNamespace:
|
||||
return SimpleNamespace(
|
||||
always_ipedal=False,
|
||||
always_on_lateral_lkas=False,
|
||||
car_model="",
|
||||
cluster_offset=1.0,
|
||||
@@ -215,31 +214,6 @@ class TestCarInterfaces:
|
||||
)
|
||||
assert fp_car_params.safetyConfigs[-1].safetyParam & HyundaiStarPilotSafetyFlags.AOL_LKAS_ON_ENGAGE.value
|
||||
|
||||
def test_hyundai_always_ipedal_flag_is_set_for_ioniq_6(self):
|
||||
toggles = get_test_starpilot_toggles()
|
||||
toggles.always_ipedal = True
|
||||
fingerprint = {bus: {} for bus in range(8)}
|
||||
fingerprint[2][0x50] = 16
|
||||
|
||||
car_params = HyundaiCarInterface.get_params(
|
||||
HYUNDAI_CAR.HYUNDAI_IONIQ_6,
|
||||
fingerprint,
|
||||
[],
|
||||
alpha_long=False,
|
||||
is_release=False,
|
||||
docs=False,
|
||||
starpilot_toggles=toggles,
|
||||
)
|
||||
|
||||
fp_car_params = HyundaiCarInterface.get_starpilot_params(
|
||||
HYUNDAI_CAR.HYUNDAI_IONIQ_6,
|
||||
fingerprint,
|
||||
[],
|
||||
car_params,
|
||||
toggles,
|
||||
)
|
||||
assert fp_car_params.safetyConfigs[-1].safetyParam & HyundaiStarPilotSafetyFlags.ALLOW_IPEDAL_PADDLE.value
|
||||
|
||||
def test_toyota_disable_openpilot_long_sets_stock_long_safety_flag(self):
|
||||
CarInterface = interfaces[TOYOTA_CAR.TOYOTA_PRIUS_TSS2]
|
||||
fingerprint = {bus: {} for bus in range(8)}
|
||||
|
||||
@@ -537,39 +537,6 @@ BO_ 593 RADAR_0x251: 16 FRONT_RADAR
|
||||
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
|
||||
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
|
||||
|
||||
BO_ 602 IONIQ_6_REGEN_CONTROL: 32 XXX
|
||||
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
|
||||
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE3 : 24|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE4 : 32|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE5 : 40|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE6 : 48|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE7 : 56|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE8 : 64|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE9 : 72|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE10 : 80|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE11 : 88|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE12 : 96|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE13 : 104|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE14 : 112|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE15 : 120|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE16 : 128|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE17 : 136|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE18 : 144|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE19 : 152|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE20 : 160|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE21 : 168|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE22 : 176|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE23 : 184|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE24 : 192|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE25 : 200|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE26 : 208|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE27 : 216|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE28 : 224|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE29 : 232|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE30 : 240|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE31 : 248|8@1+ (1,0) [0|255] "" XXX
|
||||
|
||||
BO_ 687 HOD_FD_01_100ms: 8 XXX
|
||||
SG_ HOD_Dir_Status : 18|3@0+ (1,0) [0|7] "" XXX
|
||||
SG_ NEW_SIGNAL_2 : 32|8@1+ (1,0) [0|255] "" XXX
|
||||
@@ -620,8 +587,6 @@ BO_ 736 MANUAL_SPEED_LIMIT_ASSIST: 32 XXX
|
||||
SG_ MSLA_ENABLED : 38|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ MAX_SPEED : 55|8@0+ (1,0) [0|255] "" XXX
|
||||
SG_ MAX_SPEED_COPY : 144|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ EV_REGEN_STATE : 104|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ EV_REGEN_STATE_2 : 184|8@1+ (1,0) [0|255] "" XXX
|
||||
|
||||
BO_ 837 ADRV_0x345: 8 ADRV
|
||||
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
|
||||
|
||||
@@ -774,39 +774,6 @@ BO_ 593 RADAR_0x251: 16 FRONT_RADAR
|
||||
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
|
||||
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
|
||||
|
||||
BO_ 602 IONIQ_6_REGEN_CONTROL: 32 XXX
|
||||
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
|
||||
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE3 : 24|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE4 : 32|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE5 : 40|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE6 : 48|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE7 : 56|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE8 : 64|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE9 : 72|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE10 : 80|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE11 : 88|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE12 : 96|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE13 : 104|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE14 : 112|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE15 : 120|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE16 : 128|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE17 : 136|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE18 : 144|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE19 : 152|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE20 : 160|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE21 : 168|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE22 : 176|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE23 : 184|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE24 : 192|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE25 : 200|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE26 : 208|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE27 : 216|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE28 : 224|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE29 : 232|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE30 : 240|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ BYTE31 : 248|8@1+ (1,0) [0|255] "" XXX
|
||||
|
||||
BO_ 687 HOD_FD_01_100ms: 8 XXX
|
||||
SG_ HOD_Dir_Status : 18|3@0+ (1,0) [0|7] "" XXX
|
||||
SG_ NEW_SIGNAL_2 : 32|8@1+ (1,0) [0|255] "" XXX
|
||||
@@ -857,8 +824,6 @@ BO_ 736 MANUAL_SPEED_LIMIT_ASSIST: 32 XXX
|
||||
SG_ MSLA_ENABLED : 38|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ MAX_SPEED : 55|8@0+ (1,0) [0|255] "" XXX
|
||||
SG_ MAX_SPEED_COPY : 144|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ EV_REGEN_STATE : 104|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ EV_REGEN_STATE_2 : 184|8@1+ (1,0) [0|255] "" XXX
|
||||
|
||||
BO_ 837 ADRV_0x345: 8 ADRV
|
||||
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
#define HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(bus) \
|
||||
{0x1CF, bus, 8, .check_relay = false}, /* CRUISE_BUTTON */ \
|
||||
|
||||
#define HYUNDAI_CANFD_IPEDAL_REGEN_TX_MSGS(bus) \
|
||||
{0x25A, bus, 32, .check_relay = false}, /* IONIQ_6_REGEN_CONTROL */ \
|
||||
|
||||
#define HYUNDAI_CANFD_LKA_STEERING_COMMON_TX_MSGS(a_can, e_can) \
|
||||
HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(e_can) \
|
||||
{0x50, a_can, 16, .check_relay = (a_can) == 0}, /* LKAS */ \
|
||||
@@ -59,9 +56,6 @@
|
||||
static bool hyundai_canfd_alt_buttons = false;
|
||||
static bool hyundai_canfd_lka_steering_alt = false;
|
||||
static bool hyundai_canfd_angle_steering = false;
|
||||
static bool hyundai_canfd_allow_ipedal_paddle = false;
|
||||
static bool hyundai_canfd_last_regen_control_seen = false;
|
||||
static uint8_t hyundai_canfd_last_regen_control[32] = {0U};
|
||||
|
||||
static unsigned int hyundai_canfd_get_lka_addr(void) {
|
||||
return hyundai_canfd_lka_steering_alt ? 0x110U : 0x50U;
|
||||
@@ -82,44 +76,8 @@ static uint32_t hyundai_canfd_get_checksum(const CANPacket_t *msg) {
|
||||
return chksum;
|
||||
}
|
||||
|
||||
static bool hyundai_canfd_ioniq_6_regen_tail_allowed(const CANPacket_t *msg) {
|
||||
const uint8_t stock24 = hyundai_canfd_last_regen_control[24];
|
||||
const uint8_t stock25 = hyundai_canfd_last_regen_control[25];
|
||||
const uint8_t stock26 = hyundai_canfd_last_regen_control[26];
|
||||
const uint8_t stock27 = hyundai_canfd_last_regen_control[27];
|
||||
|
||||
if ((stock24 == 0xA8U) && (stock25 == 0x0CU) && (stock26 == 0x12U) && (stock27 == 0x0EU)) {
|
||||
return (msg->data[24] == 0xC0U) && (msg->data[25] == 0x0CU) &&
|
||||
(msg->data[26] == 0x12U) && (msg->data[27] == 0x00U);
|
||||
}
|
||||
|
||||
if ((stock24 == 0xA8U) && (stock25 == 0x0EU) && (stock26 == 0x07U) && (stock27 == 0x0EU)) {
|
||||
return (msg->data[24] == 0x85U) && (msg->data[25] == 0x0EU) &&
|
||||
(msg->data[26] == 0x07U) && (msg->data[27] == 0x0CU);
|
||||
}
|
||||
|
||||
if ((stock24 == 0x18U) && (stock25 == 0x10U) && (stock26 == 0x07U) && (stock27 == 0x02U)) {
|
||||
return (msg->data[24] == 0xB5U) && (msg->data[25] == 0x10U) &&
|
||||
(msg->data[26] == 0x07U) && (msg->data[27] == 0x00U);
|
||||
}
|
||||
|
||||
if ((stock24 == 0xA8U) && (stock25 == 0x10U) && (stock26 == 0x07U) && (stock27 == 0x0EU)) {
|
||||
return (msg->data[24] == 0xB5U) && (msg->data[25] == 0x10U) &&
|
||||
(msg->data[26] == 0x07U) && (msg->data[27] == 0x00U);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void hyundai_canfd_rx_all_hook(const CANPacket_t *msg) {
|
||||
const unsigned pt_bus = hyundai_canfd_lka_steering ? 1U : 0U;
|
||||
|
||||
if (hyundai_canfd_allow_ipedal_paddle && (msg->bus == pt_bus) && (msg->addr == 0x25AU) && (GET_LEN(msg) == 32U)) {
|
||||
for (int i = 0; i < 32; i++) {
|
||||
hyundai_canfd_last_regen_control[i] = msg->data[i];
|
||||
}
|
||||
hyundai_canfd_last_regen_control_seen = true;
|
||||
}
|
||||
UNUSED(msg);
|
||||
}
|
||||
|
||||
static void hyundai_canfd_rx_hook(const CANPacket_t *msg) {
|
||||
@@ -274,47 +232,10 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *msg) {
|
||||
// cruise buttons check
|
||||
if (msg->addr == 0x1cfU) {
|
||||
int button = msg->data[2] & 0x7U;
|
||||
bool main_button = GET_BIT(msg, 19U) || GET_BIT(msg, 21U);
|
||||
bool lkas_button = GET_BIT(msg, 23U);
|
||||
bool right_paddle = GET_BIT(msg, 25U);
|
||||
bool left_paddle = GET_BIT(msg, 27U);
|
||||
bool is_cancel = (button == HYUNDAI_BTN_CANCEL);
|
||||
bool is_resume = (button == HYUNDAI_BTN_RESUME);
|
||||
bool is_left_paddle_only = hyundai_canfd_allow_ipedal_paddle &&
|
||||
!controls_allowed &&
|
||||
(button == HYUNDAI_BTN_NONE) &&
|
||||
!main_button &&
|
||||
!lkas_button &&
|
||||
!right_paddle &&
|
||||
left_paddle;
|
||||
|
||||
bool allowed = (is_cancel && cruise_engaged_prev) || (is_resume && controls_allowed) || is_left_paddle_only;
|
||||
if (!allowed) {
|
||||
tx = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (msg->addr == 0x25AU) {
|
||||
const unsigned pt_bus = hyundai_canfd_lka_steering ? 1U : 0U;
|
||||
bool allowed = hyundai_canfd_allow_ipedal_paddle &&
|
||||
!controls_allowed &&
|
||||
(msg->bus == pt_bus) &&
|
||||
(GET_LEN(msg) == 32U) &&
|
||||
hyundai_canfd_last_regen_control_seen &&
|
||||
(hyundai_canfd_get_checksum(msg) == hyundai_common_canfd_compute_checksum(msg)) &&
|
||||
hyundai_canfd_ioniq_6_regen_tail_allowed(msg);
|
||||
|
||||
if (allowed) {
|
||||
for (int i = 2; i < 32; i++) {
|
||||
if ((i < 24) || (i > 27)) {
|
||||
if (msg->data[i] != hyundai_canfd_last_regen_control[i]) {
|
||||
allowed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool allowed = (is_cancel && cruise_engaged_prev) || (is_resume && controls_allowed);
|
||||
if (!allowed) {
|
||||
tx = false;
|
||||
}
|
||||
@@ -361,26 +282,15 @@ static safety_config hyundai_canfd_init(uint16_t param) {
|
||||
const uint16_t HYUNDAI_PARAM_CANFD_LKA_STEERING_ALT = 128;
|
||||
const uint16_t HYUNDAI_PARAM_CANFD_ALT_BUTTONS = 32;
|
||||
const uint16_t HYUNDAI_PARAM_CANFD_ANGLE_STEERING = 1024;
|
||||
const uint16_t HYUNDAI_PARAM_ALLOW_IPEDAL_PADDLE = 32768;
|
||||
|
||||
static const CanMsg HYUNDAI_CANFD_LKA_STEERING_TX_MSGS[] = {
|
||||
HYUNDAI_CANFD_LKA_STEERING_COMMON_TX_MSGS(0, 1)
|
||||
};
|
||||
|
||||
static const CanMsg HYUNDAI_CANFD_LKA_STEERING_IPEDAL_TX_MSGS[] = {
|
||||
HYUNDAI_CANFD_LKA_STEERING_COMMON_TX_MSGS(0, 1)
|
||||
HYUNDAI_CANFD_IPEDAL_REGEN_TX_MSGS(1)
|
||||
};
|
||||
|
||||
static const CanMsg HYUNDAI_CANFD_LKA_STEERING_ALT_TX_MSGS[] = {
|
||||
HYUNDAI_CANFD_LKA_STEERING_ALT_COMMON_TX_MSGS(0, 1)
|
||||
};
|
||||
|
||||
static const CanMsg HYUNDAI_CANFD_LKA_STEERING_ALT_IPEDAL_TX_MSGS[] = {
|
||||
HYUNDAI_CANFD_LKA_STEERING_ALT_COMMON_TX_MSGS(0, 1)
|
||||
HYUNDAI_CANFD_IPEDAL_REGEN_TX_MSGS(1)
|
||||
};
|
||||
|
||||
static const CanMsg HYUNDAI_CANFD_LKA_STEERING_LONG_TX_MSGS[] = {
|
||||
HYUNDAI_CANFD_LKA_STEERING_COMMON_TX_MSGS(0, 1)
|
||||
HYUNDAI_CANFD_LFA_STEERING_COMMON_TX_MSGS(1)
|
||||
@@ -395,21 +305,6 @@ static safety_config hyundai_canfd_init(uint16_t param) {
|
||||
{0x1DA, 1, 32, .check_relay = false}, // ADRV_0x1da
|
||||
};
|
||||
|
||||
static const CanMsg HYUNDAI_CANFD_LKA_STEERING_LONG_IPEDAL_TX_MSGS[] = {
|
||||
HYUNDAI_CANFD_LKA_STEERING_COMMON_TX_MSGS(0, 1)
|
||||
HYUNDAI_CANFD_LFA_STEERING_COMMON_TX_MSGS(1)
|
||||
HYUNDAI_CANFD_SCC_CONTROL_COMMON_TX_MSGS(1, true)
|
||||
HYUNDAI_CANFD_BLINDSPOT_DASH_TX_MSGS(1)
|
||||
HYUNDAI_CANFD_IPEDAL_REGEN_TX_MSGS(1)
|
||||
{0x51, 0, 32, .check_relay = false}, // ADRV_0x51
|
||||
{0x730, 1, 8, .check_relay = false}, // tester present for ADAS ECU disable
|
||||
{0x160, 1, 16, .check_relay = false}, // ADRV_0x160
|
||||
{0x1EA, 1, 32, .check_relay = false}, // ADRV_0x1ea
|
||||
{0x200, 1, 8, .check_relay = false}, // ADRV_0x200
|
||||
{0x345, 1, 8, .check_relay = false}, // ADRV_0x345
|
||||
{0x1DA, 1, 32, .check_relay = false}, // ADRV_0x1da
|
||||
};
|
||||
|
||||
static const CanMsg HYUNDAI_CANFD_LFA_STEERING_TX_MSGS[] = {
|
||||
HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(2)
|
||||
HYUNDAI_CANFD_LFA_STEERING_COMMON_TX_MSGS(0)
|
||||
@@ -439,8 +334,6 @@ static safety_config hyundai_canfd_init(uint16_t param) {
|
||||
hyundai_canfd_alt_buttons = GET_FLAG(param, HYUNDAI_PARAM_CANFD_ALT_BUTTONS);
|
||||
hyundai_canfd_lka_steering_alt = GET_FLAG(param, HYUNDAI_PARAM_CANFD_LKA_STEERING_ALT);
|
||||
hyundai_canfd_angle_steering = GET_FLAG(param, HYUNDAI_PARAM_CANFD_ANGLE_STEERING);
|
||||
hyundai_canfd_allow_ipedal_paddle = GET_FLAG(param, HYUNDAI_PARAM_ALLOW_IPEDAL_PADDLE);
|
||||
hyundai_canfd_last_regen_control_seen = false;
|
||||
|
||||
safety_config ret;
|
||||
if (hyundai_longitudinal) {
|
||||
@@ -450,11 +343,7 @@ static safety_config hyundai_canfd_init(uint16_t param) {
|
||||
};
|
||||
|
||||
SET_RX_CHECKS(hyundai_canfd_lka_steering_long_rx_checks, ret);
|
||||
if (hyundai_canfd_allow_ipedal_paddle) {
|
||||
SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_LONG_IPEDAL_TX_MSGS, ret);
|
||||
} else {
|
||||
SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_LONG_TX_MSGS, ret);
|
||||
}
|
||||
SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_LONG_TX_MSGS, ret);
|
||||
|
||||
} else {
|
||||
// Longitudinal checks for LFA steering
|
||||
@@ -496,17 +385,9 @@ static safety_config hyundai_canfd_init(uint16_t param) {
|
||||
|
||||
SET_RX_CHECKS(hyundai_canfd_lka_steering_rx_checks, ret);
|
||||
if (hyundai_canfd_lka_steering_alt) {
|
||||
if (hyundai_canfd_allow_ipedal_paddle) {
|
||||
SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_ALT_IPEDAL_TX_MSGS, ret);
|
||||
} else {
|
||||
SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_ALT_TX_MSGS, ret);
|
||||
}
|
||||
SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_ALT_TX_MSGS, ret);
|
||||
} else {
|
||||
if (hyundai_canfd_allow_ipedal_paddle) {
|
||||
SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_IPEDAL_TX_MSGS, ret);
|
||||
} else {
|
||||
SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_TX_MSGS, ret);
|
||||
}
|
||||
SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_TX_MSGS, ret);
|
||||
}
|
||||
|
||||
} else if (!hyundai_camera_scc) {
|
||||
|
||||
@@ -440,112 +440,12 @@ class TestHyundaiCanfdLKASteeringEV(TestHyundaiCanfdBase):
|
||||
}
|
||||
return self.packer.make_can_msg_safety("CRUISE_BUTTONS", bus, values)
|
||||
|
||||
def _regen_control_msg(self, byte24=0xA8, byte25=0x0C, byte26=0x12, byte27=0x0E, counter=0x14, bus=None):
|
||||
if bus is None:
|
||||
bus = self.PT_BUS
|
||||
values = {
|
||||
"COUNTER": counter,
|
||||
"BYTE3": 0x40,
|
||||
"BYTE4": 0x80,
|
||||
"BYTE5": 0x1F,
|
||||
"BYTE6": 0x00,
|
||||
"BYTE7": 0x00,
|
||||
"BYTE8": 0x00,
|
||||
"BYTE9": 0x00,
|
||||
"BYTE10": 0x00,
|
||||
"BYTE11": 0x00,
|
||||
"BYTE12": 0xA8,
|
||||
"BYTE13": 0x65,
|
||||
"BYTE14": 0x17,
|
||||
"BYTE15": 0x00,
|
||||
"BYTE16": 0x00,
|
||||
"BYTE17": 0xA0,
|
||||
"BYTE18": 0x00,
|
||||
"BYTE19": 0x00,
|
||||
"BYTE20": 0x00,
|
||||
"BYTE21": 0x80,
|
||||
"BYTE22": 0xC0,
|
||||
"BYTE23": 0x71,
|
||||
"BYTE24": byte24,
|
||||
"BYTE25": byte25,
|
||||
"BYTE26": byte26,
|
||||
"BYTE27": byte27,
|
||||
"BYTE28": 0x00,
|
||||
"BYTE29": 0x00,
|
||||
"BYTE30": 0x00,
|
||||
"BYTE31": 0x00,
|
||||
}
|
||||
|
||||
def fix_checksum(msg):
|
||||
addr, dat, msg_bus = msg
|
||||
dat = bytearray(dat)
|
||||
checksum = hyundaicanfd.hkg_can_fd_checksum(addr, None, dat)
|
||||
dat[0] = checksum & 0xFF
|
||||
dat[1] = (checksum >> 8) & 0xFF
|
||||
return addr, bytes(dat), msg_bus
|
||||
|
||||
return self.packer.make_can_msg_safety("IONIQ_6_REGEN_CONTROL", bus, values, fix_checksum=fix_checksum)
|
||||
|
||||
def test_left_paddle_send(self):
|
||||
for controls_allowed in (True, False):
|
||||
self.safety.set_controls_allowed(controls_allowed)
|
||||
self.assertFalse(self._tx(self._paddle_msg(left_paddle=1)))
|
||||
|
||||
|
||||
class TestHyundaiCanfdLKASteeringEVAlwaysIPedal(TestHyundaiCanfdLKASteeringEV):
|
||||
|
||||
TX_MSGS = TestHyundaiCanfdLKASteeringEV.TX_MSGS + [[0x25A, 1]]
|
||||
|
||||
def setUp(self):
|
||||
self.packer = CANPackerSafety("hyundai_canfd_generated")
|
||||
self.safety = libsafety_py.libsafety
|
||||
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd,
|
||||
HyundaiSafetyFlags.CANFD_LKA_STEERING |
|
||||
HyundaiSafetyFlags.EV_GAS |
|
||||
HyundaiStarPilotSafetyFlags.ALLOW_IPEDAL_PADDLE)
|
||||
self.safety.init_tests()
|
||||
|
||||
def test_left_paddle_send(self):
|
||||
self.safety.set_controls_allowed(False)
|
||||
self.assertTrue(self._tx(self._paddle_msg(left_paddle=1)))
|
||||
self.assertFalse(self._tx(self._paddle_msg(right_paddle=1)))
|
||||
self.assertFalse(self._tx(self._paddle_msg(left_paddle=1, buttons=1)))
|
||||
self.assertFalse(self._tx(self._paddle_msg(left_paddle=1, main_button=1)))
|
||||
self.assertFalse(self._tx(self._paddle_msg(left_paddle=1, lka_button=1)))
|
||||
|
||||
self.safety.set_controls_allowed(True)
|
||||
self.assertFalse(self._tx(self._paddle_msg(left_paddle=1)))
|
||||
|
||||
def test_regen_control_send(self):
|
||||
stock_msg = self._regen_control_msg(byte24=0xA8, byte27=0x0E, counter=0x14)
|
||||
self._rx(stock_msg)
|
||||
|
||||
self.safety.set_controls_allowed(False)
|
||||
self.assertTrue(self._tx(self._regen_control_msg(byte24=0xC0, byte27=0x00, counter=0x14)))
|
||||
self.assertFalse(self._tx(self._regen_control_msg(byte24=0x85, byte25=0x0E, byte26=0x07, byte27=0x0C, counter=0x14)))
|
||||
self.assertFalse(self._tx(self._regen_control_msg(byte24=0xA8, byte27=0x00, counter=0x14)))
|
||||
self.assertFalse(self._tx(self._regen_control_msg(byte24=0xC0, byte27=0x0E, counter=0x14)))
|
||||
self.assertFalse(self._tx(self._regen_control_msg(byte24=0xC0, byte27=0x00, counter=0x15)))
|
||||
|
||||
stock_msg = self._regen_control_msg(byte24=0xA8, byte25=0x0E, byte26=0x07, byte27=0x0E, counter=0x58)
|
||||
self._rx(stock_msg)
|
||||
self.assertTrue(self._tx(self._regen_control_msg(byte24=0x85, byte25=0x0E, byte26=0x07, byte27=0x0C, counter=0x58)))
|
||||
self.assertFalse(self._tx(self._regen_control_msg(byte24=0xC0, byte25=0x0E, byte26=0x07, byte27=0x00, counter=0x58)))
|
||||
|
||||
stock_msg = self._regen_control_msg(byte24=0x18, byte25=0x10, byte26=0x07, byte27=0x02, counter=0x81)
|
||||
self._rx(stock_msg)
|
||||
self.assertTrue(self._tx(self._regen_control_msg(byte24=0xB5, byte25=0x10, byte26=0x07, byte27=0x00, counter=0x81)))
|
||||
self.assertFalse(self._tx(self._regen_control_msg(byte24=0xA8, byte25=0x10, byte26=0x07, byte27=0x00, counter=0x81)))
|
||||
|
||||
stock_msg = self._regen_control_msg(byte24=0xA8, byte25=0x10, byte26=0x07, byte27=0x0E, counter=0x82)
|
||||
self._rx(stock_msg)
|
||||
self.assertTrue(self._tx(self._regen_control_msg(byte24=0xB5, byte25=0x10, byte26=0x07, byte27=0x00, counter=0x82)))
|
||||
self.assertFalse(self._tx(self._regen_control_msg(byte24=0xA8, byte25=0x02, byte26=0x07, byte27=0x0E, counter=0x82)))
|
||||
|
||||
self.safety.set_controls_allowed(True)
|
||||
self.assertFalse(self._tx(self._regen_control_msg(byte24=0xC0, byte27=0x00, counter=0x14)))
|
||||
|
||||
|
||||
# TODO: Handle ICE and HEV configurations once we see cars that use the new messages
|
||||
class TestHyundaiCanfdLKASteeringAltEV(TestHyundaiCanfdBase):
|
||||
|
||||
@@ -596,26 +496,6 @@ class TestHyundaiCanfdLKASteeringLongEV(HyundaiLongitudinalBase, TestHyundaiCanf
|
||||
return self.packer.make_can_msg_safety("SCC_CONTROL", 1, values)
|
||||
|
||||
|
||||
class TestHyundaiCanfdLKASteeringLongEVAlwaysIPedal(TestHyundaiCanfdLKASteeringLongEV):
|
||||
|
||||
TX_MSGS = TestHyundaiCanfdLKASteeringLongEV.TX_MSGS + [[0x25A, 1]]
|
||||
|
||||
def setUp(self):
|
||||
self.packer = CANPackerSafety("hyundai_canfd_generated")
|
||||
self.safety = libsafety_py.libsafety
|
||||
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, HyundaiSafetyFlags.CANFD_LKA_STEERING |
|
||||
HyundaiSafetyFlags.LONG | HyundaiSafetyFlags.EV_GAS |
|
||||
HyundaiStarPilotSafetyFlags.ALLOW_IPEDAL_PADDLE)
|
||||
self.safety.init_tests()
|
||||
|
||||
def test_regen_control_send(self):
|
||||
stock_msg = self._regen_control_msg(byte24=0xA8, byte27=0x0E, counter=0x14)
|
||||
self._rx(stock_msg)
|
||||
|
||||
self.safety.set_controls_allowed(False)
|
||||
self.assertTrue(self._tx(self._regen_control_msg(byte24=0xC0, byte27=0x00, counter=0x14)))
|
||||
|
||||
|
||||
# Tests longitudinal for ICE, hybrid, EV cars with LFA steering
|
||||
class TestHyundaiCanfdLFASteeringLongBase(HyundaiLongitudinalBase, TestHyundaiCanfdLFASteeringBase):
|
||||
|
||||
|
||||
@@ -471,11 +471,6 @@ class VehicleSettingsManagerView(Widget):
|
||||
rows.append({"target_id": "toggle:RemapCancelToDistance", "type": "toggle",
|
||||
"title": tr("Remap Cancel Button"), "subtitle": tr("Treat the Cancel button as an extra mappable steering-wheel button."),
|
||||
"get_state": lambda: self._controller._params.get_bool("RemapCancelToDistance")})
|
||||
if cs.isHKGCanFd:
|
||||
rows.append({"target_id": "toggle:AlwaysIPedal", "type": "toggle",
|
||||
"title": tr("Always I-Pedal"),
|
||||
"subtitle": tr("Spoof the left paddle after shifting into Drive until i-Pedal latches."),
|
||||
"get_state": lambda: self._controller._params.get_bool("AlwaysIPedal")})
|
||||
if cs.isHKGCanFd and cs.hasOpenpilotLongitudinal:
|
||||
rows.append({"target_id": "toggle:NostalgiaMode", "type": "toggle",
|
||||
"title": tr("Nostalgia Mode"),
|
||||
|
||||
@@ -800,7 +800,6 @@ class StarPilotVariables:
|
||||
toggle.no_uploads = self.get_value("NoUploads", condition=device_management and not self.vetting_branch)
|
||||
toggle.no_onroad_uploads = self.get_value("DisableOnroadUploads", condition=toggle.no_uploads)
|
||||
|
||||
toggle.always_ipedal = self.get_value("AlwaysIPedal", condition=toggle.car_model == HYUNDAI_CAR.HYUNDAI_IONIQ_6)
|
||||
toggle.nostalgia_mode = self.get_value("NostalgiaMode", condition=toggle.openpilot_longitudinal and toggle.car_model == HYUNDAI_CAR.HYUNDAI_IONIQ_6)
|
||||
toggle.remap_cancel_to_distance = self.get_value(
|
||||
"RemapCancelToDistance",
|
||||
|
||||
@@ -2323,13 +2323,6 @@
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle"
|
||||
},
|
||||
{
|
||||
"key": "AlwaysIPedal",
|
||||
"label": "Always I-Pedal",
|
||||
"description": "Automatically spoof the left paddle when shifting into Drive until i-Pedal latches on supported Hyundai CAN-FD cars.",
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle"
|
||||
},
|
||||
{
|
||||
"key": "NostalgiaMode",
|
||||
"label": "Nostalgia Mode",
|
||||
|
||||
@@ -55,21 +55,6 @@ StarPilotWheelPanel::StarPilotWheelPanel(StarPilotSettingsWindow *parent, bool f
|
||||
update();
|
||||
});
|
||||
|
||||
ParamControl *alwaysIPedalToggle = new ParamControl(
|
||||
"AlwaysIPedal",
|
||||
tr("Always I-Pedal"),
|
||||
tr("<b>Automatically spoof the left paddle when shifting into Drive</b> until i-Pedal latches on supported Hyundai CAN-FD cars."),
|
||||
"../../starpilot/assets/toggle_icons/icon_mute.png"
|
||||
);
|
||||
toggles["AlwaysIPedal"] = alwaysIPedalToggle;
|
||||
addItem(alwaysIPedalToggle);
|
||||
QObject::connect(alwaysIPedalToggle, &AbstractControl::hideDescriptionEvent, [this]() {
|
||||
update();
|
||||
});
|
||||
QObject::connect(alwaysIPedalToggle, &AbstractControl::showDescriptionEvent, [this]() {
|
||||
update();
|
||||
});
|
||||
|
||||
const std::vector<std::tuple<QString, QString, QString, QString>> wheelToggles {
|
||||
{"CancelButtonControl", tr("Cancel Button"), tr("<b>Action performed when the remapped \"Cancel\" button is pressed.</b>"), "../../starpilot/assets/toggle_icons/icon_mute.png"},
|
||||
{"DistanceButtonControl", tr("Distance Button"), tr("<b>Action performed when the \"Distance\" button is pressed.</b>"), "../../starpilot/assets/toggle_icons/icon_mute.png"},
|
||||
@@ -150,10 +135,6 @@ void StarPilotWheelPanel::updateToggles() {
|
||||
setVisible &= parent->hasOpenpilotLongitudinal;
|
||||
}
|
||||
|
||||
if (!showAllToggles && key == "AlwaysIPedal") {
|
||||
setVisible &= parent->isHKGCanFd;
|
||||
}
|
||||
|
||||
if (!showAllToggles && (
|
||||
key == "ModeButtonControl" ||
|
||||
key == "LongModeButtonControl" ||
|
||||
|
||||
Reference in New Issue
Block a user