From fb1c2ea1c4f0db3658042adc3abe74f2f491dde2 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Sat, 27 Jun 2026 15:57:38 -0500 Subject: [PATCH] spicy --- opendbc_repo/opendbc/car/gm/carstate.py | 26 +++++++++++++------- opendbc_repo/opendbc/car/gm/tests/test_gm.py | 19 +++++++++++++- opendbc_repo/opendbc/safety/modes/gm.h | 2 +- opendbc_repo/opendbc/safety/tests/test_gm.py | 21 ++++++++++++++-- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/opendbc_repo/opendbc/car/gm/carstate.py b/opendbc_repo/opendbc/car/gm/carstate.py index e53013af7..699cad02b 100644 --- a/opendbc_repo/opendbc/car/gm/carstate.py +++ b/opendbc_repo/opendbc/car/gm/carstate.py @@ -52,6 +52,19 @@ BOLT_CANCEL_BUTTON_CARS = BOLT_GEN1_CANCEL_PERSONALITY_CARS | { } +def update_auto_hold_drive_timers(in_drive_for_hold: bool, moving_for_hold: bool, + auto_hold_drive_time: float, one_pedal_drive_time: float) -> tuple[float, float]: + if in_drive_for_hold: + if moving_for_hold: + auto_hold_drive_time = min(auto_hold_drive_time + DT_CTRL, AUTO_HOLD_MIN_DRIVE_TIME_S) + one_pedal_drive_time = min(one_pedal_drive_time + DT_CTRL, AUTO_HOLD_MIN_DRIVE_TIME_S) + else: + auto_hold_drive_time = 0.0 + one_pedal_drive_time = 0.0 + + return auto_hold_drive_time, one_pedal_drive_time + + class CarState(CarStateBase): def __init__(self, CP, FPCP): super().__init__(CP, FPCP) @@ -211,15 +224,10 @@ class CarState(CarStateBase): ret.brakePressed = ret.brake >= analog_thresh in_drive_for_hold = ret.gearShifter in (GearShifter.drive, GearShifter.low, GearShifter.manumatic) - if in_drive_for_hold: - if ret.brakePressed: - self.auto_hold_drive_time = AUTO_HOLD_MIN_DRIVE_TIME_S - else: - self.auto_hold_drive_time = min(self.auto_hold_drive_time + DT_CTRL, AUTO_HOLD_MIN_DRIVE_TIME_S) - self.one_pedal_drive_time = min(self.one_pedal_drive_time + DT_CTRL, AUTO_HOLD_MIN_DRIVE_TIME_S) - else: - self.auto_hold_drive_time = 0.0 - self.one_pedal_drive_time = 0.0 + self.auto_hold_drive_time, self.one_pedal_drive_time = update_auto_hold_drive_timers( + in_drive_for_hold, ret.vEgo > 0.1, self.auto_hold_drive_time, self.one_pedal_drive_time + ) + if not in_drive_for_hold: self.auto_hold_armed = False self.auto_hold_engaged = False diff --git a/opendbc_repo/opendbc/car/gm/tests/test_gm.py b/opendbc_repo/opendbc/car/gm/tests/test_gm.py index c198ec0ce..27645b10e 100644 --- a/opendbc_repo/opendbc/car/gm/tests/test_gm.py +++ b/opendbc_repo/opendbc/car/gm/tests/test_gm.py @@ -8,7 +8,7 @@ from opendbc.can import CANPacker, CANParser from opendbc.car import Bus, DT_CTRL, structs from opendbc.car.car_helpers import interfaces from opendbc.car.gm import gmcan -from opendbc.car.gm.carstate import CarState as GMCarState, get_hard_cruise_buttons +from opendbc.car.gm.carstate import CarState as GMCarState, get_hard_cruise_buttons, update_auto_hold_drive_timers from opendbc.car.gm.carcontroller import ( VisualAlert, get_acc_dashboard_fcw_alert, @@ -94,6 +94,23 @@ class TestGMInterface: assert get_hard_cruise_buttons({"ACCButtons": CruiseButtons.RES_ACCEL}) == CruiseButtons.INIT assert get_hard_cruise_buttons({"ACCButtonsHard": CruiseButtons.DECEL_SET}) == CruiseButtons.DECEL_SET + def test_volt_auto_hold_drive_timer_requires_motion_before_startup_arming(self): + auto_hold_time, one_pedal_time = update_auto_hold_drive_timers(True, False, 0.0, 0.0) + + assert auto_hold_time == 0.0 + assert one_pedal_time == 0.0 + + def test_volt_auto_hold_drive_timer_accumulates_only_while_moving(self): + auto_hold_time, one_pedal_time = update_auto_hold_drive_timers(True, True, 0.0, 0.0) + + assert auto_hold_time == pytest.approx(DT_CTRL) + assert one_pedal_time == pytest.approx(DT_CTRL) + + auto_hold_time, one_pedal_time = update_auto_hold_drive_timers(True, False, auto_hold_time, one_pedal_time) + + assert auto_hold_time == pytest.approx(DT_CTRL) + assert one_pedal_time == pytest.approx(DT_CTRL) + @parameterized.expand(VOLT_CARS) def test_volt_min_steer_speed_is_7_mph(self, car_model): CarInterface = interfaces[car_model] diff --git a/opendbc_repo/opendbc/safety/modes/gm.h b/opendbc_repo/opendbc/safety/modes/gm.h index e5b6d525b..b1be6644b 100644 --- a/opendbc_repo/opendbc/safety/modes/gm.h +++ b/opendbc_repo/opendbc/safety/modes/gm.h @@ -366,7 +366,7 @@ static bool gm_tx_hook(const CANPacket_t *msg) { if (msg->addr == 0x315U) { int brake = ((msg->data[0] & 0xFU) << 8) + msg->data[1]; brake = (0x1000 - brake) & 0xFFF; - bool stock_auto_hold_brake_allowed = gm_volt_auto_hold && !vehicle_moving && !gas_pressed_prev; + bool stock_auto_hold_brake_allowed = gm_volt_auto_hold && acc_main_on && !vehicle_moving && !gas_pressed_prev; bool stock_one_pedal_brake_allowed = gm_volt_one_pedal && acc_main_on && !gas_pressed_prev && !brake_pressed; bool violation = false; violation |= !(get_longitudinal_allowed() || stock_auto_hold_brake_allowed || stock_one_pedal_brake_allowed) && (brake != 0); diff --git a/opendbc_repo/opendbc/safety/tests/test_gm.py b/opendbc_repo/opendbc/safety/tests/test_gm.py index 12bb9d22e..496f9fc49 100755 --- a/opendbc_repo/opendbc/safety/tests/test_gm.py +++ b/opendbc_repo/opendbc/safety/tests/test_gm.py @@ -633,18 +633,27 @@ class TestGmVoltAutoHoldCameraSafety(TestGmCameraSafetyBase): values = {"FrictionBrakeCmd": -brake} return self.packer_chassis.make_can_msg_safety("EBCMFrictionBrakeCmd", 0, values) - def test_standstill_brake_allowed_without_controls(self): + def test_standstill_brake_allowed_without_controls_when_main_on(self): self._rx(self._speed_msg(0)) + self._rx(self._toggle_aol(True)) self.safety.set_controls_allowed(False) self.assertTrue(self._tx(self._send_brake_msg(100))) + def test_standstill_brake_blocked_without_main_on(self): + self._rx(self._speed_msg(0)) + self._rx(self._toggle_aol(False)) + self.safety.set_controls_allowed(False) + self.assertFalse(self._tx(self._send_brake_msg(100))) + def test_moving_brake_blocked_without_controls(self): self._rx(self._speed_msg(self.STANDSTILL_THRESHOLD + 1)) + self._rx(self._toggle_aol(True)) self.safety.set_controls_allowed(False) self.assertFalse(self._tx(self._send_brake_msg(100))) def test_gas_blocks_standstill_brake_without_controls(self): self._rx(self._speed_msg(0)) + self._rx(self._toggle_aol(True)) self._rx(self._user_gas_msg(True)) self.safety.set_controls_allowed(False) self.assertFalse(self._tx(self._send_brake_msg(100))) @@ -700,13 +709,21 @@ class TestGmVoltAutoHoldSdgmSafety(TestGmSafetyBase): values = {"FrictionBrakeCmd": -brake} return self.packer_chassis.make_can_msg_safety("EBCMFrictionBrakeCmd", 2, values) - def test_standstill_brake_allowed_without_controls(self): + def test_standstill_brake_allowed_without_controls_when_main_on(self): self._rx(self._speed_msg(0)) + self._rx(self._toggle_aol(True)) self.safety.set_controls_allowed(False) self.assertTrue(self._tx(self._send_brake_msg(100))) + def test_standstill_brake_blocked_without_main_on(self): + self._rx(self._speed_msg(0)) + self._rx(self._toggle_aol(False)) + self.safety.set_controls_allowed(False) + self.assertFalse(self._tx(self._send_brake_msg(100))) + def test_moving_brake_blocked_without_controls(self): self._rx(self._speed_msg(self.STANDSTILL_THRESHOLD + 1)) + self._rx(self._toggle_aol(True)) self.safety.set_controls_allowed(False) self.assertFalse(self._tx(self._send_brake_msg(100)))