mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-23 01:04:01 +08:00
nisswan
This commit is contained in:
@@ -367,10 +367,8 @@ class Car:
|
||||
was_openpilot_long = self.CP.openpilotLongitudinalControl
|
||||
self.CI.init(self.CP, *self.can_callbacks)
|
||||
# If ECU disable was skipped/failed, strip LONG safety flag from BOTH CarParams
|
||||
# and StarPilotCarParams (pandad ORs both safetyParams together)
|
||||
# Use the pre-init longitudinal state here, since Hyundai init() may already
|
||||
# flip CP.openpilotLongitudinalControl to False as part of the fallback.
|
||||
if was_openpilot_long and self.CP.brand in ("hyundai", "nissan") and self.params.get_bool("EcuDisableFailed"):
|
||||
nissan_leaf_alpha_long = self.CP.brand == "nissan" and self.CP.carFingerprint == "NISSAN_LEAF"
|
||||
if was_openpilot_long and (self.CP.brand == "hyundai" or nissan_leaf_alpha_long) and self.params.get_bool("EcuDisableFailed"):
|
||||
# ECU disable failed/rejected - switch to lateral-only mode with stock ACC
|
||||
# Keep this local to avoid importing every brand's values into card.py.
|
||||
LONG_FLAG = 4 if self.CP.brand == "hyundai" else 2 if self.CP.brand == "nissan" else 0
|
||||
@@ -378,9 +376,6 @@ class Car:
|
||||
cfg.safetyParam &= ~LONG_FLAG
|
||||
for cfg in self.FPCP.safetyConfigs:
|
||||
cfg.safetyParam &= ~LONG_FLAG
|
||||
# Let stock ACC manage cruise (prevents "controls mismatch" error)
|
||||
# Clear openpilotLongitudinalControl so controlsd doesn't set
|
||||
# cruiseControl.override=True (which fights stock ACC and causes engage flicker)
|
||||
self.CP.pcmCruise = True
|
||||
self.CP.openpilotLongitudinalControl = False
|
||||
self.params.put("CarParams", self.CP.to_bytes())
|
||||
|
||||
@@ -12,6 +12,7 @@ from openpilot.common.swaglog import cloudlog
|
||||
from opendbc.car.car_helpers import interfaces
|
||||
from opendbc.car.chrysler.values import pacifica_hybrid_aol_stock_acc_mode
|
||||
from opendbc.car.gm.values import CAR as GM_CAR
|
||||
from opendbc.car.nissan.values import CAR as NISSAN_CAR
|
||||
from opendbc.car.vehicle_model import VehicleModel
|
||||
from openpilot.selfdrive.controls.lib.drive_helpers import MAX_LATERAL_JERK, clip_curvature, get_lateral_active
|
||||
from openpilot.selfdrive.controls.lib.lane_centering import LaneCenteringController
|
||||
@@ -365,11 +366,12 @@ class Controls:
|
||||
if self.ecu_disable_failed_checked:
|
||||
return
|
||||
|
||||
# ControlsReady is set after CarInterface.init(), where Hyundai ECU disable
|
||||
# writes EcuDisableFailed. Once init has completed, the value is stable.
|
||||
if self.params.get_bool("ControlsReady"):
|
||||
self.ecu_disable_failed = self.params.get_bool("EcuDisableFailed")
|
||||
self.ecu_disable_failed_checked = True
|
||||
if self.ecu_disable_failed and self.CP.carFingerprint == NISSAN_CAR.NISSAN_LEAF:
|
||||
self.CP.openpilotLongitudinalControl = False
|
||||
self.CP.pcmCruise = True
|
||||
|
||||
def state_control(self):
|
||||
CS = self.sm['carState']
|
||||
|
||||
@@ -13,6 +13,7 @@ from msgq.visionipc import VisionIpcClient, VisionStreamType
|
||||
from opendbc.car.chrysler.values import pacifica_hybrid_aol_stock_acc_mode
|
||||
from opendbc.car.gm.values import GMFlags
|
||||
from opendbc.car.hyundai.values import CAR as HYUNDAI_CAR
|
||||
from opendbc.car.nissan.values import CAR as NISSAN_CAR
|
||||
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper, DT_CTRL
|
||||
@@ -223,6 +224,10 @@ class SelfdriveD:
|
||||
self.logged_comm_issue = None
|
||||
self.not_running_prev = None
|
||||
self.experimental_mode = False
|
||||
self.ecu_disable_failed = False
|
||||
self.ecu_disable_failed_checked = not (
|
||||
self.CP.openpilotLongitudinalControl and self.CP.carFingerprint == NISSAN_CAR.NISSAN_LEAF
|
||||
)
|
||||
self.safe_mode = self.params.get_bool("SafeMode")
|
||||
self.personality = log.LongitudinalPersonality.relaxed if self.safe_mode else self.params.get("LongitudinalPersonality", return_default=True)
|
||||
self.recalibrating_seen = False
|
||||
@@ -276,6 +281,23 @@ class SelfdriveD:
|
||||
|
||||
self.FPCP = messaging.log_from_bytes(self.params.get("StarPilotCarParams", block=True), custom.StarPilotCarParams)
|
||||
|
||||
def update_ecu_disable_failed(self):
|
||||
if self.ecu_disable_failed_checked:
|
||||
return
|
||||
if self.CP.carFingerprint != NISSAN_CAR.NISSAN_LEAF:
|
||||
self.ecu_disable_failed_checked = True
|
||||
return
|
||||
|
||||
if self.params.get_bool("ControlsReady"):
|
||||
self.ecu_disable_failed = self.params.get_bool("EcuDisableFailed")
|
||||
self.ecu_disable_failed_checked = True
|
||||
if self.ecu_disable_failed:
|
||||
fallback_cp = messaging.log_from_bytes(self.params.get("CarParams"), car.CarParams)
|
||||
fallback_fpcp = messaging.log_from_bytes(self.params.get("StarPilotCarParams"), custom.StarPilotCarParams)
|
||||
self.CP.openpilotLongitudinalControl = fallback_cp.openpilotLongitudinalControl
|
||||
self.CP.pcmCruise = fallback_cp.pcmCruise
|
||||
self.FPCP = fallback_fpcp
|
||||
|
||||
def clear_longitudinal_excessive_actuation_alert(self):
|
||||
alert = self.params.get("Offroad_ExcessiveActuation")
|
||||
if not alert:
|
||||
@@ -305,6 +327,7 @@ class SelfdriveD:
|
||||
def update_events(self, CS):
|
||||
"""Compute onroadEvents from carState"""
|
||||
|
||||
self.update_ecu_disable_failed()
|
||||
self.events.clear()
|
||||
self.starpilot_events.clear()
|
||||
|
||||
|
||||
@@ -1,7 +1,24 @@
|
||||
from cereal import car
|
||||
from cereal import car, custom
|
||||
from opendbc.car.hyundai.values import CAR as HYUNDAI_CAR
|
||||
from opendbc.car.nissan.values import CAR as NISSAN_CAR
|
||||
|
||||
from openpilot.selfdrive.selfdrived.selfdrived import commanded_torque_at_max_for_saturation
|
||||
from openpilot.selfdrive.selfdrived.selfdrived import SelfdriveD, commanded_torque_at_max_for_saturation
|
||||
|
||||
|
||||
class FakeFallbackParams:
|
||||
def __init__(self, controls_ready, ecu_disable_failed, fallback_cp, fallback_fpcp):
|
||||
self.controls_ready = controls_ready
|
||||
self.ecu_disable_failed = ecu_disable_failed
|
||||
self.values = {
|
||||
"CarParams": fallback_cp.to_bytes(),
|
||||
"StarPilotCarParams": fallback_fpcp.to_bytes(),
|
||||
}
|
||||
|
||||
def get_bool(self, key):
|
||||
return self.controls_ready if key == "ControlsReady" else self.ecu_disable_failed
|
||||
|
||||
def get(self, key):
|
||||
return self.values[key]
|
||||
|
||||
|
||||
def test_immediate_max_output_saturation_is_torque_controller_only():
|
||||
@@ -27,3 +44,64 @@ def test_gv70_uses_normal_saturation_timer_at_max_output():
|
||||
CP.lateralTuning.init("torque")
|
||||
|
||||
assert not commanded_torque_at_max_for_saturation(CP, 1.0)
|
||||
|
||||
|
||||
def test_ecu_disable_fallback_synchronizes_behavior_and_safety_params():
|
||||
initial_cp = car.CarParams.new_message()
|
||||
initial_cp.carFingerprint = NISSAN_CAR.NISSAN_LEAF
|
||||
initial_cp.openpilotLongitudinalControl = True
|
||||
initial_cp.pcmCruise = False
|
||||
initial_cp.safetyConfigs = [car.CarParams.SafetyConfig.new_message(safetyParam=2)]
|
||||
initial_fpcp = custom.StarPilotCarParams.new_message()
|
||||
initial_fpcp.safetyConfigs = [custom.StarPilotCarParams.SafetyConfig.new_message(safetyParam=2)]
|
||||
|
||||
fallback_cp = car.CarParams.new_message()
|
||||
fallback_cp.openpilotLongitudinalControl = False
|
||||
fallback_cp.pcmCruise = True
|
||||
fallback_cp.safetyConfigs = [car.CarParams.SafetyConfig.new_message(safetyParam=0)]
|
||||
fallback_fpcp = custom.StarPilotCarParams.new_message()
|
||||
fallback_fpcp.safetyConfigs = [custom.StarPilotCarParams.SafetyConfig.new_message(safetyParam=0)]
|
||||
|
||||
selfdrived = SelfdriveD.__new__(SelfdriveD)
|
||||
selfdrived.CP = initial_cp
|
||||
selfdrived.FPCP = initial_fpcp
|
||||
selfdrived.params = FakeFallbackParams(True, True, fallback_cp, fallback_fpcp)
|
||||
selfdrived.ecu_disable_failed = False
|
||||
selfdrived.ecu_disable_failed_checked = False
|
||||
|
||||
selfdrived.update_ecu_disable_failed()
|
||||
|
||||
assert selfdrived.ecu_disable_failed
|
||||
assert selfdrived.ecu_disable_failed_checked
|
||||
assert not selfdrived.CP.openpilotLongitudinalControl
|
||||
assert selfdrived.CP.pcmCruise
|
||||
assert selfdrived.FPCP.safetyConfigs[0].safetyParam == 0
|
||||
|
||||
|
||||
def test_ecu_disable_fallback_does_not_change_other_cars():
|
||||
initial_cp = car.CarParams.new_message()
|
||||
initial_cp.carFingerprint = HYUNDAI_CAR.HYUNDAI_SONATA
|
||||
initial_cp.openpilotLongitudinalControl = True
|
||||
initial_cp.pcmCruise = False
|
||||
initial_fpcp = custom.StarPilotCarParams.new_message()
|
||||
initial_fpcp.safetyConfigs = [custom.StarPilotCarParams.SafetyConfig.new_message(safetyParam=4)]
|
||||
|
||||
fallback_cp = car.CarParams.new_message()
|
||||
fallback_cp.openpilotLongitudinalControl = False
|
||||
fallback_cp.pcmCruise = True
|
||||
fallback_fpcp = custom.StarPilotCarParams.new_message()
|
||||
fallback_fpcp.safetyConfigs = [custom.StarPilotCarParams.SafetyConfig.new_message(safetyParam=0)]
|
||||
|
||||
selfdrived = SelfdriveD.__new__(SelfdriveD)
|
||||
selfdrived.CP = initial_cp
|
||||
selfdrived.FPCP = initial_fpcp
|
||||
selfdrived.params = FakeFallbackParams(True, True, fallback_cp, fallback_fpcp)
|
||||
selfdrived.ecu_disable_failed = False
|
||||
selfdrived.ecu_disable_failed_checked = False
|
||||
|
||||
selfdrived.update_ecu_disable_failed()
|
||||
|
||||
assert selfdrived.ecu_disable_failed_checked
|
||||
assert selfdrived.CP.openpilotLongitudinalControl
|
||||
assert not selfdrived.CP.pcmCruise
|
||||
assert selfdrived.FPCP.safetyConfigs[0].safetyParam == 4
|
||||
|
||||
Reference in New Issue
Block a user