diff --git a/cereal/car.capnp b/cereal/car.capnp index b3953ac2b50086..4a47ec8a0c4d8f 100644 --- a/cereal/car.capnp +++ b/cereal/car.capnp @@ -19,6 +19,7 @@ struct CarEvent @0x9b1657f34caf3ad3 { immediateDisable @6 :Bool; preEnable @7 :Bool; permanent @8 :Bool; + resetVCruise @9 :Bool; enum EventName @0xbaa8c5d505f727de { # TODO: copy from error list diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 13dd2a4e38f719..a227b367bde037 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -377,11 +377,18 @@ def update(self, c, can_strings): # handle button presses for b in ret.buttonEvents: # do enable on both accel and decel buttons - if b.type in [ButtonType.accelCruise, ButtonType.decelCruise] and not b.pressed: + # The ECM will fault if resume triggers an enable while speed is set to 0 + if b.type == ButtonType.accelCruise and c.hudControl.setSpeed > 0 and c.hudControl.setSpeed < 70 and not b.pressed: + events.append(create_event('buttonEnable', [ET.ENABLE])) + if b.type == ButtonType.decelCruise and not b.pressed: events.append(create_event('buttonEnable', [ET.ENABLE])) # do disable on button down if b.type == ButtonType.cancel and b.pressed: events.append(create_event('buttonCancel', [ET.USER_DISABLE])) + # The ECM independently tracks a ‘speed is set’ state that is reset on main off. + # To keep controlsd in sync with the ECM state, generate a RESET_V_CRUISE event on main cruise presses. + if b.type == ButtonType.altButton3 and b.pressed: + events.append(create_event('buttonCancel', [ET.RESET_V_CRUISE, ET.USER_DISABLE])) ret.events = events diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index f6a27902bd5f20..321389d7b16211 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -165,6 +165,10 @@ def state_transition(frame, CS, CP, state, events, soft_disable_timer, v_cruise_ # decrease the soft disable timer at every step, as it's reset on # entrance in SOFT_DISABLING state soft_disable_timer = max(0, soft_disable_timer - 1) + + # Reset v_cruise_kph to 0 + if get_events(events, [ET.RESET_V_CRUISE]): + v_cruise_kph = 0 # DISABLED if state == State.disabled: diff --git a/selfdrive/controls/lib/drive_helpers.py b/selfdrive/controls/lib/drive_helpers.py index a9e809a873b84e..f8d432e186435f 100644 --- a/selfdrive/controls/lib/drive_helpers.py +++ b/selfdrive/controls/lib/drive_helpers.py @@ -35,6 +35,7 @@ class EventTypes: SOFT_DISABLE = 'softDisable' IMMEDIATE_DISABLE = 'immediateDisable' PERMANENT = 'permanent' + RESET_V_CRUISE = 'resetVCruise' def create_event(name, types):