mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-20 07:43:48 +08:00
Dingo
This commit is contained in:
committed by
firestar5683
parent
98a913693d
commit
f7634ec761
@@ -415,7 +415,7 @@ class CarController(CarControllerBase):
|
||||
self._ev9_long_tuning = EV9LongitudinalTuningState()
|
||||
self._left_blindspot_warning = BlindspotWarningState()
|
||||
self._right_blindspot_warning = BlindspotWarningState()
|
||||
self.long_active_ecu = self.CP.openpilotLongitudinalControl
|
||||
self.long_active_ecu = self.CP.openpilotLongitudinalControl and not (self.CP.flags & HyundaiFlags.NON_SCC)
|
||||
self._ioniq_6_lane_change_ui_side = None
|
||||
self._ioniq_6_lane_change_ui_frames = 0
|
||||
self._ioniq_6_long_tuning = Ioniq6LongitudinalTuningState()
|
||||
@@ -594,7 +594,7 @@ class CarController(CarControllerBase):
|
||||
|
||||
# When ECU disable was skipped (car started in READY mode), don't send any
|
||||
# longitudinal messages - stock ECU is still active and these would conflict
|
||||
self.long_active_ecu = self.CP.openpilotLongitudinalControl and not self.ecu_disable_failed
|
||||
self.long_active_ecu = self.CP.openpilotLongitudinalControl and not (self.CP.flags & HyundaiFlags.NON_SCC) and not self.ecu_disable_failed
|
||||
|
||||
use_egmp_dynamic_long_tuning = egmp_dynamic_longitudinal_tuning(self.CP) and self.long_active_ecu and \
|
||||
actuators.longControlState in (LongCtrlState.starting, LongCtrlState.pid, LongCtrlState.stopping)
|
||||
|
||||
@@ -312,19 +312,19 @@ class CarState(CarStateBase):
|
||||
|
||||
# cruise state
|
||||
no_scc = bool(self.CP.flags & HyundaiFlags.NON_SCC)
|
||||
if self.CP.openpilotLongitudinalControl:
|
||||
# These are not used for engage/disengage since openpilot keeps track of state using the buttons
|
||||
ret.cruiseState.available = cp.vl["TCS13"]["ACCEnable"] == 0
|
||||
ret.cruiseState.enabled = cp.vl["TCS13"]["ACC_REQ"] == 1
|
||||
ret.cruiseState.standstill = False
|
||||
ret.cruiseState.nonAdaptive = False
|
||||
elif no_scc:
|
||||
if no_scc:
|
||||
cruise_available_msg, cruise_available_sig, cruise_enabled_msg, cruise_enabled_sig, cruise_speed_msg, cruise_speed_sig = get_non_scc_cruise_signals(self.CP)
|
||||
ret.cruiseState.available = cp.vl[cruise_available_msg][cruise_available_sig] != 0
|
||||
ret.cruiseState.enabled = cp.vl[cruise_enabled_msg][cruise_enabled_sig] != 0
|
||||
ret.cruiseState.standstill = False
|
||||
ret.cruiseState.nonAdaptive = False
|
||||
ret.cruiseState.speed = cp.vl[cruise_speed_msg][cruise_speed_sig] * speed_conv
|
||||
elif self.CP.openpilotLongitudinalControl:
|
||||
# These are not used for engage/disengage since openpilot keeps track of state using the buttons
|
||||
ret.cruiseState.available = cp.vl["TCS13"]["ACCEnable"] == 0
|
||||
ret.cruiseState.enabled = cp.vl["TCS13"]["ACC_REQ"] == 1
|
||||
ret.cruiseState.standstill = False
|
||||
ret.cruiseState.nonAdaptive = False
|
||||
else:
|
||||
scc_msg = "SCC12" if self.CP.flags & HyundaiFlags.CAN_CANFD_BLENDED else "SCC11"
|
||||
ret.cruiseState.available = cp_cruise.vl[scc_msg]["MainMode_ACC"] == 1
|
||||
|
||||
@@ -334,7 +334,7 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
ecu_log(f"=== init() called: opLong={CP.openpilotLongitudinalControl}, flags=0x{CP.flags:x}, safetyParam={CP.safetyConfigs[-1].safetyParam} ===")
|
||||
|
||||
if CP.openpilotLongitudinalControl and not (CP.flags & (HyundaiFlags.CANFD_CAMERA_SCC | HyundaiFlags.CAMERA_SCC)):
|
||||
if CP.openpilotLongitudinalControl and not (CP.flags & (HyundaiFlags.NON_SCC | HyundaiFlags.CANFD_CAMERA_SCC | HyundaiFlags.CAMERA_SCC)):
|
||||
addr, bus = 0x7d0, CanBus(CP).ECAN if CP.flags & (HyundaiFlags.CANFD | HyundaiFlags.CAN_CANFD_BLENDED) else 0
|
||||
if CP.flags & HyundaiFlags.CANFD_LKA_STEERING.value:
|
||||
addr, bus = 0x730, CanBus(CP).ECAN
|
||||
|
||||
@@ -613,12 +613,35 @@ class TestHyundaiFingerprint:
|
||||
non_scc_fpcp = CarInterface.get_starpilot_params(CAR.KIA_FORTE_2021_NON_SCC, gen_empty_fingerprint(), [], non_scc_cp, toggles)
|
||||
assert non_scc_fpcp.redneckCruiseAvailable
|
||||
assert not non_scc_fpcp.pcmCruiseSpeed
|
||||
assert non_scc_cp.openpilotLongitudinalControl
|
||||
assert non_scc_cp.pcmCruise
|
||||
assert not non_scc_cp.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG
|
||||
assert not CarInterface(non_scc_cp, non_scc_fpcp).CC.long_active_ecu
|
||||
|
||||
canfd_alt_buttons_cp = CarInterface.get_params(CAR.KIA_EV6, gen_empty_fingerprint(), [], False, False, False, toggles)
|
||||
canfd_alt_buttons_fpcp = CarInterface.get_starpilot_params(CAR.KIA_EV6, gen_empty_fingerprint(), [], canfd_alt_buttons_cp, toggles)
|
||||
assert canfd_alt_buttons_cp.flags & HyundaiFlags.CANFD_ALT_BUTTONS
|
||||
assert not canfd_alt_buttons_fpcp.redneckCruiseAvailable
|
||||
|
||||
def test_hyundai_non_scc_without_redneck_keeps_stock_longitudinal_mode(self, monkeypatch):
|
||||
class FakeParams:
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_bool(key):
|
||||
return False
|
||||
|
||||
toggles = get_test_toggles()
|
||||
monkeypatch.setattr("opendbc.car.interfaces.Params", FakeParams)
|
||||
|
||||
CP = CarInterface.get_params(CAR.KIA_FORTE_2021_NON_SCC, gen_empty_fingerprint(), [], True, False, False, toggles)
|
||||
FPCP = CarInterface.get_starpilot_params(CAR.KIA_FORTE_2021_NON_SCC, gen_empty_fingerprint(), [], CP, toggles)
|
||||
|
||||
assert not CP.openpilotLongitudinalControl
|
||||
assert CP.pcmCruise
|
||||
assert FPCP.pcmCruiseSpeed
|
||||
|
||||
def test_hyundai_full_long_keeps_redneck_cruise_disabled(self, monkeypatch):
|
||||
class FakeParams:
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
@@ -238,9 +238,9 @@ class CarInterfaceBase(ABC):
|
||||
fp_ret.flags |= HyundaiStarPilotFlags.SPEED_LIMIT_AVAILABLE.value
|
||||
|
||||
fp_ret.redneckCruiseAvailable = bool(CP.flags & HyundaiFlags.NON_SCC) and not bool(CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS)
|
||||
if fp_ret.redneckCruiseAvailable and params.get_bool("RedneckCruise") and \
|
||||
not CP.openpilotLongitudinalControl:
|
||||
if fp_ret.redneckCruiseAvailable and params.get_bool("RedneckCruise"):
|
||||
fp_ret.pcmCruiseSpeed = False
|
||||
CP.openpilotLongitudinalControl = True
|
||||
|
||||
hyundai_has_lda_button = (
|
||||
0x391 in fingerprint[0] or
|
||||
|
||||
@@ -55,7 +55,7 @@ from openpilot.tools.lib.logreader import LogReader, ReadMode
|
||||
# Constants
|
||||
# ============================================================================
|
||||
|
||||
OVERPASS_API_URL = "https://overpass-api.de/api/interpreter"
|
||||
OVERPASS_API_URL = "https://maps.mail.ru/osm/tools/overpass/api/interpreter"
|
||||
OVERPASS_UA = "starpilot-diagnose-slc/1.0 (https://github.com/FrogAi/StarPilot)"
|
||||
|
||||
JWT_HELP_URL = "https://jwt.comma.ai/"
|
||||
@@ -672,7 +672,8 @@ class OverpassClient:
|
||||
if not gps:
|
||||
return {}
|
||||
|
||||
key = hashlib.sha256(json.dumps(gps, sort_keys=True).encode()).hexdigest()[:16]
|
||||
cache_input = {"endpoint": OVERPASS_API_URL, "gps": gps}
|
||||
key = hashlib.sha256(json.dumps(cache_input, sort_keys=True).encode()).hexdigest()[:16]
|
||||
cached = self._load_cache(key)
|
||||
if cached is not None:
|
||||
return cached
|
||||
|
||||
+16
-3
@@ -421,20 +421,32 @@ class Car:
|
||||
if self.redneck_cruise is None:
|
||||
return
|
||||
|
||||
v_target_ms, lead_present = self._get_redneck_target_speed(CS)
|
||||
v_target_ms, lead_present = self._get_redneck_target_speed(CS, CC)
|
||||
send_button, v_target = self.redneck_cruise.run(CS, CC, v_target_ms, self.is_metric, lead_present=lead_present)
|
||||
self.CI.CS.redneck_send_button = send_button
|
||||
self.CI.CS.redneck_v_target = v_target
|
||||
|
||||
def _get_redneck_target_speed(self, CS: car.CarState) -> tuple[float, bool]:
|
||||
def _get_redneck_target_speed(self, CS: car.CarState, CC: car.CarControl) -> tuple[float, bool]:
|
||||
# With openpilot longitudinal active, project its acceleration demand into the stock cruise setpoint.
|
||||
if self.CP.openpilotLongitudinalControl:
|
||||
return CS.vEgo * 1.01 + 3 * CC.actuators.accel, bool(CC.hudControl.leadVisible)
|
||||
|
||||
# Preserve the existing button-only SLC path when LongControl is disabled.
|
||||
starpilot_target_speed = 0.0
|
||||
slc_target_speed = 0.0
|
||||
allow_plan_decrease = False
|
||||
lead_present = False
|
||||
lead_distance_m = 0.0
|
||||
lead_rel_speed_ms = 0.0
|
||||
lookahead_points = REDNECK_DECREASE_LOOKAHEAD_POINTS
|
||||
if self.sm.seen['starpilotPlan'] and self.sm.valid['starpilotPlan']:
|
||||
starpilot_target_speed = float(self.sm['starpilotPlan'].vCruise)
|
||||
starpilot_plan = self.sm['starpilotPlan']
|
||||
starpilot_target_speed = float(starpilot_plan.vCruise)
|
||||
if self.starpilot_toggles.speed_limit_controller:
|
||||
slc_target_speed = max(
|
||||
float(starpilot_plan.slcOverriddenSpeed),
|
||||
float(starpilot_plan.slcSpeedLimit) + float(starpilot_plan.slcSpeedLimitOffset),
|
||||
)
|
||||
|
||||
plan_speeds = []
|
||||
if self.sm.seen['longitudinalPlan'] and self.sm.valid['longitudinalPlan']:
|
||||
@@ -461,6 +473,7 @@ class Car:
|
||||
lead_present=lead_present,
|
||||
lead_distance_m=lead_distance_m,
|
||||
lead_rel_speed_ms=lead_rel_speed_ms,
|
||||
slc_target_speed_ms=slc_target_speed,
|
||||
), lead_present
|
||||
|
||||
def step(self):
|
||||
|
||||
@@ -45,9 +45,12 @@ def select_redneck_target_speed(v_cruise_kph: float, speed_cluster_ms: float,
|
||||
starpilot_target_speed_ms: float, plan_speeds_ms: list[float],
|
||||
lookahead_points: int, allow_plan_decrease: bool = True,
|
||||
lead_present: bool = False, lead_distance_m: float = 0.0,
|
||||
lead_rel_speed_ms: float = 0.0) -> float:
|
||||
lead_rel_speed_ms: float = 0.0,
|
||||
slc_target_speed_ms: float = 0.0) -> float:
|
||||
target_speed_ms = float(speed_cluster_ms)
|
||||
if v_cruise_kph > 0:
|
||||
if slc_target_speed_ms > 0:
|
||||
target_speed_ms = float(slc_target_speed_ms)
|
||||
elif v_cruise_kph > 0:
|
||||
target_speed_ms = float(v_cruise_kph) * CV.KPH_TO_MS
|
||||
elif starpilot_target_speed_ms > 0:
|
||||
target_speed_ms = float(starpilot_target_speed_ms)
|
||||
|
||||
@@ -4,6 +4,7 @@ from types import SimpleNamespace
|
||||
from cereal import car
|
||||
from openpilot.common.constants import CV
|
||||
from openpilot.common.realtime import DT_CTRL
|
||||
from openpilot.selfdrive.car.card import Car
|
||||
from openpilot.selfdrive.car.redneck_cruise import (
|
||||
DECREASE_INACTIVE_TIMER,
|
||||
INCREASE_INACTIVE_TIMER,
|
||||
@@ -168,6 +169,33 @@ class TestRedneckCruise(unittest.TestCase):
|
||||
)
|
||||
self.assertAlmostEqual(104.4 * CV.KPH_TO_MS, target_speed)
|
||||
|
||||
def test_target_speed_follows_resolved_slc_target(self):
|
||||
for internal_mph, slc_mph in ((55.0, 65.0), (65.0, 55.0)):
|
||||
with self.subTest(internal_mph=internal_mph, slc_mph=slc_mph):
|
||||
target_speed = select_redneck_target_speed(
|
||||
internal_mph * CV.MPH_TO_KPH,
|
||||
internal_mph * CV.MPH_TO_MS,
|
||||
0.0,
|
||||
[],
|
||||
10,
|
||||
allow_plan_decrease=False,
|
||||
slc_target_speed_ms=slc_mph * CV.MPH_TO_MS,
|
||||
)
|
||||
self.assertAlmostEqual(slc_mph * CV.MPH_TO_MS, target_speed)
|
||||
|
||||
def test_card_target_speed_uses_longitudinal_acceleration(self):
|
||||
card = SimpleNamespace(CP=SimpleNamespace(openpilotLongitudinalControl=True))
|
||||
car_state = SimpleNamespace(vEgo=55.0 * CV.MPH_TO_MS)
|
||||
car_control = SimpleNamespace(
|
||||
actuators=SimpleNamespace(accel=0.5),
|
||||
hudControl=SimpleNamespace(leadVisible=True),
|
||||
)
|
||||
|
||||
target_speed, lead_present = Car._get_redneck_target_speed(card, car_state, car_control)
|
||||
|
||||
self.assertAlmostEqual(55.0 * CV.MPH_TO_MS * 1.01 + 1.5, target_speed)
|
||||
self.assertTrue(lead_present)
|
||||
|
||||
def test_target_speed_returns_plan_minimum_when_slowing_down(self):
|
||||
target_speed = select_redneck_target_speed(
|
||||
120.0,
|
||||
|
||||
@@ -46,6 +46,7 @@ from openpilot.selfdrive.ui.lib.fingerprint_catalog import (
|
||||
shorten_model_label,
|
||||
)
|
||||
from openpilot.starpilot.common.starpilot_variables import migrate_cancel_button_controls
|
||||
from openpilot.selfdrive.ui.layouts.settings.common import restart_needed_callback
|
||||
|
||||
|
||||
ACTION_OPTIONS = [
|
||||
@@ -420,6 +421,13 @@ class VehicleSettingsManagerView(PanelManagerView):
|
||||
"get_state": lambda: self._controller._params.get_bool("NostalgiaMode"),
|
||||
"set_state": lambda s: self._controller._on_toggle("NostalgiaMode"),
|
||||
})
|
||||
if cs.redneckCruiseAvailable:
|
||||
toggles.append({
|
||||
"title": tr("Redneck Cruise"),
|
||||
"subtitle": tr("Use RES/SET button presses to match the stock cruise set speed to StarPilot's target."),
|
||||
"get_state": lambda: self._controller._params.get_bool("RedneckCruise"),
|
||||
"set_state": lambda s: self._controller._on_toggle("RedneckCruise"),
|
||||
})
|
||||
|
||||
return toggles
|
||||
|
||||
@@ -679,6 +687,11 @@ class StarPilotVehicleSettingsLayout(_SettingsPage):
|
||||
migrate_cancel_button_controls(self._params)
|
||||
starpilot_state.update(force=True)
|
||||
return
|
||||
if param_key == "RedneckCruise":
|
||||
self._params.put_bool("RedneckCruise", not self._params.get_bool("RedneckCruise"))
|
||||
starpilot_state.update(force=True)
|
||||
restart_needed_callback(None)
|
||||
return
|
||||
current = self._params.get_bool(param_key) if self._params.get(param_key) is not None else False
|
||||
self._params.put_bool(param_key, not current)
|
||||
starpilot_state.update(force=True)
|
||||
|
||||
@@ -38,6 +38,7 @@ class StarPilotCarState:
|
||||
hasZSS: bool = False
|
||||
canUsePedal: bool = False
|
||||
canUseSDSU: bool = False
|
||||
redneckCruiseAvailable: bool = False
|
||||
|
||||
# ========== Device/Car State ==========
|
||||
isFrogsGoMoo: bool = False
|
||||
@@ -206,12 +207,14 @@ class StarPilotState:
|
||||
|
||||
# 2. Parse StarPilotCarParamsPersistent
|
||||
fpcp_bytes = self.params.get("StarPilotCarParamsPersistent")
|
||||
self.car_state.redneckCruiseAvailable = False
|
||||
if fpcp_bytes is not None:
|
||||
try:
|
||||
FPCP = messaging.log_from_bytes(fpcp_bytes, custom.StarPilotCarParams)
|
||||
self.car_state.canUsePedal = FPCP.canUsePedal
|
||||
self.car_state.canUseSDSU = FPCP.canUseSDSU
|
||||
self.car_state.openpilotLongitudinalControlDisabled = FPCP.openpilotLongitudinalControlDisabled
|
||||
self.car_state.redneckCruiseAvailable = bool(FPCP.redneckCruiseAvailable)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ from openpilot.selfdrive.ui.lib.fingerprint_catalog import (
|
||||
shorten_model_label,
|
||||
)
|
||||
from openpilot.selfdrive.ui.layouts.settings.common import restart_needed_callback
|
||||
from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
@@ -195,10 +196,10 @@ class VehicleLayoutMici(NavScroller):
|
||||
fingerprint_btn = BigButton("fingerprint", "",gui_app.texture("icons_mici/settings/vehicle/fingerprint.png", 58, 64))
|
||||
fingerprint_btn.set_click_callback(lambda: gui_app.push_widget(fingerprint_panel))
|
||||
|
||||
# TODO: make it reloadable without restarting ui
|
||||
match ui_state.params.get("CarModel"):
|
||||
case _:
|
||||
vehicle_specific_widgets = tuple()
|
||||
starpilot_state.update(force=True)
|
||||
vehicle_specific_widgets = (
|
||||
BigParamControl("redneck cruise", "RedneckCruise", toggle_callback=restart_needed_callback),
|
||||
) if starpilot_state.car_state.redneckCruiseAvailable else tuple()
|
||||
|
||||
self._scroller.add_widgets([
|
||||
fingerprint_btn,
|
||||
@@ -206,4 +207,3 @@ class VehicleLayoutMici(NavScroller):
|
||||
])
|
||||
|
||||
self._font_medium = gui_app.font(FontWeight.MEDIUM)
|
||||
|
||||
|
||||
@@ -379,6 +379,10 @@ def set_speed_limit_available(openpilot_longitudinal: bool, has_cc_long: bool, p
|
||||
return openpilot_longitudinal or has_cc_long or not pcm_cruise_speed
|
||||
|
||||
|
||||
def speed_limit_controller_available(openpilot_longitudinal: bool, redneck_cruise: bool) -> bool:
|
||||
return openpilot_longitudinal or redneck_cruise
|
||||
|
||||
|
||||
def migrate_cancel_button_controls(params: Params | None = None) -> bool:
|
||||
params = params or Params(return_defaults=True)
|
||||
if params.get_bool(CANCEL_BUTTON_MIGRATION_KEY) or not params.get_bool("RemapCancelToDistance"):
|
||||
@@ -642,12 +646,14 @@ class StarPilotVariables:
|
||||
toggle.lkas_allowed_for_aol = hyundai_can_use_lkas_for_aol or toggle.car_make == "honda"
|
||||
longitudinalActuatorDelay = CP.longitudinalActuatorDelay
|
||||
toggle.openpilot_longitudinal = CP.openpilotLongitudinalControl and not toggle.disable_openpilot_long
|
||||
if not toggle.redneck_cruise_available or toggle.openpilot_longitudinal:
|
||||
if not toggle.redneck_cruise_available or (toggle.openpilot_longitudinal and FPCP.pcmCruiseSpeed):
|
||||
self.params.put_bool("RedneckCruise", False)
|
||||
toggle.redneck_cruise = self.get_value(
|
||||
"RedneckCruise",
|
||||
condition=toggle.redneck_cruise_available and not toggle.openpilot_longitudinal,
|
||||
)
|
||||
if toggle.redneck_cruise_available and not FPCP.pcmCruiseSpeed:
|
||||
toggle.redneck_cruise = True
|
||||
pcm_cruise = CP.pcmCruise
|
||||
prohibited_main_aol = not toggle.openpilot_longitudinal and hyundai_can_use_lkas_for_aol
|
||||
startAccel = CP.startAccel
|
||||
@@ -1292,7 +1298,8 @@ class StarPilotVariables:
|
||||
toggle.sng_hack = self.get_value("SNGHack", condition=toggle.openpilot_longitudinal and toggle.car_make == "toyota" and not toggle.has_pedal and not has_sng)
|
||||
toggle.toyota_auto_hold = self.get_value("ToyotaAutoHold", condition=toggle.car_make == "toyota")
|
||||
|
||||
toggle.speed_limit_controller = toggle.openpilot_longitudinal and self.get_value("SpeedLimitController")
|
||||
slc_available = speed_limit_controller_available(toggle.openpilot_longitudinal, toggle.redneck_cruise)
|
||||
toggle.speed_limit_controller = slc_available and self.get_value("SpeedLimitController")
|
||||
set_speed_limit_on_engage = set_speed_limit_available(toggle.openpilot_longitudinal, toggle.has_cc_long, FPCP.pcmCruiseSpeed)
|
||||
speed_limit_display = toggle.show_speed_limits or toggle.speed_limit_controller
|
||||
toggle.map_speed_lookahead_higher = self.get_value("SLCLookaheadHigher", cast=float, condition=speed_limit_display)
|
||||
|
||||
@@ -222,3 +222,9 @@ def test_set_speed_limit_available_on_redneck_helper_path():
|
||||
|
||||
def test_set_speed_limit_unavailable_on_stock_pcm_without_helper():
|
||||
assert spv.set_speed_limit_available(openpilot_longitudinal=False, has_cc_long=False, pcm_cruise_speed=True) is False
|
||||
|
||||
|
||||
def test_speed_limit_controller_available_on_openpilot_longitudinal_or_redneck():
|
||||
assert spv.speed_limit_controller_available(openpilot_longitudinal=True, redneck_cruise=False) is True
|
||||
assert spv.speed_limit_controller_available(openpilot_longitudinal=False, redneck_cruise=True) is True
|
||||
assert spv.speed_limit_controller_available(openpilot_longitudinal=False, redneck_cruise=False) is False
|
||||
|
||||
@@ -1346,15 +1346,6 @@
|
||||
"parent_key": "QOLLongitudinal",
|
||||
"settings_tier": "simple"
|
||||
},
|
||||
{
|
||||
"key": "RedneckCruise",
|
||||
"label": "Redneck Cruise",
|
||||
"description": "On supported Hyundai stock-long cars, use RES/SET button presses to match the cluster set speed to StarPilot's target.",
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle",
|
||||
"parent_key": "QOLLongitudinal",
|
||||
"settings_tier": "simple"
|
||||
},
|
||||
{
|
||||
"key": "WeatherPresets",
|
||||
"label": "Weather Condition Offsets",
|
||||
|
||||
@@ -50,6 +50,7 @@ def test_galaxy_layout_contains_basic_mode_controls():
|
||||
"HumanLaneChanges",
|
||||
"QOLLongitudinal",
|
||||
} <= sections["Longitudinal (Speed & Following)"].keys()
|
||||
assert "RedneckCruise" not in sections["Longitudinal (Speed & Following)"].keys()
|
||||
assert {"GalaxyDeveloperMode", "UseOldUI"} <= sections["Developer"].keys()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user