Speed Limit Assist: Disable for Tesla in release (#1418)
* Speed Limit Assist: Disable for Tesla in release * add test * unused * use constant * eh * flip * universal it * check release state and align in tests * use this * eh * update changelog
This commit is contained in:
@@ -17,6 +17,8 @@ sunnypilot Version 2025.001.000 (2025-10-25)
|
||||
* Intelligent longitudinal control adaptation
|
||||
* Speed Limit Assist (SLA)
|
||||
* Comprehensive speed limit integration featuring @pfeiferj's `mapd` for offline map limits downloads, a Speed Limit Resolver for sourcing data (from car, map, combined, etc), on-screen UI for Speed Limit Information/Warning, and Speed Limit Assist (SLA) to adjust cruise speed automatically.
|
||||
* Currently disabled for Tesla with sunnypilot Longitudinal Control in release
|
||||
* May return in future releases
|
||||
* Intelligent Cruise Button Management (ICBM)
|
||||
* System designed to manage the vehicle’s speed by sending cruise control button commands to the car’s ECU.
|
||||
* Smart Cruise Control Map & Vision (SCC-M / SCC-V)
|
||||
|
||||
@@ -105,6 +105,7 @@ SpeedLimitSettings::SpeedLimitSettings(QWidget *parent) : QStackedWidget(parent)
|
||||
}
|
||||
|
||||
void SpeedLimitSettings::refresh() {
|
||||
bool is_release = params.getBool("IsReleaseSpBranch");
|
||||
bool is_metric_param = params.getBool("IsMetric");
|
||||
SpeedLimitMode speed_limit_mode_param = static_cast<SpeedLimitMode>(std::atoi(params.get("SpeedLimitMode").c_str()));
|
||||
SpeedLimitOffsetType offset_type_param = static_cast<SpeedLimitOffsetType>(std::atoi(params.get("SpeedLimitOffsetType").c_str()));
|
||||
@@ -126,9 +127,11 @@ void SpeedLimitSettings::refresh() {
|
||||
|
||||
/*
|
||||
* Speed Limit Assist is available when:
|
||||
* - has_longitudinal_control or has_icbm
|
||||
* - has_longitudinal_control or has_icbm, and
|
||||
* - is not a release branch or not a disallowed brand
|
||||
*/
|
||||
sla_available = has_longitudinal_control || has_icbm;
|
||||
bool sla_disallow_in_release = CP.getBrand() == "tesla" && is_release;
|
||||
sla_available = (has_longitudinal_control || has_icbm) && !sla_disallow_in_release;
|
||||
|
||||
if (!sla_available && speed_limit_mode_param == SpeedLimitMode::ASSIST) {
|
||||
params.put("SpeedLimitMode", std::to_string(static_cast<int>(SpeedLimitMode::WARNING)));
|
||||
|
||||
@@ -22,15 +22,22 @@ def compare_cluster_target(v_cruise_cluster: float, target_set_speed: float, is_
|
||||
return req_plus, req_minus
|
||||
|
||||
|
||||
def set_speed_limit_assist_availability(CP: car.CarParams, CP_SP: custom.CarParamsSP, params: Params = None) -> None:
|
||||
def set_speed_limit_assist_availability(CP: car.CarParams, CP_SP: custom.CarParamsSP, params: Params = None) -> bool:
|
||||
if params is None:
|
||||
params = Params()
|
||||
|
||||
is_release = params.get_bool("IsReleaseSpBranch")
|
||||
disallow_in_release = CP.brand == "tesla" and is_release
|
||||
allowed = True
|
||||
|
||||
if disallow_in_release:
|
||||
allowed = False
|
||||
|
||||
if not CP.openpilotLongitudinalControl and CP_SP.pcmCruiseSpeed:
|
||||
allowed = False
|
||||
|
||||
if not allowed:
|
||||
if params.get("SpeedLimitMode", return_default=True) == SpeedLimitMode.assist:
|
||||
params.put("SpeedLimitMode", int(SpeedLimitMode.warning))
|
||||
|
||||
return allowed
|
||||
|
||||
@@ -10,13 +10,13 @@ from cereal import custom, car
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.constants import CV
|
||||
from openpilot.common.realtime import DT_MDL
|
||||
from openpilot.sunnypilot import PARAMS_UPDATE_PERIOD
|
||||
from openpilot.selfdrive.controls.lib.drive_helpers import CONTROL_N
|
||||
from openpilot.selfdrive.modeld.constants import ModelConstants
|
||||
from openpilot.sunnypilot import PARAMS_UPDATE_PERIOD
|
||||
from openpilot.sunnypilot.selfdrive.selfdrived.events import EventsSP
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit import PCM_LONG_REQUIRED_MAX_SET_SPEED, CONFIRM_SPEED_THRESHOLD
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.common import Mode
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.helpers import compare_cluster_target, set_speed_limit_assist_availability
|
||||
from openpilot.selfdrive.modeld.constants import ModelConstants
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
EventNameSP = custom.OnroadEventSP.EventName
|
||||
|
||||
@@ -4,17 +4,21 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||
This file is part of sunnypilot and is licensed under the MIT License.
|
||||
See the LICENSE.md file in the root directory for more details.
|
||||
"""
|
||||
from cereal import custom
|
||||
|
||||
import pytest
|
||||
|
||||
from cereal import custom
|
||||
from opendbc.car.car_helpers import interfaces
|
||||
from opendbc.car.tesla.values import CAR as TESLA
|
||||
from opendbc.car.toyota.values import CAR as TOYOTA
|
||||
from openpilot.common.constants import CV
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.realtime import DT_MDL
|
||||
from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET
|
||||
from openpilot.sunnypilot import PARAMS_UPDATE_PERIOD
|
||||
from openpilot.sunnypilot.selfdrive.car import interfaces as sunnypilot_interfaces
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.common import Mode
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit import PCM_LONG_REQUIRED_MAX_SET_SPEED
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.common import Mode
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.speed_limit_assist import SpeedLimitAssist, \
|
||||
PRE_ACTIVE_GUARD_PERIOD, ACTIVE_STATES
|
||||
from openpilot.sunnypilot.selfdrive.selfdrived.events import EventsSP
|
||||
@@ -30,14 +34,28 @@ SPEED_LIMITS = {
|
||||
'freeway': 80 * CV.MPH_TO_MS, # 80 mph
|
||||
}
|
||||
|
||||
DEFAULT_CAR = TOYOTA.TOYOTA_RAV4_TSS2
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def car_name(request):
|
||||
return getattr(request, "param", DEFAULT_CAR)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def set_car_name_on_instance(request, car_name):
|
||||
instance = getattr(request, "instance", None)
|
||||
if instance:
|
||||
instance.car_name = car_name
|
||||
|
||||
|
||||
class TestSpeedLimitAssist:
|
||||
|
||||
def setup_method(self):
|
||||
def setup_method(self, method):
|
||||
self.params = Params()
|
||||
self.reset_custom_params()
|
||||
self.events_sp = EventsSP()
|
||||
CI = self._setup_platform(TOYOTA.TOYOTA_RAV4_TSS2)
|
||||
CI = self._setup_platform(self.car_name)
|
||||
self.sla = SpeedLimitAssist(CI.CP, CI.CP_SP)
|
||||
self.sla.pre_active_timer = int(PRE_ACTIVE_GUARD_PERIOD[self.sla.pcm_op_long] / DT_MDL)
|
||||
self.pcm_long_max_set_speed = PCM_LONG_REQUIRED_MAX_SET_SPEED[self.sla.is_metric][1] # use 80 MPH for now
|
||||
@@ -51,10 +69,12 @@ class TestSpeedLimitAssist:
|
||||
CP = CarInterface.get_non_essential_params(car_name)
|
||||
CP_SP = CarInterface.get_non_essential_params_sp(CP, car_name)
|
||||
CI = CarInterface(CP, CP_SP)
|
||||
CI.CP.openpilotLongitudinalControl = True # always assume it's openpilot longitudinal
|
||||
sunnypilot_interfaces.setup_interfaces(CI, self.params)
|
||||
return CI
|
||||
|
||||
def reset_custom_params(self):
|
||||
self.params.put("IsReleaseSpBranch", True)
|
||||
self.params.put("SpeedLimitMode", int(Mode.assist))
|
||||
self.params.put_bool("IsMetric", False)
|
||||
self.params.put("SpeedLimitOffsetType", 0)
|
||||
@@ -84,6 +104,21 @@ class TestSpeedLimitAssist:
|
||||
assert not self.sla.is_active
|
||||
assert V_CRUISE_UNSET == self.sla.get_v_target_from_control()
|
||||
|
||||
@pytest.mark.parametrize("car_name", [TESLA.TESLA_MODEL_Y], indirect=True)
|
||||
def test_disallowed_brands(self, car_name):
|
||||
"""
|
||||
Speed Limit Assist is disabled for the following brands and conditions:
|
||||
- All Tesla and is a release branch
|
||||
"""
|
||||
assert not self.sla.enabled
|
||||
|
||||
# stay disallowed even when the param may have changed from somewhere else
|
||||
self.params.put("SpeedLimitMode", int(Mode.assist))
|
||||
for _ in range(int(PARAMS_UPDATE_PERIOD / DT_MDL)):
|
||||
self.sla.update(True, False, SPEED_LIMITS['city'], 0, SPEED_LIMITS['highway'], SPEED_LIMITS['city'],
|
||||
SPEED_LIMITS['city'], True, 0, self.events_sp)
|
||||
assert not self.sla.enabled
|
||||
|
||||
def test_disabled(self):
|
||||
self.params.put("SpeedLimitMode", int(Mode.off))
|
||||
for _ in range(int(10. / DT_MDL)):
|
||||
|
||||
Reference in New Issue
Block a user