mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-09 01:23:43 +08:00
ICCU FAILURE
This commit is contained in:
@@ -4,7 +4,7 @@ from opendbc.can import CANDefine, CANParser
|
||||
from opendbc.car import Bus, structs
|
||||
from opendbc.car.common.conversions import Conversions as CV
|
||||
from opendbc.car.interfaces import CarStateBase
|
||||
from opendbc.car.subaru.values import CAR, DBC, CanBus, SubaruFlags
|
||||
from opendbc.car.subaru.values import DBC, CanBus, SUBARU_STOP_START_CARS, SubaruFlags
|
||||
from opendbc.car import CanSignalRateCalculator
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class CarState(CarStateBase):
|
||||
cp_angle = cp_main if self.CP.flags & SubaruFlags.D_PLATFORM else cp
|
||||
ret = structs.CarState()
|
||||
|
||||
if self.CP.carFingerprint == CAR.SUBARU_OUTBACK_2023:
|
||||
if self.CP.carFingerprint in SUBARU_STOP_START_CARS:
|
||||
self.dashlights_msg = copy.copy(cp.vl["Dashlights"])
|
||||
self.stop_start_state = cp.vl["Engine_Stop_Start"]["STOP_START_STATE"]
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ def create_es_dashstatus(packer, frame, dashstatus_msg, enabled, long_enabled, l
|
||||
|
||||
|
||||
def create_stop_start_control(packer, dashlights_msg, counter=None, bus=CanBus.alt):
|
||||
"""Create the Outback 2023-24 momentary Stop/Start button request.
|
||||
"""Create the supported Subaru momentary Stop/Start button request.
|
||||
|
||||
Dashlights is a stock periodic message, so preserve the live frame and only
|
||||
change the event bit. CANPacker calculates the Subaru checksum for us.
|
||||
|
||||
@@ -206,6 +206,21 @@ def test_outback_2023_uses_d_platform_bus_layout():
|
||||
assert CP.lateralSmoothSeconds == pytest.approx(0.4)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("platform", [CAR.SUBARU_OUTBACK_2023, CAR.SUBARU_LEGACY_2025])
|
||||
def test_stop_start_inputs_are_captured_for_supported_models(platform):
|
||||
CP = CarInterface.get_non_essential_params(platform)
|
||||
car_state = CarState(CP, None)
|
||||
parsers = car_state.get_can_parsers(CP)
|
||||
parsers[Bus.pt].vl["Dashlights"]["COUNTER"] = 6
|
||||
parsers[Bus.pt].vl["Dashlights"]["STOP_START"] = 0
|
||||
parsers[Bus.pt].vl["Engine_Stop_Start"]["STOP_START_STATE"] = 3
|
||||
|
||||
car_state.update(parsers, SimpleNamespace(subaru_sng=False))
|
||||
|
||||
assert car_state.dashlights_msg["COUNTER"] == 6
|
||||
assert car_state.stop_start_state == 3
|
||||
|
||||
|
||||
@pytest.mark.parametrize("platform, expected_bus", [
|
||||
(CAR.SUBARU_OUTBACK_2023, CanBus.alt),
|
||||
(CAR.SUBARU_LEGACY_2025, CanBus.main),
|
||||
|
||||
@@ -218,12 +218,12 @@ GENESIS_GV70_FRICTION_CENTER_LAT = 0.28
|
||||
GENESIS_GV70_FRICTION_CENTER_LAT_WIDTH = 0.12
|
||||
GENESIS_GV70_FRICTION_CALM_JERK = 0.35
|
||||
GENESIS_GV70_FRICTION_CALM_JERK_WIDTH = 0.10
|
||||
GENESIS_GV70_FRICTION_JERK_DEADZONE_MAX = 0.30
|
||||
GENESIS_GV70_FRICTION_JERK_DEADZONE_MAX = 0.36
|
||||
GENESIS_GV70_FRICTION_JERK_DEADZONE_LAT = 0.30
|
||||
GENESIS_GV70_FRICTION_JERK_DEADZONE_LAT_WIDTH = 0.08
|
||||
GENESIS_GV70_FRICTION_JERK_DEADZONE_SPEED = 12.0 * CV.MPH_TO_MS
|
||||
GENESIS_GV70_FRICTION_JERK_DEADZONE_SPEED_WIDTH = 3.5 * CV.MPH_TO_MS
|
||||
GENESIS_GV70_CENTER_OUTPUT_TAPER_MAX = 0.14
|
||||
GENESIS_GV70_CENTER_OUTPUT_TAPER_MAX = 0.20
|
||||
GENESIS_GV70_CENTER_OUTPUT_TAPER_LAT = 0.30
|
||||
GENESIS_GV70_CENTER_OUTPUT_TAPER_LAT_WIDTH = 0.10
|
||||
GENESIS_GV70_CENTER_OUTPUT_TAPER_SPEED = 22.0 * CV.MPH_TO_MS
|
||||
|
||||
@@ -18,13 +18,12 @@ LONGITUDINAL_ONLY_COLOR = rl.Color(255, 105, 180, 255)
|
||||
|
||||
|
||||
def is_longitudinal_only_active(state: UIState) -> bool:
|
||||
"""Return true when control is enabled but lateral control is inactive.
|
||||
"""Return true when the user has paused lateral while control is enabled.
|
||||
|
||||
Do not use carControl.longActive here: stock-cruise cars intentionally leave
|
||||
that field false while the vehicle's own longitudinal controller is active.
|
||||
carControl.latActive also becomes false when lateral is temporarily unavailable,
|
||||
such as below minimum steer speed, so it does not represent user intent.
|
||||
"""
|
||||
car_control = state.sm["carControl"]
|
||||
return bool(state.sm["selfdriveState"].enabled and not car_control.latActive)
|
||||
return bool(state.sm["selfdriveState"].enabled and state.sm["starpilotCarState"].pauseLateral)
|
||||
|
||||
|
||||
def _override_color_applies(state: UIState) -> bool:
|
||||
|
||||
@@ -12,11 +12,12 @@ from openpilot.selfdrive.ui.lib.starpilot_status import (
|
||||
from openpilot.selfdrive.ui.ui_state import UIStatus
|
||||
|
||||
|
||||
def _state(*, enabled=False, lat_active=False, aol=False, status=None, events=()):
|
||||
def _state(*, enabled=False, lat_active=False, pause_lateral=False, aol=False, status=None, events=()):
|
||||
return SimpleNamespace(
|
||||
sm={
|
||||
"selfdriveState": SimpleNamespace(enabled=enabled, experimentalMode=False),
|
||||
"carControl": SimpleNamespace(latActive=lat_active),
|
||||
"starpilotCarState": SimpleNamespace(pauseLateral=pause_lateral),
|
||||
"onroadEvents": events,
|
||||
},
|
||||
status=status if status is not None else (UIStatus.ENGAGED if enabled else UIStatus.DISENGAGED),
|
||||
@@ -31,8 +32,22 @@ def _rgb(color):
|
||||
return color.r, color.g, color.b
|
||||
|
||||
|
||||
def test_cruise_only_uses_pink_for_border_and_screen_edge():
|
||||
state = _state(enabled=True, lat_active=False)
|
||||
def test_manual_lateral_pause_uses_pink_for_border_and_screen_edge():
|
||||
state = _state(enabled=True, lat_active=False, pause_lateral=True)
|
||||
|
||||
assert _rgb(get_border_color(state)) == _rgb(LONGITUDINAL_ONLY_COLOR)
|
||||
assert _rgb(get_screen_edge_color(state)) == _rgb(LONGITUDINAL_ONLY_COLOR)
|
||||
|
||||
|
||||
def test_temporary_lateral_inactivity_does_not_use_pink():
|
||||
state = _state(enabled=True, lat_active=False, pause_lateral=False)
|
||||
|
||||
assert _rgb(get_border_color(state)) == _rgb(ENGAGED_COLOR)
|
||||
assert _rgb(get_screen_edge_color(state)) == _rgb(ENGAGED_COLOR)
|
||||
|
||||
|
||||
def test_manual_pause_signal_controls_pink_independent_of_lat_active_timing():
|
||||
state = _state(enabled=True, lat_active=True, pause_lateral=True)
|
||||
|
||||
assert _rgb(get_border_color(state)) == _rgb(LONGITUDINAL_ONLY_COLOR)
|
||||
assert _rgb(get_screen_edge_color(state)) == _rgb(LONGITUDINAL_ONLY_COLOR)
|
||||
@@ -53,10 +68,10 @@ def test_override_color_matches_active_control_mode():
|
||||
assert _rgb(get_border_color(_state(enabled=True, lat_active=True, status=override, events=[lateral_override]))) == _rgb(OVERRIDE_COLOR)
|
||||
assert _rgb(get_border_color(_state(enabled=True, lat_active=True, status=override, events=[longitudinal_override]))) == _rgb(OVERRIDE_COLOR)
|
||||
|
||||
# Pink: steering is already inactive, so only a longitudinal override is gray.
|
||||
pink_state = _state(enabled=True, status=override, events=[lateral_override])
|
||||
pink_state = _state(enabled=True, pause_lateral=True, status=override, events=[lateral_override])
|
||||
assert _rgb(get_border_color(pink_state)) == _rgb(LONGITUDINAL_ONLY_COLOR)
|
||||
assert _rgb(get_border_color(_state(enabled=True, status=override, events=[longitudinal_override]))) == _rgb(OVERRIDE_COLOR)
|
||||
assert _rgb(get_border_color(_state(enabled=True, pause_lateral=True, status=override,
|
||||
events=[longitudinal_override]))) == _rgb(OVERRIDE_COLOR)
|
||||
|
||||
# Blue/AOL: longitudinal override is inactive, so only steering is gray.
|
||||
assert _rgb(get_border_color(_state(aol=True, status=override, events=[lateral_override]))) == _rgb(OVERRIDE_COLOR)
|
||||
|
||||
@@ -94,7 +94,8 @@ class LPABase(ABC):
|
||||
def switch_profile(self, iccid: str) -> None:
|
||||
pass
|
||||
|
||||
def is_comma_profile(self, iccid: str) -> bool:
|
||||
@staticmethod
|
||||
def is_comma_profile(iccid: str) -> bool:
|
||||
return any(iccid.startswith(prefix) for prefix in ('8985235',))
|
||||
|
||||
class HardwareBase(ABC):
|
||||
|
||||
@@ -518,7 +518,7 @@ class Tici(HardwareBase):
|
||||
|
||||
# eSIM prime
|
||||
dest = "/etc/NetworkManager/system-connections/esim.nmconnection"
|
||||
if self.get_sim_lpa().is_comma_profile(sim_id) and not os.path.exists(dest):
|
||||
if LPABase.is_comma_profile(sim_id) and not os.path.exists(dest):
|
||||
with open(Path(__file__).parent/'esim.nmconnection') as f, tempfile.NamedTemporaryFile(mode='w') as tf:
|
||||
dat = f.read()
|
||||
dat = dat.replace("sim-id=", f"sim-id={sim_id}")
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
from openpilot.system.hardware.base import LPABase
|
||||
from openpilot.system.hardware.tici.hardware import Tici
|
||||
|
||||
|
||||
def test_comma_profile_detection_without_lpa(mocker):
|
||||
hardware = Tici()
|
||||
modem = mocker.MagicMock()
|
||||
modem.Get.return_value = "Quectel"
|
||||
|
||||
mocker.patch.object(hardware, "get_sim_info", return_value={"sim_id": "8985235000000000000"})
|
||||
mocker.patch.object(hardware, "get_modem", return_value=modem)
|
||||
mocker.patch.object(hardware, "get_device_type", return_value="mici")
|
||||
get_sim_lpa = mocker.patch.object(hardware, "get_sim_lpa")
|
||||
mocker.patch("openpilot.system.hardware.tici.hardware.os.path.exists", return_value=True)
|
||||
|
||||
hardware.configure_modem()
|
||||
|
||||
get_sim_lpa.assert_not_called()
|
||||
assert LPABase.is_comma_profile("8985235000000000000")
|
||||
assert not LPABase.is_comma_profile("8900000000000000000")
|
||||
Reference in New Issue
Block a user