diff --git a/opendbc_repo/opendbc/car/toyota/carcontroller.py b/opendbc_repo/opendbc/car/toyota/carcontroller.py index bcff7f7c46..d8cb458735 100644 --- a/opendbc_repo/opendbc/car/toyota/carcontroller.py +++ b/opendbc_repo/opendbc/car/toyota/carcontroller.py @@ -85,6 +85,7 @@ class CarController(CarControllerBase): self.last_angle = 0 self.alert_active = False self.standstill_req = False + self.sng_hack = False self.last_standstill = False self.prius_longitudinal = prius_longitudinal.enabled(CP) self.sdsu_hybrid = (eps8_sdsu.configured(CP) or legacy_sdsu.configured(CP)) and bool(CP.flags & ToyotaFlags.HYBRID) @@ -360,6 +361,9 @@ class CarController(CarControllerBase): if not should_resume and CS.out.cruiseState.standstill: self.standstill_req = True + if self.sng_hack and long_active: + self.standstill_req = False + if (bypass_long or rav4h_long or pedal_owner or advert_long or original_prius_long) and (not filter_allowed or not long_active and CS.out.standstill): self.standstill_req = True diff --git a/opendbc_repo/opendbc/car/toyota/sng.py b/opendbc_repo/opendbc/car/toyota/sng.py new file mode 100644 index 0000000000..15adc42896 --- /dev/null +++ b/opendbc_repo/opendbc/car/toyota/sng.py @@ -0,0 +1,14 @@ +"""StarPilot stop-latch override for existing Toyota longitudinal owners.""" +from opendbc.car import structs +from opendbc.car.toyota.values import ToyotaFlags + + +def eligible(cp): + from opendbc.car.toyota import prius_longitudinal, rav4h_filter, advert_filter, legacy_stop_timer + return bool(cp is not None and cp.brand == 'toyota' and cp.openpilotLongitudinalControl and + not cp.autoResumeSng and not cp.deprecated.enableGasInterceptor and + not cp.flags & ToyotaFlags.GAS_INTERCEPTOR and + not cp.passive and not cp.dashcamOnly and not cp.notCar and + len(cp.safetyConfigs) == 1 and cp.safetyConfigs[0].safetyModel == structs.CarParams.SafetyModel.toyota and + (prius_longitudinal.enabled(cp) or rav4h_filter.enabled(cp) or + advert_filter.configured(cp) or legacy_stop_timer.enabled(cp))) diff --git a/openpilot/common/libcommon.a b/openpilot/common/libcommon.a index aeb269d302..9c5b705afe 100644 Binary files a/openpilot/common/libcommon.a and b/openpilot/common/libcommon.a differ diff --git a/openpilot/common/libparams_c.so b/openpilot/common/libparams_c.so index 9330bcea64..b4a0b208ff 100755 Binary files a/openpilot/common/libparams_c.so and b/openpilot/common/libparams_c.so differ diff --git a/openpilot/common/params_keys.h b/openpilot/common/params_keys.h index 9d4399af8f..2a5fd08e9c 100644 --- a/openpilot/common/params_keys.h +++ b/openpilot/common/params_keys.h @@ -21,6 +21,7 @@ inline static std::unordered_map keys = { {"PromptVolume", {PERSISTENT, INT}}, {"AlwaysOnLateral", {PERSISTENT, BOOL, "1"}}, {"NostalgiaMode", {PERSISTENT, BOOL, "0"}}, + {"SNGHack", {PERSISTENT, BOOL, "0"}}, {"ToyotaAutoHold", {PERSISTENT, BOOL, "0"}}, {"JeepBrakeHold", {PERSISTENT, BOOL, "0"}}, {"ToyotaRadarMode", {PERSISTENT, INT, "0"}}, diff --git a/openpilot/starpilot/car/toyota/tests/test_sng.py b/openpilot/starpilot/car/toyota/tests/test_sng.py new file mode 100644 index 0000000000..3c58a10544 --- /dev/null +++ b/openpilot/starpilot/car/toyota/tests/test_sng.py @@ -0,0 +1,103 @@ +"""The saved donor option reaches the real settings and controller owners.""" +from dataclasses import replace + +import pytest +from opendbc.car.toyota.interface import CarInterface +from openpilot.common.params import Params +from openpilot.common.prefix import OpenpilotPrefix +from openpilot.starpilot.car.toyota.tests.test_gas_override_cancel import setup, acc_frames, PROFILES +from openpilot.starpilot.car.toyota.tests.test_prius_sdsu_filter import factory +from openpilot.starpilot.ui.feature_settings_owner import FeatureSettingsOwner +from openpilot.starpilot.ui.feature_settings_state import row_change +from openpilot.starpilot.vehicle_preferences import VehicleStartupPreferences + + +def eligible(cp): + from opendbc.car.toyota.sng import eligible as check + return check(cp) + + +def owner_for(params, cp, parked=True): + return FeatureSettingsOwner(params, lambda _: parked, vehicle_params=lambda: cp, + vehicle_fingerprint=lambda: cp.carFingerprint) + + +def rows(owner, parked=True): + return owner.snapshot('vehicle', parked=parked, system_long=True, lateral_context=True, metric=False).rows + + +def test_saved_sng_option_is_exposed(): + with OpenpilotPrefix(): + params = Params() + assert any(row.key == 'SNGHack' for row in rows(owner_for(params, factory()))), 'TOYOTA_SNG_OPTION_MISSING' + + +def test_saved_ui_choice_binds_next_controller_without_changing_cp(): + with OpenpilotPrefix(): + params, cp = Params(), factory() + before = cp.to_dict() + owner = owner_for(params, cp) + row = next(row for row in rows(owner) if row.key == 'SNGHack') + assert row.available and row.value == 'Off' + request = row_change(row) + assert request is not None + request = replace(request, confirmation=True) + from openpilot.starpilot.ui.vehicle_bool import VEHICLE_BOOL_KEYS, confirmation_question + assert request.key in VEHICLE_BOOL_KEYS and 'Toyota stop-and-go' in confirmation_question(request) + assert owner.apply(request) and params.get_bool('SNGHack') + assert not owner.apply(request) + ci = CarInterface(cp) + prefs = VehicleStartupPreferences.read(params, enabled=True) + prefs.configure_controller(ci) + assert ci.CC.sng_hack and cp.to_dict() == before + params.put_bool('SNGHack', False, block=True) + assert ci.CC.sng_hack + VehicleStartupPreferences.read(params, enabled=True).configure_controller(ci) + assert not ci.CC.sng_hack + + +@pytest.mark.parametrize('veto', ('stock', 'automatic', 'pedal', 'passive', 'dashcam', 'notcar', 'native')) +def test_donor_eligibility_and_native_identity_are_preserved(veto): + cp = factory() + assert eligible(cp) + if veto == 'stock': + cp.openpilotLongitudinalControl = False + elif veto == 'pedal': + cp.deprecated.enableGasInterceptor = True + elif veto == 'native': + cp.safetyConfigs[0].safetyModel = 'noOutput' + else: + setattr(cp, {'automatic': 'autoResumeSng', 'passive': 'passive', 'dashcam': 'dashcamOnly', 'notcar': 'notCar'}[veto], True) + assert not eligible(cp) + with OpenpilotPrefix(): + assert all(row.key != 'SNGHack' for row in rows(owner_for(Params(), cp))) + + +def test_onroad_and_safe_mode_cannot_enable_override(): + with OpenpilotPrefix(): + params, cp = Params(), factory() + owner = owner_for(params, cp, parked=False) + assert not next(row for row in rows(owner, False) if row.key == 'SNGHack').available + params.put_bool('SNGHack', True, block=True) + params.put_bool('SafeMode', True, block=True) + ci = CarInterface(cp) + VehicleStartupPreferences.read(params, enabled=True).configure_controller(ci) + assert not ci.CC.sng_hack + + +@pytest.mark.parametrize('profile', PROFILES) +@pytest.mark.parametrize('active', (False, True)) +def test_stop_latch_override_requires_qualified_active_long(profile, active): + cp, controller, command, state = setup(profile) + controller.sng_hack = eligible(cp) + state.out.gasPressed = False + state.out.standstill = state.out.cruiseState.standstill = True + state.out.vEgo = state.out.vEgoRaw = 0. + state.pcm_acc_status = 8 + command.longActive = active + command.actuators.accel = -.5 + controller.standstill_req = True + frames = acc_frames(cp, controller, command, state) + assert frames + assert all(bool(frame['RELEASE_STANDSTILL']) == (active and eligible(cp)) for frame in frames) + assert all(not frame['CANCEL_REQ'] for frame in frames) diff --git a/openpilot/starpilot/car/toyota/tests/test_sng_callers.py b/openpilot/starpilot/car/toyota/tests/test_sng_callers.py new file mode 100644 index 0000000000..a1878a6bdb --- /dev/null +++ b/openpilot/starpilot/car/toyota/tests/test_sng_callers.py @@ -0,0 +1,33 @@ +"""Saved SNG opt-in retains the physical/native stop-engagement contract.""" +import pytest +from opendbc.car.toyota.sng import eligible +from openpilot.common.params import Params +from openpilot.starpilot.vehicle_preferences import VehicleStartupPreferences +from openpilot.starpilot.car.toyota.tests import test_prius_stop_engagement_callers as helpers +from openpilot.starpilot.car.toyota.tests.test_toyota_cpp_transport import host_heartbeat_bridge as host_heartbeat_bridge + +source_matched_native = helpers.source_matched_native +daemon_gc_scope = helpers.daemon_gc_scope + + +@pytest.mark.parametrize('advert', (False, True)) +@pytest.mark.parametrize('stock', (False, True)) +def test_saved_sng_reaches_real_native_stop_callers(monkeypatch, host_heartbeat_bridge, advert, stock): + put, configure = Params.put_bool, VehicleStartupPreferences.configure_controller + bound = [] + + def saved(params, key, value, *args, **kwargs): + result = put(params, key, value, *args, **kwargs) + if key == 'ToyotaAutoHold': + put(params, 'SNGHack', True, block=True) + return result + + def bind(prefs, ci): + configure(prefs, ci) + assert ci.CC.sng_hack == eligible(ci.CP) + bound.append(ci.CC.sng_hack) + + monkeypatch.setattr(Params, 'put_bool', saved) + monkeypatch.setattr(VehicleStartupPreferences, 'configure_controller', bind) + helpers.test_prius_accepts_stop_engagement_before_brake_release(monkeypatch, host_heartbeat_bridge, advert, stock) + assert bound and bound[-1] == (not stock) diff --git a/openpilot/starpilot/galaxy/tests/test_settings.py b/openpilot/starpilot/galaxy/tests/test_settings.py index a8d815da40..05db377303 100644 --- a/openpilot/starpilot/galaxy/tests/test_settings.py +++ b/openpilot/starpilot/galaxy/tests/test_settings.py @@ -1121,7 +1121,7 @@ class SettingsGatewayTest(unittest.TestCase): from opendbc.car.mazda.values import CAR from openpilot.starpilot.lateral.controller_selection import policy_for cp = interfaces[CAR.MAZDA_CX5_2022].get_non_essential_params(CAR.MAZDA_CX5_2022) - self.assertIsNone(policy_for(cp)) + self.assertEqual(policy_for(cp), 'generic') self.context.value = AuthorityContext(True, cp, cp.as_reader().as_builder().to_bytes()) page = self.page('torque') index = next(i for i, row in enumerate(page['rows']) if row['label'] == 'Turn Assist') diff --git a/openpilot/starpilot/lateral/controller_selection.py b/openpilot/starpilot/lateral/controller_selection.py index c2e35dbb36..3457534207 100644 --- a/openpilot/starpilot/lateral/controller_selection.py +++ b/openpilot/starpilot/lateral/controller_selection.py @@ -5,9 +5,11 @@ from __future__ import annotations from dataclasses import dataclass from enum import StrEnum import json +import math from pathlib import Path from opendbc.car import structs +from opendbc.car.values import PLATFORMS DOCUMENT_KEY = 'LateralControllerSelection' @@ -62,6 +64,25 @@ KNOWN_POLICIES.update(dict.fromkeys(( 'HYUNDAI_KONA_EV_2022', ), 'hyundai')) +KNOWN_POLICIES.update({str(identity): platform.__class__.__module__.split('.')[-2] + for identity, platform in PLATFORMS.items()}) + + +def generic_torque_supported(cp) -> bool: + try: + platform = PLATFORMS.get(str(cp.carFingerprint)) + if (platform is None or platform.__class__.__module__.split('.')[-2] != str(cp.brand) or + cp.notCar or cp.passive or cp.dashcamOnly or + cp.steerControlType != structs.CarParams.SteerControlType.torque or cp.lateralTuning.which() != 'torque'): + return False + tune = cp.lateralTuning.torque + return (math.isfinite(tune.latAccelFactor) and tune.latAccelFactor > 0 and + math.isfinite(tune.latAccelOffset) and math.isfinite(tune.friction) and tune.friction >= 0 and + math.isfinite(tune.steeringAngleDeadzoneDeg) and tune.steeringAngleDeadzoneDeg >= 0) + except (AttributeError, TypeError, ValueError, OverflowError): + return False + + class ControllerMode(StrEnum): STANDARD = 'standard' STARPILOT = 'starpilot' @@ -75,7 +96,7 @@ class ControllerSelection: def policy_for(CP) -> str | None: - """Return only an already-implemented, exact torque policy identity.""" + """Prefer exact vehicle policies, otherwise use the shared torque law.""" if CP.notCar: return None from openpilot.starpilot.lateral.hkg_vehicle_policy import policy_for as hkg_vehicle_policy @@ -132,7 +153,7 @@ def policy_for(CP) -> str | None: CP.steerControlType == structs.CarParams.SteerControlType.torque and CP.lateralTuning.which() == 'torque' and not CP.dashcamOnly and not CP.passive): return 'ioniq6' - return None + return "generic" if generic_torque_supported(CP) else None def turn_assist_supported(CP) -> bool: @@ -151,7 +172,7 @@ def default_selection(CP) -> ControllerSelection: policy = policy_for(CP) from openpilot.starpilot.lateral.hkg_vehicle_policy import PROFILES forte_non_scc = policy == 'kia_forte' and str(CP.carFingerprint) in ('KIA_FORTE_2019_NON_SCC', 'KIA_FORTE_2021_NON_SCC') - mode = ControllerMode.STARPILOT if policy and (policy not in PROFILES or forte_non_scc) else ControllerMode.STANDARD + mode = ControllerMode.STARPILOT if policy and policy != 'generic' and (policy not in PROFILES or forte_non_scc) else ControllerMode.STANDARD return ControllerSelection(mode, policy, 'default') @@ -239,9 +260,12 @@ def learning_allowed(params, CP, *, selection: ControllerSelection | None = None preference = read_preference(params, CP) if not preference.valid or not preference.enabled: return False - if policy_for(CP) is None: + policy = policy_for(CP) + if policy is None: return True selected = read_selection(params, CP) if selection is None else selection + if policy == 'generic': + return selected.source != 'invalid' from openpilot.starpilot.lateral.gm_geometry_runtime import read_geometry geometry = read_geometry(params, CP) if geometry.force_off: diff --git a/openpilot/starpilot/lateral/generic_torque_policy.py b/openpilot/starpilot/lateral/generic_torque_policy.py new file mode 100644 index 0000000000..19b0a2625f --- /dev/null +++ b/openpilot/starpilot/lateral/generic_torque_policy.py @@ -0,0 +1,19 @@ +"""Shared StarPilot torque shaping using the vehicle's own calibration and conversion.""" + +from openpilot.common.scalar_clip import clip_scalar +from openpilot.starpilot.lateral.controller_selection import generic_torque_supported +from openpilot.starpilot.lateral.hkg_torque_policy import HKGShapedTorquePolicy +from openpilot.starpilot.lateral.torque_shaping import get_standard_friction_threshold + + +class GenericTorquePolicy(HKGShapedTorquePolicy): + supported_cp = staticmethod(generic_torque_supported) + + def feedforward(self, value, setpoint, jerk, speed): + return value + + def friction(self, setpoint, jerk, speed): + return get_standard_friction_threshold(speed), 1.0 + + def output(self, value, setpoint, speed): + return clip_scalar(value, -self.parent.steer_max, self.parent.steer_max) diff --git a/openpilot/starpilot/lateral/tests/test_controller_selection.py b/openpilot/starpilot/lateral/tests/test_controller_selection.py index 90d50d2b98..94a4c2229d 100644 --- a/openpilot/starpilot/lateral/tests/test_controller_selection.py +++ b/openpilot/starpilot/lateral/tests/test_controller_selection.py @@ -95,10 +95,11 @@ class TestControllerSelection(unittest.TestCase): wrong = ioniq.as_reader().as_builder() wrong.notCar = True self.assertIsNone(policy_for(wrong)) - with self.assertRaises(ValueError): - unsupported = cp_for(TOYOTA.TOYOTA_RAV4_TSS2_2022) - LatControlTorque(unsupported.as_reader(), interfaces[TOYOTA.TOYOTA_RAV4_TSS2_2022](unsupported), DT_CTRL, - controller_mode=ControllerMode.STARPILOT) + generic = cp_for(TOYOTA.TOYOTA_RAV4_TSS2_2022) + controller = LatControlTorque(generic.as_reader(), interfaces[TOYOTA.TOYOTA_RAV4_TSS2_2022](generic), DT_CTRL, + controller_mode=ControllerMode.STARPILOT) + self.assertEqual(controller.controller_policy, 'generic') + self.assertIsNotNone(selected_policy(controller)) def test_standard_skips_policy_constructor_and_ioniq_factor_multiplier(self): for vehicle in (HYUNDAI.HYUNDAI_IONIQ_6, HYUNDAI.GENESIS_G70_2020, TOYOTA.TOYOTA_COROLLA_TSS2): diff --git a/openpilot/starpilot/lateral/tests/test_genesis_gv70_policy.py b/openpilot/starpilot/lateral/tests/test_genesis_gv70_policy.py index 9cc594d6f2..2915559c61 100644 --- a/openpilot/starpilot/lateral/tests/test_genesis_gv70_policy.py +++ b/openpilot/starpilot/lateral/tests/test_genesis_gv70_policy.py @@ -76,10 +76,10 @@ def test_exact_admission_and_saved_standard_keeps_upstream_controller(): changed = cp.as_reader().as_builder() changed.lateralTuning.init('pid') assert not policy.supported_cp(changed) - for vehicle in (CAR.GENESIS_GV70_1ST_GEN, CAR.GENESIS_GV70_ELECTRIFIED_2ND_GEN): + for vehicle, expected in ((CAR.GENESIS_GV70_1ST_GEN, 'generic'), (CAR.GENESIS_GV70_ELECTRIFIED_2ND_GEN, None)): sibling = interfaces[vehicle].get_non_essential_params(vehicle) assert not policy.supported_cp(sibling) - assert policy_for(sibling) is None + assert policy_for(sibling) == expected def test_stabilization_only_changes_feedforward_feedback_remains_immediate(): diff --git a/openpilot/starpilot/lateral/tests/test_global_controller_choice.py b/openpilot/starpilot/lateral/tests/test_global_controller_choice.py new file mode 100644 index 0000000000..264973d2b8 --- /dev/null +++ b/openpilot/starpilot/lateral/tests/test_global_controller_choice.py @@ -0,0 +1,149 @@ +import json +import math +from types import SimpleNamespace + +import pytest + +from opendbc.car import DT_CTRL, structs +from opendbc.car.car_helpers import interfaces +from opendbc.car.hyundai.values import CAR +from opendbc.car.vehicle_model import VehicleModel +from openpilot.common.params import Params +from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque +from openpilot.starpilot.lateral.controller_selection import ( + DOCUMENT_KEY, ControllerMode, default_selection, learning_allowed, + parse_document, policy_for, read_selection, replace_mode, +) +from openpilot.starpilot.lateral.torque_extension import selected_policy +from openpilot.starpilot.ui.feature_settings_owner import FeatureSettingsOwner +from openpilot.starpilot.ui.feature_settings_state import row_change + + +def cp_for(identity): + return interfaces[identity].get_non_essential_params(identity) + + +def owner_for(params, cp): + return FeatureSettingsOwner(params, lambda group: True, vehicle_fingerprint=lambda: str(cp.carFingerprint), + vehicle_params=lambda: cp) + + +def test_niro_2023_choice_is_visible_and_saves(tmp_path): + params = Params(str(tmp_path)) + cp = cp_for(CAR.KIA_NIRO_EV_2ND_GEN) + assert cp.steerControlType == structs.CarParams.SteerControlType.torque + assert cp.lateralTuning.which() == 'torque' + owner = owner_for(params, cp) + snapshot = owner.snapshot('torque', parked=True, system_long=False, lateral_context=False, metric=False) + row = next((row for row in snapshot.rows if row.key == DOCUMENT_KEY), None) + assert row is not None, '2023 Niro EV must expose the controller selector' + assert row.choices == ('Stock Controller', 'StarPilot Controller') + assert row.value == 'Stock Controller' + request = row_change(row) + assert request is not None and request.value == 'StarPilot Controller' + assert owner.apply(request) + assert read_selection(params, cp).mode == ControllerMode.STARPILOT + assert not owner.apply(request), 'stale expected bytes must remain rejected' + ci = interfaces[CAR.KIA_NIRO_EV_2ND_GEN](cp) + controller = LatControlTorque(cp.as_reader(), ci, DT_CTRL, controller_mode=read_selection(params, cp).mode) + assert selected_policy(controller) is not None + assert controller.controller_policy == 'generic' + assert controller.torque_params.to_dict() == cp.lateralTuning.torque.to_dict() + + +def test_every_registered_torque_tune_can_save_both_choices(): + from openpilot.starpilot.lateral.controller_selection import generic_torque_supported + checked = [] + for identity in interfaces: + cp = cp_for(identity) + if not generic_torque_supported(cp): + continue + assert policy_for(cp) is not None, identity + for mode in ControllerMode: + raw = replace_mode(None, cp, mode) + assert parse_document(raw)['vehicles'][str(identity)]['brand'] == str(cp.brand) + from openpilot.starpilot.lateral.controller_selection import selection_from_bytes + selected = selection_from_bytes(cp, raw) + assert selected.mode == mode and selected.source == 'saved', identity + checked.append(str(identity)) + assert str(CAR.KIA_NIRO_EV_2ND_GEN) in checked + assert len(checked) > 100 + print('Registered torque controller selection coverage:', len(checked)) + + +def test_saved_vehicle_choices_remain_independent(): + from opendbc.car.honda.values import CAR as HONDA + niro = cp_for(CAR.KIA_NIRO_EV_2ND_GEN) + honda = cp_for(HONDA.HONDA_FIT_4G) + raw = replace_mode(None, niro, ControllerMode.STARPILOT) + raw = replace_mode(raw, honda, ControllerMode.STANDARD) + from openpilot.starpilot.lateral.controller_selection import selection_from_bytes + assert selection_from_bytes(niro, raw).mode == ControllerMode.STARPILOT + assert selection_from_bytes(honda, raw).mode == ControllerMode.STANDARD + + +@pytest.mark.parametrize('failure', ['brand', 'unknown', 'angle', 'pid', 'passive', 'dashcam', 'notCar', 'nan', 'factor', 'friction']) +def test_generic_refuses_invalid_controller_configuration(failure): + from openpilot.starpilot.lateral.controller_selection import generic_torque_supported + cp = cp_for(CAR.KIA_NIRO_EV_2ND_GEN) + if failure == 'brand': + cp.brand = 'toyota' + elif failure == 'unknown': + cp.carFingerprint = 'UNREGISTERED' + elif failure == 'angle': + cp.steerControlType = structs.CarParams.SteerControlType.angle + elif failure == 'pid': + cp.lateralTuning.init('pid') + elif failure in ('passive', 'dashcam', 'notCar'): + setattr(cp, 'dashcamOnly' if failure == 'dashcam' else failure, True) + elif failure == 'nan': + cp.lateralTuning.torque.latAccelFactor = float('nan') + elif failure == 'factor': + cp.lateralTuning.torque.latAccelFactor = 0 + elif failure == 'friction': + cp.lateralTuning.torque.friction = -1 + assert not generic_torque_supported(cp) + assert policy_for(cp) is None + + +def test_generic_defaults_and_existing_learning_are_preserved(tmp_path): + params = Params(str(tmp_path)) + cp = cp_for(CAR.KIA_NIRO_EV_2ND_GEN) + assert default_selection(cp).mode == ControllerMode.STANDARD + assert learning_allowed(params, cp) + params.put_bool('ForceAutoTuneOff', True, block=True) + assert not learning_allowed(params, cp) + params.put(DOCUMENT_KEY, json.loads(replace_mode(None, cp, ControllerMode.STARPILOT)), block=True) + assert not learning_allowed(params, cp) + + +def test_shared_controller_uses_real_interfaces_and_keeps_output_limits(): + checked = set() + for identity in interfaces: + cp = cp_for(identity) + if policy_for(cp) != 'generic' or str(cp.brand) in checked: + continue + checked.add(str(cp.brand)) + ci = interfaces[identity](cp) + standard = LatControlTorque(cp.as_reader(), ci, DT_CTRL, controller_mode=ControllerMode.STANDARD) + custom = LatControlTorque(cp.as_reader(), ci, DT_CTRL, controller_mode=ControllerMode.STARPILOT) + assert standard.starpilot_extension is None + assert custom.starpilot_extension is not None + assert custom.torque_params.to_dict() == standard.torque_params.to_dict() + for acceleration in (-1., -.2, 0., .2, 1.): + assert (custom.torque_from_lateral_accel(acceleration, custom.torque_params) == + standard.torque_from_lateral_accel(acceleration, standard.torque_params)) + assert custom.pid.pos_limit == standard.pid.pos_limit + assert custom.pid.neg_limit == standard.pid.neg_limit + state = structs.CarState.new_message() + vm = VehicleModel(cp) + params = SimpleNamespace(angleOffsetDeg=0., roll=0.01) + for active, speed, curvature, pressed, limited in ((False, 0., 0., False, False), (True, 12., .001, False, False), + (True, 25., -.001, False, True), (True, 15., .002, True, False), (False, 15., .002, False, False)): + state.vEgo, state.steeringPressed = speed, pressed + output, _, message = custom.update(active, state, vm, params, limited, curvature, False, .2) + assert math.isfinite(output) and abs(output) <= custom.steer_max + assert message.active == active + if not active: + assert output == 0 + assert 'hyundai' in checked and len(checked) >= 3 diff --git a/openpilot/starpilot/lateral/tests/test_global_torque_editor.py b/openpilot/starpilot/lateral/tests/test_global_torque_editor.py index 6c909a9028..235660a649 100644 --- a/openpilot/starpilot/lateral/tests/test_global_torque_editor.py +++ b/openpilot/starpilot/lateral/tests/test_global_torque_editor.py @@ -92,7 +92,7 @@ def test_generic_partial_manual_tune_honors_scoped_learning_preference(enabled): from openpilot.starpilot.lateral.tests.test_torque_family import learner from openpilot.starpilot.lateral.torque_runtime import TorqueHost, read_settings cp = interfaces['HONDA_FIT_4G'].get_non_essential_params('HONDA_FIT_4G') - assert cp.lateralTuning.which() == 'torque' and policy_for(cp) is None + assert cp.lateralTuning.which() == 'torque' and policy_for(cp) == 'generic' with OpenpilotPrefix(): params = Params() params.put(KEY, replace_preference(None, cp, enabled), block=True) diff --git a/openpilot/starpilot/lateral/torque_extension.py b/openpilot/starpilot/lateral/torque_extension.py index 3737a09d66..b0501cc71d 100644 --- a/openpilot/starpilot/lateral/torque_extension.py +++ b/openpilot/starpilot/lateral/torque_extension.py @@ -31,6 +31,9 @@ def create_extension(parent, cp, mode, selected, *, turn_assist=False): raise ValueError('HKG torque selection does not match CarParams') policy = HKGVehicleTorquePolicy(parent, cp) return TorqueExtension(policy, parameter_factor=policy.FACTOR_MULT) + if selected == 'generic': + from openpilot.starpilot.lateral.generic_torque_policy import GenericTorquePolicy + return TorqueExtension(GenericTorquePolicy(parent, cp)) if selected == 'ioniq6': from openpilot.starpilot.lateral.ioniq6_policy import Ioniq6TorquePolicy policy = Ioniq6TorquePolicy(parent, cp, turn_assist=turn_assist) diff --git a/openpilot/starpilot/lateral/torque_runtime.py b/openpilot/starpilot/lateral/torque_runtime.py index ee65471907..3872d26148 100644 --- a/openpilot/starpilot/lateral/torque_runtime.py +++ b/openpilot/starpilot/lateral/torque_runtime.py @@ -187,7 +187,7 @@ class TorqueHost: # existing live manual preference for other optional replay-host vehicles. if allow_learning is None: from openpilot.starpilot.lateral.controller_selection import policy_for - if policy_for(CP) is None: + if policy_for(CP) in (None, 'generic'): from openpilot.starpilot.lateral.learning_preferences import read_preference preference = read_preference(params, CP) allow_learning = preference.valid and preference.enabled diff --git a/openpilot/starpilot/ui/feature_settings_owner.py b/openpilot/starpilot/ui/feature_settings_owner.py index 32fe8738ae..e01ffe067d 100644 --- a/openpilot/starpilot/ui/feature_settings_owner.py +++ b/openpilot/starpilot/ui/feature_settings_owner.py @@ -82,7 +82,7 @@ BOOL_DEFAULTS = { "SubaruStopStartOff": False, "SubaruSNG": False, "SubaruRedneckCruise": False, - "ReverseCruise": False, "ToyotaAutoHold": False, "JeepBrakeHold": False, "VoltSNG": False, "GMAutoHold": False, "VoltOnePedalMode": False, + "ReverseCruise": False, "ToyotaAutoHold": False, "SNGHack": False, "JeepBrakeHold": False, "VoltSNG": False, "GMAutoHold": False, "VoltOnePedalMode": False, "RemapCancelToDistance": False, "LongPitch": True, "DisableOpenpilotLongitudinal": False, "SpeedLimitController": False, "ShowSpeedLimits": True, "SLCConfirmation": False, @@ -427,6 +427,25 @@ class FeatureSettingsOwner: return commit_exact(self.params, key="JeepBrakeHold", max_bytes=128, raw=b"1" if request.value == "On" else b"0", expected=request.expected, authorized=authorized, temp_prefix=".jeep-hold-").verified + def _toyota_sng_capability(self): + from opendbc.car.toyota.sng import eligible + cp = self.vehicle_params() + if not eligible(cp): + return None + return (str(cp.carFingerprint), int(cp.flags), bool(cp.autoResumeSng), + tuple((str(config.safetyModel), int(config.safetyParam)) for config in cp.safetyConfigs)) + + def _apply_toyota_sng(self, request): + if not request.confirmation or request.value not in ("Off", "On") or request.dependencies: + return False + def authorized(): + return (self.authority("parked_preferences") and self.authority("vehicle") and + request.capability is not None and request.capability == self._toyota_sng_capability() and + request.vehicle_fingerprint == self.vehicle_fingerprint() and request.expected in (None, b"0", b"1")) + return commit_exact(self.params, key="SNGHack", max_bytes=8, expected=request.expected, + raw=b"1" if request.value == "On" else b"0", authorized=authorized, + temp_prefix=".toyota-sng-").verified + def _auto_hold_capability(self) -> tuple | None: from opendbc.car.toyota.interface import toyota_auto_hold_supported cp = self.vehicle_params() @@ -820,7 +839,7 @@ class FeatureSettingsOwner: FeatureRow("", "Always On Lateral", "Keep steering assistance active independently of cruise control", page=FeaturePage.AOL, available=True), FeatureRow("", "Wheel Controls", "Assign steering-wheel buttons and cruise behavior", page=FeaturePage.WHEEL, available=True)] if (self._long_pitch_capability() is not None or self._bolt_disable_capability() is not None or - self._auto_hold_capability() is not None or self._jeep_hold_capability() is not None or + self._auto_hold_capability() is not None or self._toyota_sng_capability() is not None or self._jeep_hold_capability() is not None or self._toyota_radar_capability() is not None or self._pedal_setup_capability() is not None or self.subaru_smoothing.capability() is not None or self._subaru_avh_capability() is not None or self._subaru_startup_capability() is not None or self._subaru_sng_capability() is not None or @@ -845,6 +864,12 @@ class FeatureSettingsOwner: "Hold the brake for over one second at a complete stop with cruise main on and cruise disengaged. " + "Holds until you press the gas; normal cruise stop-and-go is unchanged. Applies after the next startup.") rows.extend([replace(row, available=row.available and self._readable("ToyotaAutoHold"), capability=capability)] if capability is not None else []) + sng_capability = self._toyota_sng_capability() + if sng_capability is not None: + row = self._bool_row("SNGHack", "Stop-and-Go Hack", + configurable and parked and self.authority("vehicle") and self.authority("parked_preferences"), + "Automatic resume for Toyota/Lexus vehicles without factory stop-and-go. Applies after the next startup.") + rows.append(replace(row, available=row.available and self._readable("SNGHack"), capability=sng_capability)) radar_capability = self._toyota_radar_capability() if radar_capability is not None: from openpilot.starpilot.car.toyota.radar_preferences import CHOICES, KEY @@ -1380,6 +1405,8 @@ class FeatureSettingsOwner: return self._apply_jeep_hold(request) if key == "AlphaLongitudinalEnabled": return self._apply_alpha_long(request) + if key == "SNGHack": + return self._apply_toyota_sng(request) if key == "ToyotaAutoHold": return self._apply_auto_hold(request) if key == "ToyotaRadarMode": diff --git a/openpilot/starpilot/ui/tests/test_controller_feature.py b/openpilot/starpilot/ui/tests/test_controller_feature.py index d966d199c5..368545b4fd 100644 --- a/openpilot/starpilot/ui/tests/test_controller_feature.py +++ b/openpilot/starpilot/ui/tests/test_controller_feature.py @@ -71,10 +71,11 @@ class TestControllerFeature(unittest.TestCase): self.cp.notCar = True self.assertIsNone(self.row()) - def test_registered_stock_torque_uses_scoped_learning_without_controller_choice(self): + def test_registered_stock_torque_has_both_controllers_and_scoped_learning(self): self.cp = interfaces[HONDA.HONDA_FIT_4G].get_non_essential_params(HONDA.HONDA_FIT_4G) self.assertEqual(self.cp.lateralTuning.which(), 'torque') - self.assertIsNone(self.row()) + self.assertEqual(self.require_row().choices, ('Stock Controller', 'StarPilot Controller')) + self.assertEqual(self.require_row().value, 'Stock Controller') learning = self.require_row('ForceAutoTuneOff') self.assertEqual(learning.label, 'Use StarPilot Auto Learn') self.assertEqual(learning.value, 'On') diff --git a/openpilot/starpilot/ui/tests/test_feature_settings_owner.py b/openpilot/starpilot/ui/tests/test_feature_settings_owner.py index 79f29882f9..abbd869144 100644 --- a/openpilot/starpilot/ui/tests/test_feature_settings_owner.py +++ b/openpilot/starpilot/ui/tests/test_feature_settings_owner.py @@ -365,7 +365,7 @@ class FeatureSettingsOwnerTests(unittest.TestCase): from openpilot.starpilot.lateral.controller_selection import policy_for from openpilot.starpilot.vehicle_preferences import VehicleStartupPreferences cp = interfaces[CAR.MAZDA_CX5_2022].get_non_essential_params(CAR.MAZDA_CX5_2022) - self.assertIsNone(policy_for(cp)) + self.assertEqual(policy_for(cp), 'generic') self.owner.vehicle_params = lambda: cp self.owner.controller.vehicle_params = self.owner.vehicle_params self.fingerprint = cp.carFingerprint diff --git a/openpilot/starpilot/ui/vehicle_bool.py b/openpilot/starpilot/ui/vehicle_bool.py index 764b2bb676..f698153528 100644 --- a/openpilot/starpilot/ui/vehicle_bool.py +++ b/openpilot/starpilot/ui/vehicle_bool.py @@ -1,7 +1,7 @@ """Confirmation text for parked vehicle preferences.""" VEHICLE_BOOL_KEYS = frozenset(("AlphaLongitudinalEnabled", "SubaruAvhStartup", "SubaruStopStartOff", "SubaruSNG", "SubaruRedneckCruise", - "GMPedalLongitudinal", "DisableOpenpilotLongitudinal", "LongPitch", "VoltSNG", "GMAutoHold", "VoltOnePedalMode", + "GMPedalLongitudinal", "DisableOpenpilotLongitudinal", "LongPitch", "VoltSNG", "SNGHack", "GMAutoHold", "VoltOnePedalMode", "TeslaAOLScreenTap", "TeslaAOLDisengageOnBrake", "RemoteStartBootsComma", "HKGRemoteStartBootsComma", "IgnoreIgnitionLine", "TeslaWakeOnCAN")) @@ -30,6 +30,8 @@ def confirmation_question(request): return f"{verb} Subaru stop-and-go assistance after the next startup? Factory ACC retains speed control." if request.key == "SubaruRedneckCruise": return f"{verb} software cruise after the next startup? Stock ACC keeps pedal control." + if request.key == "SNGHack": + return f"{verb} Toyota stop-and-go assistance after the next startup?" if request.key == "VoltSNG": return f"{verb} Volt stop-and-go assistance after the next startup?" if request.key == "GMAutoHold": diff --git a/openpilot/starpilot/vehicle_preferences.py b/openpilot/starpilot/vehicle_preferences.py index 7d1c44a86a..332747aa04 100644 --- a/openpilot/starpilot/vehicle_preferences.py +++ b/openpilot/starpilot/vehicle_preferences.py @@ -20,6 +20,7 @@ def bolt_disable_supported(cp) -> bool: @dataclass(frozen=True) class VehicleStartupPreferences: toyota_auto_hold: bool = False + toyota_sng: bool = field(default=False, kw_only=True) jeep_brake_hold: bool = field(default=False, kw_only=True) turn_assist: bool = False gm_long_pitch: bool = True @@ -116,7 +117,9 @@ class VehicleStartupPreferences: ford_lateral_mode=ford_mode(params, enabled=enabled), ford_pinion=bool(enabled and read_saved(params, "SafeMode", 8) in ((None, True), (b"0", True)) and read_saved(params, "FordPrefSteerAngleCurvature", 8) == (b"1", True)), tesla_screen=screen, - tesla_screen_brake=screen_brake, toyota_auto_hold=toyota, jeep_brake_hold=jeep_hold, + tesla_screen_brake=screen_brake, toyota_auto_hold=toyota, + toyota_sng=bool(enabled and readable and safe in (None, b"0") and + read_saved(params, "SNGHack", 8) == (b"1", True)), jeep_brake_hold=jeep_hold, gm_longitudinal_tune=selected_tune(params, enabled=enabled), toyota_lock_doors=bool(enabled and readable and safe in (None, b"0") and read_saved(params, "LockDoors", 8) == (b"1", True)), @@ -276,6 +279,8 @@ class VehicleStartupPreferences: is_volt_one_pedal, camera_acc_pedal_profile, volt_cc_pedal_profile) cp = ci.CP if ci.CC is not None and cp.brand == "toyota" and not cp.passive and not cp.dashcamOnly and not cp.notCar: + from opendbc.car.toyota.sng import eligible + ci.CC.sng_hack = self.toyota_sng and eligible(cp) ci.CC.door_locks.lock = self.toyota_lock_doors ci.CC.door_locks.unlock = self.toyota_unlock_doors if ci.CC is not None and is_volt_longitudinal(cp): diff --git a/panda/board/obj/body_h7.bin.signed b/panda/board/obj/body_h7.bin.signed index 07480b86e8..a70f658d93 100644 Binary files a/panda/board/obj/body_h7.bin.signed and b/panda/board/obj/body_h7.bin.signed differ diff --git a/panda/board/obj/bootstub.body_h7.bin b/panda/board/obj/bootstub.body_h7.bin index aa50bc8e18..c0665719ea 100644 Binary files a/panda/board/obj/bootstub.body_h7.bin and b/panda/board/obj/bootstub.body_h7.bin differ diff --git a/panda/board/obj/bootstub.panda.bin b/panda/board/obj/bootstub.panda.bin index 19e002a301..1c16f7be69 100644 Binary files a/panda/board/obj/bootstub.panda.bin and b/panda/board/obj/bootstub.panda.bin differ diff --git a/panda/board/obj/bootstub.panda_can_ignition_only.bin b/panda/board/obj/bootstub.panda_can_ignition_only.bin index 19e002a301..1c16f7be69 100644 Binary files a/panda/board/obj/bootstub.panda_can_ignition_only.bin and b/panda/board/obj/bootstub.panda_can_ignition_only.bin differ diff --git a/panda/board/obj/bootstub.panda_h7.bin b/panda/board/obj/bootstub.panda_h7.bin index 430a20c0f1..7720e1efd4 100644 Binary files a/panda/board/obj/bootstub.panda_h7.bin and b/panda/board/obj/bootstub.panda_h7.bin differ diff --git a/panda/board/obj/bootstub.panda_h7_can_ignition_only.bin b/panda/board/obj/bootstub.panda_h7_can_ignition_only.bin index 430a20c0f1..7720e1efd4 100644 Binary files a/panda/board/obj/bootstub.panda_h7_can_ignition_only.bin and b/panda/board/obj/bootstub.panda_h7_can_ignition_only.bin differ diff --git a/panda/board/obj/bootstub.panda_h7_hkg_remote.bin b/panda/board/obj/bootstub.panda_h7_hkg_remote.bin index 430a20c0f1..7720e1efd4 100644 Binary files a/panda/board/obj/bootstub.panda_h7_hkg_remote.bin and b/panda/board/obj/bootstub.panda_h7_hkg_remote.bin differ diff --git a/panda/board/obj/bootstub.panda_h7_hkg_remote_can_ignition_only.bin b/panda/board/obj/bootstub.panda_h7_hkg_remote_can_ignition_only.bin index 430a20c0f1..7720e1efd4 100644 Binary files a/panda/board/obj/bootstub.panda_h7_hkg_remote_can_ignition_only.bin and b/panda/board/obj/bootstub.panda_h7_hkg_remote_can_ignition_only.bin differ diff --git a/panda/board/obj/bootstub.panda_h7_remote.bin b/panda/board/obj/bootstub.panda_h7_remote.bin index 430a20c0f1..7720e1efd4 100644 Binary files a/panda/board/obj/bootstub.panda_h7_remote.bin and b/panda/board/obj/bootstub.panda_h7_remote.bin differ diff --git a/panda/board/obj/bootstub.panda_h7_remote_can_ignition_only.bin b/panda/board/obj/bootstub.panda_h7_remote_can_ignition_only.bin index 430a20c0f1..7720e1efd4 100644 Binary files a/panda/board/obj/bootstub.panda_h7_remote_can_ignition_only.bin and b/panda/board/obj/bootstub.panda_h7_remote_can_ignition_only.bin differ diff --git a/panda/board/obj/bootstub.panda_h7_tesla_wake.bin b/panda/board/obj/bootstub.panda_h7_tesla_wake.bin index 430a20c0f1..7720e1efd4 100644 Binary files a/panda/board/obj/bootstub.panda_h7_tesla_wake.bin and b/panda/board/obj/bootstub.panda_h7_tesla_wake.bin differ diff --git a/panda/board/obj/bootstub.panda_h7_tesla_wake_can_ignition_only.bin b/panda/board/obj/bootstub.panda_h7_tesla_wake_can_ignition_only.bin index 430a20c0f1..7720e1efd4 100644 Binary files a/panda/board/obj/bootstub.panda_h7_tesla_wake_can_ignition_only.bin and b/panda/board/obj/bootstub.panda_h7_tesla_wake_can_ignition_only.bin differ diff --git a/panda/board/obj/bootstub.panda_hkg_remote.bin b/panda/board/obj/bootstub.panda_hkg_remote.bin index 19e002a301..1c16f7be69 100644 Binary files a/panda/board/obj/bootstub.panda_hkg_remote.bin and b/panda/board/obj/bootstub.panda_hkg_remote.bin differ diff --git a/panda/board/obj/bootstub.panda_hkg_remote_can_ignition_only.bin b/panda/board/obj/bootstub.panda_hkg_remote_can_ignition_only.bin index 19e002a301..1c16f7be69 100644 Binary files a/panda/board/obj/bootstub.panda_hkg_remote_can_ignition_only.bin and b/panda/board/obj/bootstub.panda_hkg_remote_can_ignition_only.bin differ diff --git a/panda/board/obj/bootstub.panda_remote.bin b/panda/board/obj/bootstub.panda_remote.bin index 19e002a301..1c16f7be69 100644 Binary files a/panda/board/obj/bootstub.panda_remote.bin and b/panda/board/obj/bootstub.panda_remote.bin differ diff --git a/panda/board/obj/bootstub.panda_remote_can_ignition_only.bin b/panda/board/obj/bootstub.panda_remote_can_ignition_only.bin index 19e002a301..1c16f7be69 100644 Binary files a/panda/board/obj/bootstub.panda_remote_can_ignition_only.bin and b/panda/board/obj/bootstub.panda_remote_can_ignition_only.bin differ diff --git a/panda/board/obj/bootstub.panda_tesla_wake.bin b/panda/board/obj/bootstub.panda_tesla_wake.bin index 19e002a301..1c16f7be69 100644 Binary files a/panda/board/obj/bootstub.panda_tesla_wake.bin and b/panda/board/obj/bootstub.panda_tesla_wake.bin differ diff --git a/panda/board/obj/bootstub.panda_tesla_wake_can_ignition_only.bin b/panda/board/obj/bootstub.panda_tesla_wake_can_ignition_only.bin index 19e002a301..1c16f7be69 100644 Binary files a/panda/board/obj/bootstub.panda_tesla_wake_can_ignition_only.bin and b/panda/board/obj/bootstub.panda_tesla_wake_can_ignition_only.bin differ diff --git a/panda/board/obj/gitversion.h b/panda/board/obj/gitversion.h index ce4bf53495..4cc06aab82 100644 --- a/panda/board/obj/gitversion.h +++ b/panda/board/obj/gitversion.h @@ -1,4 +1,4 @@ #pragma once extern const uint8_t gitversion[29]; -const uint8_t gitversion[29] = "DEV-b3b96ade-Pa5919516-DEBUG"; +const uint8_t gitversion[29] = "DEV-0fcf1277-Pa5919516-DEBUG"; diff --git a/panda/board/obj/panda.bin.signed b/panda/board/obj/panda.bin.signed index 233e1c624e..e1a6290dba 100644 Binary files a/panda/board/obj/panda.bin.signed and b/panda/board/obj/panda.bin.signed differ diff --git a/panda/board/obj/panda_can_ignition_only.bin.signed b/panda/board/obj/panda_can_ignition_only.bin.signed index 8abc5dbed9..002a7fbaef 100644 Binary files a/panda/board/obj/panda_can_ignition_only.bin.signed and b/panda/board/obj/panda_can_ignition_only.bin.signed differ diff --git a/panda/board/obj/panda_h7.bin.signed b/panda/board/obj/panda_h7.bin.signed index 354db600aa..538916a494 100644 Binary files a/panda/board/obj/panda_h7.bin.signed and b/panda/board/obj/panda_h7.bin.signed differ diff --git a/panda/board/obj/panda_h7_can_ignition_only.bin.signed b/panda/board/obj/panda_h7_can_ignition_only.bin.signed index 35c5be63df..03b8a0cf9f 100644 Binary files a/panda/board/obj/panda_h7_can_ignition_only.bin.signed and b/panda/board/obj/panda_h7_can_ignition_only.bin.signed differ diff --git a/panda/board/obj/panda_h7_hkg_remote.bin.signed b/panda/board/obj/panda_h7_hkg_remote.bin.signed index 34c79b6843..f5e0dab851 100644 Binary files a/panda/board/obj/panda_h7_hkg_remote.bin.signed and b/panda/board/obj/panda_h7_hkg_remote.bin.signed differ diff --git a/panda/board/obj/panda_h7_hkg_remote_can_ignition_only.bin.signed b/panda/board/obj/panda_h7_hkg_remote_can_ignition_only.bin.signed index 1f5239ec7d..811516cdac 100644 Binary files a/panda/board/obj/panda_h7_hkg_remote_can_ignition_only.bin.signed and b/panda/board/obj/panda_h7_hkg_remote_can_ignition_only.bin.signed differ diff --git a/panda/board/obj/panda_h7_remote.bin.signed b/panda/board/obj/panda_h7_remote.bin.signed index 7f9d31eaf5..f46b95794f 100644 Binary files a/panda/board/obj/panda_h7_remote.bin.signed and b/panda/board/obj/panda_h7_remote.bin.signed differ diff --git a/panda/board/obj/panda_h7_remote_can_ignition_only.bin.signed b/panda/board/obj/panda_h7_remote_can_ignition_only.bin.signed index 555c771612..5eb5851c75 100644 Binary files a/panda/board/obj/panda_h7_remote_can_ignition_only.bin.signed and b/panda/board/obj/panda_h7_remote_can_ignition_only.bin.signed differ diff --git a/panda/board/obj/panda_h7_tesla_wake.bin.signed b/panda/board/obj/panda_h7_tesla_wake.bin.signed index 128311c0a0..09123a9e0e 100644 Binary files a/panda/board/obj/panda_h7_tesla_wake.bin.signed and b/panda/board/obj/panda_h7_tesla_wake.bin.signed differ diff --git a/panda/board/obj/panda_h7_tesla_wake_can_ignition_only.bin.signed b/panda/board/obj/panda_h7_tesla_wake_can_ignition_only.bin.signed index 35bbbcf8ad..d9b6a6c61f 100644 Binary files a/panda/board/obj/panda_h7_tesla_wake_can_ignition_only.bin.signed and b/panda/board/obj/panda_h7_tesla_wake_can_ignition_only.bin.signed differ diff --git a/panda/board/obj/panda_hkg_remote.bin.signed b/panda/board/obj/panda_hkg_remote.bin.signed index a44bf8753a..63726f4ab9 100644 Binary files a/panda/board/obj/panda_hkg_remote.bin.signed and b/panda/board/obj/panda_hkg_remote.bin.signed differ diff --git a/panda/board/obj/panda_hkg_remote_can_ignition_only.bin.signed b/panda/board/obj/panda_hkg_remote_can_ignition_only.bin.signed index 5c2405af6a..d69ce7b7cb 100644 Binary files a/panda/board/obj/panda_hkg_remote_can_ignition_only.bin.signed and b/panda/board/obj/panda_hkg_remote_can_ignition_only.bin.signed differ diff --git a/panda/board/obj/panda_remote.bin.signed b/panda/board/obj/panda_remote.bin.signed index b6ba1bb922..b15b1a4dcd 100644 Binary files a/panda/board/obj/panda_remote.bin.signed and b/panda/board/obj/panda_remote.bin.signed differ diff --git a/panda/board/obj/panda_remote_can_ignition_only.bin.signed b/panda/board/obj/panda_remote_can_ignition_only.bin.signed index 80efb18d3d..80341b8a42 100644 Binary files a/panda/board/obj/panda_remote_can_ignition_only.bin.signed and b/panda/board/obj/panda_remote_can_ignition_only.bin.signed differ diff --git a/panda/board/obj/panda_tesla_wake.bin.signed b/panda/board/obj/panda_tesla_wake.bin.signed index 8469efaf54..4380053732 100644 Binary files a/panda/board/obj/panda_tesla_wake.bin.signed and b/panda/board/obj/panda_tesla_wake.bin.signed differ diff --git a/panda/board/obj/panda_tesla_wake_can_ignition_only.bin.signed b/panda/board/obj/panda_tesla_wake_can_ignition_only.bin.signed index 6095ac2ab2..d1e92cbe24 100644 Binary files a/panda/board/obj/panda_tesla_wake_can_ignition_only.bin.signed and b/panda/board/obj/panda_tesla_wake_can_ignition_only.bin.signed differ diff --git a/panda/board/obj/version b/panda/board/obj/version index 448811986f..87e5327ea2 100644 --- a/panda/board/obj/version +++ b/panda/board/obj/version @@ -1 +1 @@ -DEV-b3b96ade-Pa5919516-DEBUG \ No newline at end of file +DEV-0fcf1277-Pa5919516-DEBUG \ No newline at end of file diff --git a/panda/tests/libpanda/libpanda.so b/panda/tests/libpanda/libpanda.so index 812721a672..fcac3ffb3a 100755 Binary files a/panda/tests/libpanda/libpanda.so and b/panda/tests/libpanda/libpanda.so differ diff --git a/prebuilt.json b/prebuilt.json index 3ef4c89bee..7c05bb652e 100644 --- a/prebuilt.json +++ b/prebuilt.json @@ -1 +1 @@ -{"protected_inventory_sha256": "d5495bdc0d7d08ad60b75642bb28e5b88d60766332d0d8af6a0d1af0cfa8c4b4", "schema_version": 1} +{"protected_inventory_sha256": "2c4e52ddf1a87907cb47f05c74f79df2e6762489e5d13d58a53469c7c9664d69", "schema_version": 1} diff --git a/tools/ci/run_vehicle_tests.py b/tools/ci/run_vehicle_tests.py index e53be92797..e6c76005e7 100644 --- a/tools/ci/run_vehicle_tests.py +++ b/tools/ci/run_vehicle_tests.py @@ -142,6 +142,8 @@ AOL_LIFECYCLE_TARGETS = ( "openpilot/starpilot/car/toyota/tests/test_camera_2aa_native.py", "openpilot/starpilot/car/toyota/tests/test_prius_sdsu_filter.py", "openpilot/starpilot/car/toyota/tests/test_prius_sdsu_callers.py", + "openpilot/starpilot/car/toyota/tests/test_sng.py", + "openpilot/starpilot/car/toyota/tests/test_sng_callers.py", "openpilot/starpilot/car/toyota/tests/test_brake_stop_cancel.py", "openpilot/starpilot/car/toyota/tests/test_prius_stop_engagement_callers.py", "opendbc_repo/opendbc/safety/tests/test_toyota_prius_sdsu.py",