diff --git a/opendbc_repo/opendbc/car/gm/carcontroller.py b/opendbc_repo/opendbc/car/gm/carcontroller.py index 7a12823a..627b339a 100644 --- a/opendbc_repo/opendbc/car/gm/carcontroller.py +++ b/opendbc_repo/opendbc/car/gm/carcontroller.py @@ -302,7 +302,7 @@ class CarController(CarControllerBase): if (self.frame - self.last_button_frame) * DT_CTRL > 0.04: if self.cancel_counter > CAMERA_CANCEL_DELAY_FRAMES: self.last_button_frame = self.frame - can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, CS.buttons_counter, CruiseButtons.CANCEL)) + can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, (CS.buttons_counter + 1) % 4, CruiseButtons.CANCEL)) if self.CP.networkLocation == NetworkLocation.fwdCamera: # Silence "Take Steering" alert sent by camera, forward PSCMStatus with HandsOffSWlDetectionStatus=1 @@ -323,10 +323,10 @@ class CarController(CarControllerBase): # GM: AutoResume def brake_input(self, brake_force): MAX_BRAKE = 400 - ZERO_GAS = 2048 + ZERO_GAS = 0.0 if brake_force > 0.0: raise ValueError("brake_force는 0.0이하라야 됨.") scaled_brake = max(0, min(MAX_BRAKE, int(brake_force * -100))) # -를 +로 변환 - return ZERO_GAS - scaled_brake + return -scaled_brake diff --git a/opendbc_repo/opendbc/car/gm/carstate.py b/opendbc_repo/opendbc/car/gm/carstate.py index a8b71fe6..a00f0b40 100644 --- a/opendbc_repo/opendbc/car/gm/carstate.py +++ b/opendbc_repo/opendbc/car/gm/carstate.py @@ -13,7 +13,7 @@ TransmissionType = structs.CarParams.TransmissionType NetworkLocation = structs.CarParams.NetworkLocation GearShifter = structs.CarState.GearShifter STANDSTILL_THRESHOLD = 10 * 0.0311 * CV.KPH_TO_MS -LongCtrlState = car.CarControl.Actuators.LongControlState # kans + BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise, CruiseButtons.MAIN: ButtonType.mainCruise, CruiseButtons.CANCEL: ButtonType.cancel, CruiseButtons.GAP_DIST: ButtonType.gapAdjustCruise} @@ -32,15 +32,12 @@ class CarState(CarStateBase): self.cam_lka_steering_cmd_counter = 0 self.is_metric = False - # GAP_DIST - self.prev_distance_button = False - self.distance_button_pressed = False - - self.cruise_buttons = 0 self.buttons_counter = 0 self.single_pedal_mode = False self.pedal_steady = 0. - + self.cruise_buttons = 0 + # GAP_DIST + self.distance_button = 0 # cruiseMain default(test from nd0706-vision) self.cruiseMain_on = True if Params().get_int("AutoEngage") == 2 else False @@ -62,14 +59,14 @@ class CarState(CarStateBase): ret = structs.CarState() prev_cruise_buttons = self.cruise_buttons - self.prev_distance_button = self.distance_button_pressed + prev_distance_button = self.distance_button self.cruise_buttons = pt_cp.vl["ASCMSteeringButton"]["ACCButtons"] - self.distance_button_pressed = pt_cp.vl["ASCMSteeringButton"]["DistanceButton"] != 0 + self.distance_button = pt_cp.vl["ASCMSteeringButton"]["DistanceButton"] self.buttons_counter = pt_cp.vl["ASCMSteeringButton"]["RollingCounter"] self.pscm_status = copy.copy(pt_cp.vl["PSCMStatus"]) # GAP_DIST - if self.cruise_buttons in [CruiseButtons.UNPRESS, CruiseButtons.INIT] and self.distance_button_pressed: + if self.cruise_buttons in [CruiseButtons.UNPRESS, CruiseButtons.INIT] and self.distance_button: self.cruise_buttons = CruiseButtons.GAP_DIST if self.CP.enableBsm: @@ -168,7 +165,7 @@ class CarState(CarStateBase): if self.CP.networkLocation == NetworkLocation.fwdCamera and not self.CP.flags & GMFlags.NO_CAMERA.value: if self.CP.carFingerprint not in CC_ONLY_CAR: ret.cruiseState.speed = cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCSpeedSetpoint"] * CV.KPH_TO_MS - ret.stockAeb = cam_cp.vl["AEBCmd"]["AEBCmdActive"] != 0 + ret.stockAeb = False # openpilot controls nonAdaptive when not pcmCruise if self.CP.pcmCruise and self.CP.carFingerprint not in CC_ONLY_CAR: ret.cruiseState.nonAdaptive = cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCCruiseState"] not in (2, 3) @@ -176,6 +173,8 @@ class CarState(CarStateBase): ret.accFaulted = False ret.cruiseState.speed = pt_cp.vl["ECMCruiseControl"]["CruiseSetSpeed"] * CV.KPH_TO_MS ret.cruiseState.enabled = pt_cp.vl["ECMCruiseControl"]["CruiseActive"] != 0 + prev_lkas_enabled = self.lkas_enabled + self.lkas_enabled = pt_cp.vl["ASCMSteeringButton"]["LKAButton"] self.pcm_acc_status = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] if self.CP.carFingerprint in (CAR.CHEVROLET_TRAX, CAR.CHEVROLET_TRAILBLAZER, CAR.CHEVROLET_TRAILBLAZER_CC): @@ -193,15 +192,15 @@ class CarState(CarStateBase): ret.vCluRatio = 0.96 # Don't add event if transitioning from INIT, unless it's to an actual button - buttonEvents = [] # kans if self.cruise_buttons != CruiseButtons.UNPRESS or prev_cruise_buttons != CruiseButtons.INIT: - buttonEvents.extend(create_button_events(self.cruise_buttons, prev_cruise_buttons, BUTTONS_DICT, - unpressed_btn=CruiseButtons.UNPRESS)) # kans - # kans : long_button GAP for cruise Mode(safety, ecco, high-speed..) - if self.distance_button_pressed: - buttonEvents.append(car.CarState.ButtonEvent(pressed=True, type=ButtonType.gapAdjustCruise)) - ret.buttonEvents = buttonEvents # kans - + ret.buttonEvents = [ + *create_button_events(self.cruise_buttons, prev_cruise_buttons, BUTTONS_DICT, + unpressed_btn=CruiseButtons.UNPRESS), + *create_button_events(self.distance_button, prev_distance_button, + {1: ButtonType.gapAdjustCruise}), + *create_button_events(self.lkas_enabled, prev_lkas_enabled, + {1: ButtonType.lkas}) + ] return ret @@ -217,7 +216,6 @@ class CarState(CarStateBase): ("EBCMRegenPaddle", 50), ("EVDriveMode", 0), ] - loopback_messages = [ ("ASCMLKASteeringCmd", float('nan')), ] diff --git a/opendbc_repo/opendbc/car/gm/gmcan.py b/opendbc_repo/opendbc/car/gm/gmcan.py index c44af1a7..53f67fb4 100644 --- a/opendbc_repo/opendbc/car/gm/gmcan.py +++ b/opendbc_repo/opendbc/car/gm/gmcan.py @@ -72,17 +72,14 @@ def create_gas_regen_command(packer, bus, throttle, idx, enabled, at_full_stop): values = { "GasRegenCmdActive": enabled, "RollingCounter": idx, - "GasRegenCmdActiveInv": 1 - enabled, "GasRegenCmd": throttle, "GasRegenFullStopActive": at_full_stop, - "GasRegenAlwaysOne": 1, - "GasRegenAlwaysOne2": 1, - "GasRegenAlwaysOne3": 1, - #"NEW_SIGNAL_1" : 0 if at_full_stop else 3, + "GasRegenAccType": 1, } dat = packer.make_can_msg("ASCMGasRegenCmd", bus, values)[1] - values["GasRegenChecksum"] = (((0xff - dat[1]) & 0xff) << 16) | \ + values["GasRegenChecksum"] = ((1 - enabled) << 24) | \ + (((0xff - dat[1]) & 0xff) << 16) | \ (((0xff - dat[2]) & 0xff) << 8) | \ ((0x100 - dat[3] - idx) & 0xff) @@ -106,6 +103,7 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, enabled, near_s #elif near_stop: # mode = 0xb + apply_brake = max(0, min(0xFFF, apply_brake)) brake = (0x1000 - apply_brake) & 0xfff checksum = (0x10000 - (mode << 12) - brake - idx) & 0xffff @@ -113,7 +111,7 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, enabled, near_s "RollingCounter": idx, "FrictionBrakeMode": mode, "FrictionBrakeChecksum": checksum, - "FrictionBrakeCmd": -apply_brake + "FrictionBrakeCmd": (0x1000 - apply_brake) & 0xfff, } return packer.make_can_msg("EBCMFrictionBrakeCmd", bus, values) diff --git a/opendbc_repo/opendbc/car/gm/interface.py b/opendbc_repo/opendbc/car/gm/interface.py index 1ea5680d..367a0436 100644 --- a/opendbc_repo/opendbc/car/gm/interface.py +++ b/opendbc_repo/opendbc/car/gm/interface.py @@ -104,6 +104,8 @@ class CarInterface(CarInterfaceBase): ret.autoResumeSng = False ret.enableBsm = 0x142 in fingerprint[CanBus.POWERTRAIN] or 0x142 in fingerprint[CanBus.CAMERA] ret.startAccel = 1.0 + ret.radarTimeStep = 0.067 + ret.alternativeExperience = 0 useEVTables = Params().get_bool("EVTable") @@ -120,7 +122,7 @@ class CarInterface(CarInterfaceBase): ret.longitudinalTuning.kiBP = [0.] if candidate in (CAMERA_ACC_CAR | SDGM_CAR): - ret.alphaLongitudinalAvailable = candidate not in (CC_ONLY_CAR | SDGM_CAR) + ret.alphaLongitudinalAvailable = candidate not in SDGM_CAR ret.networkLocation = NetworkLocation.fwdCamera ret.radarUnavailable = True # no radar ret.pcmCruise = True @@ -129,14 +131,13 @@ class CarInterface(CarInterfaceBase): ret.minSteerSpeed = 10 * CV.KPH_TO_MS # Tuning for experimental long - ret.longitudinalTuning.kpV = [1.0] - ret.longitudinalTuning.kiV = [1.0] + ret.longitudinalTuning.kiV = [1.7] ret.stoppingDecelRate = 2.0 # reach brake quickly after enabling - ret.vEgoStopping = 0.25 - ret.vEgoStarting = 0.25 + ret.vEgoStopping = 0.5 + ret.vEgoStarting = 0.4 ret.stopAccel = -0.4 ret.startingState = True - ret.startAccel = 1.5 + ret.startAccel = 1.0 if alpha_long: ret.pcmCruise = False @@ -161,7 +162,6 @@ class CarInterface(CarInterfaceBase): ret.longitudinalTuning.kpV = [1.0] ret.longitudinalTuning.kiV = [0.3] - # TODO: Test for CADILLAC_CT6_ACC if ret.enableGasInterceptorDEPRECATED: # Need to set ASCM long limits when using pedal interceptor, instead of camera ACC long limits ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.HW_ASCM_LONG.value @@ -186,8 +186,8 @@ class CarInterface(CarInterfaceBase): ret.longitudinalTuning.kiV = [.35] ret.longitudinalTuning.kf = 1.0 ret.stoppingDecelRate = 0.2 # brake_travel/s while trying to stop - ret.vEgoStopping = 0.1 - ret.vEgoStarting = 0.05 + ret.vEgoStopping = 0.25 + ret.vEgoStarting = 0.15 ret.stopAccel = -0.5 ret.startingState = True ret.startAccel = 1.9 diff --git a/opendbc_repo/opendbc/car/gm/values.py b/opendbc_repo/opendbc/car/gm/values.py index 2738427e..9c04ece7 100644 --- a/opendbc_repo/opendbc/car/gm/values.py +++ b/opendbc_repo/opendbc/car/gm/values.py @@ -19,7 +19,7 @@ class CarControllerParams: STEER_DRIVER_ALLOWANCE = 65 STEER_DRIVER_MULTIPLIER = 4 STEER_DRIVER_FACTOR = 100 - NEAR_STOP_BRAKE_PHASE = 0.1 #0.5 # m/s + NEAR_STOP_BRAKE_PHASE = 0.4 SNG_INTERCEPTOR_GAS = 18. / 255. SNG_TIME = 30 # frames until the above is reached @@ -37,21 +37,21 @@ class CarControllerParams: def __init__(self, CP): # Gas/brake lookups - self.ZERO_GAS = 2048 # Coasting + self.ZERO_GAS = 0.0 # Coasting self.MAX_BRAKE = 400 # ~ -4.0 m/s^2 with regen if CP.carFingerprint in (CAMERA_ACC_CAR | SDGM_CAR) and CP.carFingerprint not in CC_ONLY_CAR: - self.MAX_GAS = 3400 - self.MAX_ACC_REGEN = 1514 - self.INACTIVE_REGEN = 1554 + self.MAX_GAS = 1346.0 + self.MAX_ACC_REGEN = -540.0 + self.INACTIVE_REGEN = -500.0 # Camera ACC vehicles have no regen while enabled. # Camera transitions to MAX_ACC_REGEN from ZERO_GAS and uses friction brakes instantly max_regen_acceleration = 0. else: - self.MAX_GAS = 3072 # Safety limit, not ACC max. Stock ACC >4096 from standstill. - self.MAX_ACC_REGEN = 1404 # Max ACC regen is slightly less than max paddle regen - self.INACTIVE_REGEN = 1404 + self.MAX_GAS = 1018.0 # Safety limit, not ACC max. Stock ACC >2042 from standstill. + self.MAX_ACC_REGEN = -650.0 # Max ACC regen is slightly less than max paddle regen + self.INACTIVE_REGEN = -650.0 # ICE has much less engine braking force compared to regen in EVs, # lower threshold removes some braking deadzone max_regen_acceleration = -1. if CP.carFingerprint in EV_CAR else -0.1 @@ -268,6 +268,7 @@ class CruiseButtons: class AccState: OFF = 0 ACTIVE = 1 + STANDBY = 2 FAULTED = 3 STANDSTILL = 4 diff --git a/opendbc_repo/opendbc/dbc/generator/gm/gm_global_a_powertrain.dbc b/opendbc_repo/opendbc/dbc/generator/gm/gm_global_a_powertrain.dbc index 2dd72d36..4730a0f5 100644 --- a/opendbc_repo/opendbc/dbc/generator/gm/gm_global_a_powertrain.dbc +++ b/opendbc_repo/opendbc/dbc/generator/gm/gm_global_a_powertrain.dbc @@ -1,4 +1,5 @@ +CM_ "IMPORT _community.dbc"; VERSION "" @@ -194,15 +195,12 @@ BO_ 711 BECMBatteryVoltageCurrent: 6 K17_EBCM SG_ HVBatteryCurrent : 12|13@0- (0.15,0) [-614.4|614.25] "A" NEO BO_ 715 ASCMGasRegenCmd: 8 K124_ASCM - SG_ GasRegenAlwaysOne2 : 9|1@0+ (1,0) [0|1] "" NEO - SG_ GasRegenAlwaysOne : 14|1@0+ (1,0) [0|1] "" NEO - SG_ GasRegenChecksum : 47|24@0+ (1,0) [0|0] "" NEO - SG_ GasRegenCmdActiveInv : 32|1@0+ (1,0) [0|0] "" NEO + SG_ GasRegenAccType : 15|2@0+ (1,0) [0|3] "" NEO + SG_ GasRegenChecksum : 32|25@0+ (1,0) [0|0] "" NEO SG_ GasRegenFullStopActive : 13|1@0+ (1,0) [0|0] "" NEO SG_ GasRegenCmdActive : 0|1@0+ (1,0) [0|0] "" NEO SG_ RollingCounter : 7|2@0+ (1,0) [0|0] "" NEO - SG_ GasRegenAlwaysOne3 : 23|1@0+ (1,0) [0|1] "" NEO - SG_ GasRegenCmd : 22|12@0+ (1,0) [0|0] "" NEO + SG_ GasRegenCmd : 10|19@0+ (0.125,-22534) [-22534|43001.875] "Nm" NEO BO_ 717 ASCM_2CD: 5 K124_ASCM @@ -330,7 +328,7 @@ VAL_ 481 DistanceButton 1 "Active" 0 "Inactive" ; VAL_ 481 LKAButton 1 "Active" 0 "Inactive" ; VAL_ 481 ACCButtons 6 "Cancel" 5 "Main" 3 "Set" 2 "Resume" 1 "None" ; VAL_ 481 DriveModeButton 1 "Active" 0 "Inactive" ; -VAL_ 452 CruiseState 4 "Standstill" 3 "Faulted" 1 "Active" 0 "Off" ; +VAL_ 452 CruiseState 4 "Standstill" 3 "Faulted" 2 "Standby" 1 "Active" 0 "Off" ; VAL_ 309 PRNDL 3 "R" 2 "D" 1 "N" 0 "P" ; VAL_ 309 ESPButton 1 "Active" 0 "Inactive" ; VAL_ 384 LKASteeringCmdActive 1 "Active" 0 "Inactive" ; diff --git a/opendbc_repo/opendbc/dbc/gm_global_a_powertrain_volt.dbc b/opendbc_repo/opendbc/dbc/gm_global_a_powertrain_volt.dbc index 5d03286d..75122aa2 100644 --- a/opendbc_repo/opendbc/dbc/gm_global_a_powertrain_volt.dbc +++ b/opendbc_repo/opendbc/dbc/gm_global_a_powertrain_volt.dbc @@ -1,25 +1,5 @@ -CM_ "AUTOGENERATED FILE, DO NOT EDIT"; - - -CM_ "Imported file _comma.dbc starts here"; -BO_ 512 GAS_COMMAND: 6 NEO - SG_ GAS_COMMAND : 7|16@0+ (0.125677,-75.909) [0|1] "" INTERCEPTOR - SG_ GAS_COMMAND2 : 23|16@0+ (0.251976,-76.601) [0|1] "" INTERCEPTOR - SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR - SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" INTERCEPTOR - SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" INTERCEPTOR - -BO_ 513 GAS_SENSOR: 6 INTERCEPTOR - SG_ INTERCEPTOR_GAS : 7|16@0+ (0.125677,-75.909) [0|1] "" NEO - SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.251976,-76.601) [0|1] "" NEO - SG_ STATE : 39|4@0+ (1,0) [0|15] "" NEO - SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" NEO - SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" NEO - -VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; - -CM_ "gm_global_a_powertrain.dbc starts here"; +CM_ "IMPORT _community.dbc"; VERSION "" @@ -214,15 +194,12 @@ BO_ 711 BECMBatteryVoltageCurrent: 6 K17_EBCM SG_ HVBatteryCurrent : 12|13@0- (0.15,0) [-614.4|614.25] "A" NEO BO_ 715 ASCMGasRegenCmd: 8 K124_ASCM - SG_ GasRegenAlwaysOne2 : 9|1@0+ (1,0) [0|1] "" NEO - SG_ GasRegenAlwaysOne : 14|1@0+ (1,0) [0|1] "" NEO - SG_ GasRegenChecksum : 47|24@0+ (1,0) [0|0] "" NEO - SG_ GasRegenCmdActiveInv : 32|1@0+ (1,0) [0|0] "" NEO + SG_ GasRegenAccType : 15|2@0+ (1,0) [0|3] "" NEO + SG_ GasRegenChecksum : 32|25@0+ (1,0) [0|0] "" NEO SG_ GasRegenFullStopActive : 13|1@0+ (1,0) [0|0] "" NEO SG_ GasRegenCmdActive : 0|1@0+ (1,0) [0|0] "" NEO SG_ RollingCounter : 7|2@0+ (1,0) [0|0] "" NEO - SG_ GasRegenAlwaysOne3 : 23|1@0+ (1,0) [0|1] "" NEO - SG_ GasRegenCmd : 22|12@0+ (1,0) [0|0] "" NEO + SG_ GasRegenCmd : 10|19@0+ (0.125,-22534) [-22534|43001.875] "Nm" NEO BO_ 717 ASCM_2CD: 5 K124_ASCM @@ -350,7 +327,7 @@ VAL_ 481 DistanceButton 1 "Active" 0 "Inactive" ; VAL_ 481 LKAButton 1 "Active" 0 "Inactive" ; VAL_ 481 ACCButtons 6 "Cancel" 5 "Main" 3 "Set" 2 "Resume" 1 "None" ; VAL_ 481 DriveModeButton 1 "Active" 0 "Inactive" ; -VAL_ 452 CruiseState 4 "Standstill" 3 "Faulted" 1 "Active" 0 "Off" ; +VAL_ 452 CruiseState 4 "Standstill" 3 "Faulted" 2 "Standby" 1 "Active" 0 "Off" ; VAL_ 309 PRNDL 3 "R" 2 "D" 1 "N" 0 "P" ; VAL_ 309 ESPButton 1 "Active" 0 "Inactive" ; VAL_ 384 LKASteeringCmdActive 1 "Active" 0 "Inactive" ; diff --git a/opendbc_repo/opendbc/safety/safety/safety_gm.h b/opendbc_repo/opendbc/safety/safety/safety_gm.h index f429fa5a..5547ebb1 100644 --- a/opendbc_repo/opendbc/safety/safety/safety_gm.h +++ b/opendbc_repo/opendbc/safety/safety/safety_gm.h @@ -2,6 +2,19 @@ #include "safety_declarations.h" +// TODO: do checksum and counter checks. Add correct timestep, 0.1s for now. +#define GM_COMMON_RX_CHECKS \ + {.msg = {{0x184, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, \ + {.msg = {{0x34A, 0, 5, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, \ + {.msg = {{0x1E1, 0, 7, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, \ + {.msg = {{0x1C4, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, \ + {.msg = {{0xC9, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, \ + +#define GM_ACC_RX_CHECKS \ + {.msg = {{0xBE, 0, 6, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, /* Volt, Silverado, Acadia Denali */ \ + {0xBE, 0, 7, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, /* Bolt EUV */ \ + {0xBE, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}}}, /* Escalade */ \ + static const LongitudinalLimits *gm_long_limits; enum { @@ -76,9 +89,11 @@ static void gm_rx_hook(const CANPacket_t *to_push) { if ((addr == 0xBE) && (gm_hw == GM_ASCM)) { brake_pressed = GET_BYTE(to_push, 1) >= 10U; } - - if ((addr == 0xC9) && (gm_hw == GM_CAM)) { - brake_pressed = GET_BIT(to_push, 40U); + if (addr == 0xC9) { + if (gm_hw == GM_CAM) { + brake_pressed = (GET_BYTE(to_push, 5) & 0x01U) != 0U; + } + acc_main_on = (GET_BYTE(to_push, 3) & 0x20U) != 0U; } if (addr == 0x1C4) { @@ -112,13 +127,13 @@ static void gm_rx_hook(const CANPacket_t *to_push) { int gas_interceptor = GM_GET_INTERCEPTOR(to_push); gas_pressed = gas_interceptor > GM_GAS_INTERCEPTOR_THRESHOLD; gas_interceptor_prev = gas_interceptor; -// gm_pcm_cruise = false; + // gm_pcm_cruise = false; } bool stock_ecu_detected = (addr == 0x180); // ASCMLKASteeringCmd // Check ASCMGasRegenCmd only if we're blocking it - if (!gm_pcm_cruise && !gm_pedal_long && (addr == 0x2CB)) { + if (!gm_pcm_cruise && (addr == 0x2CB)) { stock_ecu_detected = true; } generic_rx_checks(stock_ecu_detected); @@ -128,8 +143,8 @@ static void gm_rx_hook(const CANPacket_t *to_push) { static bool gm_tx_hook(const CANPacket_t *to_send) { const TorqueSteeringLimits GM_STEERING_LIMITS = { .max_steer = 300, - .max_rate_up = 10, - .max_rate_down = 15, + .max_rate_up = 20, + .max_rate_down = 25, .driver_torque_allowance = 65, .driver_torque_multiplier = 4, .max_rt_delta = 128, @@ -171,11 +186,11 @@ static bool gm_tx_hook(const CANPacket_t *to_send) { // GAS/REGEN: safety check if (addr == 0x2CB) { bool apply = GET_BIT(to_send, 0U); - if (apply) { - if(!controls_allowed) print("@@auto cruise control enabled....\n"); - controls_allowed = true; + if (apply && !controls_allowed) { + controls_allowed = true; } - int gas_regen = ((GET_BYTE(to_send, 2) & 0x7FU) << 5) + ((GET_BYTE(to_send, 3) & 0xF8U) >> 3); + // convert float CAN signal to an int for gas checks: 22534 / 0.125 = 180272 + int gas_regen = (((GET_BYTE(to_send, 1) & 0x7U) << 16) | (GET_BYTE(to_send, 2) << 8) | GET_BYTE(to_send, 3)) - 180272U; bool violation = false; // Allow apply bit in pre-enabled and overriding states @@ -188,13 +203,15 @@ static bool gm_tx_hook(const CANPacket_t *to_send) { } // BUTTONS: used for resume spamming and cruise cancellation with stock longitudinal - if ((addr == 0x1E1) && (gm_pcm_cruise || gm_pedal_long || gm_cc_long)) { + if (addr == 0x1E1) { int button = (GET_BYTE(to_send, 5) >> 4) & 0x7U; - bool allowed_btn = (button == GM_BTN_CANCEL) && cruise_engaged_prev; - // For standard CC, allow spamming of SET / RESUME + + if (!gm_pcm_cruise) { + allowed_btn |= (button == GM_BTN_SET || button == GM_BTN_RESUME || button == GM_BTN_UNPRESS); + } if (gm_cc_long) { - allowed_btn |= cruise_engaged_prev && ((button == GM_BTN_SET) || (button == GM_BTN_RESUME) || (button == GM_BTN_UNPRESS)); + allowed_btn |= cruise_engaged_prev && (button == GM_BTN_SET || button == GM_BTN_RESUME || button == GM_BTN_UNPRESS); } if (!allowed_btn) { @@ -239,10 +256,13 @@ static safety_config gm_init(uint16_t param) { const uint16_t GM_PARAM_NO_ACC = 32; const uint16_t GM_PARAM_PEDAL_LONG = 64; // TODO: this can be inferred + // common safety checks assume unscaled integer values + static const int GM_GAS_TO_CAN = 8; // 1 / 0.125 + static const LongitudinalLimits GM_ASCM_LONG_LIMITS = { - .max_gas = 3072, - .min_gas = 1404, - .inactive_gas = 1404, + .max_gas = 1018 * GM_GAS_TO_CAN, + .min_gas = -650 * GM_GAS_TO_CAN, + .inactive_gas = -650 * GM_GAS_TO_CAN, .max_brake = 400, }; @@ -251,38 +271,52 @@ static safety_config gm_init(uint16_t param) { {0x315, 2, 5}}; // ch bus - static const CanMsg GM_CC_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, // pt bus - {0x184, 2, 8}, {0x1E1, 2, 7}}; // camera bus - - static const LongitudinalLimits GM_CAM_LONG_LIMITS = { - .max_gas = 3400, - .min_gas = 1514, - .inactive_gas = 1554, + .max_gas = 1346 * GM_GAS_TO_CAN, + .min_gas = -540 * GM_GAS_TO_CAN, + .inactive_gas = -500 * GM_GAS_TO_CAN, .max_brake = 400, }; static const CanMsg GM_CAM_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x315, 0, 5}, {0x2CB, 0, 8}, {0x370, 0, 6}, {0x200, 0, 6}, {0x1E1, 0, 7}, // pt bus {0x184, 2, 8}}; // camera bus - // TODO: do checksum and counter checks. Add correct timestep, 0.1s for now. static RxCheck gm_rx_checks[] = { - {.msg = {{0x184, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, - {.msg = {{0x34A, 0, 5, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, - {.msg = {{0x1E1, 0, 7, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, - {.msg = {{0xBE, 0, 6, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, // Volt, Silverado, Acadia Denali - {0xBE, 0, 7, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, // Bolt EUV - {0xBE, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}}}, // Escalade - {.msg = {{0xF1, 0, 6, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, - {.msg = {{0x1C4, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, - {.msg = {{0xC9, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, + GM_COMMON_RX_CHECKS + GM_ACC_RX_CHECKS + }; + + static RxCheck gm_ev_rx_checks[] = { + GM_COMMON_RX_CHECKS + GM_ACC_RX_CHECKS + {.msg = {{0xBD, 0, 7, .ignore_checksum = true, .ignore_counter = true, .frequency = 40U}, { 0 }, { 0 }}}, + }; + + static RxCheck gm_no_acc_rx_checks[] = { + GM_COMMON_RX_CHECKS + {.msg = {{0x3D1, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, // Non-ACC PCM + }; + + static RxCheck gm_no_acc_ev_rx_checks[] = { + GM_COMMON_RX_CHECKS + {.msg = {{0xBD, 0, 7, .ignore_checksum = true, .ignore_counter = true, .frequency = 40U}, { 0 }, { 0 }}}, + {.msg = {{0x3D1, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, // Non-ACC PCM + }; + + static RxCheck gm_pedal_rx_checks[] = { + GM_COMMON_RX_CHECKS + {.msg = {{0xBD, 0, 7, .ignore_checksum = true, .ignore_counter = true, .frequency = 40U}, { 0 }, { 0 }}}, + {.msg = {{0x3D1, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, // Non-ACC PCM + {.msg = {{0x201, 0, 6, .ignore_checksum = true, .ignore_counter = true, .frequency = 10U}, { 0 }, { 0 }}}, // pedal }; static const CanMsg GM_CAM_TX_MSGS[] = {{0x180, 0, 4}, {0x200, 0, 6}, {0x1E1, 0, 7}, // pt bus {0x1E1, 2, 7}, {0x184, 2, 8}}; // camera bus + static const CanMsg GM_CC_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, // pt bus + {0x184, 2, 8}, {0x1E1, 2, 7}}; // camera bus gm_hw = GET_FLAG(param, GM_PARAM_HW_CAM) ? GM_CAM : GM_ASCM; gm_force_ascm = GET_FLAG(param, GM_PARAM_HW_ASCM_LONG); @@ -299,7 +333,7 @@ static safety_config gm_init(uint16_t param) { #endif gm_pedal_long = GET_FLAG(param, GM_PARAM_PEDAL_LONG); gm_cc_long = GET_FLAG(param, GM_PARAM_CC_LONG); - gm_pcm_cruise = (gm_hw == GM_CAM) && !gm_cam_long && !gm_force_ascm && !gm_pedal_long; + gm_pcm_cruise = (gm_hw == GM_CAM) && (!gm_cam_long || gm_cc_long) && !gm_force_ascm && !gm_pedal_long; gm_skip_relay_check = GET_FLAG(param, GM_PARAM_NO_CAMERA); gm_has_acc = !GET_FLAG(param, GM_PARAM_NO_ACC); @@ -310,7 +344,7 @@ static safety_config gm_init(uint16_t param) { } else print("GM Pedal Interceptor Disabled\n"); - safety_config ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_ASCM_TX_MSGS); + safety_config ret; if (gm_hw == GM_CAM) { if (gm_cc_long) { ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CC_LONG_TX_MSGS); @@ -322,7 +356,21 @@ static safety_config gm_init(uint16_t param) { ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_TX_MSGS); print("GM CAM\n"); } + } else { + ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_ASCM_TX_MSGS); } + + const bool gm_ev = GET_FLAG(param, GM_PARAM_EV); + if (enable_gas_interceptor) { + SET_RX_CHECKS(gm_pedal_rx_checks, ret); + } else if (!gm_has_acc && gm_ev) { + SET_RX_CHECKS(gm_no_acc_ev_rx_checks, ret); + } else if (!gm_has_acc && !gm_ev) { + SET_RX_CHECKS(gm_no_acc_rx_checks, ret); + } else if (gm_ev) { + SET_RX_CHECKS(gm_ev_rx_checks, ret); + } else {} + return ret; }