opendbc: fix GM pedal RX checks and restore ASCM F1 safety coverage

This commit is contained in:
firestar5683
2026-03-23 01:53:53 -05:00
parent 4368dd368b
commit 77764bd345
2 changed files with 74 additions and 13 deletions
+11 -1
View File
@@ -601,6 +601,11 @@ static safety_config gm_init(uint16_t param) {
GM_ACC_RX_CHECKS
};
static RxCheck gm_ascm_int_stock_cam_rx_checks[] = {
GM_COMMON_RX_CHECKS
{.msg = {{0xF1, 0, 6, 10U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}},
};
static const CanMsg GM_CAM_TX_MSGS[] = {{0x180, 0, 4, .check_relay = true}, {0x370, 0, 6, .check_relay = false}, {0x3D1, 0, 8, .check_relay = false}, // pt bus
{0x1E1, 2, 7, .check_relay = false}, {0x184, 2, 8, .check_relay = true}, // camera bus
// OPGM Variables
@@ -689,6 +694,7 @@ static safety_config gm_init(uint16_t param) {
gm_cam_long = GET_FLAG(param, GM_PARAM_HW_CAM_LONG) && !gm_cc_long;
gm_pcm_cruise = (gm_hw == GM_CAM || gm_sdgm) && !gm_cam_long && !gm_force_ascm && !gm_pedal_long;
const bool gm_ascm_int_stock_cam = gm_ascm_int && (gm_hw == GM_CAM) && gm_pcm_cruise && !gm_cam_long && !gm_pedal_long && !gm_cc_long;
gm_steer_limits = GET_FLAG(param, GM_PARAM_BOLT_2017) ? &GM_BOLT_2017_STEERING_LIMITS : &GM_STEERING_LIMITS;
if (gm_hw == GM_ASCM || gm_ascm_int || gm_force_ascm) {
@@ -717,7 +723,7 @@ static safety_config gm_init(uint16_t param) {
if (enable_gas_interceptor) {
if (gm_has_acc && (gm_hw == GM_CAM || gm_sdgm)) {
SET_RX_CHECKS(gm_cam_acc_pedal_rx_checks, ret);
} else if (!(gm_pedal_long && !gm_has_acc)) {
} else {
SET_RX_CHECKS(gm_pedal_rx_checks, ret);
}
} else if (gm_has_acc && (gm_hw == GM_CAM || gm_sdgm)) {
@@ -730,6 +736,10 @@ static safety_config gm_init(uint16_t param) {
SET_RX_CHECKS(gm_ev_rx_checks, ret);
}
if (gm_ascm_int_stock_cam) {
SET_RX_CHECKS(gm_ascm_int_stock_cam_rx_checks, ret);
}
// ASCM does not forward any messages
if (gm_hw == GM_ASCM) {
ret.disable_forwarding = true;
+63 -12
View File
@@ -148,6 +148,33 @@ class TestGmEVSafetyBase(TestGmSafetyBase):
return self.packer.make_can_msg_safety("EBCMRegenPaddle", 0, values)
class GmCameraAccEVRegenMixin:
# Camera-ACC EV modes don't track 0xBD in their RX checks, so regen paddle
# input should be ignored by safety state in these modes.
def test_prev_user_regen(self):
self.assertFalse(self.safety.get_regen_braking_prev())
for pressed in (False, True, False):
self._rx(self._user_regen_msg(pressed))
self.assertFalse(self.safety.get_regen_braking_prev())
def test_allow_user_regen_at_zero_speed(self):
self._rx(self._vehicle_moving_msg(0))
self.safety.set_controls_allowed(True)
self._rx(self._user_regen_msg(True))
self.assertTrue(self.safety.get_controls_allowed())
self.assertTrue(self.safety.get_longitudinal_allowed())
self.assertFalse(self.safety.get_regen_braking_prev())
def test_not_allow_user_regen_when_moving(self):
self._rx(self._vehicle_moving_msg(self.STANDSTILL_THRESHOLD + 1))
self.safety.set_controls_allowed(True)
self._rx(self._user_regen_msg(True))
self.assertTrue(self.safety.get_controls_allowed())
self.assertTrue(self.safety.get_longitudinal_allowed())
self.assertFalse(self.safety.get_regen_braking_prev())
self._rx(self._vehicle_moving_msg(0))
class TestGmAscmSafety(GmLongitudinalBase, TestGmSafetyBase):
TX_MSGS = [[0x180, 0], [0x409, 0], [0x40A, 0], [0x2CB, 0], [0x370, 0], [0x200, 0], [0x1E1, 0], [0xBD, 0], [0x1F5, 0], # pt bus
[0xA1, 1], [0x306, 1], [0x308, 1], [0x310, 1], # obs bus
@@ -207,7 +234,35 @@ class TestGmCameraSafety(TestGmCameraSafetyBase):
self.assertEqual(enabled, self._tx(self._button_msg(Buttons.CANCEL)))
class TestGmCameraEVSafety(TestGmCameraSafety, TestGmEVSafetyBase):
def _prime_gm_ascm_int_stock_cam_rx_checks(safety, f1_bus: int) -> None:
# This path should only accept the Volt/Malibu ASCM_INT stock-camera status on bus 0.
for bus, addr, length in (
(0, 0x184, 8),
(0, 0x34A, 5),
(0, 0x1E1, 7),
(f1_bus, 0xF1, 6),
(0, 0x1C4, 8),
(0, 0xC9, 8),
):
safety.safety_rx_hook(common.make_msg(bus, addr, length))
def test_gm_ascm_int_stock_cam_f1_rx_pinning():
safety = libsafety_py.libsafety
safety.set_safety_hooks(CarParams.SafetyModel.gm, GMSafetyFlags.HW_CAM | GMSafetyFlags.HW_ASCM_INT)
safety.init_tests()
_prime_gm_ascm_int_stock_cam_rx_checks(safety, 0)
assert safety.safety_config_valid()
safety.set_safety_hooks(CarParams.SafetyModel.gm, GMSafetyFlags.HW_CAM | GMSafetyFlags.HW_ASCM_INT)
safety.init_tests()
_prime_gm_ascm_int_stock_cam_rx_checks(safety, 2)
assert not safety.safety_config_valid()
class TestGmCameraEVSafety(GmCameraAccEVRegenMixin, TestGmCameraSafety, TestGmEVSafetyBase):
pass
@@ -230,7 +285,7 @@ class TestGmCameraLongitudinalSafety(GmLongitudinalBase, TestGmCameraSafetyBase)
self.safety.init_tests()
class TestGmCameraLongitudinalEVSafety(TestGmCameraLongitudinalSafety, TestGmEVSafetyBase):
class TestGmCameraLongitudinalEVSafety(GmCameraAccEVRegenMixin, TestGmCameraLongitudinalSafety, TestGmEVSafetyBase):
pass
@@ -278,20 +333,14 @@ class TestGmInterceptorSafety(common.GasInterceptorSafetyTest, TestGmCameraSafet
self.assertEqual(enable, self.safety.get_controls_allowed())
def test_buttons(self):
# Only CANCEL button is allowed while cruise is enabled
# Pedal-long non-ACC only allows CANCEL while controls are active.
self.safety.set_controls_allowed(False)
for btn in range(8):
self.assertFalse(self._tx(self._button_msg(btn)))
self.safety.set_controls_allowed(True)
for btn in range(8):
self.assertFalse(self._tx(self._button_msg(btn)))
self.safety.set_controls_allowed(True)
for enabled in (True, False):
self._rx(self._pcm_status_msg(enabled))
self.assertEqual(enabled, self._tx(self._button_msg(Buttons.CANCEL)))
self.assertTrue(self.safety.get_controls_allowed())
self.assertEqual(btn == Buttons.CANCEL, self._tx(self._button_msg(btn)))
def test_disable_control_allowed_from_cruise(self):
pass
@@ -306,8 +355,10 @@ class TestGmInterceptorSafety(common.GasInterceptorSafetyTest, TestGmCameraSafet
return interceptor_msg(gas, 0x201)
def _pcm_status_msg(self, enable):
values = {"CruiseActive": enable}
return self.packer.make_can_msg_panda("ECMCruiseControl", 0, values)
to_send = common.make_msg(0, 0x3D1, 8)
if enable:
to_send[0].data[4] |= 0x80
return to_send
class TestGmCcLongitudinalSafety(TestGmCameraSafety):