From c761a1790d038261a56c55432034dd8a270bfe06 Mon Sep 17 00:00:00 2001 From: FrogAi <91348155+FrogAi@users.noreply.github.com> Date: Wed, 29 May 2024 02:48:09 -0700 Subject: [PATCH] OPGM - Skip harness relay check if camera is missing Co-Authored-By: Eric Brown <13560103+nworb-cire@users.noreply.github.com> --- panda/board/safety.h | 2 +- panda/board/safety/safety_gm.h | 3 +++ panda/python/__init__.py | 1 + selfdrive/car/gm/carstate.py | 14 ++++++++++---- selfdrive/car/gm/interface.py | 9 ++++++++- selfdrive/car/gm/values.py | 5 ++++- 6 files changed, 27 insertions(+), 7 deletions(-) diff --git a/panda/board/safety.h b/panda/board/safety.h index 1e95244..815aa8c 100644 --- a/panda/board/safety.h +++ b/panda/board/safety.h @@ -275,7 +275,7 @@ void generic_rx_checks(bool stock_ecu_detected) { regen_braking_prev = regen_braking; // check if stock ECU is on bus broken by car harness - if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && stock_ecu_detected) { + if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && stock_ecu_detected && !gm_skip_relay_check) { relay_malfunction_set(); } } diff --git a/panda/board/safety/safety_gm.h b/panda/board/safety/safety_gm.h index 82a5d9c..99f3d62 100644 --- a/panda/board/safety/safety_gm.h +++ b/panda/board/safety/safety_gm.h @@ -52,6 +52,7 @@ RxCheck gm_rx_checks[] = { const uint16_t GM_PARAM_HW_CAM = 1; const uint16_t GM_PARAM_HW_CAM_LONG = 2; +const uint16_t GM_PARAM_NO_CAMERA = 16; enum { GM_BTN_UNPRESS = 1, @@ -63,6 +64,7 @@ enum { enum {GM_ASCM, GM_CAM} gm_hw = GM_ASCM; bool gm_cam_long = false; bool gm_pcm_cruise = false; +bool gm_skip_relay_check = false; static void gm_rx_hook(const CANPacket_t *to_push) { if (GET_BUS(to_push) == 0U) { @@ -228,6 +230,7 @@ static safety_config gm_init(uint16_t param) { gm_cam_long = GET_FLAG(param, GM_PARAM_HW_CAM_LONG); #endif gm_pcm_cruise = (gm_hw == GM_CAM) && !gm_cam_long; + gm_skip_relay_check = GET_FLAG(param, GM_PARAM_NO_CAMERA); safety_config ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_ASCM_TX_MSGS); if (gm_hw == GM_CAM) { diff --git a/panda/python/__init__.py b/panda/python/__init__.py index 063602f..0b99a62 100644 --- a/panda/python/__init__.py +++ b/panda/python/__init__.py @@ -229,6 +229,7 @@ class Panda: FLAG_GM_HW_CAM = 1 FLAG_GM_HW_CAM_LONG = 2 + FLAG_GM_NO_CAMERA = 16 FLAG_FORD_LONG_CONTROL = 1 FLAG_FORD_CANFD = 2 diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index a1129c5..ab1982c 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -5,7 +5,7 @@ from openpilot.common.numpy_fast import mean from opendbc.can.can_define import CANDefine from opendbc.can.parser import CANParser from openpilot.selfdrive.car.interfaces import CarStateBase -from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD +from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD, GMFlags TransmissionType = car.CarParams.TransmissionType NetworkLocation = car.CarParams.NetworkLocation @@ -46,7 +46,7 @@ class CarState(CarStateBase): self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0 if self.loopback_lka_steering_cmd_updated: self.loopback_lka_steering_cmd_ts_nanos = loopback_cp.ts_nanos["ASCMLKASteeringCmd"]["RollingCounter"] - if self.CP.networkLocation == NetworkLocation.fwdCamera: + if self.CP.networkLocation == NetworkLocation.fwdCamera and not self.CP.flags & GMFlags.NO_CAMERA.value: self.pt_lka_steering_cmd_counter = pt_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"] self.cam_lka_steering_cmd_counter = cam_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"] @@ -66,7 +66,10 @@ class CarState(CarStateBase): else: ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["ECMPRDNL2"]["PRNDL2"], None)) - ret.brake = pt_cp.vl["ECMAcceleratorPos"]["BrakePedalPos"] + if self.CP.flags & GMFlags.NO_CAMERA.value: + ret.brake = pt_cp.vl["EBCMBrakePedalPosition"]["BrakePedalPosition"] / 0xd0 + else: + ret.brake = pt_cp.vl["ECMAcceleratorPos"]["BrakePedalPos"] if self.CP.networkLocation == NetworkLocation.fwdCamera: ret.brakePressed = pt_cp.vl["ECMEngineStatus"]["BrakePressed"] != 0 else: @@ -129,7 +132,7 @@ class CarState(CarStateBase): @staticmethod def get_cam_can_parser(CP): messages = [] - if CP.networkLocation == NetworkLocation.fwdCamera: + if CP.networkLocation == NetworkLocation.fwdCamera and not CP.flags & GMFlags.NO_CAMERA.value: messages += [ ("AEBCmd", 10), ("ASCMLKASteeringCmd", 10), @@ -165,6 +168,9 @@ class CarState(CarStateBase): messages += [ ("ASCMLKASteeringCmd", 0), ] + if CP.flags & GMFlags.NO_CAMERA.value: + messages.remove(("ECMAcceleratorPos", 80)) + messages.append(("EBCMBrakePedalPosition", 100)) if CP.transmissionType == TransmissionType.direct: messages.append(("EBCMRegenPaddle", 50)) diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 1336e23..e2cf018 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -8,7 +8,7 @@ from openpilot.common.basedir import BASEDIR from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG -from openpilot.selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus +from openpilot.selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus, GMFlags from openpilot.selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD, LatControlInputs, NanoFFModel from openpilot.selfdrive.controls.lib.drive_helpers import get_friction @@ -20,6 +20,8 @@ NetworkLocation = car.CarParams.NetworkLocation BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise, CruiseButtons.MAIN: ButtonType.altButton3, CruiseButtons.CANCEL: ButtonType.cancel} +CAM_MSG = 0x320 # AEBCmd + # TODO: Is this always linked to camera presence?H NON_LINEAR_TORQUE_PARAMS = { CAR.BOLT_EUV: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178], @@ -200,6 +202,11 @@ class CarInterface(CarInterfaceBase): ret.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + # Exception for flashed cars, or cars whose camera was removed + if (ret.networkLocation == NetworkLocation.fwdCamera) and CAM_MSG not in fingerprint[CanBus.CAMERA]: + ret.flags |= GMFlags.NO_CAMERA.value + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_NO_CAMERA + return ret # returns a car.CarState diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index ec64537..0032b22 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -1,5 +1,5 @@ from dataclasses import dataclass, field -from enum import Enum +from enum import Enum, IntFlag from cereal import car from openpilot.selfdrive.car import dbc_dict, PlatformConfig, DbcDict, Platforms, CarSpecs @@ -190,6 +190,9 @@ class CanBus: LOOPBACK = 128 DROPPED = 192 +class GMFlags(IntFlag): + NO_CAMERA = 4 + # In a Data Module, an identifier is a string used to recognize an object, # either by itself or together with the identifiers of parent objects.