This commit is contained in:
firestar5683
2026-06-27 15:57:38 -05:00
parent 0f43f042fb
commit fb1c2ea1c4
4 changed files with 55 additions and 13 deletions
+17 -9
View File
@@ -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
+18 -1
View File
@@ -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]
+1 -1
View File
@@ -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);
+19 -2
View File
@@ -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)))