GM: Bolt EUV 2022-23 port (#24875)

* Switch to ECMPRDNL2 for GM gear

* Removing manumatic gear #

* values.py almost complete

* Silverado and Bolt EUV val and CP

* GM controller updated

* Cam hrns supp done (in theory)

* cleanup for new cars

* Remove extra constant

* WS, etc cleanup

* removing the unused

* Fix kpBP typo

* Updated docs

* Skip's PIF tune

* Dropped LKA CAN error patch

* Add silverado sigmoid ff

* CAN Err & LKA latch patch

* Remove EPS fault fix (another PR)

* Remove Silverado (another PR)

* clean up some common params

* Remove Escalade FP

Remove Escalade FP

* comment

* Premier is just a trim

Premier is just a trim

Premier is just a trim

* no footnote: new Bolt is like most other cars, older GM were outliers not at the camera

* clean up

clean up

* bump panda

* bump panda

* bump panda

* bump panda

* bump panda

* remove comments

* try spamming buttons on bus 2

* bump panda

* bumping opendbc w btn rc

* not needed for this port

This reverts commit 6af1f0ba79.

* add button safety

* Send next rc when spamming btns

* forward other signals in message

* missing DriveModeButton

* fill cruiseState.speed

* see if resume works without counter

* try the whole message

* send immediately and at 10Hz

* no resume, back to just button signal

* even holding random buttons it cancels

* Use torque controller with base tune

* stock long GM don't auto-resume yet

* Testing GM zero min steer speed

* Revert latcontrol

* revert opendbc

* latActive is basically lkas_enabled

* Update Bolt torque params

* comment

* clean up

* Add to releases

* Add test route

* Don't specify segment

* bump panda

* bump panda

* no harness for Bolt just yet

* Apply suggestions from code review

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>

* We support all and 2023

* move safetyParam up to first cam check

* Bump panda and update docs

* Update RELEASES.md

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>

Co-authored-by: Shane Smiskol <shane@smiskol.com>
Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
old-commit-hash: 4ffe9e68db
taco
Jason Shuler 3 years ago committed by GitHub
parent 634b328d7f
commit 3072fb4aec
  1. 1
      RELEASES.md
  2. 3
      docs/CARS.md
  3. 2
      panda
  4. 9
      selfdrive/car/docs_definitions.py
  5. 17
      selfdrive/car/gm/carcontroller.py
  6. 16
      selfdrive/car/gm/carstate.py
  7. 4
      selfdrive/car/gm/gmcan.py
  8. 45
      selfdrive/car/gm/interface.py
  9. 19
      selfdrive/car/gm/values.py
  10. 1
      selfdrive/car/tests/routes.py
  11. 1
      selfdrive/car/tests/test_models.py
  12. 1
      selfdrive/car/torque_data/override.yaml

@ -1,5 +1,6 @@
Version 0.8.16 (2022-XX-XX) Version 0.8.16 (2022-XX-XX)
======================== ========================
* Chevrolet Bolt EUV 2022-23 support thanks to JasonJShuler!
* Hyundai Ioniq 5 2022 support thanks to sunnyhaibin! * Hyundai Ioniq 5 2022 support thanks to sunnyhaibin!
* Hyundai Kona Electric 2022 support thanks to sunnyhaibin! * Hyundai Kona Electric 2022 support thanks to sunnyhaibin!
* Subaru Outback 2020-22 support * Subaru Outback 2020-22 support

@ -19,7 +19,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
- [![star](assets/icon-star-empty.svg)](##) - Limited ability to make tighter turns. - [![star](assets/icon-star-empty.svg)](##) - Limited ability to make tighter turns.
# 200 Supported Cars # 201 Supported Cars
|Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque| |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|
|---|---|---|:---:|:---:|:---:|:---:| |---|---|---|:---:|:---:|:---:|:---:|
@ -33,6 +33,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
|Audi|RS3 2018|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Audi|RS3 2018|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Audi|S3 2015-17|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Audi|S3 2015-17|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Cadillac|Escalade ESV 2016[<sup>1</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Cadillac|Escalade ESV 2016[<sup>1</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Chevrolet|Bolt EUV 2022-23|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Chevrolet|Volt 2017-18[<sup>1</sup>](#footnotes)|Adaptive Cruise Control|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chevrolet|Volt 2017-18[<sup>1</sup>](#footnotes)|Adaptive Cruise Control|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chrysler|Pacifica 2017-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chrysler|Pacifica 2019-20|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|

@ -1 +1 @@
Subproject commit 508ee90f8ecf1ce70fc9d002bbc14b47a50a459a Subproject commit 5e0dde7b480a930d3c3a164331c930541e905d71

@ -10,6 +10,10 @@ from common.conversions import Conversions as CV
GOOD_TORQUE_THRESHOLD = 1.0 # m/s^2 GOOD_TORQUE_THRESHOLD = 1.0 # m/s^2
MODEL_YEARS_RE = r"(?<= )((\d{4}-\d{2})|(\d{4}))(,|$)" MODEL_YEARS_RE = r"(?<= )((\d{4}-\d{2})|(\d{4}))(,|$)"
# Makes that lack auto-resume with stock long, and auto resume in any configuration
NO_AUTO_RESUME_STOCK_LONG = {"toyota", "gm"}
NO_AUTO_RESUME = NO_AUTO_RESUME_STOCK_LONG | {"nissan", "subaru"}
class Tier(Enum): class Tier(Enum):
GOLD = 0 GOLD = 0
@ -147,11 +151,11 @@ class CarInfo:
else: else:
alc = "" alc = ""
# Exception for Nissan, Subaru, and stock long Toyota which do not auto-resume yet # Exception for cars which do not auto-resume yet
acc = "" acc = ""
if self.min_enable_speed > 0: if self.min_enable_speed > 0:
acc = f" <strong>while driving above {self.min_enable_speed * CV.MS_TO_MPH:.0f} mph</strong>" acc = f" <strong>while driving above {self.min_enable_speed * CV.MS_TO_MPH:.0f} mph</strong>"
elif CP.carName not in ("nissan", "subaru", "toyota") or (CP.carName == "toyota" and CP.openpilotLongitudinalControl): elif CP.carName not in NO_AUTO_RESUME or (CP.carName in NO_AUTO_RESUME_STOCK_LONG and CP.openpilotLongitudinalControl):
acc = " <strong>that automatically resumes from a stop</strong>" acc = " <strong>that automatically resumes from a stop</strong>"
if self.row[Column.STEERING_TORQUE] != Star.FULL: if self.row[Column.STEERING_TORQUE] != Star.FULL:
@ -210,6 +214,7 @@ class Harness(Enum):
hyundai_p = "Hyundai P" hyundai_p = "Hyundai P"
custom = "Developer" custom = "Developer"
obd_ii = "OBD-II" obd_ii = "OBD-II"
gm = "GM"
nissan_a = "Nissan A" nissan_a = "Nissan A"
nissan_b = "Nissan B" nissan_b = "Nissan B"
mazda = "Mazda" mazda = "Mazda"

@ -5,7 +5,7 @@ from common.realtime import DT_CTRL
from opendbc.can.packer import CANPacker from opendbc.can.packer import CANPacker
from selfdrive.car import apply_std_steer_torque_limits from selfdrive.car import apply_std_steer_torque_limits
from selfdrive.car.gm import gmcan from selfdrive.car.gm import gmcan
from selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, EV_CAR from selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons, EV_CAR
VisualAlert = car.CarControl.HUDControl.VisualAlert VisualAlert = car.CarControl.HUDControl.VisualAlert
NetworkLocation = car.CarParams.NetworkLocation NetworkLocation = car.CarParams.NetworkLocation
@ -19,6 +19,7 @@ class CarController:
self.apply_gas = 0 self.apply_gas = 0
self.apply_brake = 0 self.apply_brake = 0
self.frame = 0 self.frame = 0
self.last_button_frame = 0
self.lka_steering_cmd_counter_last = -1 self.lka_steering_cmd_counter_last = -1
self.lka_icon_status_last = (False, False) self.lka_icon_status_last = (False, False)
@ -46,8 +47,7 @@ class CarController:
if CS.lka_steering_cmd_counter != self.lka_steering_cmd_counter_last: if CS.lka_steering_cmd_counter != self.lka_steering_cmd_counter_last:
self.lka_steering_cmd_counter_last = CS.lka_steering_cmd_counter self.lka_steering_cmd_counter_last = CS.lka_steering_cmd_counter
elif (self.frame % self.params.STEER_STEP) == 0: elif (self.frame % self.params.STEER_STEP) == 0:
lkas_enabled = CC.latActive and CS.out.vEgo > self.params.MIN_STEER_SPEED if CC.latActive:
if lkas_enabled:
new_steer = int(round(actuators.steer * self.params.STEER_MAX)) new_steer = int(round(actuators.steer * self.params.STEER_MAX))
apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params) apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params)
else: else:
@ -58,7 +58,7 @@ class CarController:
# moment of disengaging, increment the counter based on the last message known to pass Panda safety checks. # moment of disengaging, increment the counter based on the last message known to pass Panda safety checks.
idx = (CS.lka_steering_cmd_counter + 1) % 4 idx = (CS.lka_steering_cmd_counter + 1) % 4
can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, lkas_enabled)) can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, CC.latActive))
if self.CP.openpilotLongitudinalControl: if self.CP.openpilotLongitudinalControl:
# Gas/regen, brakes, and UI commands - all at 25Hz # Gas/regen, brakes, and UI commands - all at 25Hz
@ -107,6 +107,13 @@ class CarController:
if self.CP.networkLocation == NetworkLocation.gateway and self.frame % self.params.ADAS_KEEPALIVE_STEP == 0: if self.CP.networkLocation == NetworkLocation.gateway and self.frame % self.params.ADAS_KEEPALIVE_STEP == 0:
can_sends += gmcan.create_adas_keepalive(CanBus.POWERTRAIN) can_sends += gmcan.create_adas_keepalive(CanBus.POWERTRAIN)
else:
# Stock longitudinal, integrated at camera
if (self.frame - self.last_button_frame) * DT_CTRL > 0.1:
if CC.cruiseControl.cancel:
self.last_button_frame = self.frame
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, CruiseButtons.CANCEL))
# Show green icon when LKA torque is applied, and # Show green icon when LKA torque is applied, and
# alarming orange icon when approaching torque limit. # alarming orange icon when approaching torque limit.
# If not sent again, LKA icon disappears in about 5 seconds. # If not sent again, LKA icon disappears in about 5 seconds.
@ -114,6 +121,8 @@ class CarController:
lka_active = CS.lkas_status == 1 lka_active = CS.lkas_status == 1
lka_critical = lka_active and abs(actuators.steer) > 0.9 lka_critical = lka_active and abs(actuators.steer) > 0.9
lka_icon_status = (lka_active, lka_critical) lka_icon_status = (lka_active, lka_critical)
# SW_GMLAN not yet on cam harness, no HUD alerts
if self.CP.networkLocation != NetworkLocation.fwdCamera and (self.frame % self.params.CAMERA_KEEPALIVE_STEP == 0 or lka_icon_status != self.lka_icon_status_last): if self.CP.networkLocation != NetworkLocation.fwdCamera and (self.frame % self.params.CAMERA_KEEPALIVE_STEP == 0 or lka_icon_status != self.lka_icon_status_last):
steer_alert = hud_alert in (VisualAlert.steerRequired, VisualAlert.ldw) steer_alert = hud_alert in (VisualAlert.steerRequired, VisualAlert.ldw)
can_sends.append(gmcan.create_lka_icon_command(CanBus.SW_GMLAN, lka_active, lka_critical, steer_alert)) can_sends.append(gmcan.create_lka_icon_command(CanBus.SW_GMLAN, lka_active, lka_critical, steer_alert))

@ -1,4 +1,5 @@
from cereal import car from cereal import car
from common.conversions import Conversions as CV
from common.numpy_fast import mean from common.numpy_fast import mean
from opendbc.can.can_define import CANDefine from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser from opendbc.can.parser import CANParser
@ -6,6 +7,7 @@ from selfdrive.car.interfaces import CarStateBase
from selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD from selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD
TransmissionType = car.CarParams.TransmissionType TransmissionType = car.CarParams.TransmissionType
NetworkLocation = car.CarParams.NetworkLocation
class CarState(CarStateBase): class CarState(CarStateBase):
@ -15,7 +17,7 @@ class CarState(CarStateBase):
self.shifter_values = can_define.dv["ECMPRDNL2"]["PRNDL2"] self.shifter_values = can_define.dv["ECMPRDNL2"]["PRNDL2"]
self.lka_steering_cmd_counter = 0 self.lka_steering_cmd_counter = 0
def update(self, pt_cp, loopback_cp): def update(self, pt_cp, cam_cp, loopback_cp):
ret = car.CarState.new_message() ret = car.CarState.new_message()
self.prev_cruise_buttons = self.cruise_buttons self.prev_cruise_buttons = self.cruise_buttons
@ -77,9 +79,21 @@ class CarState(CarStateBase):
ret.cruiseState.enabled = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] != AccState.OFF ret.cruiseState.enabled = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] != AccState.OFF
ret.cruiseState.standstill = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.STANDSTILL ret.cruiseState.standstill = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.STANDSTILL
if self.CP.networkLocation == NetworkLocation.fwdCamera:
ret.cruiseState.speed = (cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCSpeedSetpoint"] / 16) * CV.KPH_TO_MS
return ret return ret
@staticmethod
def get_cam_can_parser(CP):
signals = []
checks = []
if CP.networkLocation == NetworkLocation.fwdCamera:
signals.append(("ACCSpeedSetpoint", "ASCMActiveCruiseControlStatus"))
checks.append(("ASCMActiveCruiseControlStatus", 25))
return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, CanBus.CAMERA)
@staticmethod @staticmethod
def get_can_parser(CP): def get_can_parser(CP):
signals = [ signals = [

@ -1,5 +1,9 @@
from selfdrive.car import make_can_msg from selfdrive.car import make_can_msg
def create_buttons(packer, bus, button):
values = {"ACCButtons": button}
return packer.make_can_msg("ASCMSteeringButton", bus, values)
def create_steering_control(packer, bus, apply_steer, idx, lkas_active): def create_steering_control(packer, bus, apply_steer, idx, lkas_active):
values = { values = {

@ -1,10 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from cereal import car from cereal import car
from math import fabs from math import fabs
from panda import Panda
from common.conversions import Conversions as CV from common.conversions import Conversions as CV
from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config
from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR
from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.interfaces import CarInterfaceBase
ButtonType = car.CarState.ButtonEvent.Type ButtonType = car.CarState.ButtonEvent.Type
@ -48,29 +49,36 @@ class CarInterface(CarInterfaceBase):
ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
ret.carName = "gm" ret.carName = "gm"
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)] ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)]
ret.pcmCruise = False # For ASCM, stock non-adaptive cruise control is kept off
ret.radarOffCan = False # For ASCM, radar exists if candidate in EV_CAR:
ret.transmissionType = TransmissionType.automatic ret.transmissionType = TransmissionType.direct
# NetworkLocation.gateway: OBD-II harness (typically ASCM), NetworkLocation.fwdCamera: non-ASCM else:
ret.networkLocation = NetworkLocation.gateway ret.transmissionType = TransmissionType.automatic
if candidate in CAMERA_ACC_CAR:
ret.openpilotLongitudinalControl = False
ret.networkLocation = NetworkLocation.fwdCamera
ret.radarOffCan = True # no radar
ret.pcmCruise = True
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM
else: # ASCM, OBD-II harness
ret.openpilotLongitudinalControl = True
ret.networkLocation = NetworkLocation.gateway
ret.radarOffCan = False
ret.pcmCruise = False # stock non-adaptive cruise control is kept off
# These cars have been put into dashcam only due to both a lack of users and test coverage. # 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 # 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. # added to selfdrive/car/tests/routes.py, we can remove it from this list.
ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL} ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL}
# Presence of a camera on the object bus is ok.
# Have to go to read_only if ASCM is online (ACC-enabled cars),
# or camera is on powertrain bus (LKA cars without ACC).
ret.openpilotLongitudinalControl = True
tire_stiffness_factor = 0.444 # not optimized yet
# Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below. # Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below.
ret.minSteerSpeed = 7 * CV.MPH_TO_MS ret.minSteerSpeed = 7 * CV.MPH_TO_MS
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]]
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.00]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.00]]
ret.lateralTuning.pid.kf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594 ret.lateralTuning.pid.kf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594
ret.steerActuatorDelay = 0.1 # Default delay, not measured yet ret.steerActuatorDelay = 0.1 # Default delay, not measured yet
tire_stiffness_factor = 0.444 # not optimized yet
ret.longitudinalTuning.kpBP = [5., 35.] ret.longitudinalTuning.kpBP = [5., 35.]
ret.longitudinalTuning.kpV = [2.4, 1.5] ret.longitudinalTuning.kpV = [2.4, 1.5]
@ -84,7 +92,6 @@ class CarInterface(CarInterfaceBase):
ret.minEnableSpeed = 18 * CV.MPH_TO_MS ret.minEnableSpeed = 18 * CV.MPH_TO_MS
if candidate == CAR.VOLT: if candidate == CAR.VOLT:
ret.transmissionType = TransmissionType.direct
ret.mass = 1607. + STD_CARGO_KG ret.mass = 1607. + STD_CARGO_KG
ret.wheelbase = 2.69 ret.wheelbase = 2.69
ret.steerRatio = 17.7 # Stock 15.7, LiveParameters ret.steerRatio = 17.7 # Stock 15.7, LiveParameters
@ -143,6 +150,16 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.pid.kf = 0.000045 ret.lateralTuning.pid.kf = 0.000045
tire_stiffness_factor = 1.0 tire_stiffness_factor = 1.0
elif candidate == CAR.BOLT_EUV:
ret.minEnableSpeed = -1
ret.mass = 1669. + STD_CARGO_KG
ret.wheelbase = 2.675
ret.steerRatio = 16.8
ret.centerToFront = ret.wheelbase * 0.4
tire_stiffness_factor = 1.0
ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
# TODO: get actual value, for now starting with reasonable value for # TODO: get actual value, for now starting with reasonable value for
# civic and scaling by mass and wheelbase # civic and scaling by mass and wheelbase
ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase)
@ -156,7 +173,7 @@ class CarInterface(CarInterfaceBase):
# returns a car.CarState # returns a car.CarState
def _update(self, c): def _update(self, c):
ret = self.CS.update(self.cp, self.cp_loopback) ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback)
if self.CS.cruise_buttons != self.CS.prev_cruise_buttons and self.CS.prev_cruise_buttons != CruiseButtons.INIT: if self.CS.cruise_buttons != self.CS.prev_cruise_buttons and self.CS.prev_cruise_buttons != CruiseButtons.INIT:
be = create_button_event(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, CruiseButtons.UNPRESS) be = create_button_event(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, CruiseButtons.UNPRESS)

@ -14,7 +14,6 @@ class CarControllerParams:
STEER_STEP = 2 # Control frames per command (50hz) STEER_STEP = 2 # Control frames per command (50hz)
STEER_DELTA_UP = 7 # Delta rates require review due to observed EPS weakness STEER_DELTA_UP = 7 # Delta rates require review due to observed EPS weakness
STEER_DELTA_DOWN = 17 STEER_DELTA_DOWN = 17
MIN_STEER_SPEED = 3. # m/s
STEER_DRIVER_ALLOWANCE = 50 STEER_DRIVER_ALLOWANCE = 50
STEER_DRIVER_MULTIPLIER = 4 STEER_DRIVER_MULTIPLIER = 4
STEER_DRIVER_FACTOR = 100 STEER_DRIVER_FACTOR = 100
@ -59,10 +58,7 @@ class CAR:
ACADIA = "GMC ACADIA DENALI 2018" ACADIA = "GMC ACADIA DENALI 2018"
BUICK_REGAL = "BUICK REGAL ESSENCE 2018" BUICK_REGAL = "BUICK REGAL ESSENCE 2018"
ESCALADE_ESV = "CADILLAC ESCALADE ESV 2016" ESCALADE_ESV = "CADILLAC ESCALADE ESV 2016"
BOLT_EUV = "CHEVROLET BOLT EUV 2022"
EV_CAR = {CAR.VOLT}
STEER_THRESHOLD = 1.0
class Footnote(Enum): class Footnote(Enum):
@ -87,6 +83,7 @@ CAR_INFO: Dict[str, Union[GMCarInfo, List[GMCarInfo]]] = {
CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"), CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"),
CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"), CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"),
CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"), CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"),
CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "All", footnotes=[], harness=Harness.gm),
} }
@ -107,6 +104,7 @@ class AccState:
class CanBus: class CanBus:
POWERTRAIN = 0 POWERTRAIN = 0
OBSTACLE = 1 OBSTACLE = 1
CAMERA = 2
CHASSIS = 2 CHASSIS = 2
SW_GMLAN = 3 SW_GMLAN = 3
LOOPBACK = 128 LOOPBACK = 128
@ -155,6 +153,17 @@ FINGERPRINTS = {
{ {
309: 1, 848: 8, 849: 8, 850: 8, 851: 8, 852: 8, 853: 8, 854: 3, 1056: 6, 1057: 8, 1058: 8, 1059: 8, 1060: 8, 1061: 8, 1062: 8, 1063: 8, 1064: 8, 1065: 8, 1066: 8, 1067: 8, 1068: 8, 1120: 8, 1121: 8, 1122: 8, 1123: 8, 1124: 8, 1125: 8, 1126: 8, 1127: 8, 1128: 8, 1129: 8, 1130: 8, 1131: 8, 1132: 8, 1133: 8, 1134: 8, 1135: 8, 1136: 8, 1137: 8, 1138: 8, 1139: 8, 1140: 8, 1141: 8, 1142: 8, 1143: 8, 1146: 8, 1147: 8, 1148: 8, 1149: 8, 1150: 8, 1151: 8, 1216: 8, 1217: 8, 1218: 8, 1219: 8, 1220: 8, 1221: 8, 1222: 8, 1223: 8, 1224: 8, 1225: 8, 1226: 8, 1232: 8, 1233: 8, 1234: 8, 1235: 8, 1236: 8, 1237: 8, 1238: 8, 1239: 8, 1240: 8, 1241: 8, 1242: 8, 1787: 8, 1788: 8 309: 1, 848: 8, 849: 8, 850: 8, 851: 8, 852: 8, 853: 8, 854: 3, 1056: 6, 1057: 8, 1058: 8, 1059: 8, 1060: 8, 1061: 8, 1062: 8, 1063: 8, 1064: 8, 1065: 8, 1066: 8, 1067: 8, 1068: 8, 1120: 8, 1121: 8, 1122: 8, 1123: 8, 1124: 8, 1125: 8, 1126: 8, 1127: 8, 1128: 8, 1129: 8, 1130: 8, 1131: 8, 1132: 8, 1133: 8, 1134: 8, 1135: 8, 1136: 8, 1137: 8, 1138: 8, 1139: 8, 1140: 8, 1141: 8, 1142: 8, 1143: 8, 1146: 8, 1147: 8, 1148: 8, 1149: 8, 1150: 8, 1151: 8, 1216: 8, 1217: 8, 1218: 8, 1219: 8, 1220: 8, 1221: 8, 1222: 8, 1223: 8, 1224: 8, 1225: 8, 1226: 8, 1232: 8, 1233: 8, 1234: 8, 1235: 8, 1236: 8, 1237: 8, 1238: 8, 1239: 8, 1240: 8, 1241: 8, 1242: 8, 1787: 8, 1788: 8
}], }],
CAR.BOLT_EUV: [
{
189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1280: 4, 1296: 4, 1300: 8, 1930: 7
}],
} }
DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict('gm_global_a_powertrain_generated', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis')) DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict('gm_global_a_powertrain_generated', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis'))
EV_CAR = {CAR.VOLT, CAR.BOLT_EUV}
# We're integrated at the camera with VOACC on these cars (instead of ASCM w/ OBD-II harness)
CAMERA_ACC_CAR = {CAR.BOLT_EUV}
STEER_THRESHOLD = 1.0

@ -47,6 +47,7 @@ routes = [
TestRoute("aa20e335f61ba898|2019-02-05--16-59-04", GM.BUICK_REGAL), TestRoute("aa20e335f61ba898|2019-02-05--16-59-04", GM.BUICK_REGAL),
TestRoute("46460f0da08e621e|2021-10-26--07-21-46", GM.ESCALADE_ESV), TestRoute("46460f0da08e621e|2021-10-26--07-21-46", GM.ESCALADE_ESV),
TestRoute("c950e28c26b5b168|2018-05-30--22-03-41", GM.VOLT), TestRoute("c950e28c26b5b168|2018-05-30--22-03-41", GM.VOLT),
TestRoute("f08912a233c1584f|2022-08-11--18-02-41", GM.BOLT_EUV),
TestRoute("0e7a2ba168465df5|2020-10-18--14-14-22", HONDA.ACURA_RDX_3G), TestRoute("0e7a2ba168465df5|2020-10-18--14-14-22", HONDA.ACURA_RDX_3G),
TestRoute("a74b011b32b51b56|2020-07-26--17-09-36", HONDA.CIVIC), TestRoute("a74b011b32b51b56|2020-07-26--17-09-36", HONDA.CIVIC),

@ -58,7 +58,6 @@ class TestCarModelBase(unittest.TestCase):
raise unittest.SkipTest raise unittest.SkipTest
if 'FILTER' in os.environ: if 'FILTER' in os.environ:
print(tuple(os.environ.get('FILTER').split(', ')))
if not cls.car_model.startswith(tuple(os.environ.get('FILTER').split(','))): if not cls.car_model.startswith(tuple(os.environ.get('FILTER').split(','))):
raise unittest.SkipTest raise unittest.SkipTest

@ -24,6 +24,7 @@ KIA EV6 2022: [3.5, 2.5, 0.0]
RAM 1500 5TH GEN: [2.0, 2.0, 0.0] RAM 1500 5TH GEN: [2.0, 2.0, 0.0]
RAM HD 5TH GEN: [1.4, 1.4, 0.0] RAM HD 5TH GEN: [1.4, 1.4, 0.0]
SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11] SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11]
CHEVROLET BOLT EUV 2022: [2.0, 2.0, 0.05]
# Dashcam or fallback configured as ideal car # Dashcam or fallback configured as ideal car
mock: [10.0, 10, 0.0] mock: [10.0, 10, 0.0]

Loading…
Cancel
Save