Prioritize Smooth Follow

This commit is contained in:
firestar5683
2026-06-08 19:15:50 -05:00
parent 796d081fce
commit 88c259a666
14 changed files with 129 additions and 49 deletions
+1
View File
@@ -335,6 +335,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"HolidayThemes", {PERSISTENT, BOOL, "1", "0", 0}},
{"HumanAcceleration", {PERSISTENT, BOOL, "0", "0", 2}},
{"CoastUpToLeads", {PERSISTENT, BOOL, "1", "1", 2}},
{"PrioritizeSmoothFollowing", {PERSISTENT, BOOL, "0", "0", 2}},
{"HumanLaneChanges", {PERSISTENT, BOOL, "0", "0", 2}},
{"IconPack", {PERSISTENT, STRING, "stock", "stock", 0}},
{"IconToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
+11 -9
View File
@@ -1886,8 +1886,11 @@ class LongitudinalPlanner:
uncert_slope > UNCERT_SLOPE_TRIG or uncertainty >= UNCERT_MAG_TRIG
)
prioritize_smooth_following = bool(getattr(starpilot_toggles, "prioritize_smooth_following", False))
allow_complex_follow_logic = not prioritize_smooth_following
steady_follow_filter_floor = 0.0
if lead_one_active and desired_gap is not None and not panic_bypass:
if allow_complex_follow_logic and lead_one_active and desired_gap is not None and not panic_bypass:
lead_brake = max(0.0, -float(getattr(self.lead_one, "aLeadK", 0.0)))
lead_radar = bool(getattr(self.lead_one, "radar", False))
lead_prob = float(getattr(self.lead_one, "modelProb", 1.0 if lead_radar else 0.0))
@@ -1945,11 +1948,10 @@ class LongitudinalPlanner:
dec_mpc_mode = self.get_mpc_mode()
if not self.mlsim:
self.mpc.mode = dec_mpc_mode
optional_far_lead_comfort = getattr(starpilot_toggles, "coast_up_to_leads", True)
self.mpc.update(sm['radarState'], v_cruise, x, v, a, j,
sm['starpilotPlan'].dangerFactor, effective_t_follow,
personality=personality, tracking_lead=lead_control_active,
optional_far_lead_comfort=optional_far_lead_comfort)
optional_far_lead_comfort=allow_complex_follow_logic)
self.a_desired_trajectory_full = np.interp(CONTROL_N_T_IDX, T_IDXS_MPC, self.mpc.a_solution)
self.v_desired_trajectory = np.interp(CONTROL_N_T_IDX, T_IDXS_MPC, self.mpc.v_solution)
@@ -1975,7 +1977,7 @@ class LongitudinalPlanner:
self.v_desired_filter.x = self.v_desired_filter.x + self.dt * (self.a_desired + a_prev) / 2.0
# Anticipatory pre-brake to avoid "coming in hot" when closing on a lead
if lead_one_active:
if allow_complex_follow_logic and lead_one_active:
rel_v = max(0.0, v_ego - self.lead_one.vLead)
# dynamic time headway adds a small buffer when uncertainty is elevated
base_th = max(1.6, effective_t_follow)
@@ -2244,7 +2246,7 @@ class LongitudinalPlanner:
lead_control_active,
scene_v_ego,
effective_t_follow,
allow_optional_far_lead_logic=optional_far_lead_comfort,
allow_optional_far_lead_logic=allow_complex_follow_logic,
)
if follow_control_lead is not None and not panic_bypass:
if not output_should_stop and not vision_low_speed_stop_active:
@@ -2259,7 +2261,7 @@ class LongitudinalPlanner:
self.a_desired = min(self.a_desired, tracked_vision_model_brake_floor)
output_a_target = min(output_a_target, tracked_vision_model_brake_floor)
if optional_far_lead_comfort:
if allow_complex_follow_logic:
matched_follow_brake_cap = self.get_matched_follow_brake_cap(follow_control_lead, scene_v_ego, effective_t_follow)
if matched_follow_brake_cap is not None:
self.a_desired = max(self.a_desired, matched_follow_brake_cap)
@@ -2278,7 +2280,7 @@ class LongitudinalPlanner:
output_a_target = max(output_a_target, low_speed_transition_brake_cap)
comfort_lead = self.lead_two if self.mpc.source == 'lead1' and self.lead_two.status else self.lead_one
if optional_far_lead_comfort and comfort_lead is not None and not panic_bypass:
if allow_complex_follow_logic and comfort_lead is not None and not panic_bypass:
far_lead_brake_cap = self.get_far_lead_brake_cap(comfort_lead, scene_v_ego, effective_t_follow)
if far_lead_brake_cap is not None:
self.a_desired = max(self.a_desired, far_lead_brake_cap)
@@ -2295,7 +2297,7 @@ class LongitudinalPlanner:
self.a_desired = max(self.a_desired, tracked_vision_model_brake_cap)
output_a_target = max(output_a_target, tracked_vision_model_brake_cap)
if optional_far_lead_comfort and follow_control_lead is not None and not panic_bypass and not output_should_stop and not vision_low_speed_stop_active:
if allow_complex_follow_logic and follow_control_lead is not None and not panic_bypass and not output_should_stop and not vision_low_speed_stop_active:
matched_follow_transition_target = self.get_matched_follow_transition_target(
follow_control_lead,
scene_v_ego,
@@ -2312,7 +2314,7 @@ class LongitudinalPlanner:
self.a_desired = max(self.a_desired, matched_follow_transition_target)
output_a_target = matched_follow_transition_target
if optional_far_lead_comfort and comfort_lead is not None and not panic_bypass and not output_should_stop and not vision_low_speed_stop_active:
if allow_complex_follow_logic and comfort_lead is not None and not panic_bypass and not output_should_stop and not vision_low_speed_stop_active:
near_duplicate_transition_target = self.get_near_duplicate_lead_transition_target(
comfort_lead,
scene_v_ego,
@@ -117,3 +117,44 @@ def test_lateral_resume_delay_ignores_signal_cycles_that_never_slow_enough(monke
assert planner.blinker_delay_active is False
finally:
planner.shutdown()
def test_prioritize_smooth_following_skips_radarless_follow_hold(monkeypatch):
planner = StarPilotPlanner(Path("/tmp/nonexistent"), DummyThemeManager())
try:
monkeypatch.setattr(starpilot_planner_module.time, "monotonic", lambda: 100.0)
planner.model_length = 30.0
planner.tracking_lead = True
planner.starpilot_following.t_follow = 1.45
planner.lead_one = SimpleNamespace(
status=True,
dRel=46.0,
vLead=27.0,
aLeadK=0.0,
modelProb=0.98,
radar=False,
)
planner.update_lead_status(27.5, stop_distance=6.0, prioritize_smooth_following=False)
assert planner.radarless_follow_hold_until > 100.0
planner_smooth = StarPilotPlanner(Path("/tmp/nonexistent"), DummyThemeManager())
planner_smooth.model_length = 30.0
planner_smooth.tracking_lead = True
planner_smooth.starpilot_following.t_follow = 1.45
planner_smooth.lead_one = SimpleNamespace(
status=True,
dRel=46.0,
vLead=27.0,
aLeadK=0.0,
modelProb=0.98,
radar=False,
)
planner_smooth.update_lead_status(27.5, stop_distance=6.0, prioritize_smooth_following=True)
assert planner_smooth.radarless_follow_hold_until == 0.0
finally:
planner.shutdown()
if 'planner_smooth' in locals():
planner_smooth.shutdown()
@@ -351,10 +351,10 @@ class StarPilotLongitudinalTuneLayout(_SettingsPage):
visible=self._longitudinal_enabled),
]),
SettingSection(tr_noop("Human-Like Driving"), [
SettingRow("CoastUpToLeads", "toggle", tr_noop("Coast Up To Leads"),
subtitle=tr_noop("Keep optional far-lead comfort logic on. Recommended unless your car shows lead-follow stutter or springy gas/brake behavior."),
get_state=lambda: self._params.get_bool("CoastUpToLeads"),
set_state=lambda s: self._params.put_bool("CoastUpToLeads", s),
SettingRow("PrioritizeSmoothFollowing", "toggle", tr_noop("Prioritize Smooth Following"),
subtitle=tr_noop("Disables the newer far-lead follow logic on cars that show lead-follow stutter. Tradeoff: it may react later in some edge-case lead stops."),
get_state=lambda: self._params.get_bool("PrioritizeSmoothFollowing"),
set_state=lambda s: self._params.put_bool("PrioritizeSmoothFollowing", s),
visible=self._longitudinal_enabled),
], column_pair="human_driving"),
SettingSection(tr_noop("Lane Changes"), [
+1 -1
View File
@@ -71,7 +71,7 @@ SAFE_MODE_MANAGED_KEYS = (
"AccelerationProfile",
"DecelerationProfile",
"HumanAcceleration",
"CoastUpToLeads",
"PrioritizeSmoothFollowing",
"HumanLaneChanges",
"LeadDetectionThreshold",
"RecoveryPower",
+7 -3
View File
@@ -1083,9 +1083,13 @@ class StarPilotVariables:
else:
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.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.prioritize_smooth_following = self.get_value("PrioritizeSmoothFollowing", condition=longitudinal_tuning)
if longitudinal_tuning and self.params_raw.get("PrioritizeSmoothFollowing") is None:
legacy_coast_value = self.params_raw.get("CoastUpToLeads")
if legacy_coast_value is not None:
toggle.prioritize_smooth_following = not self.params_raw.get_bool("CoastUpToLeads")
else:
toggle.prioritize_smooth_following = False
toggle.human_lane_changes = has_radar and self.get_value("HumanLaneChanges", condition=longitudinal_tuning)
toggle.nav_longitudinal_allowed = toggle.openpilot_longitudinal and self.get_value("NavLongitudinalAllowed", condition=longitudinal_tuning)
# Keep lead detection sensitivity normalized even when longitudinal tuning is disabled.
@@ -84,8 +84,9 @@ class StarPilotFollowing:
if self.starpilot_planner.starpilot_weather.weather_id != 0:
self.t_follow = min(self.t_follow + self.starpilot_planner.starpilot_weather.increase_following_distance, MAX_T_FOLLOW)
prioritize_smooth_following = bool(getattr(starpilot_toggles, "prioritize_smooth_following", False))
self.disable_throttle = False
if getattr(starpilot_toggles, "coast_up_to_leads", True) and self.starpilot_planner.tracking_lead and self.starpilot_planner.lead_one.status:
if not prioritize_smooth_following 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)
+9 -5
View File
@@ -192,7 +192,11 @@ class StarPilotPlanner:
self.road_curvature_detected = (1 / abs(self.road_curvature))**0.5 < v_ego > CRUISING_SPEED and not (sm["carState"].leftBlinker or sm["carState"].rightBlinker)
if not sm["carState"].standstill:
self.tracking_lead = self.update_lead_status(v_ego, starpilot_toggles.stop_distance)
self.tracking_lead = self.update_lead_status(
v_ego,
starpilot_toggles.stop_distance,
prioritize_smooth_following=bool(getattr(starpilot_toggles, "prioritize_smooth_following", False)),
)
self.starpilot_following.update(controls_enabled, v_ego, sm, starpilot_toggles)
@@ -219,7 +223,7 @@ class StarPilotPlanner:
else:
self.starpilot_weather.weather_id = 0
def update_lead_status(self, v_ego, stop_distance=STOP_DISTANCE):
def update_lead_status(self, v_ego, stop_distance=STOP_DISTANCE, prioritize_smooth_following=False):
following_lead = should_track_lead(
self.lead_one.status,
self.lead_one.dRel,
@@ -241,12 +245,12 @@ class StarPilotPlanner:
lead_brake=max(0.0, -float(getattr(self.lead_one, "aLeadK", 0.0))),
lead_prob=float(getattr(self.lead_one, "modelProb", 0.0)),
)
if matched_follow_window and (following_lead or self.tracking_lead or self.tracking_lead_filter.x >= THRESHOLD * 0.6):
if not prioritize_smooth_following and matched_follow_window and (following_lead or self.tracking_lead or self.tracking_lead_filter.x >= THRESHOLD * 0.6):
self.radarless_follow_hold_until = now_t + RADARLESS_TRACK_HOLD_TIME
elif lead_radar or not self.lead_one.status:
elif prioritize_smooth_following or lead_radar or not self.lead_one.status:
self.radarless_follow_hold_until = 0.0
if not following_lead and matched_follow_window and now_t < self.radarless_follow_hold_until:
if not prioritize_smooth_following and not following_lead and matched_follow_window and now_t < self.radarless_follow_hold_until:
following_lead = True
self.tracking_lead_filter.update(following_lead)
@@ -1001,9 +1001,9 @@
"parent_key": "LongitudinalTune"
},
{
"key": "CoastUpToLeads",
"label": "Coast Up To Leads",
"description": "Keep the optional far-lead comfort logic enabled, including gentle coasting and matched-follow smoothing for distant leads. Recommended to leave on unless your vehicle shows lead-follow stutter or springy gas/brake behavior.",
"key": "PrioritizeSmoothFollowing",
"label": "Prioritize Smooth Following",
"description": "Disable the newer far-lead follow logic on cars that show lead-follow stutter or springy gas/brake behavior. Tradeoff: the car may react later and brake less proactively in some edge-case lead approaches.",
"data_type": "bool",
"ui_type": "toggle",
"parent_key": "LongitudinalTune"
@@ -158,7 +158,7 @@ StarPilotLongitudinalPanel::StarPilotLongitudinalPanel(StarPilotSettingsWindow *
{"AccelerationProfile", tr("Acceleration Profile"), tr("<b>How quickly openpilot speeds up.</b> \"Eco\" is gentle and efficient, \"Sport\" is firmer and more responsive, and \"Sport+\" accelerates at the maximum rate allowed."), ""},
{"DecelerationProfile", tr("Deceleration Profile"), tr("<b>How firmly openpilot slows down.</b> \"Eco\" favors coasting, \"Sport\" applies stronger braking."), ""},
{"HumanAcceleration", tr("Human-Like Acceleration"), tr("<b>Acceleration that mimics human behavior</b> by easing the throttle at low speeds and adding extra power when taking off from a stop."), ""},
{"CoastUpToLeads", tr("Coast Up To Leads"), tr("<b>Keep the optional far-lead comfort logic enabled, including gentle coasting and matched-follow smoothing for distant leads.</b> Recommended to leave on unless your vehicle shows lead-follow stutter or springy gas/brake behavior."), ""},
{"PrioritizeSmoothFollowing", tr("Prioritize Smooth Following"), tr("<b>Disable the newer far-lead follow logic that can cause springy gas/brake behavior on some cars.</b> Enable this if your vehicle shows lead-follow stutter or oscillation.<br><br><i>Tradeoff: the car may react later and brake less proactively in some edge-case lead approaches.</i>"), ""},
{"HumanLaneChanges", tr("Human-Like Lane Changes"), tr("<b>Lane-change behavior that mimics human drivers</b> by anticipating and tracking adjacent vehicles during lane changes."), ""},
{"LeadDetectionThreshold", tr("Lead Detection Sensitivity"), tr("<b>How sensitive openpilot is to detecting vehicles.</b> 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("<b>The turn-speed hack from comma's 2022 \"Taco Bell Run\".</b> Designed to slow down for left and right turns."), ""},
@@ -34,7 +34,7 @@ private:
QSet<QString> conditionalExperimentalKeys = {"PersistExperimentalState", "CESpeed", "CESpeedLead", "CECurves", "CELead", "CEModelStopTime", "CESignalSpeed", "CEStopLights", "ShowCEMStatus"};
QSet<QString> curveSpeedKeys = {"CalibratedLateralAcceleration", "CalibrationProgress", "ResetCurveData", "ShowCSCStatus"};
QSet<QString> customDrivingPersonalityKeys = {"AggressivePersonalityProfile", "RelaxedPersonalityProfile", "StandardPersonalityProfile", "TrafficPersonalityProfile"};
QSet<QString> longitudinalTuneKeys = {"AccelerationProfile", "DecelerationProfile", "HumanAcceleration", "CoastUpToLeads", "HumanLaneChanges", "LeadDetectionThreshold", "TacoTune", "NavLongitudinalAllowed"};
QSet<QString> longitudinalTuneKeys = {"AccelerationProfile", "DecelerationProfile", "HumanAcceleration", "PrioritizeSmoothFollowing", "HumanLaneChanges", "LeadDetectionThreshold", "TacoTune", "NavLongitudinalAllowed"};
QSet<QString> qolKeys = {"CustomCruise", "CustomCruiseLong", "ForceStops", "ForceStopDistanceOffset", "ForceStandstill", "RadarTakeoffs", "IncreasedStoppedDistance", "MapGears", "ReverseCruise", "SetSpeedOffset", "WeatherPresets"};
QSet<QString> relaxedPersonalityKeys = {"RelaxedFollow", "RelaxedFollowHigh", "RelaxedJerkAcceleration", "RelaxedJerkDeceleration", "RelaxedJerkDanger", "RelaxedJerkSpeed", "RelaxedJerkSpeedDecrease", "ResetRelaxedPersonality"};
QSet<QString> speedLimitControllerKeys = {"SLCOffsets", "SLCFallback", "SLCOverride", "SLCPriority", "SLCQOL", "SLCVisuals"};
+24 -11
View File
@@ -36,7 +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_PRIORITIZE_SMOOTH_FOLLOWING_MIGRATION_FLAG = Path("/data") / "starpilot_prioritize_smooth_following_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"
@@ -463,20 +463,33 @@ 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():
def migrate_prioritize_smooth_following_default(params: Params, params_cache: Params) -> None:
if STARPILOT_PRIORITIZE_SMOOTH_FOLLOWING_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")
if not (_has_persisted_param_file(params, "PrioritizeSmoothFollowing") or _has_persisted_param_file(params_cache, "PrioritizeSmoothFollowing")):
migrated_from_legacy = False
for params_obj in (params, params_cache):
if not _has_persisted_param_file(params_obj, "CoastUpToLeads"):
continue
prioritize_smooth_following = not params_obj.get_bool("CoastUpToLeads")
params.put_bool("PrioritizeSmoothFollowing", prioritize_smooth_following)
params_cache.put_bool("PrioritizeSmoothFollowing", prioritize_smooth_following)
cloudlog.warning(f"Migrated CoastUpToLeads to PrioritizeSmoothFollowing={int(prioritize_smooth_following)}")
migrated_from_legacy = True
break
if not migrated_from_legacy:
params.put_bool("PrioritizeSmoothFollowing", False)
params_cache.put_bool("PrioritizeSmoothFollowing", False)
cloudlog.warning("Seeded PrioritizeSmoothFollowing to default disabled")
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")
STARPILOT_PRIORITIZE_SMOOTH_FOLLOWING_MIGRATION_FLAG.parent.mkdir(parents=True, exist_ok=True)
STARPILOT_PRIORITIZE_SMOOTH_FOLLOWING_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}")
cloudlog.exception(f"Failed to write migration flag: {STARPILOT_PRIORITIZE_SMOOTH_FOLLOWING_MIGRATION_FLAG}")
def _read_raw_param_bytes(params: Params, key: str | bytes):
@@ -648,7 +661,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)
migrate_prioritize_smooth_following_default(params, params_cache)
# set unset params to their default value
for k in params.all_keys():
+23 -9
View File
@@ -224,28 +224,42 @@ 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")
def test_migrate_prioritize_smooth_following_default_seeds_disabled(self, tmp_path, monkeypatch):
monkeypatch.setattr(manager, "STARPILOT_PRIORITIZE_SMOOTH_FOLLOWING_MIGRATION_FLAG", tmp_path / "starpilot_prioritize_smooth_following_v1")
params = FileBackedFakeParams(tmp_path / "params", {})
params_cache = FileBackedFakeParams(tmp_path / "cache", {})
manager.migrate_coast_up_to_leads_default(params, params_cache)
manager.migrate_prioritize_smooth_following_default(params, params_cache)
assert params.get_bool("CoastUpToLeads")
assert params_cache.get_bool("CoastUpToLeads")
assert not params.get_bool("PrioritizeSmoothFollowing")
assert not params_cache.get_bool("PrioritizeSmoothFollowing")
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")
def test_migrate_prioritize_smooth_following_default_inverts_legacy_coast_toggle(self, tmp_path, monkeypatch):
monkeypatch.setattr(manager, "STARPILOT_PRIORITIZE_SMOOTH_FOLLOWING_MIGRATION_FLAG", tmp_path / "starpilot_prioritize_smooth_following_v1")
params = FileBackedFakeParams(tmp_path / "params", {
"CoastUpToLeads": False,
})
params_cache = FileBackedFakeParams(tmp_path / "cache", {})
manager.migrate_coast_up_to_leads_default(params, params_cache)
manager.migrate_prioritize_smooth_following_default(params, params_cache)
assert not params.get_bool("CoastUpToLeads")
assert params.get_bool("PrioritizeSmoothFollowing")
assert params_cache.get_bool("PrioritizeSmoothFollowing")
def test_migrate_prioritize_smooth_following_default_preserves_existing_values(self, tmp_path, monkeypatch):
monkeypatch.setattr(manager, "STARPILOT_PRIORITIZE_SMOOTH_FOLLOWING_MIGRATION_FLAG", tmp_path / "starpilot_prioritize_smooth_following_v1")
params = FileBackedFakeParams(tmp_path / "params", {
"PrioritizeSmoothFollowing": True,
"CoastUpToLeads": True,
})
params_cache = FileBackedFakeParams(tmp_path / "cache", {})
manager.migrate_prioritize_smooth_following_default(params, params_cache)
assert params.get_bool("PrioritizeSmoothFollowing")
@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):
+1 -1
View File
@@ -57,11 +57,11 @@ CalibrationParams
CalibrationProgress
CameraView
CancelButtonControl
CoastUpToLeads
ColorScheme
CommunityFavorites
ConditionalChill
ConditionalExperimental
PrioritizeSmoothFollowing
CurveSpeedController
CustomAlerts
CustomCruise