ICCU FAILURE

This commit is contained in:
firestar5683
2026-08-29 11:55:16 -05:00
parent 4486dc2f14
commit 465ac2651a
9 changed files with 68 additions and 18 deletions
+2 -2
View File
@@ -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"]
+1 -1
View File
@@ -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
+4 -5
View File
@@ -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:
+21 -6
View File
@@ -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)
+2 -1
View File
@@ -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):
+1 -1
View File
@@ -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")