ioniq tune | blindspot | paddle

This commit is contained in:
firestar5683
2026-04-25 20:05:10 -05:00
parent ed695fab1b
commit 330a811114
9 changed files with 62 additions and 12 deletions
@@ -238,7 +238,9 @@ class CarController(CarControllerBase):
if CS.blindspots_rear_corners_ts > 0 and CS.blindspots_front_corner_1_ts > 0 and rear_stale and front_stale:
can_sends.extend(hyundaicanfd.create_blindspot_status_messages(self.packer, self.CAN,
CS.blindspots_rear_corners,
CS.blindspots_front_corner_1))
CS.blindspots_front_corner_1,
CS.left_blindspot_from_radar,
CS.right_blindspot_from_radar))
if self.frame % 2 == 0:
can_sends.append(hyundaicanfd.create_acc_control(self.packer, self.CAN, CC.enabled, self.accel_last, accel, stopping, CC.cruiseControl.override,
set_speed_in_units, hud_control))
+17 -2
View File
@@ -21,6 +21,9 @@ ENABLE_BUTTONS = (Buttons.RES_ACCEL, Buttons.SET_DECEL, Buttons.CANCEL)
BUTTONS_DICT = {Buttons.RES_ACCEL: ButtonType.accelCruise, Buttons.SET_DECEL: ButtonType.decelCruise,
Buttons.GAP_DIST: ButtonType.gapAdjustCruise, Buttons.CANCEL: ButtonType.cancel}
IONIQ_6_BLINDSPOT_RIGHT_MASK = 0x08
IONIQ_6_BLINDSPOT_LEFT_MASK = 0x10
def calculate_canfd_speed_limit(CP, FPCP, cp, cp_cam, speed_factor):
if not (FPCP.flags & HyundaiStarPilotFlags.SPEED_LIMIT_AVAILABLE):
@@ -34,6 +37,11 @@ def calculate_canfd_speed_limit(CP, FPCP, cp, cp_cam, speed_factor):
return 0.0
def decode_ioniq_6_blindspot_radar_state(state: int) -> tuple[bool, bool]:
state_int = int(state)
return bool(state_int & IONIQ_6_BLINDSPOT_LEFT_MASK), bool(state_int & IONIQ_6_BLINDSPOT_RIGHT_MASK)
class CarState(CarStateBase):
@staticmethod
def get_canfd_blinker_sig_names(car_fingerprint, use_alt_lamp: bool) -> tuple[str, str]:
@@ -82,6 +90,8 @@ class CarState(CarStateBase):
self.blindspots_front_corner_1 = {}
self.blindspots_rear_corners_ts = 0
self.blindspots_front_corner_1_ts = 0
self.left_blindspot_from_radar = False
self.right_blindspot_from_radar = False
# On some cars, CLU15->CF_Clu_VehicleSpeed can oscillate faster than the dash updates. Sample at 5 Hz
self.cluster_speed = 0
@@ -290,10 +300,15 @@ class CarState(CarStateBase):
cp.vl["BLINKERS"]["USE_ALT_LAMP"] == 1)
ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["BLINKERS"][left_blinker_sig],
cp.vl["BLINKERS"][right_blinker_sig])
self.left_blindspot_from_radar = False
self.right_blindspot_from_radar = False
if self.CP.carFingerprint == CAR.HYUNDAI_IONIQ_6:
self.left_blindspot_from_radar, self.right_blindspot_from_radar = decode_ioniq_6_blindspot_radar_state(
cp.vl["BLINDSPOTS_FRONT_CORNER_2"]["SIDE_DETECT_STATE"])
if self.CP.enableBsm:
if self.CP.carFingerprint == CAR.HYUNDAI_IONIQ_6:
ret.leftBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["LEFT_MB"] != 0
ret.rightBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["MORE_LEFT_PROB"] != 0
ret.leftBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["LEFT_MB"] != 0 or self.left_blindspot_from_radar
ret.rightBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["MORE_LEFT_PROB"] != 0 or self.right_blindspot_from_radar
else:
ret.leftBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["FL_INDICATOR"] != 0
ret.rightBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["FR_INDICATOR"] != 0
@@ -196,10 +196,12 @@ def create_lfahda_cluster(packer, CAN, enabled):
return packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values)
def create_blindspot_status_messages(packer, CAN, rear_values, front_corner_values):
def create_blindspot_status_messages(packer, CAN, rear_values, front_corner_values, left_blindspot=False, right_blindspot=False):
# Reuse the last known-good payload but regenerate the rolling counter/checksum.
rear = {k: v for k, v in rear_values.items() if k not in ("CHECKSUM", "COUNTER")}
front = {k: v for k, v in front_corner_values.items() if k not in ("CHECKSUM", "COUNTER")}
rear["LEFT_MB"] = int(left_blindspot)
rear["MORE_LEFT_PROB"] = int(right_blindspot)
if "NEW_SIGNAL_3" not in front:
front["NEW_SIGNAL_3"] = 1
@@ -7,7 +7,7 @@ from opendbc.can import CANPacker, CANParser
from opendbc.car import Bus, ButtonType, gen_empty_fingerprint
from opendbc.car.structs import CarParams
from opendbc.car.fw_versions import build_fw_dict, match_fw_to_car
from opendbc.car.hyundai.carstate import CarState
from opendbc.car.hyundai.carstate import CarState, decode_ioniq_6_blindspot_radar_state
from opendbc.car.hyundai.interface import CarInterface
from opendbc.car.hyundai import hyundaicanfd
from opendbc.car.hyundai.hyundaicanfd import CanBus
@@ -269,15 +269,23 @@ class TestHyundaiFingerprint:
"NEW_SIGNAL_1": 0,
}
msgs = hyundaicanfd.create_blindspot_status_messages(packer, can_bus, rear, front)
msgs = hyundaicanfd.create_blindspot_status_messages(packer, can_bus, rear, front, left_blindspot=True, right_blindspot=False)
parser.update([(1, msgs)])
assert parser.can_valid
assert parser.vl["BLINDSPOTS_REAR_CORNERS"]["COUNTER"] == 0
assert parser.vl["BLINDSPOTS_FRONT_CORNER_1"]["COUNTER"] == 0
assert parser.vl["BLINDSPOTS_REAR_CORNERS"]["LEFT_BLOCKED"] == 0
assert parser.vl["BLINDSPOTS_REAR_CORNERS"]["LEFT_MB"] == 1
assert parser.vl["BLINDSPOTS_REAR_CORNERS"]["MORE_LEFT_PROB"] == 0
assert parser.vl["BLINDSPOTS_FRONT_CORNER_1"]["NEW_SIGNAL_3"] == 1
def test_ioniq_6_blindspot_radar_state_decode(self):
assert decode_ioniq_6_blindspot_radar_state(0x02) == (False, False)
assert decode_ioniq_6_blindspot_radar_state(0x0A) == (False, True)
assert decode_ioniq_6_blindspot_radar_state(0x12) == (True, False)
assert decode_ioniq_6_blindspot_radar_state(0x1A) == (True, True)
assert decode_ioniq_6_blindspot_radar_state(10.0) == (False, True)
def test_sportage_angle_jerk_override_is_scoped(self):
sportage = CarParams.new_message()
sportage.carFingerprint = CAR.KIA_SPORTAGE_HEV_2026
@@ -622,6 +622,7 @@ BO_ 866 CAM_0x362: 32 CAMERA
BO_ 874 BLINDSPOTS_FRONT_CORNER_2: 16 XXX
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ SIDE_DETECT_STATE : 24|8@1+ (1,0) [0|255] "" XXX
BO_ 896 ADAS_0x380: 24 XXX
SG_ STOP_SIGN : 83|1@1+ (1,0) [0|1] "" XXX
@@ -859,6 +859,7 @@ BO_ 866 CAM_0x362: 32 CAMERA
BO_ 874 BLINDSPOTS_FRONT_CORNER_2: 16 XXX
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ SIDE_DETECT_STATE : 24|8@1+ (1,0) [0|255] "" XXX
BO_ 896 ADAS_0x380: 24 XXX
SG_ STOP_SIGN : 83|1@1+ (1,0) [0|1] "" XXX
+4 -4
View File
@@ -212,20 +212,20 @@ IONIQ_6_FF_CUTOFF_WIDTH = 0.12
IONIQ_6_TRANSITION_SPEED = 10.0
IONIQ_6_PHASE_SCALE = 0.10
IONIQ_6_TURN_IN_BOOST_LEFT = 0.52
IONIQ_6_TURN_IN_BOOST_RIGHT = 0.50
IONIQ_6_TURN_IN_BOOST_RIGHT = 0.44
IONIQ_6_UNWIND_TAPER_LEFT = 0.60
IONIQ_6_UNWIND_TAPER_RIGHT = 1.08
IONIQ_6_UNWIND_TAPER_RIGHT = 1.12
IONIQ_6_FRICTION_MULT = 0.995
IONIQ_6_FRICTION_LAT_RISE = 0.20
IONIQ_6_FRICTION_JERK_RISE = 0.24
IONIQ_6_TURN_IN_THRESHOLD_REDUCTION_LEFT = 0.12
IONIQ_6_TURN_IN_THRESHOLD_REDUCTION_RIGHT = 0.10
IONIQ_6_UNWIND_THRESHOLD_INCREASE_LEFT = 0.42
IONIQ_6_UNWIND_THRESHOLD_INCREASE_RIGHT = 0.92
IONIQ_6_UNWIND_THRESHOLD_INCREASE_RIGHT = 0.96
IONIQ_6_TURN_IN_FRICTION_BOOST_LEFT = 0.05
IONIQ_6_TURN_IN_FRICTION_BOOST_RIGHT = 0.04
IONIQ_6_UNWIND_FRICTION_REDUCTION_LEFT = 0.36
IONIQ_6_UNWIND_FRICTION_REDUCTION_RIGHT = 0.72
IONIQ_6_UNWIND_FRICTION_REDUCTION_RIGHT = 0.76
IONIQ_6_CENTER_TAPER_MAX = 0.015
IONIQ_6_CENTER_TAPER_LAT = 0.06
IONIQ_6_CENTER_TAPER_LAT_WIDTH = 0.02
+21
View File
@@ -3,6 +3,27 @@ from openpilot.common.constants import CV
HIGHWAY_LEAD_BEHAVIOR_MIN_SPEED = 45. * CV.MPH_TO_MS
VISION_LEAD_TRACK_MIN_DISTANCE = 25.0
VISION_LEAD_TRACK_BASE_TIME_GAP = 1.75
VISION_LEAD_TRACK_CLOSING_GAIN = 0.20
VISION_LEAD_TRACK_CLOSING_CAP = 2.50
def should_track_lead(lead_status: bool, lead_distance: float, model_length: float, stop_distance: float,
v_ego: float, *, v_lead: float | None = None, radar: bool = False) -> bool:
if not lead_status:
return False
tracking_buffer = max(float(stop_distance), 4.0)
model_limit = float(model_length) + tracking_buffer
if radar:
return float(lead_distance) < model_limit
closing_speed = max(0.0, float(v_ego) - float(v_lead if v_lead is not None else v_ego))
vision_time_gap = VISION_LEAD_TRACK_BASE_TIME_GAP + min(closing_speed * VISION_LEAD_TRACK_CLOSING_GAIN,
VISION_LEAD_TRACK_CLOSING_CAP)
vision_limit = max(VISION_LEAD_TRACK_MIN_DISTANCE, float(v_ego) * vision_time_gap + tracking_buffer)
return float(lead_distance) < min(model_limit, vision_limit)
def get_tracked_lead_catchup_bias(v_ego: float, lead_distance: float, desired_gap: float, closing_speed: float,
+1 -1
View File
@@ -242,7 +242,7 @@ class SelfdriveD:
if (getattr(self.starpilot_toggles, "nostalgia_mode", False) and
self.CP.openpilotLongitudinalControl and
self.sm['carControl'].longActive and
self.enabled and
any(be.type == ButtonType.altButton2 for be in CS.buttonEvents)):
self.events.add(EventName.buttonCancel)