diff --git a/opendbc_repo/opendbc/car/gm/carcontroller.py b/opendbc_repo/opendbc/car/gm/carcontroller.py index cedc2e1a0..1f3f17881 100644 --- a/opendbc_repo/opendbc/car/gm/carcontroller.py +++ b/opendbc_repo/opendbc/car/gm/carcontroller.py @@ -6,7 +6,7 @@ from opendbc.car.lateral import apply_driver_steer_torque_limits from opendbc.car.gm import gmcan from opendbc.car.common.conversions import Conversions as CV from opendbc.car.gm.values import ( - ASCM_INT, CAR, CC_ONLY_CAR, CC_REGEN_PADDLE_CAR, DBC, EV_CAR, SDGM_CAR, AccState, CanBus, CarControllerParams, + ASCM_INT, CAMERA_ACC_CAR, CAR, CC_ONLY_CAR, CC_REGEN_PADDLE_CAR, DBC, EV_CAR, SDGM_CAR, AccState, CanBus, CarControllerParams, CruiseButtons, GMFlags, GMSafetyFlags, ) from opendbc.car.interfaces import CarControllerBase @@ -194,6 +194,15 @@ def should_send_adas_status(CP, is_kaofui_car): return CP.networkLocation != NetworkLocation.fwdCamera and CP.carFingerprint not in SDGM_CAR +def should_send_acc_2cd(CP): + return ( + CP.networkLocation == NetworkLocation.fwdCamera and + CP.carFingerprint in CAMERA_ACC_CAR and + CP.carFingerprint not in (CC_ONLY_CAR | SDGM_CAR) and + not bool(getattr(CP, "flags", 0) & GMFlags.NO_CAMERA.value) + ) + + def get_testing_ground_1_brake_switch_bias(v_ego: float) -> int: return int(round(np.interp(v_ego, [0.0, 6.0, 15.0, 30.0], [40.0, 85.0, 130.0, 170.0]))) @@ -1078,6 +1087,8 @@ class CarController(CarControllerBase): # TODO: can we always check the longControlState? if self.CP.networkLocation == NetworkLocation.fwdCamera: at_full_stop = at_full_stop and stopping + if should_send_acc_2cd(self.CP): + can_sends.append(gmcan.create_acc_2cd_command(CanBus.POWERTRAIN, idx)) if self.CP.autoResumeSng: resume = actuators.longControlState != LongCtrlState.starting or CC.cruiseControl.resume diff --git a/opendbc_repo/opendbc/car/gm/gmcan.py b/opendbc_repo/opendbc/car/gm/gmcan.py index 68d047dce..d0a70caef 100644 --- a/opendbc_repo/opendbc/car/gm/gmcan.py +++ b/opendbc_repo/opendbc/car/gm/gmcan.py @@ -217,6 +217,13 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, enabled, near_s return packer.make_can_msg("EBCMFrictionBrakeCmd", bus, values) +def create_acc_2cd_command(bus, idx): + dat = bytearray([0x00, 0x2c, 0x03, 0xd3, 0x00]) + dat[0] = (idx & 0x3) << 6 + dat[4] = (0xfd - (idx & 0x3)) & 0xff + return CanData(0x2CD, bytes(dat), bus) + + def create_acc_dashboard_command(packer, bus, enabled, target_speed_kph, hud_control, fcw_alert, acc_always_one=1): target_speed = min(target_speed_kph, 255) diff --git a/opendbc_repo/opendbc/car/gm/tests/test_carcontroller.py b/opendbc_repo/opendbc/car/gm/tests/test_carcontroller.py index 7b18c808b..f44c1aede 100644 --- a/opendbc_repo/opendbc/car/gm/tests/test_carcontroller.py +++ b/opendbc_repo/opendbc/car/gm/tests/test_carcontroller.py @@ -58,6 +58,7 @@ from opendbc.car.gm.carcontroller import ( should_use_fixed_stopping_brake, should_activate_auto_hold, should_activate_volt_one_pedal, + should_send_acc_2cd, should_send_adas_status, should_send_stock_long_cancel, should_spoof_dash_speed, @@ -356,6 +357,19 @@ def test_live_camera_path_does_not_send_pt_keepalive(): assert get_adas_keepalive_step(cp, is_kaofui_car=True) is None +def test_acc_2cd_replacement_only_used_with_live_camera_path(): + assert should_send_acc_2cd(SimpleNamespace( + carFingerprint=CAR.CHEVROLET_TRAILBLAZER, networkLocation=CarParams.NetworkLocation.fwdCamera, flags=0)) + assert not should_send_acc_2cd(SimpleNamespace( + carFingerprint=CAR.CHEVROLET_TRAILBLAZER, networkLocation=CarParams.NetworkLocation.fwdCamera, flags=GMFlags.NO_CAMERA.value)) + assert not should_send_acc_2cd(SimpleNamespace( + carFingerprint=CAR.CHEVROLET_TRAILBLAZER, networkLocation=CarParams.NetworkLocation.gateway, flags=0)) + assert not should_send_acc_2cd(SimpleNamespace( + carFingerprint=CAR.CHEVROLET_TRAILBLAZER_CC, networkLocation=CarParams.NetworkLocation.fwdCamera, flags=0)) + assert not should_send_acc_2cd(SimpleNamespace( + carFingerprint=CAR.CHEVROLET_BLAZER, networkLocation=CarParams.NetworkLocation.fwdCamera, flags=0)) + + def test_ascm_int_cars_do_not_send_radar_status(): common = { "networkLocation": CarParams.NetworkLocation.fwdCamera, diff --git a/opendbc_repo/opendbc/car/gm/tests/test_gmcan.py b/opendbc_repo/opendbc/car/gm/tests/test_gmcan.py index f3ceab26f..639e36d74 100644 --- a/opendbc_repo/opendbc/car/gm/tests/test_gmcan.py +++ b/opendbc_repo/opendbc/car/gm/tests/test_gmcan.py @@ -28,6 +28,14 @@ class TestGMCan: assert dat[1] & 0x1 assert decoded == 8848 + def test_acc_2cd_command_matches_stock_camera_counter_layout(self): + assert [gmcan.create_acc_2cd_command(0, idx)[1].hex() for idx in range(4)] == [ + "002c03d3fd", + "402c03d3fc", + "802c03d3fb", + "c02c03d3fa", + ] + def test_prndl2_command_matches_bolt_gen2_regen_paddle_spoof(self): CP = SimpleNamespace(carFingerprint=CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL) diff --git a/opendbc_repo/opendbc/safety/modes/gm.h b/opendbc_repo/opendbc/safety/modes/gm.h index b1be6644b..9029606c7 100644 --- a/opendbc_repo/opendbc/safety/modes/gm.h +++ b/opendbc_repo/opendbc/safety/modes/gm.h @@ -517,13 +517,14 @@ static bool gm_fwd_hook(int bus_num, int addr) { bool is_lkas_msg = addr == 0x180U; bool is_acc_status_msg = addr == 0x370U; bool is_acc_actuation_msg = (addr == 0x315U) || (addr == 0x2CBU); + bool is_acc_counter_msg = addr == 0x2CDU; block_msg = is_lkas_msg; if (gm_cam_long || gm_pedal_long) { block_msg |= is_acc_status_msg; } if (gm_cam_long) { - block_msg |= is_acc_actuation_msg; + block_msg |= is_acc_actuation_msg || is_acc_counter_msg; } } } @@ -579,7 +580,7 @@ static safety_config gm_init(uint16_t param) { }; // block PSCMStatus (0x184); forwarded through openpilot to hide an alert from the camera - static const CanMsg GM_CAM_LONG_TX_MSGS[] = {{0x180, 0, 4, .check_relay = true}, {0x315, 0, 5, .check_relay = true}, {0x2CB, 0, 8, .check_relay = true}, {0x370, 0, 6, .check_relay = true}, {0x3D1, 0, 8, .check_relay = false}, // pt bus + static const CanMsg GM_CAM_LONG_TX_MSGS[] = {{0x180, 0, 4, .check_relay = true}, {0x315, 0, 5, .check_relay = true}, {0x2CB, 0, 8, .check_relay = true}, {0x2CD, 0, 5, .check_relay = true}, {0x370, 0, 6, .check_relay = true}, {0x3D1, 0, 8, .check_relay = false}, // pt bus {0x184, 2, 8, .check_relay = true}, // camera 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 diff --git a/opendbc_repo/opendbc/safety/tests/test_gm.py b/opendbc_repo/opendbc/safety/tests/test_gm.py index 496f9fc49..4b6715679 100755 --- a/opendbc_repo/opendbc/safety/tests/test_gm.py +++ b/opendbc_repo/opendbc/safety/tests/test_gm.py @@ -346,10 +346,10 @@ class TestGmCameraNoCameraSafety(TestGmCameraSafety): class TestGmCameraLongitudinalSafety(GmLongitudinalBase, TestGmCameraSafetyBase): - TX_MSGS = [[0x180, 0], [0x315, 0], [0x2CB, 0], [0x370, 0], [0x200, 0], [0x1E1, 0], [0x3D1, 0], [0xBD, 0], [0x1F5, 0], # pt bus + TX_MSGS = [[0x180, 0], [0x315, 0], [0x2CB, 0], [0x2CD, 0], [0x370, 0], [0x200, 0], [0x1E1, 0], [0x3D1, 0], [0xBD, 0], [0x1F5, 0], # pt bus [0x184, 2]] # camera bus - FWD_BLACKLISTED_ADDRS = {2: [0x180, 0x2CB, 0x370, 0x315], 0: [0x184]} # block LKAS, ACC messages and PSCMStatus - RELAY_MALFUNCTION_ADDRS = {0: (0x180, 0x2CB, 0x370, 0x315), 2: (0x184,)} + FWD_BLACKLISTED_ADDRS = {2: [0x180, 0x2CB, 0x2CD, 0x370, 0x315], 0: [0x184]} # block LKAS, ACC messages and PSCMStatus + RELAY_MALFUNCTION_ADDRS = {0: (0x180, 0x2CB, 0x2CD, 0x370, 0x315), 2: (0x184,)} BUTTONS_BUS = 0 # rx only MAX_GAS = 2698