Restore Ioniq 6 Alpha Long compatibility across camera and external Panda layouts

This commit is contained in:
firestar5683
2026-11-09 23:59:52 -06:00
parent f43de18e00
commit 4e0942a553
11 changed files with 225 additions and 24 deletions
@@ -52,7 +52,6 @@ def _base_word(cp, *, experiences=(0,)):
return None
if (
cp.brand != 'hyundai'
or factory == CAR.HYUNDAI_IONIQ_6
or not factory.config.flags & HyundaiFlags.CANFD
or factory.config.flags & (HyundaiFlags.CANFD_ANGLE_STEERING | HyundaiFlags.NON_SCC)
or cp.passive
@@ -85,6 +84,8 @@ def _base_word(cp, *, experiences=(0,)):
word |= 0x0400
if factory in CARNIVAL_CARS and alt_buttons:
word |= 0x2000
if factory == CAR.HYUNDAI_IONIQ_6 and word != 0x09:
return None
return word if word | STOCK_AOL_MARKER in STOCK_AOL_WORDS else None
@@ -100,7 +101,7 @@ CARNIVAL_LONG_AOL_WORD = 0x28B4
LONG_AOL_WORDS = frozenset((CARNIVAL_LONG_AOL_WORD, 0x080D, 0x0815, 0x0895, 0x2815, 0x2895)) | SPORTAGE_LONG_AOL_WORDS
LONG_EV_CARS = frozenset((CAR.HYUNDAI_IONIQ_5, CAR.HYUNDAI_KONA_EV_2ND_GEN))
INDEPENDENT_LONG_BUTTON_CARS = LONG_EV_CARS | {
CAR.GENESIS_GV70_ELECTRIFIED_1ST_GEN, CAR.GENESIS_GV60_EV_1ST_GEN, CAR.KIA_SPORTAGE_5TH_GEN, CAR.KIA_CARNIVAL_2025,
CAR.HYUNDAI_IONIQ_6, CAR.GENESIS_GV70_ELECTRIFIED_1ST_GEN, CAR.GENESIS_GV60_EV_1ST_GEN, CAR.KIA_SPORTAGE_5TH_GEN, CAR.KIA_CARNIVAL_2025,
}
@@ -115,7 +116,7 @@ def qualified_long(cp, *, marked_only=False):
if not eligible(cp):
return False
word = _base_word(cp, experiences=(0, 32))
if cp.carFingerprint == CAR.GENESIS_GV60_EV_1ST_GEN:
if cp.carFingerprint in (CAR.GENESIS_GV60_EV_1ST_GEN, CAR.HYUNDAI_IONIQ_6):
if word != 0x09:
return False
elif cp.carFingerprint == CAR.KIA_SPORTAGE_5TH_GEN:
@@ -138,7 +138,8 @@ class CarController(CarControllerBase):
self.last_ccnc_now_ns = 0
self.ccnc_baselined = False
self.ioniq6_longitudinal = (Ioniq6LongitudinalPolicy()
if CP.carFingerprint == CAR.HYUNDAI_IONIQ_6 and CP.openpilotLongitudinalControl else None)
if CP.carFingerprint == CAR.HYUNDAI_IONIQ_6 and CP.openpilotLongitudinalControl and
int(CP.safetyConfigs[-1].safetyParam) in (0x8015, 0x8095, 0x8815, 0x8895) else None)
self.pe_longitudinal = PELongitudinalPolicy() if pe_long_qualified(CP) else None
self.pe_startup = None
self.ev9_longitudinal = EV9LongitudinalPolicy() if ev9_long_qualified(CP) else None
+6 -4
View File
@@ -685,17 +685,19 @@ class CarState(CarStateBase):
if CP.flags & HyundaiFlags.CANFD_LKA_STEER_MSG:
cam_msgs.append(("CAM_0x362" if CP.flags & HyundaiFlags.CANFD_LKA_STEER_MSG_ALT else "CAM_0x2a4", 20))
elif CP.carFingerprint == CAR.HYUNDAI_IONIQ_6 and CP.openpilotLongitudinalControl:
# The acknowledged ADAS takeover removes stock SCC from E-CAN. Require
# every independent native input and the matching camera source instead.
# Both topologies require genuine chassis inputs; only HDA-II uses
# the camera template after acknowledged ADAS takeover.
msgs.extend((("ACCELERATOR", 100), ("TCS", 50), ("WHEEL_SPEEDS", 100), ("MDPS", 100)))
msgs.extend((("CRUISE_BUTTONS_ALT", math.nan), ("DOORS_SEATBELTS", math.nan),
("STEERING_SENSORS", math.nan), ("BLINKERS", math.nan)))
cam_msgs.append(("CAM_0x362" if CP.flags & HyundaiFlags.CANFD_LKA_STEER_MSG_ALT else "CAM_0x2a4", 20))
if CP.flags & HyundaiFlags.CANFD_LKA_STEER_MSG:
cam_msgs.append(("CAM_0x362" if CP.flags & HyundaiFlags.CANFD_LKA_STEER_MSG_ALT else "CAM_0x2a4", 20))
elif CP.carFingerprint == CAR.HYUNDAI_IONIQ_6 and not CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS:
# Stock standard-button Ioniq 6 reads alternate DISTANCE_UNIT too, but
# that frame may be absent. Subscribe before the lazy lookup makes it
# required; existing native and CarState safety inputs remain required.
msgs.append(("CRUISE_BUTTONS_ALT", math.nan))
if not any(name == "CRUISE_BUTTONS_ALT" for name, _ in msgs):
msgs.append(("CRUISE_BUTTONS_ALT", math.nan))
from opendbc.car.hyundai.ev6_startup import eligible as ev6_eligible
from opendbc.car.hyundai.gv70_startup import eligible as gv70_eligible
if ev6_eligible(CP) or gv70_eligible(CP):
@@ -142,6 +142,9 @@ class CarInterface(CarInterfaceBase):
CAN = CanBus(None, fingerprint, lka_steering)
ret.alphaLongitudinalAvailable = not (ret.flags & HyundaiFlags.CANFD_NO_RADAR_DISABLE)
if (candidate == CAR.HYUNDAI_IONIQ_6 and not lka_steering and
fingerprint[CAN.CAM].get(0x1A0) == 32 and fingerprint[CAN.ECAN].get(0x1CF) == 8):
ret.alphaLongitudinalAvailable = True
if ret.flags & HyundaiFlags.CANFD_ANGLE_STEERING:
# These manual angle profiles retain stock SCC in both builds.
ret.alphaLongitudinalAvailable = False
@@ -0,0 +1,187 @@
from tempfile import TemporaryDirectory
from types import SimpleNamespace
from unittest.mock import Mock, patch
import pytest
from opendbc.car import Bus, gen_empty_fingerprint, structs
from opendbc.car.hyundai.interface import CarInterface
from opendbc.car.hyundai.carcontroller import CarController
from opendbc.car.hyundai.canfd_stock_aol import qualified, qualified_long
from opendbc.car.hyundai.hyundaicanfd import CanBus
from opendbc.car.hyundai.tests.test_ioniq6_handoff import ioniq6_profiles
from opendbc.car.hyundai.values import CAR, DBC
from opendbc.can import CANPacker
from opendbc.safety.tests.libsafety import libsafety_py
from opendbc.safety.tests import test_hyundai_gv60_hda1_long_aol as native_fixture
from openpilot.common.params import Params
from openpilot.starpilot.car.hyundai.aol import policy_for, native_accepts_cp
from openpilot.selfdrive.ui.layouts.settings import toggles
def camera_params(offset=0, alpha=False):
fp = gen_empty_fingerprint()
fp[offset].update({0x1CF: 8, 0x35: 32, 0x175: 24, 0xA0: 24, 0xEA: 24, 0x1BA: 24, 0x1E5: 16})
fp[offset + 2].update({0x12A: 16, 0x1A0: 32})
fp[offset + 1].update({0x110: 32, 0x100: 24})
return CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, fp, [], alpha, False, False)
@pytest.mark.parametrize('offset', (0, 4))
def test_camera_scc_factory_offers_long_without_hda2_takeover(offset):
stock = camera_params(offset)
cp = camera_params(offset, True)
assert stock.alphaLongitudinalAvailable, 'HDA1_ALPHA_CAPABILITY_MISSING'
assert not stock.openpilotLongitudinalControl and stock.pcmCruise
assert cp.alphaLongitudinalAvailable and cp.openpilotLongitudinalControl and not cp.pcmCruise
assert cp.steerControlType == structs.CarParams.SteerControlType.torque
assert cp.safetyConfigs[-1].safetyParam == 0x0D
assert CanBus(cp).ECAN == offset
assert CarController(DBC[cp.carFingerprint], cp).ioniq6_longitudinal is None
with patch('opendbc.car.hyundai.interface.disable_ecu') as disable:
CarInterface.init(cp, Mock(), Mock())
disable.assert_not_called()
for value in (stock, cp):
policy = policy_for(value)
assert policy.runtime_supported and policy.explicit_latch
value.safetyConfigs[-1].safetyParam |= policy.safety_param_addition
value.alternativeExperience |= policy.alternative_experience_addition
word = 0x80D if value.openpilotLongitudinalControl else 0x809
assert value.safetyConfigs[-1].safetyParam == word
assert native_accepts_cp(value, int(structs.CarParams.SafetyModel.hyundaiCanfd), word)
assert not native_accepts_cp(value, int(structs.CarParams.SafetyModel.hyundai), word)
assert not native_accepts_cp(value, int(structs.CarParams.SafetyModel.hyundaiCanfd), word ^ 16)
@pytest.mark.parametrize('offset', (0, 4))
def test_external_hda2_settings_explain_opt_in_without_claiming_stock_acc_authority(offset):
_, stock, _ = ioniq6_profiles(bus_offset=offset, alternate=True)
with TemporaryDirectory() as root:
params = Params(root)
params.put_bool('ExperimentalMode', True, block=True)
class Toggle:
def __init__(self):
self.action_item = self
self.description = ''
def set_enabled(self, enabled):
self.enabled = enabled
def set_description(self, description):
self.description = description
def set_state(self, state):
self.state = state
panel = toggles.TogglesLayout.__new__(toggles.TogglesLayout)
panel._params = params
panel._is_release = False
panel._initial_cruise_speed = Mock()
panel._long_personality_setting = SimpleNamespace(action_item=Toggle())
panel._toggles = {'ExperimentalMode': Toggle(), 'IsRhdDetected': Toggle()}
panel._toggle_defs = {}
panel._locked_toggles = set()
panel._update_experimental_mode_icon = Mock()
panel._slc_offsets = SimpleNamespace(_raw=lambda key: None)
panel._localization = SimpleNamespace(snapshot=lambda: SimpleNamespace(rows=(None, SimpleNamespace(source=None, available=True))))
ui = SimpleNamespace(CP=stock, has_longitudinal_control=False, update_params=lambda: None)
with patch.object(toggles, 'ui_state', ui):
panel._update_toggles()
assert 'Enable the openpilot longitudinal control (alpha)' in panel._toggles['ExperimentalMode'].description
assert not panel._toggles['ExperimentalMode'].enabled
assert params.get_bool('ExperimentalMode')
@pytest.mark.parametrize('offset', (0, 4))
def test_camera_long_actual_controller_packets_use_existing_native_contract(offset):
cp = camera_params(offset, True)
assert cp.openpilotLongitudinalControl
cp.safetyConfigs[-1].safetyParam |= 0x800
cp.alternativeExperience = 32
ci = CarInterface(cp)
packer = CANPacker(DBC[cp.carFingerprint][Bus.pt])
bus = CanBus(cp)
frames = [packer.make_can_msg(name, bus.ECAN, values) for name, values in (
('ACCELERATOR', {'GEAR': 5}), ('TCS', {'ACCEnable': 0}), ('WHEEL_SPEEDS', {}), ('MDPS', {}),
('CRUISE_BUTTONS', {'COUNTER': 1}), ('DOORS_SEATBELTS', {'DRIVER_SEATBELT': 1}), ('STEERING_SENSORS', {}))]
ci.update([(1_000_000_000, frames)])
case = native_fixture.TestGv60Hda1LongAol(methodName='runTest')
case.setUp()
try:
case.mode(0x80D)
if case.release:
assert not case.safety.safety_config_valid()
return
case.healthy(0x80D, omit='CRUISE_BUTTONS')
case.safety.set_aol_test_heartbeat(True)
case.safety.aol_set_host_request(3)
for tick, counter, button in ((0, 13, 0), (1, 14, 2), (2, 0, 0)):
case.safety.set_timer(1_000_000 + tick * 20_000)
assert case.safety.safety_rx_hook(case.packet(packer.make_can_msg('CRUISE_BUTTONS', 0, {'COUNTER': counter, 'CRUISE_BUTTONS': button})))
case.safety.aol_set_host_request(3)
assert case.safety.aol_get_permission_mask() == 3
cc = structs.CarControl(enabled=True, latActive=True, longActive=True)
cc.actuators.torque = .01
cc.actuators.accel = .1
cc.actuators.longControlState = structs.CarControl.Actuators.LongControlState.pid
controller = CarController(DBC[cp.carFingerprint], cp)
assert controller.ioniq6_longitudinal is None
_, sent = controller.update(cc.as_reader(), ci.CS, 1_000_000_000)
assert any(frame[0] == 0x1A0 for frame in sent)
assert not any(frame[0] == 0x730 for frame in sent)
for frame in sent:
assert frame[2] in (offset, offset + 1, offset + 2)
packet = libsafety_py.make_CANPacket(frame[0], frame[2] - offset, frame[1])
assert case.safety.safety_tx_hook(packet), (hex(frame[0]), frame[2])
finally:
case.tearDown()
@pytest.mark.parametrize('mutation', ('aux_word', 'wrong_model', 'angle', 'lka', 'passive'))
def test_camera_admission_never_borrows_other_topologies(mutation):
cp = camera_params(4, True)
cp.safetyConfigs[-1].safetyParam |= 0x800
cp.alternativeExperience = 32
if mutation == 'aux_word':
cp.safetyConfigs[0].safetyParam = 1
elif mutation == 'wrong_model':
cp.safetyConfigs[-1].safetyModel = structs.CarParams.SafetyModel.hyundai
elif mutation == 'angle':
cp.steerControlType = structs.CarParams.SteerControlType.angle
elif mutation == 'lka':
cp.flags |= 1
else:
cp.passive = True
assert not qualified(cp) and not qualified_long(cp)
assert not policy_for(cp).runtime_supported
@pytest.mark.parametrize('offset', (0, 4))
def test_galaxy_exposes_external_stock_alpha_request_and_preserves_choice(offset):
from openpilot.starpilot.ui.feature_settings_owner import FeatureSettingsOwner
_, stock, _ = ioniq6_profiles(bus_offset=offset, alternate=True)
with TemporaryDirectory() as root:
params = Params(root)
params.put_bool('IsReleaseBranch', False, block=True)
params.put_bool('AlphaLongitudinalEnabled', True, block=True)
stock.radarUnavailable = True
owner = FeatureSettingsOwner(params, lambda scope: True,
vehicle_params=lambda: stock, vehicle_fingerprint=lambda: str(stock.carFingerprint), galaxy=lambda: True)
assert owner._alpha_long_capability() is not None
rows = owner._alpha_long_rows(True)
assert len(rows) == 1 and rows[0].key == 'AlphaLongitudinalEnabled'
assert params.get_bool('AlphaLongitudinalEnabled')
stock.passive = True
assert owner._alpha_long_capability() is None
assert params.get_bool('AlphaLongitudinalEnabled')
@pytest.mark.parametrize('offset', (0, 4))
def test_cached_radar_discovery_can_save_request_but_cannot_grant_long_or_aol(offset):
from opendbc.car.hyundai.ioniq6_handoff import build_ioniq6_hda2_long_candidate
from openpilot.starpilot.car.hyundai.aol import ioniq6_alpha_long_available, ioniq6_settings_capable
fingerprint, stock, _ = ioniq6_profiles(bus_offset=offset, alternate=True)
stock.radarUnavailable = True
assert ioniq6_alpha_long_available(stock), 'CACHED_EXTERNAL_RADAR_BLOCKS_ALPHA_REQUEST'
assert not ioniq6_settings_capable(stock)
assert not policy_for(stock).runtime_supported
assert build_ioniq6_hda2_long_candidate(stock, fingerprint) is None
assert not stock.openpilotLongitudinalControl and stock.pcmCruise
stock.safetyConfigs[-1].safetyParam ^= 16
assert not ioniq6_alpha_long_available(stock)
@@ -1,7 +1,7 @@
from collections.abc import Callable
from openpilot.common.params import Params
from openpilot.starpilot.car.hyundai.aol import ioniq6_settings_capable
from openpilot.starpilot.car.hyundai.aol import ioniq6_alpha_long_available
from openpilot.starpilot.car.ford.longitudinal_preferences import release_long_available as ford_release_long_available
from opendbc.car.volkswagen.meb_modes import MEB_CARS, settings_capable as meb_settings_capable
from openpilot.starpilot.car.volkswagen.preferences import stock_long_requested
@@ -144,7 +144,7 @@ class DeveloperLayout(Widget):
# CP gating
if ui_state.CP is not None:
alpha_avail = (meb_settings_capable(ui_state.CP) if ui_state.CP.brand == 'volkswagen' and ui_state.CP.carFingerprint in MEB_CARS
else ui_state.CP.alphaLongitudinalAvailable or ioniq6_settings_capable(ui_state.CP))
else ui_state.CP.alphaLongitudinalAvailable or ioniq6_alpha_long_available(ui_state.CP))
if not alpha_avail or (self._is_release and not (meb_settings_capable(ui_state.CP) or ford_release_long_available(ui_state.CP))):
self._alpha_long_toggle.set_visible(False)
else:
@@ -216,7 +216,7 @@ class DeveloperLayout(Widget):
if result == DialogResult.CONFIRM:
if (not ui_state.is_offroad() or ui_state.CP is None or
not (meb_settings_capable(ui_state.CP) if ui_state.CP.brand == 'volkswagen' and ui_state.CP.carFingerprint in MEB_CARS
else ui_state.CP.alphaLongitudinalAvailable or ioniq6_settings_capable(ui_state.CP)) or
else ui_state.CP.alphaLongitudinalAvailable or ioniq6_alpha_long_available(ui_state.CP)) or
self._is_release and not (meb_settings_capable(ui_state.CP) or ford_release_long_available(ui_state.CP))):
self._alpha_long_toggle.action_item.set_state(False)
return
@@ -1,3 +1,4 @@
from openpilot.starpilot.car.hyundai.aol import ioniq6_alpha_long_available
from openpilot.starpilot.car.ford.longitudinal_preferences import release_long_available as ford_release_long_available
from openpilot.cereal import log
from openpilot.common.params import Params, UnknownKeyName
@@ -196,7 +197,7 @@ class TogglesLayout(Widget):
unavailable = tr("Experimental mode is currently unavailable on this car since the car's stock ACC is used for longitudinal control.")
long_desc = unavailable + " " + tr("openpilot longitudinal control may come in a future update.")
if ui_state.CP.alphaLongitudinalAvailable:
if ui_state.CP.alphaLongitudinalAvailable or ioniq6_alpha_long_available(ui_state.CP):
if self._is_release and not ford_release_long_available(ui_state.CP):
long_desc = unavailable + " " + tr("An alpha version of openpilot longitudinal control can be tested, along with " +
"Experimental mode, on non-release branches.")
@@ -7,7 +7,7 @@ from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog, BigInputDialog
from openpilot.system.ui.lib.application import gui_app
from openpilot.selfdrive.ui.layouts.settings.common import restart_needed_callback
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.starpilot.car.hyundai.aol import ioniq6_settings_capable
from openpilot.starpilot.car.hyundai.aol import ioniq6_alpha_long_available
from openpilot.starpilot.car.ford.longitudinal_preferences import release_long_available as ford_release_long_available
from opendbc.car.volkswagen.meb_modes import MEB_CARS, settings_capable as meb_settings_capable
from openpilot.starpilot.car.volkswagen.preferences import stock_long_requested
@@ -177,7 +177,7 @@ class DeveloperLayoutMici(NavScroller):
# CP gating
if ui_state.CP is not None:
alpha_avail = (meb_settings_capable(ui_state.CP) if ui_state.CP.brand == 'volkswagen' and ui_state.CP.carFingerprint in MEB_CARS
else ui_state.CP.alphaLongitudinalAvailable or ioniq6_settings_capable(ui_state.CP))
else ui_state.CP.alphaLongitudinalAvailable or ioniq6_alpha_long_available(ui_state.CP))
if not alpha_avail or (ui_state.is_release and not (meb_settings_capable(ui_state.CP) or ford_release_long_available(ui_state.CP))):
self._alpha_long_toggle.set_visible(False)
else:
@@ -201,7 +201,7 @@ class DeveloperLayoutMici(NavScroller):
def do_toggle(_state: bool):
if (not ui_state.is_offroad() or (_state and (ui_state.CP is None or
not (meb_settings_capable(ui_state.CP) if ui_state.CP.brand == 'volkswagen' and ui_state.CP.carFingerprint in MEB_CARS
else ui_state.CP.alphaLongitudinalAvailable or ioniq6_settings_capable(ui_state.CP)) or
else ui_state.CP.alphaLongitudinalAvailable or ioniq6_alpha_long_available(ui_state.CP)) or
ui_state.is_release and not (meb_settings_capable(ui_state.CP) or ford_release_long_available(ui_state.CP))))):
self._update_toggles()
return
+12 -6
View File
@@ -45,11 +45,11 @@ _REQUIRED_FLAGS = int(HyundaiFlags.CANFD | HyundaiFlags.EV | HyundaiFlags.CANFD_
_FORBIDDEN_FLAGS = int(HyundaiFlags.CANFD_ALT_BUTTONS | HyundaiFlags.CANFD_ANGLE_STEERING | HyundaiFlags.CANFD_CAMERA_SCC)
def _ioniq6_hda2_base(CP) -> bool:
def _ioniq6_hda2_base(CP, *, require_radar=True) -> bool:
if (
str(CP.carFingerprint) != str(HyundaiCAR.HYUNDAI_IONIQ_6)
or CP.brand != 'hyundai'
or CP.radarUnavailable
or (require_radar and CP.radarUnavailable)
or CP.notCar
or CP.passive
or CP.dashcamOnly
@@ -61,8 +61,8 @@ def _ioniq6_hda2_base(CP) -> bool:
return flags & _REQUIRED_FLAGS == _REQUIRED_FLAGS and not flags & _FORBIDDEN_FLAGS
def _stock_ioniq6(CP, *, marked_only=False) -> bool:
if not _ioniq6_hda2_base(CP) or CP.openpilotLongitudinalControl or not CP.pcmCruise:
def _stock_ioniq6(CP, *, marked_only=False, require_radar=True) -> bool:
if not _ioniq6_hda2_base(CP, require_radar=require_radar) or CP.openpilotLongitudinalControl or not CP.pcmCruise:
return False
stock = 0x91 if int(CP.flags) & int(HyundaiFlags.CANFD_LKA_STEER_MSG_ALT) else 0x11
raw = int(CP.safetyConfigs[config_index(CP)].safetyParam)
@@ -98,6 +98,12 @@ def ioniq6_settings_capable(CP) -> bool:
return _stock_ioniq6(CP) or (IONIQ6_LONG_PREARM_ENABLED and ioniq6_long_eligible(CP))
def ioniq6_alpha_long_available(CP) -> bool:
# Cached radar discovery may predate the external-bus repair. This saves only
# an opt-in; the takeover still requires fresh physical radar and ECU evidence.
return _stock_ioniq6(CP, require_radar=False) or (IONIQ6_LONG_PREARM_ENABLED and ioniq6_long_eligible(CP))
def qualified_ccnc_long_aol(CP, *, marked_only=False):
return qualified_ev9_long_aol(CP, marked_only=marked_only) or qualified_pe_long_aol(CP, marked_only=marked_only)
@@ -232,9 +238,9 @@ def native_profile_supported(model: int, param: int) -> bool:
def native_accepts_cp(CP, model: int, param: int) -> bool:
# Ioniq 6 has its own exact contract; no generic Hyundai owner accepts it.
# HDA-II retains its dedicated namespace; camera SCC uses the shared exact word.
# Revalidate the complete contract on every call, without caching live authority.
if CP.carFingerprint == HyundaiCAR.HYUNDAI_IONIQ_6:
if CP.carFingerprint == HyundaiCAR.HYUNDAI_IONIQ_6 and not CP.flags & HyundaiFlags.CANFD_CAMERA_SCC:
return qualified_ioniq6(CP)
if qualified_ccnc_long_aol(CP, marked_only=True):
return model == int(car.CarParams.SafetyModel.hyundaiCanfd) and param == CP.safetyConfigs[0].safetyParam
@@ -205,12 +205,12 @@ class FeatureSettingsOwner:
release, readable = read_saved(self.params, 'IsReleaseBranch', 8)
try:
from opendbc.car.values import PLATFORMS
from openpilot.starpilot.car.hyundai.aol import ioniq6_settings_capable
from openpilot.starpilot.car.hyundai.aol import ioniq6_alpha_long_available
from openpilot.starpilot.car.ford.longitudinal_preferences import release_long_available as ford_release_long_available
platform = PLATFORMS.get(str(cp.carFingerprint))
if (not self._galaxy() or platform is None or platform.__class__.__module__.split('.')[-2] != str(cp.brand) or
not readable or release not in (None, b'0', b'1') or cp.notCar or cp.passive or cp.dashcamOnly or
not (cp.alphaLongitudinalAvailable or ioniq6_settings_capable(cp)) or
not (cp.alphaLongitudinalAvailable or ioniq6_alpha_long_available(cp)) or
(release == b'1' and not ford_release_long_available(cp))):
return None
return (str(cp.carFingerprint), str(cp.brand), int(cp.flags), int(cp.alternativeExperience),
+1 -1
View File
@@ -1 +1 @@
{"protected_inventory_sha256": "634cdb0998641b505e1f24b4fb715965c778b355de58ecfb7cf292b5616941e2", "schema_version": 1}
{"protected_inventory_sha256": "b93d12cdd85e78c16f978b68bd56777fab78fa2a3a94beb99a7ed0a2a635466f", "schema_version": 1}