mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-06-23 06:52:07 +08:00
GM camera ACC: vision-only ACC behind toggle (#25631)
* put gm camera voacc behind disable radar toggle * bump panda * bump panda * bump panda * experimental long * fixes * car control notes and fixes for Bolt EUV * might enable stop and go * consistent name * min enable speed seems to be around 5 kph * camera acc can engage under 5 kph if stopped * comment * comment * remove this for now * only real brake * comments * update max brake * bump * clean up/fix * same if * simplify * fix * old comment * no brake_pressed * temporary fault fix * tune longitudinal * update docs * bump panda * GM camera ACC cars have no regen in ACC * cleaner * cleaner * fix * set max gas * fixes * fix LKAS unavailable warning from camera * only camera * bump panda * bump panda * bump panda * bump panda * clean up gmcan * clean up CC * flip * rm * rm comment * clean up * custom starting/stopping probably not needed * Update selfdrive/car/gm/carcontroller.py * fix crash * long tuning * we need long control state to resume * CAMERA_ACC_CAR not needed * no interp on accel * tuning * formatting * formatting * formatting * formatting * formatting * no need to init ccp * makes more sense now
This commit is contained in:
+3
-3
@@ -18,8 +18,8 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|Stock|0 mph|0 mph|[](##)|[](##)|VW|
|
||||
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|Stock|0 mph|0 mph|[](##)|[](##)|VW|
|
||||
|Cadillac|Escalade ESV 2016[<sup>2</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|6 mph|[](##)|[](##)|OBD-II|
|
||||
|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim without Super Cruise Package|Stock|3 mph|6 mph|[](##)|[](##)|GM|
|
||||
|Chevrolet|Silverado 1500 2020-21|Safety Package II|Stock|3 mph|6 mph|[](##)|[](##)|GM|
|
||||
|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim without Super Cruise Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|GM|
|
||||
|Chevrolet|Silverado 1500 2020-21|Safety Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|GM|
|
||||
|Chevrolet|Volt 2017-18[<sup>2</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|6 mph|[](##)|[](##)|OBD-II|
|
||||
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|FCA|
|
||||
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|FCA|
|
||||
@@ -32,7 +32,7 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Genesis|G80 2017-19|All|Stock|0 mph|0 mph|[](##)|[](##)|Hyundai H|
|
||||
|Genesis|G90 2017-18|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|Hyundai C|
|
||||
|GMC|Acadia 2018[<sup>2</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|6 mph|[](##)|[](##)|OBD-II|
|
||||
|GMC|Sierra 1500 2020-21|Driver Alert Package II|Stock|3 mph|6 mph|[](##)|[](##)|GM|
|
||||
|GMC|Sierra 1500 2020-21|Driver Alert Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|GM|
|
||||
|Honda|Accord 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|Honda Bosch A|
|
||||
|Honda|Accord Hybrid 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|Honda Bosch A|
|
||||
|Honda|Civic 2016-18|Honda Sensing|openpilot|0 mph|12 mph|[](##)|[](##)|Honda Nidec|
|
||||
|
||||
@@ -5,10 +5,11 @@ from common.realtime import DT_CTRL
|
||||
from opendbc.can.packer import CANPacker
|
||||
from selfdrive.car import apply_std_steer_torque_limits
|
||||
from selfdrive.car.gm import gmcan
|
||||
from selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons, EV_CAR
|
||||
from selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons
|
||||
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
NetworkLocation = car.CarParams.NetworkLocation
|
||||
LongCtrlState = car.CarControl.Actuators.LongControlState
|
||||
|
||||
# Camera cancels up to 0.1s after brake is pressed, ECM allows 0.5s
|
||||
CAMERA_CANCEL_DELAY_FRAMES = 10
|
||||
@@ -30,7 +31,7 @@ class CarController:
|
||||
self.sent_lka_steering_cmd = False
|
||||
self.lka_icon_status_last = (False, False)
|
||||
|
||||
self.params = CarControllerParams()
|
||||
self.params = CarControllerParams(self.CP)
|
||||
|
||||
self.packer_pt = CANPacker(DBC[self.CP.carFingerprint]['pt'])
|
||||
self.packer_obj = CANPacker(DBC[self.CP.carFingerprint]['radar'])
|
||||
@@ -83,20 +84,23 @@ class CarController:
|
||||
self.apply_gas = self.params.INACTIVE_REGEN
|
||||
self.apply_brake = 0
|
||||
else:
|
||||
if self.CP.carFingerprint in EV_CAR:
|
||||
self.apply_gas = int(round(interp(actuators.accel, self.params.EV_GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V)))
|
||||
self.apply_brake = int(round(interp(actuators.accel, self.params.EV_BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
|
||||
else:
|
||||
self.apply_gas = int(round(interp(actuators.accel, self.params.GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V)))
|
||||
self.apply_brake = int(round(interp(actuators.accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
|
||||
self.apply_gas = int(round(interp(actuators.accel, self.params.GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V)))
|
||||
self.apply_brake = int(round(interp(actuators.accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
|
||||
|
||||
idx = (self.frame // 4) % 4
|
||||
|
||||
at_full_stop = CC.longActive and CS.out.standstill
|
||||
near_stop = CC.longActive and (CS.out.vEgo < self.params.NEAR_STOP_BRAKE_PHASE)
|
||||
friction_brake_bus = CanBus.CHASSIS
|
||||
# GM Camera exceptions
|
||||
# TODO: can we always check the longControlState?
|
||||
if self.CP.networkLocation == NetworkLocation.fwdCamera:
|
||||
at_full_stop = at_full_stop and actuators.longControlState == LongCtrlState.stopping
|
||||
friction_brake_bus = CanBus.POWERTRAIN
|
||||
|
||||
# GasRegenCmdActive needs to be 1 to avoid cruise faults. It describes the ACC state, not actuation
|
||||
can_sends.append(gmcan.create_gas_regen_command(self.packer_pt, CanBus.POWERTRAIN, self.apply_gas, idx, CC.enabled, at_full_stop))
|
||||
can_sends.append(gmcan.create_friction_brake_command(self.packer_ch, CanBus.CHASSIS, self.apply_brake, idx, near_stop, at_full_stop))
|
||||
can_sends.append(gmcan.create_friction_brake_command(self.packer_ch, friction_brake_bus, self.apply_brake, idx, CC.enabled, near_stop, at_full_stop, self.CP))
|
||||
|
||||
# Send dashboard UI commands (ACC status)
|
||||
send_fcw = hud_alert == VisualAlert.fcw
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from selfdrive.car import make_can_msg
|
||||
from selfdrive.car.gm.values import CAR
|
||||
|
||||
|
||||
def create_buttons(packer, bus, idx, button):
|
||||
@@ -52,15 +53,20 @@ def create_gas_regen_command(packer, bus, throttle, idx, enabled, at_full_stop):
|
||||
return packer.make_can_msg("ASCMGasRegenCmd", bus, values)
|
||||
|
||||
|
||||
def create_friction_brake_command(packer, bus, apply_brake, idx, near_stop, at_full_stop):
|
||||
def create_friction_brake_command(packer, bus, apply_brake, idx, enabled, near_stop, at_full_stop, CP):
|
||||
mode = 0x1
|
||||
|
||||
# TODO: Understand this better. Volts and ICE Camera ACC cars are 0x1 when enabled with no brake
|
||||
if enabled and CP.carFingerprint in (CAR.BOLT_EUV,):
|
||||
mode = 0x9
|
||||
|
||||
if apply_brake > 0:
|
||||
mode = 0xa
|
||||
if at_full_stop:
|
||||
mode = 0xd
|
||||
|
||||
# TODO: this is to have GM bringing the car to complete stop,
|
||||
# but currently it conflicts with OP controls, so turned off.
|
||||
# but currently it conflicts with OP controls, so turned off. Not set by all cars
|
||||
#elif near_stop:
|
||||
# mode = 0xb
|
||||
|
||||
|
||||
@@ -20,8 +20,7 @@ BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.D
|
||||
class CarInterface(CarInterfaceBase):
|
||||
@staticmethod
|
||||
def get_pid_accel_limits(CP, current_speed, cruise_speed):
|
||||
params = CarControllerParams()
|
||||
return params.ACCEL_MIN, params.ACCEL_MAX
|
||||
return CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX
|
||||
|
||||
# Determined by iteratively plotting and minimizing error for f(angle, speed) = steer.
|
||||
@staticmethod
|
||||
@@ -56,13 +55,34 @@ class CarInterface(CarInterfaceBase):
|
||||
else:
|
||||
ret.transmissionType = TransmissionType.automatic
|
||||
|
||||
ret.longitudinalTuning.deadzoneBP = [0.]
|
||||
ret.longitudinalTuning.deadzoneV = [0.15]
|
||||
|
||||
ret.longitudinalTuning.kpBP = [5., 35.]
|
||||
ret.longitudinalTuning.kiBP = [0.]
|
||||
|
||||
if candidate in CAMERA_ACC_CAR:
|
||||
ret.openpilotLongitudinalControl = False
|
||||
ret.experimentalLongitudinalAvailable = True
|
||||
ret.networkLocation = NetworkLocation.fwdCamera
|
||||
ret.radarOffCan = True # no radar
|
||||
ret.pcmCruise = True
|
||||
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM
|
||||
ret.minEnableSpeed = 5 * CV.KPH_TO_MS
|
||||
|
||||
if experimental_long:
|
||||
ret.pcmCruise = False
|
||||
ret.openpilotLongitudinalControl = True
|
||||
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
|
||||
|
||||
# Tuning
|
||||
ret.longitudinalTuning.kpV = [2.0, 1.5]
|
||||
ret.longitudinalTuning.kiV = [0.72]
|
||||
ret.stopAccel = -2.0
|
||||
ret.stoppingDecelRate = 2.0 # reach brake quickly after enabling
|
||||
ret.vEgoStopping = 0.25
|
||||
ret.vEgoStarting = 0.25
|
||||
ret.longitudinalActuatorDelayUpperBound = 0.5
|
||||
|
||||
else: # ASCM, OBD-II harness
|
||||
ret.openpilotLongitudinalControl = True
|
||||
ret.networkLocation = NetworkLocation.gateway
|
||||
@@ -71,6 +91,10 @@ class CarInterface(CarInterfaceBase):
|
||||
# supports stop and go, but initial engage must (conservatively) be above 18mph
|
||||
ret.minEnableSpeed = 18 * CV.MPH_TO_MS
|
||||
|
||||
# Tuning
|
||||
ret.longitudinalTuning.kpV = [2.4, 1.5]
|
||||
ret.longitudinalTuning.kiV = [0.36]
|
||||
|
||||
# These cars have been put into dashcam only due to both a lack of users and test coverage.
|
||||
# These cars likely still work fine. Once a user confirms each car works and a test route is
|
||||
# added to selfdrive/car/tests/routes.py, we can remove it from this list.
|
||||
@@ -85,14 +109,6 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.steerActuatorDelay = 0.1 # Default delay, not measured yet
|
||||
tire_stiffness_factor = 0.444 # not optimized yet
|
||||
|
||||
ret.longitudinalTuning.kpBP = [5., 35.]
|
||||
ret.longitudinalTuning.kpV = [2.4, 1.5]
|
||||
ret.longitudinalTuning.kiBP = [0.]
|
||||
ret.longitudinalTuning.kiV = [0.36]
|
||||
|
||||
ret.longitudinalTuning.deadzoneBP = [0.]
|
||||
ret.longitudinalTuning.deadzoneV = [0.15]
|
||||
|
||||
ret.steerLimitTimer = 0.4
|
||||
ret.radarTimeStep = 0.0667 # GM radar runs at 15Hz instead of standard 20Hz
|
||||
|
||||
|
||||
+25
-17
@@ -24,15 +24,6 @@ class CarControllerParams:
|
||||
ADAS_KEEPALIVE_STEP = 100
|
||||
CAMERA_KEEPALIVE_STEP = 100
|
||||
|
||||
# Volt gas/brake lookups
|
||||
# TODO: These values should be confirmed on non-Volt vehicles.
|
||||
# MAX_GAS should achieve 2 m/s^2 and MAX_BRAKE with regen should achieve -4.0 m/s^2
|
||||
MAX_GAS = 3072 # Safety limit, not ACC max. Stock ACC >4096 from standstill.
|
||||
ZERO_GAS = 2048 # Coasting
|
||||
MAX_BRAKE = 400 # ~ -4.0 m/s^2 with regen
|
||||
MAX_ACC_REGEN = 1404 # Max ACC regen is slightly less than max paddle regen
|
||||
INACTIVE_REGEN = 1404
|
||||
|
||||
# Allow small margin below -3.5 m/s^2 from ISO 15622:2018 since we
|
||||
# perform the closed loop control, and might need some
|
||||
# to apply some more braking if we're on a downhill slope.
|
||||
@@ -41,15 +32,32 @@ class CarControllerParams:
|
||||
ACCEL_MAX = 2. # m/s^2
|
||||
ACCEL_MIN = -4. # m/s^2
|
||||
|
||||
# ICE has much less engine braking force compared to regen in EVs,
|
||||
# lower threshold removes some braking deadzone
|
||||
GAS_LOOKUP_BP = [-0.1, 0., ACCEL_MAX]
|
||||
EV_GAS_LOOKUP_BP = [-1., 0., ACCEL_MAX]
|
||||
GAS_LOOKUP_V = [MAX_ACC_REGEN, ZERO_GAS, MAX_GAS]
|
||||
def __init__(self, CP):
|
||||
# Gas/brake lookups
|
||||
self.ZERO_GAS = 2048 # Coasting
|
||||
self.MAX_BRAKE = 400 # ~ -4.0 m/s^2 with regen
|
||||
|
||||
BRAKE_LOOKUP_BP = [ACCEL_MIN, -0.1]
|
||||
EV_BRAKE_LOOKUP_BP = [ACCEL_MIN, -1.]
|
||||
BRAKE_LOOKUP_V = [MAX_BRAKE, 0.]
|
||||
if CP.carFingerprint in CAMERA_ACC_CAR:
|
||||
self.MAX_GAS = 3400
|
||||
self.MAX_ACC_REGEN = 1514
|
||||
self.INACTIVE_REGEN = 1554
|
||||
# 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
|
||||
# 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
|
||||
|
||||
self.GAS_LOOKUP_BP = [max_regen_acceleration, 0., self.ACCEL_MAX]
|
||||
self.GAS_LOOKUP_V = [self.MAX_ACC_REGEN, self.ZERO_GAS, self.MAX_GAS]
|
||||
|
||||
self.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, max_regen_acceleration]
|
||||
self.BRAKE_LOOKUP_V = [self.MAX_BRAKE, 0.]
|
||||
|
||||
|
||||
class CAR:
|
||||
|
||||
@@ -1 +1 @@
|
||||
46922acfb984342daa35734e4297ff9d2ddfb18b
|
||||
d37afafc466661262b34631e32e4c383f1277bc5
|
||||
Reference in New Issue
Block a user