From c7a71c36cebce2224ced4b5cb5236537f68ccd32 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Sun, 1 Feb 2026 22:03:59 -0500 Subject: [PATCH] Revert "Toyota: remove NO_STOP_TIMER flag (#3076)" This reverts commit 1cd92abbf86b50ccd0a5782e6a5d598c14d94e7e. --- opendbc/car/toyota/carcontroller.py | 29 ++++++++++++++++++++++------- opendbc/car/toyota/carstate.py | 13 ++++++++----- opendbc/car/toyota/interface.py | 9 +++++---- opendbc/car/toyota/values.py | 15 +++++++++++---- 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/opendbc/car/toyota/carcontroller.py b/opendbc/car/toyota/carcontroller.py index 82371d43..e5e3df96 100644 --- a/opendbc/car/toyota/carcontroller.py +++ b/opendbc/car/toyota/carcontroller.py @@ -8,7 +8,9 @@ from opendbc.car.common.pid import PIDController from opendbc.car.secoc import add_mac, build_sync_mac from opendbc.car.interfaces import CarControllerBase from opendbc.car.toyota import toyotacan -from opendbc.car.toyota.values import CAR, TSS2_CAR, UNSUPPORTED_DSU_CAR, CarControllerParams, ToyotaFlags +from opendbc.car.toyota.values import CAR, NO_STOP_TIMER_CAR, TSS2_CAR, \ + CarControllerParams, ToyotaFlags, \ + UNSUPPORTED_DSU_CAR from opendbc.can import CANPacker Ecu = structs.CarParams.Ecu @@ -53,6 +55,7 @@ class CarController(CarControllerBase): self.last_torque = 0 self.last_angle = 0 self.alert_active = False + self.last_standstill = False self.standstill_req = False self.permit_braking = True self.steer_rate_counter = 0 @@ -165,13 +168,17 @@ class CarController(CarControllerBase): self.secoc_lta_message_counter += 1 can_sends.append(lta_steer_2) - # handle UI messages - fcw_alert = hud_control.visualAlert == VisualAlert.fcw - steer_alert = hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw) - lead = hud_control.leadVisible or CS.out.vEgo < 12. # at low speed we always assume the lead is present so ACC can be engaged - # *** gas and brake *** - if self.CP.openpilotLongitudinalControl: + + # on entering standstill, send standstill request for older TSS-P cars that aren't designed to stay engaged at a stop + if self.CP.carFingerprint not in NO_STOP_TIMER_CAR: + if CS.out.standstill and not self.last_standstill: + self.standstill_req = True + if CS.pcm_acc_status != 8: + # pcm entered standstill or it's disabled + self.standstill_req = False + + else: # if user engages at a stop with foot on brake, PCM starts in a special cruise standstill mode. on resume press, # brakes can take a while to ramp up causing a lurch forward. prevent resume press until planner wants to move. # don't use CC.cruiseControl.resume since it is gated on CS.cruiseState.standstill which goes false for 3s after resume press @@ -184,6 +191,14 @@ class CarController(CarControllerBase): if not should_resume and CS.out.cruiseState.standstill: self.standstill_req = True + self.last_standstill = CS.out.standstill + + # handle UI messages + fcw_alert = hud_control.visualAlert == VisualAlert.fcw + steer_alert = hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw) + lead = hud_control.leadVisible or CS.out.vEgo < 12. # at low speed we always assume the lead is present so ACC can be engaged + + if self.CP.openpilotLongitudinalControl: if self.frame % 3 == 0: # Press distance button until we are at the correct bar length. Only change while enabled to avoid skipping startup popup if self.frame % 6 == 0 and self.CP.openpilotLongitudinalControl: diff --git a/opendbc/car/toyota/carstate.py b/opendbc/car/toyota/carstate.py index ca50e70b..3fb22740 100644 --- a/opendbc/car/toyota/carstate.py +++ b/opendbc/car/toyota/carstate.py @@ -5,8 +5,9 @@ from opendbc.car import Bus, DT_CTRL, create_button_events, structs from opendbc.car.common.conversions import Conversions as CV from opendbc.car.common.filter_simple import FirstOrderFilter from opendbc.car.interfaces import CarStateBase -from opendbc.car.toyota.values import ToyotaFlags, CAR, DBC, STEER_THRESHOLD, TSS2_CAR, RADAR_ACC_CAR, \ - EPS_SCALE, UNSUPPORTED_DSU_CAR, SECOC_CAR +from opendbc.car.toyota.values import ToyotaFlags, CAR, DBC, STEER_THRESHOLD, NO_STOP_TIMER_CAR, \ + TSS2_CAR, RADAR_ACC_CAR, EPS_SCALE, UNSUPPORTED_DSU_CAR, \ + SECOC_CAR ButtonType = structs.CarState.ButtonEvent.Type SteerControlType = structs.CarParams.SteerControlType @@ -159,10 +160,12 @@ class CarState(CarStateBase): if self.CP.openpilotLongitudinalControl: ret.accFaulted = ret.accFaulted or cp.vl["PCM_CRUISE_2"]["LOW_SPEED_LOCKOUT"] == 2 - pcm_acc_status = cp.vl["PCM_CRUISE"]["CRUISE_STATE"] - ret.cruiseState.standstill = pcm_acc_status == 7 + self.pcm_acc_status = cp.vl["PCM_CRUISE"]["CRUISE_STATE"] + if self.CP.carFingerprint not in (NO_STOP_TIMER_CAR - TSS2_CAR): + # ignore standstill state in certain vehicles, since pcm allows to restart with just an acceleration request + ret.cruiseState.standstill = self.pcm_acc_status == 7 ret.cruiseState.enabled = bool(cp.vl["PCM_CRUISE"]["CRUISE_ACTIVE"]) - ret.cruiseState.nonAdaptive = pcm_acc_status in (1, 2, 3, 4, 5, 6) + ret.cruiseState.nonAdaptive = self.pcm_acc_status in (1, 2, 3, 4, 5, 6) ret.genericToggle = bool(cp.vl["LIGHT_STALK"]["AUTO_HIGH_BEAM"]) ret.espDisabled = cp.vl["ESP_CONTROL"]["TC_DISABLED"] != 0 diff --git a/opendbc/car/toyota/interface.py b/opendbc/car/toyota/interface.py index 5f44a58e..03cab7dd 100644 --- a/opendbc/car/toyota/interface.py +++ b/opendbc/car/toyota/interface.py @@ -3,7 +3,7 @@ from opendbc.car.toyota.carstate import CarState from opendbc.car.toyota.carcontroller import CarController from opendbc.car.toyota.radar_interface import RadarInterface from opendbc.car.toyota.values import Ecu, CAR, DBC, ToyotaFlags, CarControllerParams, TSS2_CAR, RADAR_ACC_CAR, MIN_ACC_SPEED, \ - EPS_SCALE, ANGLE_CONTROL_CAR, ToyotaSafetyFlags + EPS_SCALE, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR, ToyotaSafetyFlags from opendbc.car.disable_ecu import disable_ecu from opendbc.car.interfaces import CarInterfaceBase @@ -86,7 +86,7 @@ class CarInterface(CarInterfaceBase): ret.radarUnavailable = Bus.radar not in DBC[candidate] - # since we don't yet parse radar on TSS2 radar-based ACC cars, gate longitudinal behind alpha toggle + # since we don't yet parse radar on TSS2 radar-based ACC cars, gate longitudinal behind experimental toggle if candidate in RADAR_ACC_CAR: ret.alphaLongitudinalAvailable = True @@ -94,14 +94,15 @@ class CarInterface(CarInterfaceBase): ret.flags |= ToyotaFlags.DISABLE_RADAR.value # openpilot longitudinal enabled by default: + # - cars w/ DSU disconnected # - TSS2 cars with camera sending ACC_CONTROL where we can block it - # openpilot longitudinal behind alpha long toggle: + # openpilot longitudinal behind experimental long toggle: # - TSS2 radar ACC cars (disables radar) ret.openpilotLongitudinalControl = (candidate in (TSS2_CAR - RADAR_ACC_CAR) or bool(ret.flags & ToyotaFlags.DISABLE_RADAR.value)) - ret.autoResumeSng = ret.openpilotLongitudinalControl + ret.autoResumeSng = ret.openpilotLongitudinalControl and candidate in NO_STOP_TIMER_CAR if not ret.openpilotLongitudinalControl: ret.safetyConfigs[0].safetyParam |= ToyotaSafetyFlags.STOCK_LONGITUDINAL.value diff --git a/opendbc/car/toyota/values.py b/opendbc/car/toyota/values.py index 69d9b330..e482e86f 100644 --- a/opendbc/car/toyota/values.py +++ b/opendbc/car/toyota/values.py @@ -70,6 +70,7 @@ class ToyotaFlags(IntFlag): RADAR_ACC = 64 # these cars use the Lane Tracing Assist (LTA) message for lateral control ANGLE_CONTROL = 128 + NO_STOP_TIMER = 256 # these cars can utilize 2.0 m/s^2 RAISED_ACCEL_LIMIT = 1024 SECOC = 2048 @@ -77,8 +78,6 @@ class ToyotaFlags(IntFlag): # deprecated flags # these cars are speculated to allow stop and go when the DSU is unplugged SNG_WITHOUT_DSU_DEPRECATED = 512 - # no resume button press required - NO_STOP_TIMER_DEPRECATED = 256 def dbc_dict(pt, radar): @@ -108,7 +107,7 @@ class ToyotaTSS2PlatformConfig(PlatformConfig): dbc_dict: dict = field(default_factory=lambda: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas')) def init(self): - self.flags |= ToyotaFlags.TSS2 | ToyotaFlags.NO_DSU + self.flags |= ToyotaFlags.TSS2 | ToyotaFlags.NO_STOP_TIMER | ToyotaFlags.NO_DSU if self.flags & ToyotaFlags.RADAR_ACC: self.dbc_dict = {Bus.pt: 'toyota_nodsu_pt_generated'} @@ -119,7 +118,7 @@ class ToyotaSecOCPlatformConfig(PlatformConfig): dbc_dict: dict = field(default_factory=lambda: dbc_dict('toyota_secoc_pt_generated', 'toyota_tss2_adas')) def init(self): - self.flags |= ToyotaFlags.TSS2 | ToyotaFlags.NO_DSU | ToyotaFlags.SECOC + self.flags |= ToyotaFlags.TSS2 | ToyotaFlags.NO_STOP_TIMER | ToyotaFlags.NO_DSU | ToyotaFlags.SECOC if self.flags & ToyotaFlags.RADAR_ACC: self.dbc_dict = {Bus.pt: 'toyota_secoc_pt_generated'} @@ -217,6 +216,7 @@ class CAR(Platforms): ], CarSpecs(mass=4516. * CV.LB_TO_KG, wheelbase=2.8194, steerRatio=16.0, tireStiffnessFactor=0.8), dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), + flags=ToyotaFlags.NO_STOP_TIMER, ) TOYOTA_HIGHLANDER_TSS2 = ToyotaTSS2PlatformConfig( [ @@ -238,6 +238,7 @@ class CAR(Platforms): [ToyotaCarDocs("Toyota Prius v 2017", "Toyota Safety Sense P", min_enable_speed=MIN_ACC_SPEED)], CarSpecs(mass=3340. * CV.LB_TO_KG, wheelbase=2.78, steerRatio=17.4, tireStiffnessFactor=0.5533), dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'), + flags=ToyotaFlags.NO_STOP_TIMER, ) TOYOTA_PRIUS_TSS2 = ToyotaTSS2PlatformConfig( [ @@ -261,6 +262,8 @@ class CAR(Platforms): ], TOYOTA_RAV4.specs, dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), + # Note that the ICE RAV4 does not respect positive acceleration commands under 19 mph + flags=ToyotaFlags.NO_STOP_TIMER, ) TOYOTA_RAV4_TSS2 = ToyotaTSS2PlatformConfig( [ @@ -302,6 +305,7 @@ class CAR(Platforms): [ToyotaCarDocs("Toyota Sienna 2018-20", video="https://www.youtube.com/watch?v=q1UPOo4Sh68", min_enable_speed=MIN_ACC_SPEED)], CarSpecs(mass=4590. * CV.LB_TO_KG, wheelbase=3.03, steerRatio=15.5, tireStiffnessFactor=0.444), dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), + flags=ToyotaFlags.NO_STOP_TIMER, ) TOYOTA_SIENNA_4TH_GEN = ToyotaSecOCPlatformConfig( [ToyotaSecOcCarDocs("Toyota Sienna 2021-23", min_enable_speed=MIN_ACC_SPEED)], @@ -601,4 +605,7 @@ ANGLE_CONTROL_CAR = CAR.with_flags(ToyotaFlags.ANGLE_CONTROL) SECOC_CAR = CAR.with_flags(ToyotaFlags.SECOC) +# no resume button press required +NO_STOP_TIMER_CAR = CAR.with_flags(ToyotaFlags.NO_STOP_TIMER) + DBC = CAR.create_dbc_map()