From 91a6df08b0b5454090a891369e8725fa347b5862 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Wed, 29 Apr 2026 14:02:42 -0500 Subject: [PATCH] Plexy --- opendbc_repo/opendbc/car/gm/carcontroller.py | 7 ++++++- opendbc_repo/opendbc/car/gm/carstate.py | 5 ++++- opendbc_repo/opendbc/car/gm/interface.py | 3 +++ opendbc_repo/opendbc/car/gm/tests/test_gm.py | 1 + opendbc_repo/opendbc/safety/modes/gm.h | 16 +++++++++++++++- opendbc_repo/opendbc/safety/tests/test_gm.py | 10 +++++++++- 6 files changed, 38 insertions(+), 4 deletions(-) diff --git a/opendbc_repo/opendbc/car/gm/carcontroller.py b/opendbc_repo/opendbc/car/gm/carcontroller.py index 391b9e5ac..58f3e1f7c 100644 --- a/opendbc_repo/opendbc/car/gm/carcontroller.py +++ b/opendbc_repo/opendbc/car/gm/carcontroller.py @@ -607,7 +607,12 @@ class CarController(CarControllerBase): if self.CP.enableGasInterceptorDEPRECATED: can_sends.append(create_gas_interceptor_command(self.packer_pt, interceptor_gas_cmd, idx)) if self.CP.carFingerprint not in CC_ONLY_CAR: - friction_brake_bus = CanBus.CHASSIS + volt_gateway_alt_brake = ( + self.CP.carFingerprint == CAR.CHEVROLET_VOLT and + self.CP.networkLocation == NetworkLocation.gateway and + bool(self.CP.flags & GMFlags.NO_ACCELERATOR_POS_MSG.value) + ) + friction_brake_bus = CanBus.POWERTRAIN if volt_gateway_alt_brake else CanBus.CHASSIS # GM Camera exceptions # TODO: can we always check the longControlState? if self.CP.networkLocation == NetworkLocation.fwdCamera: diff --git a/opendbc_repo/opendbc/car/gm/carstate.py b/opendbc_repo/opendbc/car/gm/carstate.py index 35f3ae247..d0183c031 100644 --- a/opendbc_repo/opendbc/car/gm/carstate.py +++ b/opendbc_repo/opendbc/car/gm/carstate.py @@ -27,6 +27,7 @@ TransmissionType = structs.CarParams.TransmissionType NetworkLocation = structs.CarParams.NetworkLocation STANDSTILL_THRESHOLD = 10 * 0.0311 +VOLT_EBCM_BRAKE_PRESSED_THRESHOLD = 6 / 0xd0 AUTO_HOLD_MIN_DRIVE_TIME_S = 3.0 AUTO_HOLD_REGEN_RELEASE_COOLDOWN_S = 1.0 @@ -162,7 +163,9 @@ class CarState(CarStateBase): else: ret.brake = pt_cp.vl["ECMAcceleratorPos"]["BrakePedalPos"] - if self.CP.carFingerprint in {CAR.CHEVROLET_MALIBU_CC} or (self.CP.carFingerprint == CAR.CHEVROLET_BLAZER and not no_accel_pos): + if self.CP.carFingerprint == CAR.CHEVROLET_VOLT and no_accel_pos: + ret.brakePressed = ret.brake >= VOLT_EBCM_BRAKE_PRESSED_THRESHOLD + elif self.CP.carFingerprint in {CAR.CHEVROLET_MALIBU_CC} or (self.CP.carFingerprint == CAR.CHEVROLET_BLAZER and not no_accel_pos): ret.brakePressed = ret.brake >= 8 elif (self.CP.flags & GMFlags.FORCE_BRAKE_C9.value) or ((self.CP.networkLocation == NetworkLocation.fwdCamera) and (self.CP.carFingerprint != CAR.CHEVROLET_BLAZER)): ret.brakePressed = pt_cp.vl["ECMEngineStatus"]["BrakePressed"] != 0 diff --git a/opendbc_repo/opendbc/car/gm/interface.py b/opendbc_repo/opendbc/car/gm/interface.py index 3ca01219b..e3573b947 100755 --- a/opendbc_repo/opendbc/car/gm/interface.py +++ b/opendbc_repo/opendbc/car/gm/interface.py @@ -620,6 +620,9 @@ class CarInterface(CarInterfaceBase): if ACCELERATOR_POS_MSG not in fingerprint[CanBus.POWERTRAIN]: ret.flags |= GMFlags.NO_ACCELERATOR_POS_MSG.value + if candidate == CAR.CHEVROLET_VOLT and ret.networkLocation == NetworkLocation.gateway: + # Reuse the no-camera safety bit as an ASCM Volt selector for the alternate EBCM brake path. + ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_NO_CAMERA.value try: remote_start_boots_comma = params.get_bool("RemoteStartBootsComma") diff --git a/opendbc_repo/opendbc/car/gm/tests/test_gm.py b/opendbc_repo/opendbc/car/gm/tests/test_gm.py index a3ef1dede..f90109ca1 100644 --- a/opendbc_repo/opendbc/car/gm/tests/test_gm.py +++ b/opendbc_repo/opendbc/car/gm/tests/test_gm.py @@ -103,6 +103,7 @@ class TestGMInterface: starpilot_toggles=_test_starpilot_toggles()) assert car_params.flags & GMFlags.NO_ACCELERATOR_POS_MSG.value + assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_NO_CAMERA.value pt_parser = CarInterface.CarState.get_can_parsers(car_params)[Bus.pt] assert "ECMAcceleratorPos" not in pt_parser.vl diff --git a/opendbc_repo/opendbc/safety/modes/gm.h b/opendbc_repo/opendbc/safety/modes/gm.h index a1be98f37..9e91b2cc1 100644 --- a/opendbc_repo/opendbc/safety/modes/gm.h +++ b/opendbc_repo/opendbc/safety/modes/gm.h @@ -59,6 +59,7 @@ static bool gm_force_brake_c9 = false; static bool gm_panda_3d1_sched = false; static bool gm_panda_paddle_sched = false; static bool gm_bolt_2022_pedal = false; +static bool gm_alt_brake = false; static bool gm_cc_long = false; static bool gm_has_acc = true; @@ -246,10 +247,14 @@ static void gm_rx_hook(const CANPacket_t *msg) { brake_pressed = GET_BIT(msg, 40U); } - if ((msg->addr == 0xBEU) && ((gm_hw == GM_ASCM) || gm_sdgm || gm_ascm_int)) { + if ((msg->addr == 0xBEU) && (((gm_hw == GM_ASCM) && !gm_alt_brake) || gm_sdgm || gm_ascm_int)) { brake_pressed = msg->data[1] >= 8U; } + if ((msg->addr == 0xF1U) && gm_alt_brake) { + brake_pressed = msg->data[1] >= 6U; + } + if ((msg->addr == 0xC9U) && (gm_hw == GM_CAM) && !gm_force_brake_c9) { brake_pressed = GET_BIT(msg, 40U); } @@ -546,6 +551,12 @@ static safety_config gm_init(uint16_t param) { {0x1E1, 0, 7, .check_relay = false}, {0xBD, 0, 7, .check_relay = false}, {0x1F5, 0, 8, .check_relay = false}}; // pt bus + static const CanMsg GM_ASCM_ALT_BRAKE_TX_MSGS[] = {{0x180, 0, 4, .check_relay = true}, {0x409, 0, 7, .check_relay = false}, {0x40A, 0, 7, .check_relay = false}, {0x2CB, 0, 8, .check_relay = true}, {0x370, 0, 6, .check_relay = false}, {0x315, 0, 5, .check_relay = true}, // pt bus + {0xA1, 1, 7, .check_relay = false}, {0x306, 1, 8, .check_relay = false}, {0x308, 1, 7, .check_relay = false}, {0x310, 1, 2, .check_relay = false}, // obs bus + {0x200, 0, 6, .check_relay = false}, + {0x1E1, 0, 7, .check_relay = false}, + {0xBD, 0, 7, .check_relay = false}, + {0x1F5, 0, 8, .check_relay = false}}; // pt bus static const LongitudinalLimits GM_CAM_LONG_LIMITS = { @@ -660,6 +671,7 @@ static safety_config gm_init(uint16_t param) { gm_remote_start_boots_comma = GET_FLAG(param, GM_PARAM_REMOTE_START_BOOTS_COMMA); gm_panda_3d1_sched = GET_FLAG(param, GM_PARAM_PANDA_3D1_SCHED) && gm_pedal_long && !gm_has_acc && !gm_bolt_2022_pedal; gm_panda_paddle_sched = GET_FLAG(param, GM_PARAM_PANDA_PADDLE_SCHED) && gm_pedal_long && enable_gas_interceptor; + gm_alt_brake = GET_FLAG(param, GM_PARAM_NO_CAMERA) && (gm_hw == GM_ASCM) && !gm_sdgm && !gm_ascm_int; gm_3d1_spoof_valid = false; gm_3d1_internal_tx = false; @@ -726,6 +738,8 @@ static safety_config gm_init(uint16_t param) { ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_TX_MSGS); } } + } else if (gm_alt_brake) { + ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_ASCM_ALT_BRAKE_TX_MSGS); } else { ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_ASCM_TX_MSGS); } diff --git a/opendbc_repo/opendbc/safety/tests/test_gm.py b/opendbc_repo/opendbc/safety/tests/test_gm.py index 55796356e..cf0e0f6a2 100755 --- a/opendbc_repo/opendbc/safety/tests/test_gm.py +++ b/opendbc_repo/opendbc/safety/tests/test_gm.py @@ -196,7 +196,15 @@ class TestGmAscmSafety(GmLongitudinalBase, TestGmSafetyBase): class TestGmAscmEVSafety(TestGmAscmSafety, TestGmEVSafetyBase): - pass + EXTRA_SAFETY_PARAM = GMSafetyFlags.FLAG_GM_NO_CAMERA + TX_MSGS = [[0x180, 0], [0x409, 0], [0x40A, 0], [0x2CB, 0], [0x370, 0], [0x200, 0], [0x1E1, 0], [0xBD, 0], [0x1F5, 0], [0x315, 0], + [0xA1, 1], [0x306, 1], [0x308, 1], [0x310, 1]] + RELAY_MALFUNCTION_ADDRS = {0: (0x180, 0x2CB, 0x315)} + BRAKE_BUS = 0 + + def _user_brake_msg(self, brake): + values = {"BrakePedalPosition": 6 if brake else 0} + return self.packer.make_can_msg_panda("EBCMBrakePedalPosition", 0, values) class TestGmCameraSafetyBase(TestGmSafetyBase):