diff --git a/docs/CARS.md b/docs/CARS.md index b06ceefefa..be4528f311 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -254,7 +254,7 @@ A supported vehicle is one that just works when you install a comma device. All |Škoda|Scala 2020-23[13](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,14](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma four
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
[15](#footnotes)||| |Škoda|Superb 2015-22[13](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,14](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma four
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| |Tesla[9](#footnotes)|Model 3 (with HW3) 2019-23[8](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Tesla A connector
- 1 USB-C coupler
- 1 comma four
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| -|Tesla[9](#footnotes)|Model 3 (with HW4) 2024-25[8](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Tesla B connector
- 1 USB-C coupler
- 1 comma four
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| +|Tesla[9](#footnotes)|Model 3 (with HW4) 2024-26[8](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Tesla B connector
- 1 USB-C coupler
- 1 comma four
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| |Tesla[9](#footnotes)|Model Y (with HW3) 2020-23[8](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Tesla A connector
- 1 USB-C coupler
- 1 comma four
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| |Tesla[9](#footnotes)|Model Y (with HW4) 2024-25[8](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Tesla B connector
- 1 USB-C coupler
- 1 comma four
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| |Toyota|Alphard 2019-20|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Toyota A connector
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
||| diff --git a/opendbc_repo/opendbc/car/gm/values.py b/opendbc_repo/opendbc/car/gm/values.py index 264896de3d..2f03517a83 100644 --- a/opendbc_repo/opendbc/car/gm/values.py +++ b/opendbc_repo/opendbc/car/gm/values.py @@ -313,16 +313,16 @@ class CAR(Platforms): ) CHEVROLET_BOLT_ACC_2022_2023 = GMPlatformConfig( [ - GMCarDocs("Chevrolet Bolt ACC 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video="https://youtu.be/xvwzGMUA210"), + GMCarDocs("Chevrolet Bolt EV & EUV ACC 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video="https://youtu.be/xvwzGMUA210"), ], GMCarSpecs(mass=1669, wheelbase=2.63779, steerRatio=16.8, centerToFrontRatio=0.4, tireStiffnessFactor=1.0), ) CHEVROLET_BOLT_ACC_2022_2023_PEDAL = GMPlatformConfig( - [GMCarDocs("Chevrolet Bolt EV ACC w Pedal 2022-23")], + [GMCarDocs("Chevrolet Bolt EV & EUV ACC w Pedal 2022-23")], CHEVROLET_BOLT_ACC_2022_2023.specs, ) CHEVROLET_BOLT_CC_2022_2023 = GMPlatformConfig( - [GMCarDocs("Chevrolet Bolt EV No-ACC 2022-23")], + [GMCarDocs("Chevrolet Bolt EV & EUV No-ACC 2022-23")], CHEVROLET_BOLT_ACC_2022_2023.specs, ) CHEVROLET_BOLT_CC_2018_2021 = GMPlatformConfig( diff --git a/opendbc_repo/opendbc/car/tesla/values.py b/opendbc_repo/opendbc/car/tesla/values.py index a696e31bcc..dbd045c437 100644 --- a/opendbc_repo/opendbc/car/tesla/values.py +++ b/opendbc_repo/opendbc/car/tesla/values.py @@ -45,7 +45,7 @@ class CAR(Platforms): [ # TODO: do we support 2017? It's HW3 TeslaCarDocsHW3("Tesla Model 3 (with HW3) 2019-23"), - TeslaCarDocsHW4("Tesla Model 3 (with HW4) 2024-25"), + TeslaCarDocsHW4("Tesla Model 3 (with HW4) 2024-26"), ], CarSpecs(mass=1899., wheelbase=2.875, steerRatio=12.0), ) diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index 74affd1752..f5a2fc4df5 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -88,6 +88,7 @@ class LatControlTorque(LatControl): self.is_genesis_gv70 = CP.carFingerprint in GENESIS_GV70_CARS self.is_palisade = CP.carFingerprint in PALISADE_CARS self.is_prius = CP.carFingerprint in PRIUS_CARS + self.is_camry = CP.carFingerprint in CAMRY_CARS self.is_rav4_prime = CP.carFingerprint in RAV4_PRIME_CARS self.is_sienna_4th_gen = CP.carFingerprint in SIENNA_4TH_GEN_CARS self.is_lexus_is = CP.carFingerprint in LEXUS_IS_CARS @@ -257,6 +258,7 @@ class LatControlTorque(LatControl): genesis_g90_test_active = self.is_genesis_g90 and genesis_g90_lateral_testing_ground_active() palisade_active = self.is_palisade prius_active = self.is_prius + camry_active = self.is_camry rav4_prime_active = self.is_rav4_prime sienna_4th_gen_active = self.is_sienna_4th_gen lexus_is_active = self.is_lexus_is @@ -328,6 +330,8 @@ class LatControlTorque(LatControl): friction_threshold = get_prius_friction_threshold(CS.vEgo, setpoint, desired_lateral_jerk) friction_scale = get_prius_friction_scale(CS.vEgo, setpoint, desired_lateral_jerk) friction_scale = 1.0 + ((friction_scale - 1.0) * prius_center_taper) + elif camry_active: + friction_threshold = get_camry_friction_threshold(CS.vEgo, setpoint, desired_lateral_jerk) elif rav4_prime_active: ff *= get_rav4_prime_ff_scale(setpoint, desired_lateral_jerk, CS.vEgo) friction_threshold = get_rav4_prime_friction_threshold(CS.vEgo, setpoint, desired_lateral_jerk) diff --git a/selfdrive/controls/lib/latcontrol_vehicle_tunes.py b/selfdrive/controls/lib/latcontrol_vehicle_tunes.py index 3b1f245afd..be65d996de 100644 --- a/selfdrive/controls/lib/latcontrol_vehicle_tunes.py +++ b/selfdrive/controls/lib/latcontrol_vehicle_tunes.py @@ -144,6 +144,10 @@ PRIUS_CARS = ( TOYOTA_CAR.TOYOTA_PRIUS, ) +CAMRY_CARS = ( + TOYOTA_CAR.TOYOTA_CAMRY, +) + RAV4_PRIME_CARS = ( TOYOTA_CAR.TOYOTA_RAV4_PRIME, ) @@ -805,6 +809,12 @@ PRIUS_CENTER_FRICTION_THRESHOLD_LAT_WIDTH = 0.07 PRIUS_CENTER_FRICTION_THRESHOLD_SPEED = 18.0 PRIUS_CENTER_FRICTION_THRESHOLD_SPEED_WIDTH = 2.2 +CAMRY_CENTER_FRICTION_THRESHOLD_GAIN = 0.06 +CAMRY_CENTER_FRICTION_THRESHOLD_LAT = 0.22 +CAMRY_CENTER_FRICTION_THRESHOLD_LAT_WIDTH = 0.06 +CAMRY_CENTER_FRICTION_THRESHOLD_SPEED = 25.0 +CAMRY_CENTER_FRICTION_THRESHOLD_SPEED_WIDTH = 3.0 + RAV4_PRIME_PHASE_SCALE = 0.12 RAV4_PRIME_TURN_IN_FF_BOOST_LEFT = 0.055 RAV4_PRIME_TURN_IN_FF_BOOST_RIGHT = 0.040 @@ -1155,6 +1165,18 @@ def get_prius_center_taper_scale(desired_lateral_accel: float, v_ego: float) -> return 1.0 - reduction +def get_camry_friction_threshold(v_ego: float, desired_lateral_accel: float = 0.0, + desired_lateral_jerk: float = 0.0) -> float: + del desired_lateral_jerk + speed_weight = _sigmoid((v_ego - CAMRY_CENTER_FRICTION_THRESHOLD_SPEED) / + CAMRY_CENTER_FRICTION_THRESHOLD_SPEED_WIDTH) + center_weight = _sigmoid((CAMRY_CENTER_FRICTION_THRESHOLD_LAT - abs(desired_lateral_accel)) / + CAMRY_CENTER_FRICTION_THRESHOLD_LAT_WIDTH) + gain = _flm_vehicle_knob("toyota_camry.center_friction_threshold_gain", + CAMRY_CENTER_FRICTION_THRESHOLD_GAIN) + return get_standard_friction_threshold(v_ego) * (1.0 + gain * speed_weight * center_weight) + + def _rav4_prime_side_value(desired_lateral_accel: float, left_value: float, right_value: float) -> float: return left_value if desired_lateral_accel >= 0.0 else right_value @@ -3179,6 +3201,7 @@ FLM_RICH_PROFILE_CARS = { "hyundai_ioniq_6": set(IONIQ_6_CARS), "hyundai_kia_ev6": set(KIA_EV6_CARS), "toyota_prius": set(PRIUS_CARS), + "toyota_camry": set(CAMRY_CARS), } FLM_RICH_PROFILE_LABELS = { @@ -3186,6 +3209,7 @@ FLM_RICH_PROFILE_LABELS = { "hyundai_ioniq_6": "Ioniq 6", "hyundai_kia_ev6": "EV6", "toyota_prius": "Prius", + "toyota_camry": "Camry", FLM_UNIVERSAL_PROFILE_KEY: "Torque Controller", } @@ -3251,6 +3275,7 @@ FLM_SUPPORTED_VEHICLE_KNOBS = { "toyota_prius.unwind_threshold_increase_left": {"profile": "toyota_prius", "min": 0.0, "max": 0.90, "precision": 0.001, "deltaType": "absolute", "safeLiveTrial": True, "defaultValue": PRIUS_UNWIND_THRESHOLD_INCREASE_LEFT}, "toyota_prius.unwind_threshold_increase_right": {"profile": "toyota_prius", "min": 0.0, "max": 0.90, "precision": 0.001, "deltaType": "absolute", "safeLiveTrial": True, "defaultValue": PRIUS_UNWIND_THRESHOLD_INCREASE_RIGHT}, "toyota_prius.center_friction_threshold_gain": {"profile": "toyota_prius", "min": 0.0, "max": 0.20, "precision": 0.001, "deltaType": "absolute", "safeLiveTrial": True, "defaultValue": PRIUS_CENTER_FRICTION_THRESHOLD_GAIN}, + "toyota_camry.center_friction_threshold_gain": {"profile": "toyota_camry", "min": 0.0, "max": 0.15, "precision": 0.001, "deltaType": "absolute", "safeLiveTrial": True, "defaultValue": CAMRY_CENTER_FRICTION_THRESHOLD_GAIN}, } @@ -3275,7 +3300,7 @@ def _add_flm_full_surface_profile_knobs(profile_key: str, defaults: dict[str, fl } -for _flm_profile_key in ("gm_bolt_2022_2023", "hyundai_ioniq_6", "hyundai_kia_ev6", "toyota_prius", FLM_UNIVERSAL_PROFILE_KEY): +for _flm_profile_key in ("gm_bolt_2022_2023", "hyundai_ioniq_6", "hyundai_kia_ev6", "toyota_prius", "toyota_camry", FLM_UNIVERSAL_PROFILE_KEY): _add_flm_full_surface_profile_knobs(_flm_profile_key) @@ -3309,7 +3334,7 @@ def get_flm_capabilities(car_fingerprint, brand: str = "", hyundai_canfd: bool = dedicated_friction = car_fingerprint in ( set(BOLT_2022_2023_CARS) | set(BOLT_2018_2021_CARS) | set(VOLT_STANDARD_CARS) | set(PALISADE_CARS) | set(PRIUS_CARS) | set(RAV4_PRIME_CARS) | set(SIENNA_4TH_GEN_CARS) | set(IONIQ_5_CARS) | set(IONIQ_6_CARS) | set(KIA_EV6_CARS) | set(KIA_FORTE_CARS) | - set(KIA_NIRO_PHEV_2022_CARS) | set(KIA_CARNIVAL_CARS) | set(GENESIS_G90_CARS) + set(KIA_NIRO_PHEV_2022_CARS) | set(KIA_CARNIVAL_CARS) | set(GENESIS_G90_CARS) | set(CAMRY_CARS) ) dedicated_center_taper = car_fingerprint in ( set(PRIUS_CARS) | set(SIENNA_4TH_GEN_CARS) | set(BOLT_CARS) | set(VOLT_STANDARD_CARS) | set(IONIQ_5_CARS) | diff --git a/selfdrive/controls/tests/test_latcontrol.py b/selfdrive/controls/tests/test_latcontrol.py index f21e16789b..c67361b827 100644 --- a/selfdrive/controls/tests/test_latcontrol.py +++ b/selfdrive/controls/tests/test_latcontrol.py @@ -68,6 +68,7 @@ from openpilot.selfdrive.controls.lib.latcontrol_torque import ( get_prius_ff_scale, get_prius_friction_scale, get_prius_friction_threshold, + get_camry_friction_threshold, get_rav4_prime_ff_scale, get_rav4_prime_friction_scale, get_rav4_prime_friction_threshold, @@ -658,6 +659,15 @@ class TestLatControl: assert right_turn_in_scale == left_turn_in_scale > base_scale assert base_scale > left_unwind_scale == right_unwind_scale + def test_camry_friction_threshold_only_fades_in_for_calm_high_speed(self): + low_speed_center = get_camry_friction_threshold(10.0, 0.0) + high_speed_center = get_camry_friction_threshold(32.0, 0.0) + high_speed_curve = get_camry_friction_threshold(32.0, 0.8) + + assert low_speed_center == pytest.approx(get_standard_friction_threshold(10.0), rel=0.01) + assert high_speed_center > get_standard_friction_threshold(32.0) + assert high_speed_curve < high_speed_center + def test_generic_friction_threshold_floor(self): assert get_standard_friction_threshold(0.0) == 0.30 assert get_standard_friction_threshold(6.0) == 0.30 diff --git a/selfdrive/ui/layouts/settings/starpilot/appearance.py b/selfdrive/ui/layouts/settings/starpilot/appearance.py index 04b7b94c8c..3d918b40d2 100644 --- a/selfdrive/ui/layouts/settings/starpilot/appearance.py +++ b/selfdrive/ui/layouts/settings/starpilot/appearance.py @@ -334,11 +334,6 @@ class StarPilotAppearanceLayout(_SettingsPage): subtitle="", get_state=lambda: self._params.get_bool("HideMaxSpeed"), set_state=lambda s: self._params.put_bool("HideMaxSpeed", s)), - SettingRow("HideSpeedLimit", "toggle", tr_noop("Hide Speed Limit"), - subtitle="", - get_state=lambda: self._params.get_bool("HideSpeedLimit"), - set_state=lambda s: self._params.put_bool("HideSpeedLimit", s), - visible=lambda: ol() and self._params.get_bool("SpeedLimitController")), SettingRow("HideAlerts", "toggle", tr_noop("Hide Alerts"), subtitle="", get_state=lambda: self._params.get_bool("HideAlerts"), @@ -384,16 +379,15 @@ class StarPilotAppearanceLayout(_SettingsPage): subtitle="", get_state=lambda: self._params.get_bool("RoadNameUI"), set_state=lambda s: self._params.put_bool("RoadNameUI", s)), - SettingRow("ShowSpeedLimits", "toggle", tr_noop("Speed Limits"), + SettingRow("ShowSpeedLimits", "toggle", tr_noop("Show Speed Limits"), subtitle="", get_state=lambda: self._params.get_bool("ShowSpeedLimits"), - set_state=lambda s: self._params.put_bool("ShowSpeedLimits", s), - visible=lambda: not (self._params.get_bool("SpeedLimitController") and ol())), + set_state=lambda s: self._params.put_bool("ShowSpeedLimits", s)), SettingRow("UseVienna", "toggle", tr_noop("Vienna Signs"), subtitle="", get_state=lambda: self._params.get_bool("UseVienna"), set_state=lambda s: self._params.put_bool("UseVienna", s), - visible=lambda: self._params.get_bool("ShowSpeedLimits") or self._params.get_bool("SpeedLimitController")), + visible=lambda: self._params.get_bool("ShowSpeedLimits")), SettingRow("QOLVisuals", "toggle", tr_noop("Quality of Life"), subtitle=tr_noop("Convenience features for everyday driving."), get_state=lambda: self._params.get_bool("QOLVisuals"), diff --git a/selfdrive/ui/mici/layouts/settings/visuals.py b/selfdrive/ui/mici/layouts/settings/visuals.py index 84f9edf6ef..d89d2a4d75 100644 --- a/selfdrive/ui/mici/layouts/settings/visuals.py +++ b/selfdrive/ui/mici/layouts/settings/visuals.py @@ -63,7 +63,7 @@ class VisualsLayoutMici(NavScroller): self._torque_bar_btn = BigParamControl("torque bar", "EnableTorqueBarWidget") self._rainbow_path_btn = BigParamControl("rainbow road", "RainbowPath") self._lead_indicator_btn = LeadIndicatorBigButton() - self._speed_limit_signs_btn = BigParamControl("speed limit signs", "ShowSpeedLimits") + self._speed_limit_signs_btn = BigParamControl("show speed limits", "ShowSpeedLimits") self._slc_confirmation_btn = BigParamControl("confirm new speed limits", "SLCConfirmation") self._slc_confirmation_lower_btn = BigParamControl("confirm lower limits", "SLCConfirmationLower") self._slc_confirmation_higher_btn = BigParamControl("confirm higher limits", "SLCConfirmationHigher") diff --git a/selfdrive/ui/mici/onroad/hud_renderer.py b/selfdrive/ui/mici/onroad/hud_renderer.py index d1912f120e..93934e155f 100644 --- a/selfdrive/ui/mici/onroad/hud_renderer.py +++ b/selfdrive/ui/mici/onroad/hud_renderer.py @@ -202,7 +202,7 @@ class HudRenderer(Widget): if sm.recv_frame["starpilotPlan"] >= ui_state.started_frame: starpilot_plan = sm["starpilotPlan"] - self._show_speed_limit = ui_state.params.get_bool("ShowSpeedLimits") or ui_state.params.get_bool("SpeedLimitController") + self._show_speed_limit = ui_state.params.get_bool("ShowSpeedLimits") if self._show_speed_limit: dashboard_speed_limit = sm["starpilotCarState"].dashboardSpeedLimit if sm.valid.get("starpilotCarState", False) else 0.0 vision_speed_limit = ui_state.params_memory.get_float("VisionSpeedLimit") if ui_state.params.get_bool("VisionSpeedLimitDetection") else 0.0 diff --git a/selfdrive/ui/onroad/starpilot/slc_speed_limit.py b/selfdrive/ui/onroad/starpilot/slc_speed_limit.py index ce5914f5e8..b2910d0281 100644 --- a/selfdrive/ui/onroad/starpilot/slc_speed_limit.py +++ b/selfdrive/ui/onroad/starpilot/slc_speed_limit.py @@ -124,13 +124,10 @@ def _get_slc_state(): speed_limit_changed = plan.speedLimitChanged params = ui_state.ui_params - show_slc = params.get_bool("ShowSpeedLimits") or params.get_bool("SpeedLimitController") - hide_sl = params.get_bool("HideSpeedLimit") + show_slc = params.get_bool("ShowSpeedLimits") unconfirmed_valid = plan.unconfirmedSlcSpeedLimit > 1 - # A pending (unconfirmed) limit overrides HideSpeedLimit so the prompt always shows. - hide = not (speed_limit_changed and unconfirmed_valid) and hide_sl - if not show_slc and not speed_limit_changed: + if not show_slc: _reset_pulse() return None @@ -170,7 +167,6 @@ def _get_slc_state(): 'unconfirmed_speed_limit': max(0.0, plan.unconfirmedSlcSpeedLimit * speed_conversion), 'unconfirmed_valid': unconfirmed_valid, 'speed_limit_changed': speed_limit_changed, - 'hide': hide, 'show_offset': show_offset, 'use_vienna': params.get_bool("UseVienna"), 'offset_str': offset_str, @@ -479,9 +475,6 @@ def render_speed_limit_at(state: dict, rect: rl.Rectangle, expanded: bool = Fals _draw_sign(state, rect, pending=True) return None - if state['hide']: - return None - _draw_sign(state, rect, pending=False) use_vienna = state['use_vienna'] diff --git a/selfdrive/ui/onroad/starpilot/widgets/speed_limit.py b/selfdrive/ui/onroad/starpilot/widgets/speed_limit.py index 63e28d2b55..8dcc0dc4da 100644 --- a/selfdrive/ui/onroad/starpilot/widgets/speed_limit.py +++ b/selfdrive/ui/onroad/starpilot/widgets/speed_limit.py @@ -22,8 +22,7 @@ class SpeedLimitWidget(LayoutWidget): if self._slc_state is None: self._pill_rect = None return False - flashing_pending = self._slc_state['speed_limit_changed'] and self._slc_state['unconfirmed_valid'] - return flashing_pending or not self._slc_state['hide'] + return True def get_size(self) -> tuple[float, float]: if self._slc_state is None: diff --git a/selfdrive/ui/tests/test_fingerprint_catalog.py b/selfdrive/ui/tests/test_fingerprint_catalog.py index bdce311641..2854e91bb2 100644 --- a/selfdrive/ui/tests/test_fingerprint_catalog.py +++ b/selfdrive/ui/tests/test_fingerprint_catalog.py @@ -5,7 +5,7 @@ def test_tesla_hardware_specific_docs_are_available_for_manual_fingerprinting(): tesla_models = _extract_fingerprint_models_for_make("tesla") assert ("TESLA_MODEL_3", "Tesla Model 3 (with HW3) 2019-23", "Tesla") in tesla_models - assert ("TESLA_MODEL_3", "Tesla Model 3 (with HW4) 2024-25", "Tesla") in tesla_models + assert ("TESLA_MODEL_3", "Tesla Model 3 (with HW4) 2024-26", "Tesla") in tesla_models assert ("TESLA_MODEL_Y", "Tesla Model Y (with HW3) 2020-23", "Tesla") in tesla_models assert ("TESLA_MODEL_X", "Tesla Model X (with HW4) 2024", "Tesla") in tesla_models @@ -16,5 +16,5 @@ def test_tesla_model_3_hardware_variants_remain_distinct_menu_options(): assert [option.label for option in model_3_options] == [ "Tesla Model 3 (with HW3) 2019-23", - "Tesla Model 3 (with HW4) 2024-25", + "Tesla Model 3 (with HW4) 2024-26", ] diff --git a/starpilot/system/the_galaxy/assets/components/tools/device_settings_layout.json b/starpilot/system/the_galaxy/assets/components/tools/device_settings_layout.json index 5917d457d1..c7738b8657 100644 --- a/starpilot/system/the_galaxy/assets/components/tools/device_settings_layout.json +++ b/starpilot/system/the_galaxy/assets/components/tools/device_settings_layout.json @@ -2048,15 +2048,6 @@ "parent_key": "AdvancedCustomUI", "settings_tier": "simple" }, - { - "key": "HideSpeedLimit", - "label": "Hide Speed Limits", - "description": "Hide posted speed limits from the driving screen.", - "data_type": "bool", - "ui_type": "toggle", - "parent_key": "AdvancedCustomUI", - "settings_tier": "simple" - }, { "key": "HideSteeringWheel", "label": "Hide Steering Wheel", @@ -2368,7 +2359,7 @@ { "key": "ShowSpeedLimits", "label": "Show Speed Limits", - "description": "Show speed limits in the top-left corner of the driving screen. Uses data from the car's dashboard (if supported) and \"OpenStreetMap (OSM)\".", + "description": "Show the current speed limit on the driving screen. The position depends on the device UI. Uses data from the car's dashboard (if supported) and \"OpenStreetMap (OSM)\".", "data_type": "bool", "ui_type": "toggle", "parent_key": "NavigationUI", diff --git a/starpilot/system/the_galaxy/tests/test_fingerprint_catalog.py b/starpilot/system/the_galaxy/tests/test_fingerprint_catalog.py index 550869410c..e585dc36fb 100644 --- a/starpilot/system/the_galaxy/tests/test_fingerprint_catalog.py +++ b/starpilot/system/the_galaxy/tests/test_fingerprint_catalog.py @@ -18,6 +18,6 @@ def test_galaxy_lists_tesla_hardware_specific_docs_for_manual_fingerprinting(): tesla_models = the_galaxy._extract_fingerprint_models_for_make("tesla") assert {"value": "TESLA_MODEL_3", "label": "Tesla Model 3 (with HW3) 2019-23"} in tesla_models - assert {"value": "TESLA_MODEL_3", "label": "Tesla Model 3 (with HW4) 2024-25"} in tesla_models + assert {"value": "TESLA_MODEL_3", "label": "Tesla Model 3 (with HW4) 2024-26"} in tesla_models assert {"value": "TESLA_MODEL_Y", "label": "Tesla Model Y (with HW3) 2020-23"} in tesla_models assert {"value": "TESLA_MODEL_X", "label": "Tesla Model X (with HW4) 2024"} in tesla_models diff --git a/system/manager/launch_param_migrations.py b/system/manager/launch_param_migrations.py index 82b2767675..1d9451f576 100644 --- a/system/manager/launch_param_migrations.py +++ b/system/manager/launch_param_migrations.py @@ -33,6 +33,7 @@ LATERAL_METHOD_REBRAND_MIGRATION_MARKER = ".starpilot_lateral_method_rebrand_v1" VISION_SPEED_LIMIT_DETECTION_MIGRATION_MARKER = ".starpilot_vision_speed_limit_detection_v1" DEVELOPER_METRIC_DISPLAY_MIGRATION_MARKER = ".starpilot_developer_metric_display_off_v1" LANE_CHANGE_SMOOTHING_MIGRATION_MARKER = ".starpilot_lane_change_smoothing_default_v1" +SPEED_LIMIT_VISIBILITY_MIGRATION_MARKER = ".starpilot_speed_limit_visibility_v1" MARKER_DIRNAME = ".starpilot_param_migrations" LATERAL_METHOD_PARAM_SUFFIXES = ( @@ -126,6 +127,10 @@ def _lane_change_smoothing_marker_path(params: ParamsLike) -> Path: return _marker_dir_path(params) / LANE_CHANGE_SMOOTHING_MIGRATION_MARKER +def _speed_limit_visibility_marker_path(params: ParamsLike) -> Path: + return _marker_dir_path(params) / SPEED_LIMIT_VISIBILITY_MIGRATION_MARKER + + def _marker_dir_path(params: ParamsLike) -> Path: params_path = Path(params.get_param_path()) # Params.clear_all() removes unknown files inside the params directory, so @@ -270,6 +275,21 @@ def _apply_lane_change_smoothing_default_migration(params: ParamsLike, marker: P marker.touch() +def _apply_speed_limit_visibility_migration(params: ParamsLike, marker: Path) -> None: + if marker.exists(): + return + + marker.parent.mkdir(parents=True, exist_ok=True) + + # Preserve users who explicitly enabled the legacy hide control while making + # ShowSpeedLimits the only visibility setting used by the raylib UIs. + if params.get_bool("HideSpeedLimit"): + params.put_bool("ShowSpeedLimits", False) + params.put_bool("HideSpeedLimit", False) + + marker.touch() + + def apply_launch_param_migrations(params: ParamsLike, marker_path: Path | None = None, branch_defaults_marker_path: Path | None = None, acceleration_profile_marker_path: Path | None = None, @@ -277,7 +297,8 @@ def apply_launch_param_migrations(params: ParamsLike, marker_path: Path | None = lateral_method_rebrand_marker_path: Path | None = None, vision_speed_limit_detection_marker_path: Path | None = None, developer_metric_display_marker_path: Path | None = None, - lane_change_smoothing_marker_path: Path | None = None) -> None: + lane_change_smoothing_marker_path: Path | None = None, + speed_limit_visibility_marker_path: Path | None = None) -> None: _apply_legacy_launch_param_migrations(params, marker_path or _default_marker_path(params)) # Keep branch-default rollout on its own marker so older installs that already # have the legacy marker still receive this one-time param reset. @@ -298,6 +319,9 @@ def apply_launch_param_migrations(params: ParamsLike, marker_path: Path | None = _apply_lane_change_smoothing_default_migration( params, lane_change_smoothing_marker_path or _lane_change_smoothing_marker_path(params) ) + _apply_speed_limit_visibility_migration( + params, speed_limit_visibility_marker_path or _speed_limit_visibility_marker_path(params) + ) def main() -> int: diff --git a/system/manager/test/test_launch_param_migrations.py b/system/manager/test/test_launch_param_migrations.py index a13a522e30..ceaf91976d 100644 --- a/system/manager/test/test_launch_param_migrations.py +++ b/system/manager/test/test_launch_param_migrations.py @@ -12,6 +12,7 @@ from openpilot.system.manager.launch_param_migrations import ( LATERAL_METHOD_REBRAND_MIGRATION_MARKER, MARKER_DIRNAME, STANDARD_ACCELERATION_PROFILE, + SPEED_LIMIT_VISIBILITY_MIGRATION_MARKER, USE_OLD_UI_MIGRATION_MARKER, VISION_SPEED_LIMIT_DETECTION_MIGRATION_MARKER, apply_launch_param_migrations, @@ -113,6 +114,35 @@ def test_apply_launch_param_migrations_does_not_reapply_after_marker(tmp_path): assert params.get_float("SteerKPStock") == DEFAULT_STEER_KP +def test_apply_launch_param_migrations_converts_legacy_speed_limit_hide_once(tmp_path): + params = FileBackedFakeParams(tmp_path / "params") + params.put_bool("ShowSpeedLimits", True) + params.put_bool("HideSpeedLimit", True) + + apply_launch_param_migrations(params) + + assert not params.get_bool("ShowSpeedLimits") + assert not params.get_bool("HideSpeedLimit") + assert marker_path(tmp_path, SPEED_LIMIT_VISIBILITY_MIGRATION_MARKER).is_file() + + +def test_apply_launch_param_migrations_preserves_speed_limit_visibility_choice(tmp_path): + params = FileBackedFakeParams(tmp_path / "params") + params.put_bool("ShowSpeedLimits", False) + params.put_bool("HideSpeedLimit", False) + marker = marker_path(tmp_path, SPEED_LIMIT_VISIBILITY_MIGRATION_MARKER) + + apply_launch_param_migrations(params) + + assert not params.get_bool("ShowSpeedLimits") + assert not params.get_bool("HideSpeedLimit") + assert marker.is_file() + + params.put_bool("ShowSpeedLimits", True) + apply_launch_param_migrations(params) + assert params.get_bool("ShowSpeedLimits") + + def test_apply_launch_param_migrations_applies_branch_defaults_for_existing_installs(tmp_path): params = FileBackedFakeParams(tmp_path / "params")