diff --git a/opendbc_repo/opendbc/car/subaru/carcontroller.py b/opendbc_repo/opendbc/car/subaru/carcontroller.py index 13f671c9db..24c14a631f 100644 --- a/opendbc_repo/opendbc/car/subaru/carcontroller.py +++ b/opendbc_repo/opendbc/car/subaru/carcontroller.py @@ -120,7 +120,9 @@ class CarController(CarControllerBase): if (self.frame % self.p.STEER_STEP) == 0: if self.CP.carFingerprint in GEN2_ANGLE_PORTS: independent_lateral = subaru_aol_qualified(self.CP, marked_only=True) - angle_available = (CC.latActive and CS.out.cruiseState.available and + # Match Dom's independent-lateral envelope during large manual turns and parking speeds. + aol_motion_ok = CC.enabled or (CS.out.vEgoRaw > 0.44704 and abs(CS.out.steeringAngleDeg) < 120.) + angle_available = (CC.latActive and aol_motion_ok and CS.out.cruiseState.available and (independent_lateral or CC.enabled and CS.out.cruiseState.enabled and not CS.out.brakePressed) and CS.out.gearShifter == structs.CarState.GearShifter.drive and not CS.out.standstill and not CS.out.steerFaultTemporary and not CS.out.steerFaultPermanent) diff --git a/opendbc_repo/opendbc/car/subaru/tests/test_angle_handoff.py b/opendbc_repo/opendbc/car/subaru/tests/test_angle_handoff.py index 0ea7295bce..b21c746fb0 100644 --- a/opendbc_repo/opendbc/car/subaru/tests/test_angle_handoff.py +++ b/opendbc_repo/opendbc/car/subaru/tests/test_angle_handoff.py @@ -51,3 +51,43 @@ class TestAngleHandoff(unittest.TestCase): command.latActive = True _, decoded = step(controller, command, state) self.assertEqual(decoded['LKAS_Request'], 1) + + +class TestIndependentAngleEnvelope(unittest.TestCase): + def test_dom_aol_envelope_uses_actual_steering_request(self): + cars = (CAR.SUBARU_CROSSTREK_2025, CAR.SUBARU_LEGACY_2025, CAR.SUBARU_ASCENT_2023, + CAR.SUBARU_FORESTER_2022, CAR.SUBARU_OUTBACK_2023) + for car in cars: + for speed, angle, expected in ((5., 119.5, True), (5., -119.5, True), + (5., 120., False), (5., -120., False), + (5., 200., False), (5., -200., False), + (.4, 10., False), (.5, 10., True)): + with self.subTest(car=car, speed=speed, angle=angle): + cp, controller, command, state = setup_controller(car) + cp.alternativeExperience = 32 + command.enabled = False + command.actuators.steeringAngleDeg = angle + 5. + state.out.cruiseState.enabled = False + state.out.steeringTorque = state.out.steeringRateDeg = 0 + state.out.steeringAngleDeg = angle + state.out.vEgoRaw = state.out.vEgo = speed + state.out.standstill = False + for _ in range(3): + _, decoded = step(controller, command, state) + self.assertEqual(bool(decoded['LKAS_Request']), expected) + if not expected: + self.assertAlmostEqual(decoded['LKAS_Output'], angle, places=2) + + def test_ordinary_engagement_keeps_existing_angle_behavior(self): + for car in (CAR.SUBARU_CROSSTREK_2025, CAR.SUBARU_LEGACY_2025, CAR.SUBARU_ASCENT_2023, + CAR.SUBARU_FORESTER_2022, CAR.SUBARU_OUTBACK_2023): + for speed, angle in ((5., 200.), (.4, 10.)): + with self.subTest(car=car, speed=speed, angle=angle): + _, controller, command, state = setup_controller(car) + state.out.vEgoRaw = state.out.vEgo = speed + state.out.steeringAngleDeg = angle + state.out.steeringRateDeg = state.out.steeringTorque = 0 + state.out.standstill = False + for _ in range(3): + _, decoded = step(controller, command, state) + self.assertTrue(decoded['LKAS_Request']) diff --git a/prebuilt.json b/prebuilt.json index cac11ad6b8..373b949522 100644 --- a/prebuilt.json +++ b/prebuilt.json @@ -1 +1 @@ -{"protected_inventory_sha256": "b6dbedd7e09e9c0ccb699e58b2d3626bd3883bc6c44e998e239790056489d51c", "schema_version": 1} +{"protected_inventory_sha256": "0cd8f1e7cb4d23e7789cc44698d82a9e0de13be304f26a9cf40b5fee2e054965", "schema_version": 1}