diff --git a/openpilot/selfdrive/selfdrived/selfdrived.py b/openpilot/selfdrive/selfdrived/selfdrived.py old mode 100644 new mode 100755 diff --git a/openpilot/selfdrive/ui/layouts/settings/toggles.py b/openpilot/selfdrive/ui/layouts/settings/toggles.py index 1d294b08c1..2d02dd7e8b 100644 --- a/openpilot/selfdrive/ui/layouts/settings/toggles.py +++ b/openpilot/selfdrive/ui/layouts/settings/toggles.py @@ -79,7 +79,8 @@ class TogglesLayout(Widget): ), "IsRhdDetected": ( lambda: tr("Right Hand Driving"), - "Select the right-hand driver-monitoring side for the next drive. Off selects left-hand. Automatic side detection continues. Park and close driver camera preview before changing.", + ("Select the right-hand driver-monitoring side for the next drive. Off selects left-hand. Automatic side detection continues. " + + "Park and close driver camera preview before changing."), "monitoring.png", False, ), diff --git a/openpilot/starpilot/aol/transport_pause.py b/openpilot/starpilot/aol/transport_pause.py index 46c77dfa4a..91b1e101b2 100644 --- a/openpilot/starpilot/aol/transport_pause.py +++ b/openpilot/starpilot/aol/transport_pause.py @@ -13,7 +13,6 @@ def cp_identity(cp): def _configured_transport_native(sm, cp, session, now_ns, native=None, *, require_longitudinal=True, allow_restricted_lateral=False): - """Validate the exact live native configuration and every Panda.""" try: validated_here = native is None native = native or current_native(sm, cp, now_ns=now_ns, axis_session_id=session) @@ -52,7 +51,6 @@ def _configured_transport_native(sm, cp, session, now_ns, native=None, *, requir def _healthy_transport_native(sm, cp, cs, session, now_ns, native=None, *, require_longitudinal=True): - """Require both current vehicle health and the exact live native configuration.""" try: if not cs.canValid or cs.canTimeout or cs.steerFaultTemporary or cs.steerFaultPermanent: return None @@ -79,13 +77,11 @@ def _newer_combined_intent_native(sm, cp, cs, axis, now_ns): def independent_lateral_health(sm, cp, cs, session, now_ns): - """Structural health for retaining LAT intent; never grant either output axis.""" native = _healthy_transport_native(sm, cp, cs, session, now_ns, require_longitudinal=False) return native if native is not None and native.requestedLateral and native.lateralAllowed else None def healthy_transport(sm, cp, cs, session, now_ns, native=None): - """Require the live, exact native configuration, including every Panda.""" return _healthy_transport_native(sm, cp, cs, session, now_ns, native) is not None @@ -102,7 +98,6 @@ HOST_SOURCE_AVAILABILITY_EVENTS = (*AVAILABILITY_EVENTS, log.OnroadEvent.EventNa def host_source_availability_only(events): - """Closed host SOFT set for qualified inactive source-zero intent only.""" faults = [event for event in events if event.immediateDisable or event.softDisable] return bool(faults and not any(event.userDisable for event in events) and all(event.name in HOST_SOURCE_AVAILABILITY_EVENTS and event.softDisable and @@ -110,7 +105,6 @@ def host_source_availability_only(events): def stock_lateral_user_event(cp): - """Current ordinary-owner USER event for an established stock LAT role.""" if not cp.pcmCruise: return None if cp.brand == 'honda': @@ -225,7 +219,6 @@ class TransportPause: def observe(self, *, cp, session, sm, cs, native, now_ns, companion, previous_intent, intent, expired_healthy_source, previously_active, hard_fault, model_ready, user_disable): - """Return (temporary inhibit, hard upgrade); require a prior accepted pair.""" # Per observation; adjacent producer only. self.observed_native = None context_current = bool(cp_identity(cp) == self.cp and session == self.session and model_ready and companion is not None) @@ -308,7 +301,6 @@ class TransportPauseFeedback: self.healthy_inventory = None def _first_ford_gas_lateral_grant(self, sm, cp, cs, axis, now_ns, *, latched, producer): - """Bind the first real LAT-only grant while gas independently vetoes LONG.""" from opendbc.car import structs from opendbc.car.ford.values import CAR from opendbc.car.ford.aol import qualified as ford_qualified @@ -344,7 +336,6 @@ class TransportPauseFeedback: return native def _native_long_withdrawal_lateral_current(self, sm, cp, cs, axis, now_ns, *, latched, producer): - """Retain LAT intent from a fresh native LAT grant; never grant LONG or bypass faults.""" from openpilot.starpilot.nostalgia import physical_cancel from openpilot.starpilot.car.gm.aol import native_accepts_cp from openpilot.starpilot.car.hyundai.aol import early_native_long_withdrawal_supported, classic_brake_withdrawal @@ -410,7 +401,6 @@ class TransportPauseFeedback: return native def _ordinary_warning_intent_current(self, sm, cp, cs, axis, stamp, now_ns, *, latched, producer): - """Retain armed intent through a fresh SOFT withdrawal; grant no output.""" from openpilot.starpilot.aol.vehicle import policy_for from openpilot.starpilot.nostalgia import physical_cancel from opendbc.car import structs @@ -507,7 +497,6 @@ class TransportPauseFeedback: return True def _temporary_host_intent_current(self, sm, cp, cs, axis, stamp, now_ns, *, latched, producer): - """A fresh inactive proof may retain intent, never native/output authority.""" from openpilot.starpilot.nostalgia import physical_cancel if physical_cancel(cs, cp) or cs.steeringDisengage: return False @@ -622,7 +611,6 @@ class TransportPauseFeedback: return True def _temporary_lag_intent_current(self, sm, cp, cs, axis, stamp, now_ns, *, latched, producer, signature): - """Retain intent only through isolated lag or its bounded critical/event join.""" reason = str(axis.faultReason) events = sm['onroadEvents'] faults = [event for event in events if event.immediateDisable or event.softDisable] @@ -761,7 +749,6 @@ class TransportPauseFeedback: self.lateral_inventory==(native.pandaSerial,tuple(p.hardwareSerial for p in native.pandaInventory))) def _temporary_steering_intent_current(self, sm, cp, cs, axis, stamp, now_ns, *, latched, producer, signature): - """Keep an existing armed intent during isolated temporary EPS withdrawal.""" if (not latched or self.failed or self.paused or self.retention_started_ns or not self.session or str(axis.sessionId) != self.session or not cs.steerFaultTemporary or cs.steerFaultPermanent or not cs.canValid or cs.canTimeout or @@ -910,7 +897,6 @@ class TransportPauseFeedback: return True def _honda_brake_lateral_current(self, sm, cp, cs, axis, now_ns, *, latched, brake_source_ns): - """Preserve existing LAT intent through brake's LONG withdrawal, never output.""" from opendbc.car.honda.stock_aol import qualified from opendbc.car.structs import car @@ -942,7 +928,6 @@ class TransportPauseFeedback: return native def _longitudinal_cancel_current(self, sm, cp, cs, axis, now_ns, *, latched, cancel_source_ns, withdrawal_required=True) -> SafetyState | None: - """Retain existing intent during Cancel's bounded LONG withdrawal handshake.""" from opendbc.car.hyundai.ev6_aol import qualified from openpilot.starpilot.car.hyundai.aol import qualified_ccnc_long_aol as ev9_qualified from opendbc.car.structs import car @@ -1097,7 +1082,6 @@ class TransportPauseFeedback: return True def _availability_recovery_current(self, sm, cp, cs, axis, stamp, now_ns, *, latched, current, continuity, producer): - """Join a verified pause's healthy recovery pair; this never grants output.""" event_ns = int(sm.logMonoTime['onroadEvents']) # Pending healthy SOFT join needs both owners + original deadlines/source/event/producer/epoch/inventory # and current native LAT grant. @@ -1141,7 +1125,6 @@ class TransportPauseFeedback: (native.pandaSerial, tuple(p.hardwareSerial for p in native.pandaInventory)) == self.lateral_inventory) def _new_expired_combined_source(self, sm, cp, axis, stamp, now_ns, signature): - """An established combined producer advanced while Card missed its output lease.""" previous = self.signature if (now_ns <= signature[4] or previous is None or self.retention_started_ns or not (sm.seen['aolAxisState'] and sm.valid['aolAxisState'] and sm.alive['aolAxisState']) or @@ -1310,12 +1293,6 @@ class TransportPauseFeedback: (native.pandaSerial, tuple(p.hardwareSerial for p in native.pandaInventory)) == self.lateral_inventory) def _inactive_gear_source_gap(self, sm, cp, cs, axis, stamp, now_ns, *, latched, producer): - """Keep existing intent through a source-zero OFF sample while reversing. - - Both axes must already be OFF in the host and native inventory. Only the - original healthy source's 200ms intent-retention bound applies; this never - grants output or advances any source, native, output or baseline lease. - """ from opendbc.car import structs previous = self.signature if (not latched or self.failed or self.paused or self.pending_event or self.retention_started_ns or @@ -1358,7 +1335,6 @@ class TransportPauseFeedback: (native.pandaSerial, tuple(slot.hardwareSerial for slot in native.pandaInventory))) def _inactive_source_pause_current(self, sm, cp, cs, axis, stamp, now_ns, *, latched, producer): - """Retain accepted intent through a bounded, fully withdrawn source pause.""" from opendbc.car import structs previous = self.signature if (not latched or self.failed or self.paused or self.pending_event or self.retention_started_ns or diff --git a/openpilot/starpilot/car/toyota/tests/test_pedal_caller_native.py b/openpilot/starpilot/car/toyota/tests/test_pedal_caller_native.py index e4e969a30a..5a0871b94a 100644 --- a/openpilot/starpilot/car/toyota/tests/test_pedal_caller_native.py +++ b/openpilot/starpilot/car/toyota/tests/test_pedal_caller_native.py @@ -298,7 +298,10 @@ def run_case(stock, scenario='nominal', *, aol=True, candidate=CAR.TOYOTA_COROLL else: assert 'Bookmark' in rows['wheel:LKASButtonControl'].choices assert 'Toggle AOL' not in rows['wheel:LKASButtonControl'].choices - assert not any('Cancel' in k or 'MainCruise' in k for k in rows) + assert not any('Cancel' in k for k in rows) + main = rows['wheel:MainCruiseButtonControl'] + assert main.value == 'Factory cruise / AOL' and not main.available and not main.choices + assert not wheel.choices('MainCruiseButtonControl') assert display_supported(host.CP) and longitudinal_supported(host.CP) == (not stock) params.put('CancelButtonControl', 9, block=True) # Unsupported saved remap cannot steal MAIN/physical Cancel ownership. seen_active = False diff --git a/openpilot/starpilot/car/toyota/tests/test_rav4h_caller_native.py b/openpilot/starpilot/car/toyota/tests/test_rav4h_caller_native.py index b2801b661d..4a2944957a 100644 --- a/openpilot/starpilot/car/toyota/tests/test_rav4h_caller_native.py +++ b/openpilot/starpilot/car/toyota/tests/test_rav4h_caller_native.py @@ -349,7 +349,10 @@ def run_case(stock, scenario='nominal', *, aol=True, candidate=CAR.TOYOTA_RAV4H, if candidate == CAR.TOYOTA_RAV4H and not bypass_owner: assert 'Bookmark' in rows['wheel:LKASButtonControl'].choices assert 'Toggle AOL' not in rows['wheel:LKASButtonControl'].choices - assert not any('Cancel' in k or 'MainCruise' in k for k in rows) + assert not any('Cancel' in k for k in rows) + main = rows['wheel:MainCruiseButtonControl'] + assert main.value == 'Factory cruise / AOL' and not main.available and not main.choices + assert not wheel.choices('MainCruiseButtonControl') assert display_supported(host.CP) and longitudinal_supported(host.CP) == (not stock) params.put('CancelButtonControl', 9, block=True) # Unsupported saved remap cannot steal MAIN/physical Cancel ownership. seen_active = positive_steering = positive_accel = False diff --git a/openpilot/starpilot/car/toyota/tests/test_wheel_actions.py b/openpilot/starpilot/car/toyota/tests/test_wheel_actions.py index c149f67f3e..402e0474a1 100644 --- a/openpilot/starpilot/car/toyota/tests/test_wheel_actions.py +++ b/openpilot/starpilot/car/toyota/tests/test_wheel_actions.py @@ -83,7 +83,10 @@ def test_factory_settings_allow_auxiliary_lkas_hide_unreported_cancel_and_keep_c row = rows['wheel:' + KEY] assert {'Off', 'Bookmark', 'Traffic mode', 'Cycle personality', 'Experimental override'} <= set(row.choices) assert not {'Pause steering', 'Pause longitudinal', 'Toggle AOL'} & set(row.choices) - assert not any('Cancel' in key or 'MainCruise' in key for key in rows) + assert not any('Cancel' in key for key in rows) + main = rows['wheel:MainCruiseButtonControl'] + assert main.value == 'Factory cruise / AOL' and not main.available and not main.choices + assert not wheel.apply(FeatureSettingsRequest(main.key, main.source, 'Toggle AOL', capability=main.capability)) assert wheel.apply(FeatureSettingsRequest(row.key, row.source, 'Bookmark', capability=row.capability)) assert params.get(KEY) == 8 assert not wheel.apply(FeatureSettingsRequest(row.key, b'8', 'Toggle AOL', capability=row.capability)) @@ -283,7 +286,12 @@ def test_parser_supported_toyota_auxiliary_lkas_does_not_require_aol_admission(t row = rows['wheel:' + KEY] assert 'Bookmark' in row.choices assert not {'Pause steering', 'Pause longitudinal', 'Toggle AOL'} & set(row.choices) - assert not any('MainCruise' in key or 'Cancel' in key for key in rows) + assert not any('Cancel' in key for key in rows) + assert ('wheel:MainCruiseButtonControl' in rows) == admitted + if admitted: + main = rows['wheel:MainCruiseButtonControl'] + assert main.value == 'Factory cruise / AOL' and not main.available and not main.choices + assert not wheel.apply(FeatureSettingsRequest(main.key, main.source, 'Toggle AOL', capability=main.capability)) assert wheel.apply(FeatureSettingsRequest(row.key, row.source, 'Bookmark', capability=row.capability)) assert not wheel.apply(FeatureSettingsRequest(row.key, b'8', 'Toggle AOL', capability=row.capability)) # This bench uses full factory parser transport, without forcing CAN validity. diff --git a/openpilot/starpilot/tests/test_ford_recorded_green.py b/openpilot/starpilot/tests/test_ford_recorded_green.py index 8ab43b1e83..34f060dca7 100644 --- a/openpilot/starpilot/tests/test_ford_recorded_green.py +++ b/openpilot/starpilot/tests/test_ford_recorded_green.py @@ -1,4 +1,4 @@ -import gzip +import lzma import json from pathlib import Path @@ -14,7 +14,7 @@ from openpilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPl @pytest.mark.parametrize('alpha', [True]) @pytest.mark.parametrize('hands_free', [True]) def test_captured_green_forecast_releases_existing_model_hold(ford_joined, monkeypatch, geometry): - samples = json.loads(gzip.decompress((Path(__file__).parent / 'testdata/ford_mache_green_origin.json.gz').read_bytes()))['frames'] + samples = json.loads(lzma.decompress((Path(__file__).parent / 'testdata/ford_mache_green_origin.json.xz').read_bytes()))['frames'] case = green.CemGreenCallerTests(methodName='runTest') case.setUp() case.cp = ford_joined.host.CP diff --git a/openpilot/starpilot/tests/testdata/ford_mache_green_origin.json.gz b/openpilot/starpilot/tests/testdata/ford_mache_green_origin.json.gz deleted file mode 100644 index a4b40382b7..0000000000 Binary files a/openpilot/starpilot/tests/testdata/ford_mache_green_origin.json.gz and /dev/null differ diff --git a/openpilot/starpilot/tests/testdata/ford_mache_green_origin.json.xz b/openpilot/starpilot/tests/testdata/ford_mache_green_origin.json.xz new file mode 100644 index 0000000000..5bf66690c4 Binary files /dev/null and b/openpilot/starpilot/tests/testdata/ford_mache_green_origin.json.xz differ diff --git a/prebuilt.json b/prebuilt.json index 63e0475cd2..e41e0ebba8 100644 --- a/prebuilt.json +++ b/prebuilt.json @@ -1 +1 @@ -{"protected_inventory_sha256": "32675d7ccca0fc6a03db2b06173dd65ffe7e7bc760b80e4cfb91c698943609b0", "schema_version": 1} +{"protected_inventory_sha256": "5cb05464fef68119dc627d5193381dbfd20c804df01732d9dc100ff739ae7cd9", "schema_version": 1}