diff --git a/frogpilot/common/frogpilot_variables.py b/frogpilot/common/frogpilot_variables.py index b91ca57de..63ae0040b 100644 --- a/frogpilot/common/frogpilot_variables.py +++ b/frogpilot/common/frogpilot_variables.py @@ -1002,6 +1002,7 @@ class FrogPilotVariables: volt_models = { "CHEVROLET_VOLT", + "CHEVROLET_VOLT_2019", "CHEVROLET_VOLT_ASCM", "CHEVROLET_VOLT_CAMERA", } diff --git a/panda/board/obj/bootstub.panda.bin b/panda/board/obj/bootstub.panda.bin index 8efaaee50..8ff046882 100755 Binary files a/panda/board/obj/bootstub.panda.bin and b/panda/board/obj/bootstub.panda.bin differ diff --git a/panda/board/obj/bootstub.panda_h7.bin b/panda/board/obj/bootstub.panda_h7.bin index 2bc4c10dc..2ed656a52 100755 Binary files a/panda/board/obj/bootstub.panda_h7.bin and b/panda/board/obj/bootstub.panda_h7.bin differ diff --git a/panda/board/obj/panda.bin.signed b/panda/board/obj/panda.bin.signed index 1877c532a..1a28efa33 100644 Binary files a/panda/board/obj/panda.bin.signed and b/panda/board/obj/panda.bin.signed differ diff --git a/panda/board/obj/panda_h7.bin.signed b/panda/board/obj/panda_h7.bin.signed index 9065a076f..99011df36 100644 Binary files a/panda/board/obj/panda_h7.bin.signed and b/panda/board/obj/panda_h7.bin.signed differ diff --git a/panda/board/safety/safety_gm.h b/panda/board/safety/safety_gm.h index be2cb7adc..1e0ebb326 100644 --- a/panda/board/safety/safety_gm.h +++ b/panda/board/safety/safety_gm.h @@ -10,14 +10,14 @@ const SteeringLimits GM_STEERING_LIMITS = { }; const LongitudinalLimits GM_ASCM_LONG_LIMITS = { - .max_gas = 7168, + .max_gas = 8191, .min_gas = 5500, .inactive_gas = 5500, .max_brake = 400, }; const LongitudinalLimits GM_CAM_LONG_LIMITS = { - .max_gas = 7496, + .max_gas = 8848, .min_gas = 5610, .inactive_gas = 5650, .max_brake = 400, diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index cf1f68280..ec4432576 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -48,13 +48,12 @@ class CarController(CarControllerBase): self.lka_icon_status_last = (False, False) self.params = CarControllerParams(self.CP) - self.is_volt = self.CP.carFingerprint in (CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_ASCM, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_VOLT_CC) - if self.is_volt: - self.mass = CP.mass - self.tireRadius = 0.075 * CP.wheelbase + 0.1453 - self.frontalArea = 1.05 * CP.wheelbase + 0.0679 - self.coeffDrag = 0.30 - self.airDensity = 1.225 + self.is_volt = self.CP.carFingerprint in (CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_2019, CAR.CHEVROLET_VOLT_ASCM, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_VOLT_CC) + self.mass = CP.mass + self.tireRadius = 0.075 * CP.wheelbase + 0.1453 + self.frontalArea = 1.05 * CP.wheelbase + 0.0679 + self.coeffDrag = 0.30 + self.airDensity = 1.225 self.params_ = Params() self.packer_pt = CANPacker(DBC[self.CP.carFingerprint]['pt']) @@ -166,21 +165,46 @@ class CarController(CarControllerBase): accel = clip(accel, self.params.ACCEL_MIN, self.params.ACCEL_MAX) brake_accel = clip(brake_accel, self.params.ACCEL_MIN, self.params.ACCEL_MAX) - if self.CP.carFingerprint in EV_CAR: - self.params.update_ev_gas_brake_threshold(CS.out.vEgo) - self.apply_gas = int(round(interp(accel, self.params.EV_GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V))) - self.apply_brake = int(round(interp(brake_accel, self.params.EV_BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V))) + if self.CP.carFingerprint in EV_CAR: + self.params.update_ev_gas_brake_threshold(CS.out.vEgo) + self.apply_gas = int(round(interp(accel, self.params.EV_GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V))) + self.apply_brake = int(round(interp(brake_accel, self.params.EV_BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V))) + else: + self.apply_gas = int(round(interp(accel, self.params.GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V))) + self.apply_brake = int(round(interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V))) + + # Clamp within message-valid ranges to avoid ASCM faults from overshoot or rounding + self.apply_gas = int(round(clip(self.apply_gas, self.params.MAX_ACC_REGEN, self.params.MAX_GAS))) + self.apply_brake = int(round(clip(self.apply_brake, 0, self.params.MAX_BRAKE))) + + if self.apply_brake > 0: + # Volt should never present positive torque alongside friction braking + self.apply_gas = self.params.INACTIVE_REGEN else: - self.apply_gas = int(round(interp(accel, self.params.GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V))) + if len(CC.orientationNED) == 3 and CS.out.vEgo > self.CP.vEgoStopping: + accel_due_to_pitch = math.sin(CC.orientationNED[1]) * ACCELERATION_DUE_TO_GRAVITY + else: + accel_due_to_pitch = 0.0 + + gas_max = self.params.MAX_GAS + accel_max = self.params.ACCEL_MAX + + accel = clip(actuators.accel + accel_due_to_pitch, self.params.ACCEL_MIN, accel_max) + torque = self.tireRadius * ((self.mass * accel) + (0.5 * self.coeffDrag * self.frontalArea * self.airDensity * CS.out.vEgo ** 2)) + + scaled_torque = torque + self.params.ZERO_GAS + apply_gas_torque = clip(scaled_torque, self.params.MAX_ACC_REGEN, gas_max) + BRAKE_SWITCH = int(round(interp(CS.out.vEgo, self.params.BRAKE_SWITCH_LOOKUP_BP, self.params.BRAKE_SWITCH_LOOKUP_V))) + brake_accel = min((scaled_torque - BRAKE_SWITCH) / (self.tireRadius * self.mass), 0) + self.apply_gas = int(round(apply_gas_torque)) self.apply_brake = int(round(interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V))) - # Clamp within message-valid ranges to avoid ASCM faults from overshoot or rounding - self.apply_gas = int(round(clip(self.apply_gas, self.params.MAX_ACC_REGEN, self.params.MAX_GAS))) - self.apply_brake = int(round(clip(self.apply_brake, 0, self.params.MAX_BRAKE))) + # Clamp within message-valid ranges to avoid ASCM faults from overshoot or rounding + self.apply_gas = int(round(clip(self.apply_gas, self.params.MAX_ACC_REGEN, self.params.MAX_GAS))) + self.apply_brake = int(round(clip(self.apply_brake, 0, self.params.MAX_BRAKE))) - if self.is_volt and self.apply_brake > 0: - # Volt should never present positive torque alongside friction braking - self.apply_gas = self.params.INACTIVE_REGEN + if self.apply_brake > 0 and self.apply_gas > self.params.INACTIVE_REGEN: + self.apply_gas = self.params.INACTIVE_REGEN # Don't allow any gas above inactive regen while stopping # FIXME: brakes aren't applied immediately when enabling at a stop if stopping: diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index ed505e270..e566946fd 100644 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -148,12 +148,12 @@ class CarInterface(CarInterfaceBase): ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM # Tuning for experimental long - ret.longitudinalTuning.kiV = [1.0, 1.0] + ret.longitudinalTuning.kiV = [0.5, 0.5] ret.stoppingDecelRate = 1.0 # reach brake quickly after enabling ret.vEgoStopping = 0.25 ret.vEgoStarting = 0.25 - ret.stopAccel = -0.20 + ret.stopAccel = -0.25 if ret.experimentalLongitudinalAvailable and experimental_long: ret.pcmCruise = False diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 2e78cb4da..a3a5e513e 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -38,12 +38,12 @@ class CarControllerParams: def __init__(self, CP): # Gas/brake lookups - self.ZERO_GAS = 6144 # Coasting + self.ZERO_GAS = 6150 # Coasting self.MAX_BRAKE = 400 # ~ -4.0 m/s^2 with regen self.BRAKE_SWITCH_MAX = self.ZERO_GAS - if CP.carFingerprint in (CAMERA_ACC_CAR | SDGM_CAR) and CP.carFingerprint not in CC_ONLY_CAR and CP.carFingerprint != CAR.CHEVROLET_BOLT_EUV: - self.MAX_GAS = 7496 + if CP.carFingerprint in CAMERA_ACC_CAR and CP.carFingerprint not in CC_ONLY_CAR and CP.carFingerprint != CAR.CHEVROLET_BOLT_EUV: + self.MAX_GAS = 8848 self.MAX_GAS_PLUS = 8848 self.MAX_ACC_REGEN = 5610 self.INACTIVE_REGEN = 5650 @@ -51,9 +51,17 @@ class CarControllerParams: # Camera transitions to MAX_ACC_REGEN from ZERO_GAS and uses friction brakes instantly self.max_regen_acceleration = 0. + elif CP.carFingerprint in SDGM_CAR and CP.carFingerprint not in CC_ONLY_CAR and CP.carFingerprint != CAR.CHEVROLET_BOLT_EUV: + self.MAX_GAS = 8191 + self.MAX_GAS_PLUS = 8191 + self.MAX_ACC_REGEN = 5500 + self.INACTIVE_REGEN = 5500 + # SDGM integrations match the ASCM longitudinal envelope + self.max_regen_acceleration = 0. + else: - self.MAX_GAS = 7168 # Safety limit, not ACC max. Stock ACC >8192 from standstill. - self.MAX_GAS_PLUS = 8191 # 8292 uses new bit, possible but not tested. Matches Twilsonco tw-main max + self.MAX_GAS = 8191 # Safety limit, not ACC max. Stock ACC >8192 from standstill. + self.MAX_GAS_PLUS = 8191 self.MAX_ACC_REGEN = 5500 # Max ACC regen is slightly less than max paddle regen self.INACTIVE_REGEN = 5500 # ICE has much less engine braking force compared to regen in EVs,