diff --git a/common/libcommon.a b/common/libcommon.a index 51a941f94..73fe17534 100644 Binary files a/common/libcommon.a and b/common/libcommon.a differ diff --git a/common/params_keys.h b/common/params_keys.h index 4b1d431b9..bafd4f58e 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -297,6 +297,7 @@ inline static std::unordered_map keys = { {"HolidayThemes", {PERSISTENT, BOOL, "1", "0", 0}}, {"HumanAcceleration", {PERSISTENT, BOOL, "0", "0", 2}}, {"HumanFollowing", {PERSISTENT, BOOL, "0", "0", 2}}, + {"CoastUpToLeads", {PERSISTENT, BOOL, "1", "1", 2}}, {"HumanLaneChanges", {PERSISTENT, BOOL, "0", "0", 2}}, {"IconPack", {PERSISTENT, STRING, "frog-animated", "stock", 0}}, {"IconToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, diff --git a/common/params_pyx.so b/common/params_pyx.so index 9a9be8985..73607d9df 100755 Binary files a/common/params_pyx.so and b/common/params_pyx.so differ diff --git a/panda/board/obj/body_h7.bin.signed b/panda/board/obj/body_h7.bin.signed index 84992a0f0..6d86ce044 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/body_h7/bootstub.elf b/panda/board/obj/body_h7/bootstub.elf index 54f8c4f14..1889481ff 100755 Binary files a/panda/board/obj/body_h7/bootstub.elf and b/panda/board/obj/body_h7/bootstub.elf differ diff --git a/panda/board/obj/body_h7/main.bin b/panda/board/obj/body_h7/main.bin index b5ce908ca..b26a45cd7 100755 Binary files a/panda/board/obj/body_h7/main.bin and b/panda/board/obj/body_h7/main.bin differ diff --git a/panda/board/obj/body_h7/main.elf b/panda/board/obj/body_h7/main.elf index 9fa7d5f4c..d46777cd7 100755 Binary files a/panda/board/obj/body_h7/main.elf and b/panda/board/obj/body_h7/main.elf differ diff --git a/panda/board/obj/bootstub.body_h7.bin b/panda/board/obj/bootstub.body_h7.bin index d4959688e..9bf677efa 100755 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 cd877c509..db3700b87 100755 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_h7.bin b/panda/board/obj/bootstub.panda_h7.bin index a3a5e532e..af72a0a11 100755 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_remote.bin b/panda/board/obj/bootstub.panda_h7_remote.bin index a3a5e532e..af72a0a11 100755 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_jungle_h7.bin b/panda/board/obj/bootstub.panda_jungle_h7.bin index bc15b7d93..88b70b70f 100755 Binary files a/panda/board/obj/bootstub.panda_jungle_h7.bin and b/panda/board/obj/bootstub.panda_jungle_h7.bin differ diff --git a/panda/board/obj/bootstub.panda_remote.bin b/panda/board/obj/bootstub.panda_remote.bin index cd877c509..db3700b87 100755 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/gitversion.h b/panda/board/obj/gitversion.h index 91387f4d6..6be9fd2bd 100644 --- a/panda/board/obj/gitversion.h +++ b/panda/board/obj/gitversion.h @@ -1,2 +1,2 @@ extern const uint8_t gitversion[19]; -const uint8_t gitversion[19] = "DEV-392d38c5-DEBUG"; +const uint8_t gitversion[19] = "DEV-688e0c3f-DEBUG"; diff --git a/panda/board/obj/panda.bin.signed b/panda/board/obj/panda.bin.signed index 9770fc36f..11504a8ae 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/bootstub.elf b/panda/board/obj/panda/bootstub.elf index 0b0574466..e17555a0e 100755 Binary files a/panda/board/obj/panda/bootstub.elf and b/panda/board/obj/panda/bootstub.elf differ diff --git a/panda/board/obj/panda/main.bin b/panda/board/obj/panda/main.bin index a86f6da17..2d050a0aa 100755 Binary files a/panda/board/obj/panda/main.bin and b/panda/board/obj/panda/main.bin differ diff --git a/panda/board/obj/panda/main.elf b/panda/board/obj/panda/main.elf index c7c3dc4eb..eab952ea7 100755 Binary files a/panda/board/obj/panda/main.elf and b/panda/board/obj/panda/main.elf differ diff --git a/panda/board/obj/panda_h7.bin.signed b/panda/board/obj/panda_h7.bin.signed index 5da05efab..ddd75c844 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/bootstub.elf b/panda/board/obj/panda_h7/bootstub.elf index 965590325..30432e9a3 100755 Binary files a/panda/board/obj/panda_h7/bootstub.elf and b/panda/board/obj/panda_h7/bootstub.elf differ diff --git a/panda/board/obj/panda_h7/main.bin b/panda/board/obj/panda_h7/main.bin index e8c314805..f72397a89 100755 Binary files a/panda/board/obj/panda_h7/main.bin and b/panda/board/obj/panda_h7/main.bin differ diff --git a/panda/board/obj/panda_h7/main.elf b/panda/board/obj/panda_h7/main.elf index 3750f4db8..a443a203b 100755 Binary files a/panda/board/obj/panda_h7/main.elf and b/panda/board/obj/panda_h7/main.elf differ diff --git a/panda/board/obj/panda_h7_remote.bin.signed b/panda/board/obj/panda_h7_remote.bin.signed index f5cded17b..b6fbd346a 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/bootstub.elf b/panda/board/obj/panda_h7_remote/bootstub.elf index 72e4fb21f..f15f0d913 100755 Binary files a/panda/board/obj/panda_h7_remote/bootstub.elf and b/panda/board/obj/panda_h7_remote/bootstub.elf differ diff --git a/panda/board/obj/panda_h7_remote/main.bin b/panda/board/obj/panda_h7_remote/main.bin index d809d53cb..9286b544e 100755 Binary files a/panda/board/obj/panda_h7_remote/main.bin and b/panda/board/obj/panda_h7_remote/main.bin differ diff --git a/panda/board/obj/panda_h7_remote/main.elf b/panda/board/obj/panda_h7_remote/main.elf index bd5b2f5a6..56b1dd6b5 100755 Binary files a/panda/board/obj/panda_h7_remote/main.elf and b/panda/board/obj/panda_h7_remote/main.elf differ diff --git a/panda/board/obj/panda_jungle_h7.bin.signed b/panda/board/obj/panda_jungle_h7.bin.signed index c57111c44..e0fd06d72 100644 Binary files a/panda/board/obj/panda_jungle_h7.bin.signed and b/panda/board/obj/panda_jungle_h7.bin.signed differ diff --git a/panda/board/obj/panda_jungle_h7/bootstub.elf b/panda/board/obj/panda_jungle_h7/bootstub.elf index 4b98ea945..221b4f219 100755 Binary files a/panda/board/obj/panda_jungle_h7/bootstub.elf and b/panda/board/obj/panda_jungle_h7/bootstub.elf differ diff --git a/panda/board/obj/panda_jungle_h7/main.bin b/panda/board/obj/panda_jungle_h7/main.bin index c190b9e7a..6e72af78a 100755 Binary files a/panda/board/obj/panda_jungle_h7/main.bin and b/panda/board/obj/panda_jungle_h7/main.bin differ diff --git a/panda/board/obj/panda_jungle_h7/main.elf b/panda/board/obj/panda_jungle_h7/main.elf index dbc7e580f..a7069f7ef 100755 Binary files a/panda/board/obj/panda_jungle_h7/main.elf and b/panda/board/obj/panda_jungle_h7/main.elf differ diff --git a/panda/board/obj/panda_remote.bin.signed b/panda/board/obj/panda_remote.bin.signed index d0d8adbcf..c60684281 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/bootstub.elf b/panda/board/obj/panda_remote/bootstub.elf index cd0c29522..ffefe756d 100755 Binary files a/panda/board/obj/panda_remote/bootstub.elf and b/panda/board/obj/panda_remote/bootstub.elf differ diff --git a/panda/board/obj/panda_remote/main.bin b/panda/board/obj/panda_remote/main.bin index 8ac6ec71e..e5f2cb1cd 100755 Binary files a/panda/board/obj/panda_remote/main.bin and b/panda/board/obj/panda_remote/main.bin differ diff --git a/panda/board/obj/panda_remote/main.elf b/panda/board/obj/panda_remote/main.elf index 3a667a3f9..025224e42 100755 Binary files a/panda/board/obj/panda_remote/main.elf and b/panda/board/obj/panda_remote/main.elf differ diff --git a/panda/board/obj/version b/panda/board/obj/version index 272535500..181f13d90 100644 --- a/panda/board/obj/version +++ b/panda/board/obj/version @@ -1 +1 @@ -DEV-392d38c5-DEBUG \ No newline at end of file +DEV-688e0c3f-DEBUG \ No newline at end of file diff --git a/selfdrive/pandad/pandad b/selfdrive/pandad/pandad index ba0708fe4..da4ff57e8 100755 Binary files a/selfdrive/pandad/pandad and b/selfdrive/pandad/pandad differ diff --git a/selfdrive/ui/layouts/settings/starpilot/longitudinal.py b/selfdrive/ui/layouts/settings/starpilot/longitudinal.py index beeb96ec1..35edd6e35 100644 --- a/selfdrive/ui/layouts/settings/starpilot/longitudinal.py +++ b/selfdrive/ui/layouts/settings/starpilot/longitudinal.py @@ -596,6 +596,15 @@ class StarPilotLongitudinalTuneLayout(StarPilotPanel): "color": "#597497", "visible": self._longitudinal_enabled, }, + { + "title": tr_noop("Coast Up To Leads"), + "desc": tr_noop("Allow openpilot to briefly coast toward far leads before applying normal throttle again."), + "type": "toggle", + "get_state": lambda: self._params.get_bool("CoastUpToLeads"), + "set_state": lambda s: self._params.put_bool("CoastUpToLeads", s), + "color": "#597497", + "visible": self._longitudinal_enabled, + }, { "title": tr_noop("Human-Like Lane Changes"), "desc": tr_noop("Use radar-informed behavior during lane changes when radar support is available."), diff --git a/selfdrive/ui/ui b/selfdrive/ui/ui index dd7b23a6f..35a6d37d6 100755 Binary files a/selfdrive/ui/ui and b/selfdrive/ui/ui differ diff --git a/starpilot/common/safe_mode.py b/starpilot/common/safe_mode.py index 2a770a470..464232e4b 100644 --- a/starpilot/common/safe_mode.py +++ b/starpilot/common/safe_mode.py @@ -68,6 +68,7 @@ SAFE_MODE_MANAGED_KEYS = ( "DecelerationProfile", "HumanAcceleration", "HumanFollowing", + "CoastUpToLeads", "HumanLaneChanges", "LeadDetectionThreshold", "RecoveryPower", diff --git a/starpilot/common/starpilot_variables.py b/starpilot/common/starpilot_variables.py index 054ba9928..25b42f736 100644 --- a/starpilot/common/starpilot_variables.py +++ b/starpilot/common/starpilot_variables.py @@ -851,6 +851,9 @@ class StarPilotVariables: toggle.custom_accel_profile_values = [custom_accel_defaults[key] for key in CUSTOM_ACCEL_PROFILE_PARAM_KEYS] toggle.human_acceleration = self.get_value("HumanAcceleration", condition=longitudinal_tuning) toggle.human_following = self.get_value("HumanFollowing", condition=longitudinal_tuning) + toggle.coast_up_to_leads = self.get_value("CoastUpToLeads", condition=longitudinal_tuning) + if longitudinal_tuning and self.params.get("CoastUpToLeads") is None: + toggle.coast_up_to_leads = True toggle.human_lane_changes = has_radar and self.get_value("HumanLaneChanges", condition=longitudinal_tuning) # Keep lead detection sensitivity normalized even when longitudinal tuning is disabled. # Some branches can return raw integer defaults (e.g. 35) when condition=False. diff --git a/starpilot/controls/lib/starpilot_following.py b/starpilot/controls/lib/starpilot_following.py index 3c87ff92c..baee7bddb 100644 --- a/starpilot/controls/lib/starpilot_following.py +++ b/starpilot/controls/lib/starpilot_following.py @@ -85,7 +85,7 @@ class StarPilotFollowing: self.t_follow = min(self.t_follow + self.starpilot_planner.starpilot_weather.increase_following_distance, MAX_T_FOLLOW) self.disable_throttle = False - if self.starpilot_planner.tracking_lead and self.starpilot_planner.lead_one.status: + if getattr(starpilot_toggles, "coast_up_to_leads", True) and self.starpilot_planner.tracking_lead and self.starpilot_planner.lead_one.status: lead_distance = self.starpilot_planner.lead_one.dRel v_lead = self.starpilot_planner.lead_one.vLead closing_speed = max(0.0, v_ego - v_lead) diff --git a/starpilot/system/the_pond/assets/components/tools/device_settings_layout.json b/starpilot/system/the_pond/assets/components/tools/device_settings_layout.json index 63b80393c..32ddcdf17 100644 --- a/starpilot/system/the_pond/assets/components/tools/device_settings_layout.json +++ b/starpilot/system/the_pond/assets/components/tools/device_settings_layout.json @@ -967,6 +967,14 @@ "ui_type": "toggle", "parent_key": "LongitudinalTune" }, + { + "key": "CoastUpToLeads", + "label": "Coast Up To Leads", + "description": "Allow openpilot to briefly coast toward far leads before resuming normal throttle. Disable this if your vehicle shows gas/brake alternation while approaching distant traffic.", + "data_type": "bool", + "ui_type": "toggle", + "parent_key": "LongitudinalTune" + }, { "key": "HumanLaneChanges", "label": "Human-Like Lane Changes", diff --git a/starpilot/ui/qt/offroad/longitudinal_settings.cc b/starpilot/ui/qt/offroad/longitudinal_settings.cc index b334c8250..2141aea3c 100644 --- a/starpilot/ui/qt/offroad/longitudinal_settings.cc +++ b/starpilot/ui/qt/offroad/longitudinal_settings.cc @@ -148,6 +148,7 @@ StarPilotLongitudinalPanel::StarPilotLongitudinalPanel(StarPilotSettingsWindow * {"DecelerationProfile", tr("Deceleration Profile"), tr("How firmly openpilot slows down. \"Eco\" favors coasting, \"Sport\" applies stronger braking."), ""}, {"HumanAcceleration", tr("Human-Like Acceleration"), tr("Acceleration that mimics human behavior by easing the throttle at low speeds and adding extra power when taking off from a stop."), ""}, {"HumanFollowing", tr("Human-Like Following"), tr("Following behavior that mimics human drivers by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking."), ""}, + {"CoastUpToLeads", tr("Coast Up To Leads"), tr("Allow openpilot to coast toward far leads before resuming normal throttle. Disable this if your vehicle shows noticeable gas/brake alternation while approaching distant traffic."), ""}, {"HumanLaneChanges", tr("Human-Like Lane Changes"), tr("Lane-change behavior that mimics human drivers by anticipating and tracking adjacent vehicles during lane changes."), ""}, {"LeadDetectionThreshold", tr("Lead Detection Sensitivity"), tr("How sensitive openpilot is to detecting vehicles. Higher sensitivity allows quicker detection at longer distances but may react to non-vehicle objects; lower sensitivity is more conservative and reduces false detections."), ""}, {"TacoTune", tr("\"Taco Bell Run\" Turn Speed Hack"), tr("The turn-speed hack from comma's 2022 \"Taco Bell Run\". Designed to slow down for left and right turns."), ""}, diff --git a/starpilot/ui/qt/offroad/longitudinal_settings.h b/starpilot/ui/qt/offroad/longitudinal_settings.h index 86b280f8c..0ae714501 100644 --- a/starpilot/ui/qt/offroad/longitudinal_settings.h +++ b/starpilot/ui/qt/offroad/longitudinal_settings.h @@ -33,7 +33,7 @@ private: QSet conditionalExperimentalKeys = {"PersistExperimentalState", "CESpeed", "CESpeedLead", "CECurves", "CELead", "CEModelStopTime", "CESignalSpeed", "CEStopLights", "ShowCEMStatus"}; QSet curveSpeedKeys = {"CalibratedLateralAcceleration", "CalibrationProgress", "ResetCurveData", "ShowCSCStatus"}; QSet customDrivingPersonalityKeys = {"AggressivePersonalityProfile", "RelaxedPersonalityProfile", "StandardPersonalityProfile", "TrafficPersonalityProfile"}; - QSet longitudinalTuneKeys = {"AccelerationProfile", "DecelerationProfile", "HumanAcceleration", "HumanFollowing", "HumanLaneChanges", "LeadDetectionThreshold", "TacoTune"}; + QSet longitudinalTuneKeys = {"AccelerationProfile", "DecelerationProfile", "HumanAcceleration", "HumanFollowing", "CoastUpToLeads", "HumanLaneChanges", "LeadDetectionThreshold", "TacoTune"}; QSet qolKeys = {"CustomCruise", "CustomCruiseLong", "ForceStops", "ForceStandstill", "IncreasedStoppedDistance", "MapGears", "ReverseCruise", "SetSpeedOffset", "WeatherPresets"}; QSet relaxedPersonalityKeys = {"RelaxedFollow", "RelaxedFollowHigh", "RelaxedJerkAcceleration", "RelaxedJerkDeceleration", "RelaxedJerkDanger", "RelaxedJerkSpeed", "RelaxedJerkSpeedDecrease", "ResetRelaxedPersonality"}; QSet speedLimitControllerKeys = {"SLCOffsets", "SLCFallback", "SLCOverride", "SLCPriority", "SLCQOL", "SLCVisuals"}; diff --git a/system/camerad/camerad b/system/camerad/camerad index cf748cd03..e93d50b46 100755 Binary files a/system/camerad/camerad and b/system/camerad/camerad differ diff --git a/system/loggerd/bootlog b/system/loggerd/bootlog index ab9faa056..91869ab60 100755 Binary files a/system/loggerd/bootlog and b/system/loggerd/bootlog differ diff --git a/system/loggerd/encoderd b/system/loggerd/encoderd index e480adb11..191dd7b3d 100755 Binary files a/system/loggerd/encoderd and b/system/loggerd/encoderd differ diff --git a/system/loggerd/loggerd b/system/loggerd/loggerd index 52b3947f2..bfcf7dffd 100755 Binary files a/system/loggerd/loggerd and b/system/loggerd/loggerd differ diff --git a/system/manager/manager.py b/system/manager/manager.py index 5d0f4f98f..f324dd7bc 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -36,6 +36,7 @@ LEGACY_BOLT_FP_MIGRATION_FLAG = Path("/data") / "legacy_bolt_fp_migration_v1" STARPILOT_DEFAULTS_PARITY_MIGRATION_FLAG = Path("/data") / "starpilot_defaults_parity_v1" STARPILOT_HUMANLIKE_DISABLE_MIGRATION_FLAG = Path("/data") / "starpilot_humanlike_disable_v1" STARPILOT_CLUSTER_OFFSET_MIGRATION_FLAG = Path("/data") / "starpilot_cluster_offset_v1" +STARPILOT_COAST_UP_TO_LEADS_MIGRATION_FLAG = Path("/data") / "starpilot_coast_up_to_leads_v1" STARPILOT_PARAM_RENAME_MIGRATION_FLAG = Path("/data") / "starpilot_param_rename_v1" STARPILOT_PARAM_CANONICALIZATION_MIGRATION_FLAG = Path("/data") / "starpilot_param_canonicalization_v1" STARPILOT_PC_ROOT_MIGRATION_FLAG = Path("/data") / "starpilot_pc_root_v1" @@ -433,6 +434,22 @@ def migrate_cluster_offset_default(params: Params, params_cache: Params) -> None cloudlog.exception(f"Failed to write migration flag: {STARPILOT_CLUSTER_OFFSET_MIGRATION_FLAG}") +def migrate_coast_up_to_leads_default(params: Params, params_cache: Params) -> None: + if STARPILOT_COAST_UP_TO_LEADS_MIGRATION_FLAG.exists(): + return + + if not _has_persisted_param_file(params, "CoastUpToLeads") and not _has_persisted_param_file(params_cache, "CoastUpToLeads"): + params.put_bool("CoastUpToLeads", True) + params_cache.put_bool("CoastUpToLeads", True) + cloudlog.warning("Seeded CoastUpToLeads to default enabled") + + try: + STARPILOT_COAST_UP_TO_LEADS_MIGRATION_FLAG.parent.mkdir(parents=True, exist_ok=True) + STARPILOT_COAST_UP_TO_LEADS_MIGRATION_FLAG.write_text(f"{datetime.datetime.now(datetime.UTC).isoformat()}\n") + except Exception: + cloudlog.exception(f"Failed to write migration flag: {STARPILOT_COAST_UP_TO_LEADS_MIGRATION_FLAG}") + + def _read_raw_param_bytes(params: Params, key: str | bytes): try: path = params.get_param_path(key) @@ -601,6 +618,7 @@ def manager_init() -> None: migrate_starpilot_default_parity(params, params_cache) migrate_disable_humanlike_defaults(params, params_cache) migrate_cluster_offset_default(params, params_cache) + migrate_coast_up_to_leads_default(params, params_cache) # set unset params to their default value for k in params.all_keys(): diff --git a/system/manager/test/test_manager.py b/system/manager/test/test_manager.py index dc199315e..202d9f1f4 100644 --- a/system/manager/test/test_manager.py +++ b/system/manager/test/test_manager.py @@ -217,6 +217,29 @@ class TestManager: assert params.get("ClusterOffset") == "1.02" assert params_cache.get("ClusterOffset") is None + def test_migrate_coast_up_to_leads_default_seeds_enabled(self, tmp_path, monkeypatch): + monkeypatch.setattr(manager, "STARPILOT_COAST_UP_TO_LEADS_MIGRATION_FLAG", tmp_path / "starpilot_coast_up_to_leads_v1") + + params = FileBackedFakeParams(tmp_path / "params", {}) + params_cache = FileBackedFakeParams(tmp_path / "cache", {}) + + manager.migrate_coast_up_to_leads_default(params, params_cache) + + assert params.get_bool("CoastUpToLeads") + assert params_cache.get_bool("CoastUpToLeads") + + def test_migrate_coast_up_to_leads_default_preserves_existing_values(self, tmp_path, monkeypatch): + monkeypatch.setattr(manager, "STARPILOT_COAST_UP_TO_LEADS_MIGRATION_FLAG", tmp_path / "starpilot_coast_up_to_leads_v1") + + params = FileBackedFakeParams(tmp_path / "params", { + "CoastUpToLeads": False, + }) + params_cache = FileBackedFakeParams(tmp_path / "cache", {}) + + manager.migrate_coast_up_to_leads_default(params, params_cache) + + assert not params.get_bool("CoastUpToLeads") + @pytest.mark.skip("this test is flaky the way it's currently written, should be moved to test_onroad") def test_clean_exit(self, subtests): """