Arm Outback lateral on physical cruise MAIN

This commit is contained in:
firestar5683
2026-10-30 13:07:30 -05:00
parent f7b85976a5
commit 0fcf127704
7 changed files with 37 additions and 14 deletions
+1 -1
View File
@@ -403,7 +403,7 @@ static safety_config subaru_init(uint16_t raw_param) {
subaru_aol_enabled = ((unsigned int)alternative_experience == 32U) &&
((param == 209U) || (param == 465U) || (param == 16U) || (param == 0U) || (param == 1U) || (param == 17U) || (param == 145U) ||
avh || (param == 177U) || (param == 401U) || (param == 8U) || (param == 520U) || (param == 512U) || (param == 2225U));
subaru_aol_main_arm = subaru_aol_enabled && ((param == 17U) || impreza_main);
subaru_aol_main_arm = subaru_aol_enabled && ((param == 17U) || impreza_main || subaru_d_platform);
if (subaru_aol_enabled) {
static const AolSafetyPolicy policy = {
.reset = subaru_aol_reset,
@@ -5,7 +5,7 @@ from opendbc.safety.tests.libsafety import libsafety_py
from opendbc.safety.tests import test_subaru_stock_aol as stock_module
@pytest.fixture(params=(17, 4096, 4104, 4608, 4616))
@pytest.fixture(params=(17, 209, 465, 4096, 4104, 4608, 4616))
def owner(request):
item = stock_module.TestSubaruStockAol(methodName='runTest')
item.setUp()
@@ -71,7 +71,7 @@ def test_new_physical_acc_source_is_required_before_main_edge(owner):
def test_acc_wire_checksum_and_counter_cannot_be_faked_by_host(owner):
neutral(owner)
assert owner.feed() == 1
bus = 1 if owner.param == 17 else 2
bus = 1 if owner.param in (17, 209, 465) else 2
bad = owner.frame('ES_Distance', {}, bus)
raw = bytearray(bytes(bad.data))
raw[0] ^= 1
@@ -97,9 +97,9 @@ def test_acc_fault_cannot_be_bypassed_by_stock_enable_packets(owner):
assert owner.feed() == 1
assert owner.feed(acc_fault=True) == 0
for enabled in (0, 1):
name = 'ES_Status' if owner.param == 17 else 'CruiseControl'
name = 'ES_Status' if owner.param in (17, 209, 465) else 'CruiseControl'
values = {'Cruise_Activated': enabled, 'Cruise_On': 1} if name == 'CruiseControl' else {'Cruise_Activated': enabled}
assert owner.safety.safety_rx_hook(owner.frame(name, values, 1 if owner.param == 17 else 0))
assert owner.safety.safety_rx_hook(owner.frame(name, values, 1 if owner.param in (17, 209, 465) else 0))
owner.safety.aol_set_host_request(1)
assert owner.safety.aol_get_permission_mask() == 0
@@ -47,8 +47,8 @@ class TestSubaruStockAol(unittest.TestCase):
('ES_Status', {'Cruise_Activated': int(cruise)}, 2 if self.param == 16 else 1),
('ES_DashStatus', {'Cruise_On': int(main)}, 2),
]
if not omit_distance and self.param in (17, 4096, 4104, 4608, 4616):
frames.append(('ES_Distance', {'Cruise_Fault': int(acc_fault)}, 1 if self.param == 17 else 2))
if not omit_distance and self.param in (17, 209, 465, 4096, 4104, 4608, 4616):
frames.append(('ES_Distance', {'Cruise_Fault': int(acc_fault)}, 1 if self.param in (17, 209, 465) else 2))
if not omit_gear:
frames.append(('Transmission', {'Gear': gear}, gear_bus))
for name, fields, bus in frames:
@@ -79,7 +79,7 @@ class TestSubaruStockAol(unittest.TestCase):
self.assertEqual(self.feed(temporary=True), 0)
self.assertEqual(self.feed(), 1)
self.assertEqual(self.feed(main=False), 0)
self.assertEqual(self.feed(main=True), int(param in (17, 4096, 4104, 4608, 4616)))
self.assertEqual(self.feed(main=True), int(param in (17, 209, 465, 4096, 4104, 4608, 4616)))
self.assertEqual(self.feed(cruise=True), 1)
def test_permanent_fault_and_rx_fault_require_fresh_ordinary_engagement(self):
+1 -1
View File
@@ -89,7 +89,7 @@ def ordinary_axis_request_allowed(cp, state):
def create_intent(cp, settings):
main_arm = (cp.carFingerprint == CAR.SUBARU_CROSSTREK_2025 or
(cp.carFingerprint == CAR.SUBARU_IMPREZA_2020 and qualified(cp)))
(cp.carFingerprint in (CAR.SUBARU_IMPREZA_2020, CAR.SUBARU_OUTBACK_2023) and qualified(cp)))
return SubaruStockCardIntent(settings, main_arm=main_arm)
@@ -97,3 +97,26 @@ def test_impreza_main_setting_is_exact_and_preserves_stock_assist_selection():
cp.alternativeExperience = 32
cp.safetyConfigs[0].safetyParam |= IMPREZA_MAIN_AOL
assert not qualified(cp) and not sng.eligible(cp)
def test_outback_main_intent_uses_only_existing_exact_native_profiles():
from opendbc.car.subaru.interface import CarInterface
from opendbc.car.subaru.values import CAR, SubaruFlags
from opendbc.car.subaru.stock_aol import qualified
from openpilot.starpilot.car.subaru.aol import create_intent
for stopped_start in (False, True):
cp = CarInterface.get_non_essential_params(CAR.SUBARU_OUTBACK_2023)
if stopped_start:
cp.flags = int(cp.flags) | int(SubaruFlags.STOP_START_OFF)
cp.safetyConfigs[0].safetyParam |= 256
assert qualified(cp)
assert create_intent(cp, owner().settings).main_arm
cp.alternativeExperience = 32
assert qualified(cp, marked_only=True)
cp.safetyConfigs[0].safetyParam |= 2
assert not qualified(cp) and not create_intent(cp, owner().settings).main_arm
for candidate in (CAR.SUBARU_OUTBACK, CAR.SUBARU_LEGACY_2025):
cp = CarInterface.get_non_essential_params(candidate)
cp.alternativeExperience = 32
assert qualified(cp) and not create_intent(cp, owner().settings).main_arm
@@ -23,8 +23,8 @@ from openpilot.starpilot.car.subaru.tests.native_fixture import subaru_native_pa
@pytest.mark.parametrize('candidate', [CAR.SUBARU_ASCENT_2023, CAR.SUBARU_LEGACY_2025, CAR.SUBARU_CROSSTREK_2025, CAR.SUBARU_FORESTER, CAR.SUBARU_OUTBACK])
def test_actual_full_engage_brake_reverse_temporary_recovery_mainoff(candidate, subaru_native_pair, tmp_path, aol=True, manual=False, stop_resume=False,
hard_stop_native_first=False, main_only=False, preferences=None):
fw = firmware_records(candidate, FW_VERSIONS, 'subaru')
hard_stop_native_first=False, main_only=False, preferences=None, firmware=None):
fw = firmware_records(candidate, FW_VERSIONS, 'subaru') if firmware is None else firmware
rows = []
with actual_factory(candidate, gen_empty_fingerprint(), fw, '0' * 17, manual=manual, aol=aol, preferences=preferences) as (card, params, matches):
cp = card.CP
@@ -232,7 +232,7 @@ def test_actual_full_engage_brake_reverse_temporary_recovery_mainoff(candidate,
bool(intent and intent.lateralArmed) == aol and row['cardLatch'] == aol and row['permission'] == 0), row
if 240 <= tick < 255:
assert not command.latActive and bool(intent and intent.lateralArmed) == aol and row['cardLatch'] == aol and row['permission'] == 0, row
main_rearm = aol and candidate in (CAR.SUBARU_CROSSTREK_2025, CAR.SUBARU_IMPREZA_2020)
main_rearm = aol and candidate in (CAR.SUBARU_CROSSTREK_2025, CAR.SUBARU_IMPREZA_2020, CAR.SUBARU_OUTBACK_2023)
if 330 <= tick < (350 if main_rearm else 400):
assert not command.latActive and not bool(intent and intent.allowedLatch), row
if main_rearm and 375 <= tick < 400:
@@ -323,7 +323,7 @@ def test_actual_native_first_hard_stop_retains_intent_and_resumes(candidate, sub
assert settled and all(not command['request'] and command['nativeAccepted'] for command in settled)
@pytest.mark.parametrize('candidate', [CAR.SUBARU_CROSSTREK_2025, CAR.SUBARU_IMPREZA_2020])
@pytest.mark.parametrize('candidate', [CAR.SUBARU_CROSSTREK_2025, CAR.SUBARU_IMPREZA_2020, CAR.SUBARU_OUTBACK_2023])
def test_actual_main_without_set_retains_native_first_stop_intent(subaru_native_pair, tmp_path, candidate):
test_actual_full_engage_brake_reverse_temporary_recovery_mainoff(
candidate, subaru_native_pair, tmp_path,
+1 -1
View File
@@ -1 +1 @@
{"protected_inventory_sha256": "342afaf60ffcf7ce4a22e944e4aa384bfb13c5c08688db613d9a6795bab44822", "schema_version": 1}
{"protected_inventory_sha256": "d5495bdc0d7d08ad60b75642bb28e5b88d60766332d0d8af6a0d1af0cfa8c4b4", "schema_version": 1}