mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-30 03:13:48 +08:00
In&Out
This commit is contained in:
@@ -413,6 +413,12 @@ class CarState(CarStateBase):
|
||||
else:
|
||||
ret.gasPressed = bool(cp.vl["EMS16"]["CF_Ems_AclAct"])
|
||||
|
||||
if self.CP.carFingerprint == CAR.KIA_RAY_EV and self.CP.enableGasInterceptorDEPRECATED and self.ray_pedal_valid:
|
||||
driver_pedal = cp_pedal.vl_raw["GAS_SENSOR"]
|
||||
track1 = int.from_bytes(driver_pedal[:2], "big")
|
||||
track2 = int.from_bytes(driver_pedal[2:4], "big")
|
||||
ret.gasPressed = track1 > 272 or track2 > 513
|
||||
|
||||
# Gear Selection via Cluster - For those Kia/Hyundai which are not fully discovered, we can use the Cluster Indicator for Gear Selection,
|
||||
# as this seems to be standard over all cars, but is not the preferred method.
|
||||
if self.CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV):
|
||||
|
||||
@@ -91,6 +91,43 @@ def test_ray_pedal_fault_clears_only_with_healthy_sensor_state():
|
||||
assert not ret.accFaulted
|
||||
|
||||
|
||||
def test_ray_driver_override_uses_physical_interceptor_tracks():
|
||||
CP = CarInterface.get_params(CAR.KIA_RAY_EV, ray_fingerprint(), [], False, False, False, None)
|
||||
state = CarState(CP, None)
|
||||
parsers = state.get_can_parsers(CP)
|
||||
native_gas = (0x371, bytes.fromhex("004e008000ae0700"), 0)
|
||||
physical_rest = (0x201, bytes.fromhex("010801f30cef"), 0)
|
||||
for parser in parsers.values():
|
||||
parser.update([(1_000_000_000, [native_gas, physical_rest])])
|
||||
ret, _ = state.update(parsers, SimpleNamespace())
|
||||
assert state.ray_pedal_valid
|
||||
assert not ret.gasPressed
|
||||
|
||||
packer = CANPacker("hyundai_kia_ray_pedal")
|
||||
physical_press = packer.make_can_msg("GAS_SENSOR", 0, {
|
||||
"INTERCEPTOR_GAS": (310 - 264) * 0.672,
|
||||
"INTERCEPTOR_GAS2": (593 - 497) * 0.332,
|
||||
"STATE": 0, "COUNTER_PEDAL": 13,
|
||||
})
|
||||
for parser in parsers.values():
|
||||
parser.update([(1_020_000_000, [physical_press])])
|
||||
ret, _ = state.update(parsers, SimpleNamespace())
|
||||
assert ret.gasPressed
|
||||
|
||||
|
||||
def test_ray_without_pedal_keeps_native_gas_detection():
|
||||
CP = CarInterface.get_params(CAR.KIA_RAY_EV, ray_fingerprint(sensor_length=8), [], False, False, False, None)
|
||||
assert not CP.enableGasInterceptorDEPRECATED
|
||||
state = CarState(CP, None)
|
||||
parsers = state.get_can_parsers(CP)
|
||||
assert Bus.party not in parsers
|
||||
native_gas = (0x371, bytes.fromhex("004e008000ae0700"), 0)
|
||||
for parser in parsers.values():
|
||||
parser.update([(1_000_000_000, [native_gas])])
|
||||
ret, _ = state.update(parsers, SimpleNamespace())
|
||||
assert ret.gasPressed
|
||||
|
||||
|
||||
def test_ray_controller_heartbeats_and_only_actuates_when_ready():
|
||||
CP = CarInterface.get_params(CAR.KIA_RAY_EV, ray_fingerprint(), [], False, False, False, None)
|
||||
controller = CarController(DBC[CP.carFingerprint], CP)
|
||||
|
||||
@@ -259,7 +259,11 @@ static void hyundai_rx_hook(const CANPacket_t *msg) {
|
||||
}
|
||||
|
||||
// gas press, different for EV, hybrid, and ICE models
|
||||
if ((msg->addr == 0x371U) && hyundai_ev_gas_signal) {
|
||||
if ((msg->addr == 0x201U) && hyundai_ray_pedal) {
|
||||
const uint16_t track1 = ((uint16_t)msg->data[0] << 8U) | msg->data[1];
|
||||
const uint16_t track2 = ((uint16_t)msg->data[2] << 8U) | msg->data[3];
|
||||
gas_pressed = (track1 > 272U) || (track2 > 513U);
|
||||
} else if ((msg->addr == 0x371U) && hyundai_ev_gas_signal && !hyundai_ray_pedal) {
|
||||
gas_pressed = (((msg->data[4] & 0x7FU) << 1) | (msg->data[3] >> 7)) != 0U;
|
||||
} else if ((msg->addr == 0x371U) && hyundai_hybrid_gas_signal) {
|
||||
gas_pressed = msg->data[7] != 0U;
|
||||
|
||||
@@ -47,3 +47,38 @@ def test_ray_pedal_rx_crc_is_checked_only_for_ray_signature():
|
||||
bad_crc = bytearray(dat)
|
||||
bad_crc[-1] ^= 1
|
||||
assert not safety.safety_rx_hook(libsafety_py.make_CANPacket(0x201, 0, bytes(bad_crc)))
|
||||
|
||||
|
||||
def test_ray_native_commanded_gas_does_not_cancel_driver_override_safety():
|
||||
safety = libsafety_py.libsafety
|
||||
safety.set_safety_hooks(CarParams.SafetyModel.hyundai, 0x9405)
|
||||
safety.init_tests()
|
||||
safety.set_controls_allowed(True)
|
||||
packer = CANPacker("hyundai_kia_ray_pedal")
|
||||
|
||||
physical_rest = bytes.fromhex("010801f30cef")
|
||||
native_gas = bytes.fromhex("004e008000ae0700")
|
||||
assert safety.safety_rx_hook(libsafety_py.make_CANPacket(0x201, 0, physical_rest))
|
||||
assert safety.safety_rx_hook(libsafety_py.make_CANPacket(0x371, 0, native_gas))
|
||||
assert not safety.get_gas_pressed_prev()
|
||||
addr, dat, bus = create_gas_interceptor_command(packer, 0.1, 3)
|
||||
assert safety.safety_tx_hook(libsafety_py.make_CANPacket(addr, bus, dat))
|
||||
|
||||
physical_press = packer.make_can_msg("GAS_SENSOR", 0, {
|
||||
"INTERCEPTOR_GAS": (310 - 264) * 0.672,
|
||||
"INTERCEPTOR_GAS2": (593 - 497) * 0.332,
|
||||
"STATE": 0, "COUNTER_PEDAL": 13,
|
||||
})
|
||||
press_addr, press_dat, press_bus = physical_press
|
||||
assert safety.safety_rx_hook(libsafety_py.make_CANPacket(press_addr, press_bus, press_dat))
|
||||
assert safety.get_gas_pressed_prev()
|
||||
assert not safety.safety_tx_hook(libsafety_py.make_CANPacket(addr, bus, dat))
|
||||
|
||||
|
||||
def test_non_ray_hyundai_ev_keeps_native_driver_gas_detection():
|
||||
safety = libsafety_py.libsafety
|
||||
safety.set_safety_hooks(CarParams.SafetyModel.hyundai, 0x1001)
|
||||
safety.init_tests()
|
||||
native_gas = bytes.fromhex("004e008000ae0700")
|
||||
assert safety.safety_rx_hook(libsafety_py.make_CANPacket(0x371, 0, native_gas))
|
||||
assert safety.get_gas_pressed_prev()
|
||||
|
||||
@@ -195,12 +195,20 @@ class HudRenderer(Widget):
|
||||
controls_state = sm['controlsState']
|
||||
car_state = sm['carState']
|
||||
rivian_lateral_mode.update()
|
||||
car_control = sm['carControl'] if sm.valid.get('carControl', False) else None
|
||||
actuators = getattr(car_control, "actuators", None)
|
||||
long_active = bool(getattr(car_control, "longActive", False))
|
||||
starpilot_car_state = sm['starpilotCarState'] if sm.valid.get('starpilotCarState', False) else None
|
||||
pedal_feedback_enabled = ui_state.ui_params.get_bool("PedalsOnUI") or ui_state.ui_params.get_bool("ShowBrakeStatus")
|
||||
self._wheel_tint = get_wheel_tint(
|
||||
getattr(car_state, "brakePressed", False),
|
||||
getattr(car_state, "brakePressed", False) or getattr(car_state, "regenBraking", False),
|
||||
rivian_lateral_mode.wheel_tint,
|
||||
ui_state.ui_params.get_bool("ShowBrakeStatus"),
|
||||
pedal_feedback_enabled,
|
||||
getattr(starpilot_car_state, "brakeLights", False),
|
||||
getattr(car_state, "aEgo", 0.0),
|
||||
getattr(car_state, "gasPressed", False),
|
||||
getattr(actuators, "accel", 0.0) if long_active else 0.0,
|
||||
getattr(actuators, "gas", 0.0) if long_active else 0.0,
|
||||
)
|
||||
|
||||
v_cruise_cluster = car_state.vCruiseCluster
|
||||
|
||||
@@ -14,11 +14,27 @@ from openpilot.starpilot.common.experimental_state import (
|
||||
|
||||
|
||||
BRAKE_WHEEL_COLOR = rl.Color(255, 0, 0, 255)
|
||||
ACCEL_WHEEL_COLOR = rl.Color(22, 127, 64, 255)
|
||||
BRAKE_ACCEL_THRESHOLD = 0.25
|
||||
COMMAND_ACCEL_THRESHOLD = 0.05
|
||||
|
||||
|
||||
def get_wheel_tint(brake_pressed: bool, mode_tint: rl.Color | None, brake_status_enabled: bool,
|
||||
brake_lights: bool = False) -> rl.Color | None:
|
||||
return BRAKE_WHEEL_COLOR if brake_status_enabled and (brake_pressed or brake_lights) else mode_tint
|
||||
def get_wheel_tint(brake_pressed: bool, mode_tint: rl.Color | None, pedal_feedback_enabled: bool,
|
||||
brake_lights: bool = False, acceleration: float = 0.0,
|
||||
gas_pressed: bool = False, commanded_accel: float = 0.0,
|
||||
commanded_gas: float = 0.0) -> rl.Color | None:
|
||||
if not pedal_feedback_enabled:
|
||||
return mode_tint
|
||||
|
||||
braking = brake_pressed or brake_lights or acceleration < -BRAKE_ACCEL_THRESHOLD or \
|
||||
commanded_accel < -COMMAND_ACCEL_THRESHOLD
|
||||
accelerating = gas_pressed or acceleration > BRAKE_ACCEL_THRESHOLD or \
|
||||
commanded_accel > COMMAND_ACCEL_THRESHOLD or commanded_gas > COMMAND_ACCEL_THRESHOLD
|
||||
if braking:
|
||||
return BRAKE_WHEEL_COLOR
|
||||
if accelerating:
|
||||
return ACCEL_WHEEL_COLOR
|
||||
return mode_tint
|
||||
|
||||
|
||||
class ExpButton(Widget):
|
||||
@@ -112,12 +128,21 @@ class ExpButton(Widget):
|
||||
texture = self._txt_exp if exp_mode else self._txt_wheel
|
||||
color = self._white_color
|
||||
tint = None
|
||||
car_state = ui_state.sm["carState"]
|
||||
car_control = ui_state.sm["carControl"] if getattr(ui_state.sm, "valid", {}).get("carControl", False) else None
|
||||
actuators = getattr(car_control, "actuators", None)
|
||||
long_active = bool(getattr(car_control, "longActive", False))
|
||||
starpilot_car_state = ui_state.sm["starpilotCarState"] if getattr(ui_state.sm, "valid", {}).get("starpilotCarState", False) else None
|
||||
pedal_feedback_enabled = self._params.get_bool("PedalsOnUI") or self._params.get_bool("ShowBrakeStatus")
|
||||
wheel_tint = get_wheel_tint(
|
||||
getattr(ui_state.sm["carState"], "brakePressed", False),
|
||||
getattr(car_state, "brakePressed", False) or getattr(car_state, "regenBraking", False),
|
||||
self.wheel_tint,
|
||||
self._params.get_bool("ShowBrakeStatus"),
|
||||
pedal_feedback_enabled,
|
||||
getattr(starpilot_car_state, "brakeLights", False),
|
||||
getattr(car_state, "aEgo", 0.0),
|
||||
getattr(car_state, "gasPressed", False),
|
||||
getattr(actuators, "accel", 0.0) if long_active else 0.0,
|
||||
getattr(actuators, "gas", 0.0) if long_active else 0.0,
|
||||
)
|
||||
if wheel_tint is not None:
|
||||
tint = rl.Color(wheel_tint.r, wheel_tint.g, wheel_tint.b, self._white_color.a)
|
||||
|
||||
@@ -15,7 +15,11 @@ def render_pedal_icons(start_x: float, start_y: float, font):
|
||||
return
|
||||
|
||||
standstill = getattr(car_state, "standstill", False)
|
||||
brake_lights = getattr(car_state, "brakeLights", False)
|
||||
starpilot_car_state = ui_state.sm["starpilotCarState"] if ui_state.sm.valid.get("starpilotCarState", False) else None
|
||||
brake_lights = (getattr(car_state, "brakeLights", False) or
|
||||
getattr(car_state, "brakeLightsDEPRECATED", False) or
|
||||
getattr(car_state, "regenBraking", False) or
|
||||
getattr(starpilot_car_state, "brakeLights", False))
|
||||
acceleration_ego = getattr(car_state, "aEgo", 0.0)
|
||||
|
||||
dynamic_pedals = params.get_bool("DynamicPedalsOnUI")
|
||||
|
||||
@@ -300,7 +300,7 @@ def test_non_mici_wheel_icon_turns_red_when_brakes_are_pressed(monkeypatch):
|
||||
module, draws = load_exp_button(monkeypatch)
|
||||
button = module.ExpButton(192, 144)
|
||||
button.wheel_tint = FakeColor(0x4D, 0x9D, 0xFF, 255)
|
||||
module.ui_state.ui_params.get_bool = lambda key, *args, **kwargs: key == "ShowBrakeStatus"
|
||||
module.ui_state.ui_params.get_bool = lambda key, *args, **kwargs: key == "PedalsOnUI"
|
||||
module.ui_state.sm["carState"].brakePressed = True
|
||||
button._update_state()
|
||||
|
||||
@@ -311,6 +311,20 @@ def test_non_mici_wheel_icon_turns_red_when_brakes_are_pressed(monkeypatch):
|
||||
assert (texture_color.r, texture_color.g, texture_color.b, texture_color.a) == (255, 0, 0, 255)
|
||||
|
||||
|
||||
def test_non_mici_wheel_icon_turns_green_when_accelerating(monkeypatch):
|
||||
module, draws = load_exp_button(monkeypatch)
|
||||
button = module.ExpButton(192, 144)
|
||||
button.wheel_tint = FakeColor(0x4D, 0x9D, 0xFF, 255)
|
||||
module.ui_state.ui_params.get_bool = lambda key, *args, **kwargs: key == "PedalsOnUI"
|
||||
module.ui_state.sm["carState"].aEgo = 0.4
|
||||
button._update_state()
|
||||
|
||||
button._render(FakeRectangle(0, 0, 192, 192))
|
||||
|
||||
texture_color = draws["textures"][0][-1]
|
||||
assert (texture_color.r, texture_color.g, texture_color.b, texture_color.a) == (22, 127, 64, 255)
|
||||
|
||||
|
||||
def test_non_mici_wheel_icon_uses_reported_brake_lights(monkeypatch):
|
||||
module, draws = load_exp_button(monkeypatch)
|
||||
button = module.ExpButton(192, 144)
|
||||
@@ -321,7 +335,7 @@ def test_non_mici_wheel_icon_uses_reported_brake_lights(monkeypatch):
|
||||
module.ui_state.sm = FakeUiSubMaster(module.ui_state.sm)
|
||||
module.ui_state.sm.valid = {"starpilotCarState": True}
|
||||
module.ui_state.sm["starpilotCarState"] = SimpleNamespace(brakeLights=True)
|
||||
module.ui_state.ui_params.get_bool = lambda key, *args, **kwargs: key == "ShowBrakeStatus"
|
||||
module.ui_state.ui_params.get_bool = lambda key, *args, **kwargs: key == "PedalsOnUI"
|
||||
button._update_state()
|
||||
|
||||
button._render(FakeRectangle(0, 0, 192, 192))
|
||||
|
||||
@@ -13,6 +13,7 @@ from openpilot.selfdrive.ui.lib.prime_state import PrimeState
|
||||
from openpilot.selfdrive.ui.lib.ui_param_cache import shared_ui_params
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.starpilot.common.lateral_only_experimental import lateral_only_experimental_available
|
||||
from openpilot.starpilot.common.car_params_capability import capability_car_params_bytes
|
||||
from openpilot.system.hardware import HARDWARE, PC
|
||||
from openpilot.starpilot.common.screen_settings import (
|
||||
alert_wake_key, brightness_preferences, calculate_screen_brightness, enabled_wake_keys, standby_button_press_time,
|
||||
@@ -284,7 +285,7 @@ class UIState:
|
||||
def update_params(self) -> None:
|
||||
# For slower operations
|
||||
# Update longitudinal control state
|
||||
CP_bytes = self.params.get("CarParamsPersistent")
|
||||
CP_bytes = capability_car_params_bytes(self.params)
|
||||
if CP_bytes is not None:
|
||||
self.CP = messaging.log_from_bytes(CP_bytes, car.CarParams)
|
||||
if self.CP.alphaLongitudinalAvailable:
|
||||
@@ -296,6 +297,8 @@ class UIState:
|
||||
lateral_only_experimental_available(self.CP)
|
||||
)
|
||||
else:
|
||||
self.CP = None
|
||||
self.has_longitudinal_control = False
|
||||
self.experimental_mode_available = False
|
||||
self._param_update_time = time.monotonic()
|
||||
|
||||
|
||||
@@ -2768,9 +2768,9 @@
|
||||
},
|
||||
{
|
||||
"key": "PedalsOnUI",
|
||||
"label": "Gas / Brake Pedal Indicators",
|
||||
"description": "On-screen gas and brake indicators.\n\nDynamic: Opacity changes according to how much openpilot is accelerating or braking\nStatic: Full when active, dim when not",
|
||||
"picker_description": "Shows gas and brake indicators on the driving screen.",
|
||||
"label": "Pedal-Responsive Wheel",
|
||||
"description": "Tint the on-screen steering-wheel icon green while accelerating and red while braking. Also show gas and brake indicators.\n\nDynamic: Opacity changes according to how much openpilot is accelerating or braking\nStatic: Full when active, dim when not",
|
||||
"picker_description": "Colors the driving-screen wheel by acceleration and braking, with optional pedal indicators.",
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle",
|
||||
"is_parent_toggle": true,
|
||||
@@ -2807,16 +2807,6 @@
|
||||
"parent_key": "CustomUI",
|
||||
"settings_tier": "simple"
|
||||
},
|
||||
{
|
||||
"key": "ShowBrakeStatus",
|
||||
"label": "Show Brake Status",
|
||||
"description": "Tint the on-screen steering-wheel icon red while the car reports that its brake lights are on.",
|
||||
"picker_description": "Tints the on-screen steering-wheel icon red while the brake lights are on.",
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle",
|
||||
"galaxy_only": true,
|
||||
"settings_tier": "simple"
|
||||
},
|
||||
{
|
||||
"key": "ModelUI",
|
||||
"label": "Model UI",
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
"""Choose a recognized CarParams snapshot for capability-gated settings.
|
||||
|
||||
The current persistent snapshot may temporarily be MOCK while the car process
|
||||
starts. A matching previous route is safe for displaying an *available* toggle;
|
||||
it never enables control or changes the panda safety configuration by itself.
|
||||
"""
|
||||
|
||||
from cereal import car
|
||||
|
||||
|
||||
def _fingerprint(raw: bytes | None) -> str:
|
||||
if not raw:
|
||||
return ""
|
||||
try:
|
||||
with car.CarParams.from_bytes(raw) as cp:
|
||||
return str(cp.carFingerprint)
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def capability_car_params_bytes(params) -> bytes | None:
|
||||
"""Prefer live/recognized params; fallback only to the exact forced model."""
|
||||
model = params.get("CarModel", encoding="utf-8") or ""
|
||||
forced = params.get_bool("ForceFingerprint")
|
||||
current_keys = ("CarParams", "CarParamsPersistent") if params.get_bool("IsOnroad") else ("CarParamsPersistent",)
|
||||
|
||||
for key in current_keys:
|
||||
raw = params.get(key)
|
||||
fingerprint = _fingerprint(raw)
|
||||
if fingerprint and fingerprint != "MOCK":
|
||||
if forced and model and fingerprint != model:
|
||||
return None
|
||||
return raw
|
||||
|
||||
if forced and model:
|
||||
previous = params.get("CarParamsPrevRoute")
|
||||
if _fingerprint(previous) == model:
|
||||
return previous
|
||||
return None
|
||||
@@ -0,0 +1,63 @@
|
||||
from cereal import car
|
||||
|
||||
from openpilot.starpilot.common.car_params_capability import capability_car_params_bytes
|
||||
|
||||
|
||||
class FakeParams:
|
||||
def __init__(self, values):
|
||||
self.values = values
|
||||
|
||||
def get(self, key, encoding=None):
|
||||
value = self.values.get(key)
|
||||
return value.decode() if encoding and isinstance(value, bytes) else value
|
||||
|
||||
def get_bool(self, key):
|
||||
return self.values.get(key) in (True, b"1", "1")
|
||||
|
||||
|
||||
def cp_bytes(fingerprint, alpha_available=False):
|
||||
cp = car.CarParams.new_message()
|
||||
cp.carFingerprint = fingerprint
|
||||
cp.alphaLongitudinalAvailable = alpha_available
|
||||
return cp.to_bytes()
|
||||
|
||||
|
||||
def test_matching_previous_route_unblocks_capability_after_transient_mock():
|
||||
hw1 = cp_bytes("TESLA_MODEL_S_HW1", alpha_available=True)
|
||||
params = FakeParams({
|
||||
"CarModel": "TESLA_MODEL_S_HW1", "ForceFingerprint": True,
|
||||
"CarParamsPersistent": cp_bytes("MOCK"), "CarParamsPrevRoute": hw1,
|
||||
})
|
||||
assert capability_car_params_bytes(params) == hw1
|
||||
|
||||
|
||||
def test_live_recognized_params_take_precedence_over_previous_route():
|
||||
hw1 = cp_bytes("TESLA_MODEL_S_HW1", alpha_available=True)
|
||||
live = cp_bytes("TESLA_MODEL_S_HW1", alpha_available=False)
|
||||
params = FakeParams({
|
||||
"CarModel": "TESLA_MODEL_S_HW1", "ForceFingerprint": True, "IsOnroad": True,
|
||||
"CarParams": live, "CarParamsPersistent": cp_bytes("MOCK"), "CarParamsPrevRoute": hw1,
|
||||
})
|
||||
assert capability_car_params_bytes(params) == live
|
||||
|
||||
|
||||
def test_previous_route_must_match_explicit_forced_model():
|
||||
previous = cp_bytes("TESLA_MODEL_S_HW1", alpha_available=True)
|
||||
params = FakeParams({
|
||||
"CarModel": "TESLA_MODEL_S_PREAP", "ForceFingerprint": True,
|
||||
"CarParamsPersistent": cp_bytes("MOCK"), "CarParamsPrevRoute": previous,
|
||||
})
|
||||
assert capability_car_params_bytes(params) is None
|
||||
|
||||
params.values["CarModel"] = "TESLA_MODEL_S_HW1"
|
||||
params.values["ForceFingerprint"] = False
|
||||
assert capability_car_params_bytes(params) is None
|
||||
|
||||
|
||||
def test_current_recognized_mismatch_blocks_stale_fallback():
|
||||
params = FakeParams({
|
||||
"CarModel": "TESLA_MODEL_S_HW1", "ForceFingerprint": True,
|
||||
"CarParamsPersistent": cp_bytes("TESLA_MODEL_S_PREAP"),
|
||||
"CarParamsPrevRoute": cp_bytes("TESLA_MODEL_S_HW1", alpha_available=True),
|
||||
})
|
||||
assert capability_car_params_bytes(params) is None
|
||||
@@ -111,13 +111,14 @@ def test_driving_personality_controls_are_not_parked_only():
|
||||
assert all(params[key].get("requires_offroad") is not True for key in personality_keys)
|
||||
|
||||
|
||||
def test_brake_status_toggle_is_galaxy_only():
|
||||
setting = _params_by_section(_layout())["Visual (Display & UI)"]["ShowBrakeStatus"]
|
||||
def test_pedal_feedback_wheel_uses_existing_pedal_toggle():
|
||||
setting = _params_by_section(_layout())["Visual (Display & UI)"]["PedalsOnUI"]
|
||||
|
||||
assert _declared_default("ShowBrakeStatus") == "0"
|
||||
assert setting["galaxy_only"] is True
|
||||
assert _declared_default("PedalsOnUI") == "0"
|
||||
assert setting["label"] == "Pedal-Responsive Wheel"
|
||||
assert setting["settings_tier"] == "simple"
|
||||
assert setting["ui_type"] == "toggle"
|
||||
assert "ShowBrakeStatus" not in _params_by_section(_layout())["Visual (Display & UI)"]
|
||||
|
||||
|
||||
def test_ford_lateral_controls_are_ford_only_and_galaxy_only():
|
||||
|
||||
@@ -78,6 +78,7 @@ from openpilot.starpilot.common.model_lab import (
|
||||
)
|
||||
from openpilot.starpilot.assets.theme_manager import HOLIDAY_THEME_PATH, THEME_COMPONENT_PARAMS
|
||||
from openpilot.starpilot.common import param_profiles
|
||||
from openpilot.starpilot.common.car_params_capability import capability_car_params_bytes
|
||||
from openpilot.starpilot.system.the_galaxy import version_history, version_install
|
||||
from openpilot.starpilot.common.accel_profile import (
|
||||
A_CRUISE_MAX_BP_CUSTOM,
|
||||
@@ -4463,7 +4464,7 @@ def _get_is_tici_or_tizi():
|
||||
return HARDWARE.get_device_type() in ("tici", "tizi")
|
||||
|
||||
def _get_alpha_longitudinal_available():
|
||||
cp_bytes = _safe_params_get_live_raw("CarParamsPersistent")
|
||||
cp_bytes = capability_car_params_bytes(params)
|
||||
if not cp_bytes:
|
||||
return False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user