CAN parser dict (#1470)

* refactor in base classes

* refactor body + chrysler

* refactor the rest

* tiny cleanup

* Bus enum

* lowercase buses

* small cleanups

* no str allowed

* no None allowed

* type hint

* name cleanup

* rm empty line

* never None

* never Str

* this isn't valid

* fix

* = > |=
This commit is contained in:
Robbe Derks 2024-11-15 22:50:21 +01:00 committed by GitHub
parent 423de1223b
commit 38c867912a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 521 additions and 516 deletions

View File

@ -2,7 +2,7 @@
import logging
from collections import namedtuple
from dataclasses import dataclass, field
from enum import IntFlag, ReprEnum, EnumType
from enum import IntFlag, ReprEnum, StrEnum, EnumType, auto
from dataclasses import replace
from panda import uds
@ -84,11 +84,20 @@ def scale_tire_stiffness(mass, wheelbase, center_to_front, tire_stiffness_factor
return tire_stiffness_front, tire_stiffness_rear
DbcDict = dict[str, str]
DbcDict = dict[StrEnum, str]
def dbc_dict(pt_dbc, radar_dbc, chassis_dbc=None, body_dbc=None) -> DbcDict:
return {'pt': pt_dbc, 'radar': radar_dbc, 'chassis': chassis_dbc, 'body': body_dbc}
class Bus(StrEnum):
pt = auto()
cam = auto()
radar = auto()
adas = auto()
alt = auto()
body = auto()
chassis = auto()
loopback = auto()
main = auto()
party = auto()
ap_party = auto()
def apply_driver_steer_torque_limits(apply_torque, apply_torque_last, driver_torque, LIMITS):
@ -306,7 +315,7 @@ class PlatformConfig(PlatformConfigBase):
class ExtraPlatformConfig(PlatformConfigBase):
car_docs: list[ExtraCarDocs]
specs: CarSpecs = CarSpecs(mass=0., wheelbase=0., steerRatio=0.)
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('unknown', None))
dbc_dict: DbcDict = field(default_factory=lambda: dict())
class PlatformsType(EnumType):

View File

@ -1,7 +1,7 @@
import numpy as np
from opendbc.can.packer import CANPacker
from opendbc.car import DT_CTRL
from opendbc.car import Bus, DT_CTRL
from opendbc.car.common.pid import PIDController
from opendbc.car.body import bodycan
from opendbc.car.body.values import SPEED_FROM_RPM
@ -15,9 +15,9 @@ MAX_TURN_INTEGRATOR = 0.1 # meters
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
self.packer = CANPacker(dbc_name)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.packer = CANPacker(dbc_names[Bus.main])
# PIDs
self.turn_pid = PIDController(110, k_i=11.5, rate=1/DT_CTRL)

View File

@ -1,11 +1,12 @@
from opendbc.can.parser import CANParser
from opendbc.car import structs
from opendbc.car import Bus, structs
from opendbc.car.interfaces import CarStateBase
from opendbc.car.body.values import DBC
class CarState(CarStateBase):
def update(self, cp, *_) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
cp = can_parsers[Bus.main]
ret = structs.CarState()
ret.wheelSpeeds.fl = cp.vl['MOTORS_DATA']['SPEED_L']
@ -30,10 +31,10 @@ class CarState(CarStateBase):
return ret
@staticmethod
def get_can_parser(CP):
def get_can_parsers(CP):
messages = [
("MOTORS_DATA", 100),
("VAR_VALUES", 10),
("BODY_DATA", 1),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0)
return {Bus.main: CANParser(DBC[CP.carFingerprint][Bus.main], messages, 0)}

View File

@ -1,4 +1,4 @@
from opendbc.car import CarSpecs, PlatformConfig, Platforms, dbc_dict
from opendbc.car import Bus, CarSpecs, PlatformConfig, Platforms
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarDocs
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
@ -23,7 +23,7 @@ class CAR(Platforms):
COMMA_BODY = PlatformConfig(
[CarDocs("comma body", package="All")],
CarSpecs(mass=9, wheelbase=0.406, steerRatio=0.5, centerToFrontRatio=0.44),
dbc_dict('comma_body', None),
{Bus.main: 'comma_body'},
)

View File

@ -1,13 +1,13 @@
from opendbc.can.packer import CANPacker
from opendbc.car import DT_CTRL, apply_meas_steer_torque_limits
from opendbc.car import Bus, DT_CTRL, apply_meas_steer_torque_limits
from opendbc.car.chrysler import chryslercan
from opendbc.car.chrysler.values import RAM_CARS, CarControllerParams, ChryslerFlags
from opendbc.car.interfaces import CarControllerBase
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.apply_steer_last = 0
self.hud_count = 0
@ -15,7 +15,7 @@ class CarController(CarControllerBase):
self.lkas_control_bit_prev = False
self.last_button_frame = 0
self.packer = CANPacker(dbc_name)
self.packer = CANPacker(dbc_names[Bus.pt])
self.params = CarControllerParams(CP)
def update(self, CC, CS, now_nanos):

View File

@ -1,6 +1,6 @@
from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine
from opendbc.car import create_button_events, structs
from opendbc.car import Bus, create_button_events, structs
from opendbc.car.chrysler.values import DBC, STEER_THRESHOLD, RAM_CARS
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.interfaces import CarStateBase
@ -12,7 +12,7 @@ class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
self.CP = CP
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
self.auto_high_beam = 0
self.button_counter = 0
@ -25,7 +25,9 @@ class CarState(CarStateBase):
self.distance_button = 0
def update(self, cp, cp_cam, *_) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
ret = structs.CarState()
@ -115,8 +117,8 @@ class CarState(CarStateBase):
return messages
@staticmethod
def get_can_parser(CP):
messages = [
def get_can_parsers(CP):
pt_messages = [
# sig_address, frequency
("ESP_1", 50),
("EPS_2", 100),
@ -130,30 +132,29 @@ class CarState(CarStateBase):
]
if CP.enableBsm:
messages.append(("BSM_1", 2))
pt_messages.append(("BSM_1", 2))
if CP.carFingerprint in RAM_CARS:
messages += [
pt_messages += [
("ESP_8", 50),
("EPS_3", 50),
("Transmission_Status", 50),
]
else:
messages += [
pt_messages += [
("GEAR", 50),
("SPEED_1", 100),
]
messages += CarState.get_cruise_messages()
pt_messages += CarState.get_cruise_messages()
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0)
@staticmethod
def get_cam_can_parser(CP):
messages = [
cam_messages = [
("DAS_6", 4),
]
if CP.carFingerprint in RAM_CARS:
messages += CarState.get_cruise_messages()
cam_messages += CarState.get_cruise_messages()
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 2)
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, 0),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, 2),
}

View File

@ -12,7 +12,7 @@ class CarInterface(CarInterfaceBase):
ret.dashcamOnly = candidate in RAM_HD
# radar parsing needs some work, see https://github.com/commaai/openpilot/issues/26842
ret.radarUnavailable = True # DBC[candidate]['radar'] is None
ret.radarUnavailable = True # DBC[candidate][Bus.radar] is None
ret.steerActuatorDelay = 0.1
ret.steerLimitTimer = 0.4

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
from opendbc.can.parser import CANParser
from opendbc.car import structs
from opendbc.car import Bus, structs
from opendbc.car.interfaces import RadarInterfaceBase
from opendbc.car.chrysler.values import DBC
@ -10,8 +10,7 @@ LAST_MSG = max(RADAR_MSGS_C + RADAR_MSGS_D)
NUMBER_MSGS = len(RADAR_MSGS_C) + len(RADAR_MSGS_D)
def _create_radar_can_parser(car_fingerprint):
dbc = DBC[car_fingerprint]['radar']
if dbc is None:
if Bus.radar not in DBC[car_fingerprint]:
return None
msg_n = len(RADAR_MSGS_C)
@ -27,7 +26,7 @@ def _create_radar_can_parser(car_fingerprint):
[20] * msg_n + # 20Hz (0.05s)
[20] * msg_n, strict=True)) # 20Hz (0.05s)
return CANParser(DBC[car_fingerprint]['radar'], messages, 1)
return CANParser(DBC[car_fingerprint][Bus.radar], messages, 1)
def _address_to_track(address):
if address in RADAR_MSGS_C:

View File

@ -2,7 +2,7 @@ from enum import IntFlag
from dataclasses import dataclass, field
from panda import uds
from opendbc.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from opendbc.car import Bus, CarSpecs, DbcDict, PlatformConfig, Platforms
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarHarness, CarDocs, CarParts
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, p16
@ -22,7 +22,10 @@ class ChryslerCarDocs(CarDocs):
@dataclass
class ChryslerPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'))
dbc_dict: DbcDict = field(default_factory=lambda: {
Bus.pt: 'chrysler_pacifica_2017_hybrid_generated',
Bus.radar: 'chrysler_pacifica_2017_hybrid_private_fusion',
})
@dataclass(frozen=True)
@ -73,7 +76,7 @@ class CAR(Platforms):
RAM_1500_5TH_GEN = ChryslerPlatformConfig(
[ChryslerCarDocs("Ram 1500 2019-24", car_parts=CarParts.common([CarHarness.ram]))],
ChryslerCarSpecs(mass=2493., wheelbase=3.88, steerRatio=16.3, minSteerSpeed=14.5),
dbc_dict('chrysler_ram_dt_generated', None),
{Bus.pt: 'chrysler_ram_dt_generated'},
)
RAM_HD_5TH_GEN = ChryslerPlatformConfig(
[
@ -81,7 +84,7 @@ class CAR(Platforms):
ChryslerCarDocs("Ram 3500 2019-22", car_parts=CarParts.common([CarHarness.ram])),
],
ChryslerCarSpecs(mass=3405., wheelbase=3.785, steerRatio=15.61, minSteerSpeed=16.),
dbc_dict('chrysler_ram_hd_generated', None),
{Bus.pt: 'chrysler_ram_hd_generated'},
)

View File

@ -1,6 +1,6 @@
import math
from opendbc.can.packer import CANPacker
from opendbc.car import ACCELERATION_DUE_TO_GRAVITY, DT_CTRL, apply_std_steer_angle_limits, structs
from opendbc.car import ACCELERATION_DUE_TO_GRAVITY, Bus, DT_CTRL, apply_std_steer_angle_limits, structs
from opendbc.car.ford import fordcan
from opendbc.car.ford.values import CarControllerParams, FordFlags
from opendbc.car.common.numpy_fast import clip, interp
@ -30,9 +30,9 @@ def apply_creep_compensation(accel: float, v_ego: float) -> float:
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
self.packer = CANPacker(dbc_name)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.packer = CANPacker(dbc_names[Bus.pt])
self.CAN = fordcan.CanBus(CP)
self.apply_curvature_last = 0

View File

@ -1,6 +1,6 @@
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import create_button_events, structs
from opendbc.car import Bus, create_button_events, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.ford.fordcan import CanBus
from opendbc.car.ford.values import DBC, CarControllerParams, FordFlags
@ -14,13 +14,16 @@ TransmissionType = structs.CarParams.TransmissionType
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
if CP.transmissionType == TransmissionType.automatic:
self.shifter_values = can_define.dv["PowertrainData_10"]["TrnRng_D_Rq"]
self.distance_button = 0
def update(self, cp, cp_cam, *_) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
ret = structs.CarState()
# Occasionally on startup, the ABS module recalibrates the steering pinion offset, so we need to block engagement
@ -112,8 +115,8 @@ class CarState(CarStateBase):
return ret
@staticmethod
def get_can_parser(CP):
messages = [
def get_can_parsers(CP):
pt_messages = [
# sig_address, frequency
("VehicleOperatingModes", 100),
("BrakeSysFeatures", 50),
@ -131,35 +134,31 @@ class CarState(CarStateBase):
]
if CP.flags & FordFlags.CANFD:
messages += [
pt_messages += [
("Lane_Assist_Data3_FD1", 33),
]
else:
messages += [
pt_messages += [
("INSTRUMENT_PANEL", 1),
]
if CP.transmissionType == TransmissionType.automatic:
messages += [
pt_messages += [
("PowertrainData_10", 10),
]
elif CP.transmissionType == TransmissionType.manual:
messages += [
pt_messages += [
("Engine_Clutch_Data", 33),
("BCM_Lamp_Stat_FD1", 1),
]
if CP.enableBsm and not (CP.flags & FordFlags.CANFD):
messages += [
pt_messages += [
("Side_Detect_L_Stat", 5),
("Side_Detect_R_Stat", 5),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus(CP).main)
@staticmethod
def get_cam_can_parser(CP):
messages = [
cam_messages = [
# sig_address, frequency
("ACCDATA", 50),
("ACCDATA_2", 50),
@ -168,9 +167,12 @@ class CarState(CarStateBase):
]
if CP.enableBsm and CP.flags & FordFlags.CANFD:
messages += [
cam_messages += [
("Side_Detect_L_Stat", 5),
("Side_Detect_R_Stat", 5),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus(CP).camera)
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, CanBus(CP).main),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, CanBus(CP).camera),
}

View File

@ -1,6 +1,6 @@
from panda import Panda
from opendbc.car.common.numpy_fast import interp
from opendbc.car import get_safety_config, structs
from opendbc.car import Bus, get_safety_config, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.ford.fordcan import CanBus
from opendbc.car.ford.values import CarControllerParams, DBC, Ecu, FordFlags, RADAR
@ -23,7 +23,7 @@ class CarInterface(CarInterfaceBase):
ret.carName = "ford"
ret.dashcamOnly = bool(ret.flags & FordFlags.CANFD)
ret.radarUnavailable = DBC[candidate]['radar'] is None
ret.radarUnavailable = Bus.radar not in DBC[candidate]
ret.steerControlType = structs.CarParams.SteerControlType.angle
ret.steerActuatorDelay = 0.2
ret.steerLimitTimer = 1.0
@ -31,7 +31,7 @@ class CarInterface(CarInterfaceBase):
ret.longitudinalTuning.kiBP = [0.]
ret.longitudinalTuning.kiV = [0.5]
if DBC[candidate]['radar'] == RADAR.DELPHI_MRR:
if not ret.radarUnavailable and DBC[candidate][Bus.radar] == RADAR.DELPHI_MRR:
# average of 33.3 Hz radar timestep / 4 scan modes = 60 ms
# MRR_Header_Timestamps->CAN_DET_TIME_SINCE_MEAS reports 61.3 ms
ret.radarDelay = 0.06

View File

@ -4,7 +4,7 @@ from collections import defaultdict
from math import cos, sin
from dataclasses import dataclass
from opendbc.can.parser import CANParser
from opendbc.car import structs
from opendbc.car import Bus, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.ford.fordcan import CanBus
from opendbc.car.ford.values import DBC, RADAR
@ -98,7 +98,7 @@ class RadarInterface(RadarInterfaceBase):
self.updated_messages = set()
self.track_id = 0
self.radar = DBC[CP.carFingerprint]['radar']
self.radar = DBC[CP.carFingerprint].get(Bus.radar)
if CP.radarUnavailable:
self.rcp = None
elif self.radar == RADAR.DELPHI_ESR:

View File

@ -4,7 +4,7 @@ from dataclasses import dataclass, field, replace
from enum import Enum, IntFlag
from panda import uds
from opendbc.car import AngleRateLimit, CarSpecs, dbc_dict, DbcDict, PlatformConfig, Platforms
from opendbc.car import AngleRateLimit, Bus, CarSpecs, DbcDict, PlatformConfig, Platforms
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \
Device, SupportType
@ -76,7 +76,10 @@ class FordCarDocs(CarDocs):
@dataclass
class FordPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('ford_lincoln_base_pt', RADAR.DELPHI_MRR))
dbc_dict: DbcDict = field(default_factory=lambda: {
Bus.pt: 'ford_lincoln_base_pt',
Bus.radar: RADAR.DELPHI_MRR,
})
def init(self):
for car_docs in list(self.car_docs):
@ -90,7 +93,9 @@ class FordPlatformConfig(PlatformConfig):
@dataclass
class FordCANFDPlatformConfig(FordPlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('ford_lincoln_base_pt', None))
dbc_dict: DbcDict = field(default_factory=lambda: {
Bus.pt: 'ford_lincoln_base_pt',
})
def init(self):
super().init()

View File

@ -1,5 +1,5 @@
from opendbc.can.packer import CANPacker
from opendbc.car import DT_CTRL, apply_driver_steer_torque_limits, structs
from opendbc.car import Bus, DT_CTRL, apply_driver_steer_torque_limits, structs
from opendbc.car.gm import gmcan
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons
@ -17,8 +17,8 @@ MIN_STEER_MSG_INTERVAL_MS = 15
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.start_time = 0.
self.apply_steer_last = 0
self.apply_gas = 0
@ -32,9 +32,9 @@ class CarController(CarControllerBase):
self.params = CarControllerParams(self.CP)
self.packer_pt = CANPacker(DBC[self.CP.carFingerprint]['pt'])
self.packer_obj = CANPacker(DBC[self.CP.carFingerprint]['radar'])
self.packer_ch = CANPacker(DBC[self.CP.carFingerprint]['chassis'])
self.packer_pt = CANPacker(DBC[self.CP.carFingerprint][Bus.pt])
self.packer_obj = CANPacker(DBC[self.CP.carFingerprint][Bus.radar])
self.packer_ch = CANPacker(DBC[self.CP.carFingerprint][Bus.chassis])
def update(self, CC, CS, now_nanos):
actuators = CC.actuators

View File

@ -1,11 +1,11 @@
import copy
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import create_button_events, structs
from opendbc.car import Bus, create_button_events, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.common.numpy_fast import mean
from opendbc.car.interfaces import CarStateBase
from opendbc.car.gm.values import DBC, AccState, CanBus, CruiseButtons, STEER_THRESHOLD, SDGM_CAR
from opendbc.car.gm.values import DBC, AccState, CruiseButtons, STEER_THRESHOLD, SDGM_CAR
ButtonType = structs.CarState.ButtonEvent.Type
TransmissionType = structs.CarParams.TransmissionType
@ -20,7 +20,7 @@ BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.D
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
self.shifter_values = can_define.dv["ECMPRDNL2"]["PRNDL2"]
self.cluster_speed_hyst_gap = CV.KPH_TO_MS / 2.
self.cluster_min_speed = CV.KPH_TO_MS / 2.
@ -33,7 +33,11 @@ class CarState(CarStateBase):
self.distance_button = 0
def update(self, pt_cp, cam_cp, _, __, loopback_cp) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
pt_cp = can_parsers[Bus.pt]
cam_cp = can_parsers[Bus.cam]
loopback_cp = can_parsers[Bus.loopback]
ret = structs.CarState()
prev_cruise_buttons = self.cruise_buttons
@ -142,23 +146,8 @@ class CarState(CarStateBase):
return ret
@staticmethod
def get_cam_can_parser(CP):
messages = []
if CP.networkLocation == NetworkLocation.fwdCamera:
messages += [
("ASCMLKASteeringCmd", 10),
("ASCMActiveCruiseControlStatus", 25),
]
if CP.carFingerprint not in SDGM_CAR:
messages += [
("AEBCmd", 10),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus.CAMERA)
@staticmethod
def get_can_parser(CP):
messages = [
def get_can_parsers(CP):
pt_messages = [
("BCMTurnSignals", 1),
("ECMPRDNL2", 10),
("PSCMStatus", 10),
@ -176,23 +165,35 @@ class CarState(CarStateBase):
]
if CP.enableBsm:
messages.append(("BCMBlindSpotMonitor", 10))
pt_messages.append(("BCMBlindSpotMonitor", 10))
# Used to read back last counter sent to PT by camera
if CP.networkLocation == NetworkLocation.fwdCamera:
messages += [
pt_messages += [
("ASCMLKASteeringCmd", 0),
]
if CP.transmissionType == TransmissionType.direct:
messages.append(("EBCMRegenPaddle", 50))
pt_messages.append(("EBCMRegenPaddle", 50))
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus.POWERTRAIN)
cam_messages = []
if CP.networkLocation == NetworkLocation.fwdCamera:
cam_messages += [
("ASCMLKASteeringCmd", 10),
("ASCMActiveCruiseControlStatus", 25),
]
if CP.carFingerprint not in SDGM_CAR:
cam_messages += [
("AEBCmd", 10),
]
@staticmethod
def get_loopback_can_parser(CP):
messages = [
loopback_messages = [
("ASCMLKASteeringCmd", 0),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus.LOOPBACK)
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, 0),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, 2),
Bus.loopback: CANParser(DBC[CP.carFingerprint][Bus.pt], loopback_messages, 128),
}

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
import math
from opendbc.can.parser import CANParser
from opendbc.car import structs
from opendbc.car import Bus, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.gm.values import DBC, CanBus
from opendbc.car.interfaces import RadarInterfaceBase
@ -29,7 +29,7 @@ def create_radar_can_parser(car_fingerprint):
messages = list({(s[1], 14) for s in signals})
return CANParser(DBC[car_fingerprint]['radar'], messages, CanBus.OBSTACLE)
return CANParser(DBC[car_fingerprint][Bus.radar], messages, CanBus.OBSTACLE)
class RadarInterface(RadarInterfaceBase):

View File

@ -1,6 +1,6 @@
from dataclasses import dataclass, field
from opendbc.car import dbc_dict, PlatformConfig, DbcDict, Platforms, CarSpecs
from opendbc.car import Bus, PlatformConfig, DbcDict, Platforms, CarSpecs
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarHarness, CarDocs, CarParts
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
@ -80,7 +80,11 @@ class GMCarSpecs(CarSpecs):
@dataclass
class GMPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('gm_global_a_powertrain_generated', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis'))
dbc_dict: DbcDict = field(default_factory=lambda: {
Bus.pt: 'gm_global_a_powertrain_generated',
Bus.radar: 'gm_global_a_object',
Bus.chassis: 'gm_global_a_chassis',
})
@dataclass

View File

@ -1,7 +1,7 @@
from collections import namedtuple
from opendbc.can.packer import CANPacker
from opendbc.car import DT_CTRL, rate_limit, make_tester_present_msg, structs
from opendbc.car import Bus, DT_CTRL, rate_limit, make_tester_present_msg, structs
from opendbc.car.common.numpy_fast import clip, interp
from opendbc.car.honda import hondacan
from opendbc.car.honda.values import CruiseButtons, VISUAL_HUD, HONDA_BOSCH, HONDA_BOSCH_RADARLESS, HONDA_NIDEC_ALT_PCM_ACCEL, CarControllerParams
@ -97,9 +97,9 @@ HUDData = namedtuple("HUDData",
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
self.packer = CANPacker(dbc_name)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.packer = CANPacker(dbc_names[Bus.pt])
self.params = CarControllerParams(CP)
self.CAN = hondacan.CanBus(CP)

View File

@ -2,7 +2,7 @@ from collections import defaultdict
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import create_button_events, structs
from opendbc.car import Bus, create_button_events, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.common.numpy_fast import interp
from opendbc.car.honda.hondacan import CanBus, get_cruise_speed_conversion
@ -88,7 +88,7 @@ def get_can_messages(CP, gearbox_msg):
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
self.gearbox_msg = "GEARBOX"
if CP.carFingerprint == CAR.HONDA_ACCORD and CP.transmissionType == TransmissionType.cvt:
self.gearbox_msg = "GEARBOX_15T"
@ -109,7 +109,12 @@ class CarState(CarStateBase):
# However, on cars without a digital speedometer this is not always present (HRV, FIT, CRV 2016, ILX and RDX)
self.dash_speed_seen = False
def update(self, cp, cp_cam, _, cp_body, __) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
if self.CP.enableBsm:
cp_body = can_parsers[Bus.body]
ret = structs.CarState()
# car params
@ -270,38 +275,36 @@ class CarState(CarStateBase):
return ret
def get_can_parser(self, CP):
messages = get_can_messages(CP, self.gearbox_msg)
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus(CP).pt)
def get_can_parsers(self, CP):
pt_messages = get_can_messages(CP, self.gearbox_msg)
@staticmethod
def get_cam_can_parser(CP):
messages = [
cam_messages = [
("STEERING_CONTROL", 100),
]
if CP.carFingerprint in HONDA_BOSCH_RADARLESS:
messages += [
cam_messages += [
("ACC_HUD", 10),
("LKAS_HUD", 10),
]
elif CP.carFingerprint not in HONDA_BOSCH:
messages += [
cam_messages += [
("ACC_HUD", 10),
("LKAS_HUD", 10),
("BRAKE_COMMAND", 50),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus(CP).camera)
@staticmethod
def get_body_can_parser(CP):
if CP.enableBsm:
messages = [
body_messages = [
("BSM_STATUS_LEFT", 3),
("BSM_STATUS_RIGHT", 3),
]
bus_body = CanBus(CP).radar # B-CAN is forwarded to ACC-CAN radar side (CAN 0 on fake ethernet port)
return CANParser(DBC[CP.carFingerprint]["body"], messages, bus_body)
return None
parsers = {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, CanBus(CP).pt),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, CanBus(CP).camera),
}
if CP.enableBsm:
parsers[Bus.body] = CANParser(DBC[CP.carFingerprint][Bus.body], body_messages, CanBus(CP).radar)
return parsers

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
from opendbc.can.parser import CANParser
from opendbc.car import structs
from opendbc.car import Bus, structs
from opendbc.car.interfaces import RadarInterfaceBase
from opendbc.car.honda.values import DBC
@ -8,7 +8,7 @@ from opendbc.car.honda.values import DBC
def _create_nidec_can_parser(car_fingerprint):
radar_messages = [0x400] + list(range(0x430, 0x43A)) + list(range(0x440, 0x446))
messages = [(m, 20) for m in radar_messages]
return CANParser(DBC[car_fingerprint]['radar'], messages, 1)
return CANParser(DBC[car_fingerprint][Bus.radar], messages, 1)
class RadarInterface(RadarInterfaceBase):

View File

@ -2,7 +2,7 @@ from dataclasses import dataclass
from enum import Enum, IntFlag
from panda import uds
from opendbc.car import CarSpecs, PlatformConfig, Platforms, dbc_dict, structs
from opendbc.car import Bus, CarSpecs, PlatformConfig, Platforms, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16
@ -116,6 +116,10 @@ class HondaNidecPlatformConfig(PlatformConfig):
self.flags |= HondaFlags.NIDEC
def radar_dbc_dict(pt_dict):
return {Bus.pt: pt_dict, Bus.radar: 'acura_ilx_2016_nidec'}
class CAR(Platforms):
# Bosch Cars
HONDA_ACCORD = HondaBoschPlatformConfig(
@ -126,7 +130,7 @@ class CAR(Platforms):
],
# steerRatio: 11.82 is spec end-to-end
CarSpecs(mass=3279 * CV.LB_TO_KG, wheelbase=2.83, steerRatio=16.33, centerToFrontRatio=0.39, tireStiffnessFactor=0.8467),
dbc_dict('honda_accord_2018_can_generated', None),
{Bus.pt: 'honda_accord_2018_can_generated'},
)
HONDA_CIVIC_BOSCH = HondaBoschPlatformConfig(
[
@ -135,12 +139,12 @@ class CAR(Platforms):
HondaCarDocs("Honda Civic Hatchback 2017-21", min_steer_speed=12. * CV.MPH_TO_MS),
],
CarSpecs(mass=1326, wheelbase=2.7, steerRatio=15.38, centerToFrontRatio=0.4), # steerRatio: 10.93 is end-to-end spec
dbc_dict('honda_civic_hatchback_ex_2017_can_generated', None),
{Bus.pt: 'honda_civic_hatchback_ex_2017_can_generated'},
)
HONDA_CIVIC_BOSCH_DIESEL = HondaBoschPlatformConfig(
[], # don't show in docs
HONDA_CIVIC_BOSCH.specs,
dbc_dict('honda_accord_2018_can_generated', None),
{Bus.pt: 'honda_accord_2018_can_generated'},
)
HONDA_CIVIC_2022 = HondaBoschPlatformConfig(
[
@ -148,98 +152,98 @@ class CAR(Platforms):
HondaCarDocs("Honda Civic Hatchback 2022-24", "All", video_link="https://youtu.be/ytiOT5lcp6Q"),
],
HONDA_CIVIC_BOSCH.specs,
dbc_dict('honda_civic_ex_2022_can_generated', None),
{Bus.pt: 'honda_civic_ex_2022_can_generated'},
flags=HondaFlags.BOSCH_RADARLESS,
)
HONDA_CRV_5G = HondaBoschPlatformConfig(
[HondaCarDocs("Honda CR-V 2017-22", min_steer_speed=12. * CV.MPH_TO_MS)],
# steerRatio: 12.3 is spec end-to-end
CarSpecs(mass=3410 * CV.LB_TO_KG, wheelbase=2.66, steerRatio=16.0, centerToFrontRatio=0.41, tireStiffnessFactor=0.677),
dbc_dict('honda_crv_ex_2017_can_generated', None, body_dbc='honda_crv_ex_2017_body_generated'),
{Bus.pt: 'honda_crv_ex_2017_can_generated', Bus.body: 'honda_crv_ex_2017_body_generated'},
flags=HondaFlags.BOSCH_ALT_BRAKE,
)
HONDA_CRV_HYBRID = HondaBoschPlatformConfig(
[HondaCarDocs("Honda CR-V Hybrid 2017-22", min_steer_speed=12. * CV.MPH_TO_MS)],
# mass: mean of 4 models in kg, steerRatio: 12.3 is spec end-to-end
CarSpecs(mass=1667, wheelbase=2.66, steerRatio=16, centerToFrontRatio=0.41, tireStiffnessFactor=0.677),
dbc_dict('honda_accord_2018_can_generated', None),
{Bus.pt: 'honda_accord_2018_can_generated'},
)
HONDA_HRV_3G = HondaBoschPlatformConfig(
[HondaCarDocs("Honda HR-V 2023", "All")],
CarSpecs(mass=3125 * CV.LB_TO_KG, wheelbase=2.61, steerRatio=15.2, centerToFrontRatio=0.41, tireStiffnessFactor=0.5),
dbc_dict('honda_civic_ex_2022_can_generated', None),
{Bus.pt: 'honda_civic_ex_2022_can_generated'},
flags=HondaFlags.BOSCH_RADARLESS,
)
ACURA_RDX_3G = HondaBoschPlatformConfig(
[HondaCarDocs("Acura RDX 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS)],
CarSpecs(mass=4068 * CV.LB_TO_KG, wheelbase=2.75, steerRatio=11.95, centerToFrontRatio=0.41, tireStiffnessFactor=0.677), # as spec
dbc_dict('acura_rdx_2020_can_generated', None),
{Bus.pt: 'acura_rdx_2020_can_generated'},
flags=HondaFlags.BOSCH_ALT_BRAKE,
)
HONDA_INSIGHT = HondaBoschPlatformConfig(
[HondaCarDocs("Honda Insight 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS)],
CarSpecs(mass=2987 * CV.LB_TO_KG, wheelbase=2.7, steerRatio=15.0, centerToFrontRatio=0.39, tireStiffnessFactor=0.82), # as spec
dbc_dict('honda_insight_ex_2019_can_generated', None),
{Bus.pt: 'honda_insight_ex_2019_can_generated'},
)
HONDA_E = HondaBoschPlatformConfig(
[HondaCarDocs("Honda e 2020", "All", min_steer_speed=3. * CV.MPH_TO_MS)],
CarSpecs(mass=3338.8 * CV.LB_TO_KG, wheelbase=2.5, centerToFrontRatio=0.5, steerRatio=16.71, tireStiffnessFactor=0.82),
dbc_dict('acura_rdx_2020_can_generated', None),
{Bus.pt: 'acura_rdx_2020_can_generated'},
)
# Nidec Cars
ACURA_ILX = HondaNidecPlatformConfig(
[HondaCarDocs("Acura ILX 2016-19", "AcuraWatch Plus", min_steer_speed=25. * CV.MPH_TO_MS)],
CarSpecs(mass=3095 * CV.LB_TO_KG, wheelbase=2.67, steerRatio=18.61, centerToFrontRatio=0.37, tireStiffnessFactor=0.72), # 15.3 is spec end-to-end
dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('acura_ilx_2016_can_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
HONDA_CRV = HondaNidecPlatformConfig(
[HondaCarDocs("Honda CR-V 2015-16", "Touring Trim", min_steer_speed=12. * CV.MPH_TO_MS)],
CarSpecs(mass=3572 * CV.LB_TO_KG, wheelbase=2.62, steerRatio=16.89, centerToFrontRatio=0.41, tireStiffnessFactor=0.444), # as spec
dbc_dict('honda_crv_touring_2016_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('honda_crv_touring_2016_can_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
HONDA_CRV_EU = HondaNidecPlatformConfig(
[], # Euro version of CRV Touring, don't show in docs
HONDA_CRV.specs,
dbc_dict('honda_crv_executive_2016_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('honda_crv_executive_2016_can_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
HONDA_FIT = HondaNidecPlatformConfig(
[HondaCarDocs("Honda Fit 2018-20", min_steer_speed=12. * CV.MPH_TO_MS)],
CarSpecs(mass=2644 * CV.LB_TO_KG, wheelbase=2.53, steerRatio=13.06, centerToFrontRatio=0.39, tireStiffnessFactor=0.75),
dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('honda_fit_ex_2018_can_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
HONDA_FREED = HondaNidecPlatformConfig(
[HondaCarDocs("Honda Freed 2020", min_steer_speed=12. * CV.MPH_TO_MS)],
CarSpecs(mass=3086. * CV.LB_TO_KG, wheelbase=2.74, steerRatio=13.06, centerToFrontRatio=0.39, tireStiffnessFactor=0.75), # mostly copied from FIT
dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('honda_fit_ex_2018_can_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
HONDA_HRV = HondaNidecPlatformConfig(
[HondaCarDocs("Honda HR-V 2019-22", min_steer_speed=12. * CV.MPH_TO_MS)],
HONDA_HRV_3G.specs,
dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('honda_fit_ex_2018_can_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
HONDA_ODYSSEY = HondaNidecPlatformConfig(
[HondaCarDocs("Honda Odyssey 2018-20")],
CarSpecs(mass=1900, wheelbase=3.0, steerRatio=14.35, centerToFrontRatio=0.41, tireStiffnessFactor=0.82),
dbc_dict('honda_odyssey_exl_2018_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('honda_odyssey_exl_2018_generated'),
flags=HondaFlags.NIDEC_ALT_PCM_ACCEL,
)
HONDA_ODYSSEY_CHN = HondaNidecPlatformConfig(
[], # Chinese version of Odyssey, don't show in docs
HONDA_ODYSSEY.specs,
dbc_dict('honda_odyssey_extreme_edition_2018_china_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('honda_odyssey_extreme_edition_2018_china_can_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
ACURA_RDX = HondaNidecPlatformConfig(
[HondaCarDocs("Acura RDX 2016-18", "AcuraWatch Plus", min_steer_speed=12. * CV.MPH_TO_MS)],
CarSpecs(mass=3925 * CV.LB_TO_KG, wheelbase=2.68, steerRatio=15.0, centerToFrontRatio=0.38, tireStiffnessFactor=0.444), # as spec
dbc_dict('acura_rdx_2018_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('acura_rdx_2018_can_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
HONDA_PILOT = HondaNidecPlatformConfig(
@ -248,19 +252,19 @@ class CAR(Platforms):
HondaCarDocs("Honda Passport 2019-23", "All", min_steer_speed=12. * CV.MPH_TO_MS),
],
CarSpecs(mass=4278 * CV.LB_TO_KG, wheelbase=2.86, centerToFrontRatio=0.428, steerRatio=16.0, tireStiffnessFactor=0.444), # as spec
dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('acura_ilx_2016_can_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
HONDA_RIDGELINE = HondaNidecPlatformConfig(
[HondaCarDocs("Honda Ridgeline 2017-24", min_steer_speed=12. * CV.MPH_TO_MS)],
CarSpecs(mass=4515 * CV.LB_TO_KG, wheelbase=3.18, centerToFrontRatio=0.41, steerRatio=15.59, tireStiffnessFactor=0.444), # as spec
dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('acura_ilx_2016_can_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
HONDA_CIVIC = HondaNidecPlatformConfig(
[HondaCarDocs("Honda Civic 2016-18", min_steer_speed=12. * CV.MPH_TO_MS, video_link="https://youtu.be/-IkImTe1NYE")],
CarSpecs(mass=1326, wheelbase=2.70, centerToFrontRatio=0.4, steerRatio=15.38), # 10.93 is end-to-end spec
dbc_dict('honda_civic_touring_2016_can_generated', 'acura_ilx_2016_nidec'),
radar_dbc_dict('honda_civic_touring_2016_can_generated'),
)

View File

@ -1,5 +1,5 @@
from opendbc.can.packer import CANPacker
from opendbc.car import DT_CTRL, apply_driver_steer_torque_limits, common_fault_avoidance, make_tester_present_msg, structs
from opendbc.car import Bus, DT_CTRL, apply_driver_steer_torque_limits, common_fault_avoidance, make_tester_present_msg, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.common.numpy_fast import clip
from opendbc.car.hyundai import hyundaicanfd, hyundaican
@ -43,11 +43,11 @@ def process_hud_alert(enabled, fingerprint, hud_control):
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.CAN = CanBus(CP)
self.params = CarControllerParams(CP)
self.packer = CANPacker(dbc_name)
self.packer = CANPacker(dbc_names[Bus.pt])
self.angle_limit_counter = 0
self.accel_last = 0

View File

@ -4,7 +4,7 @@ import math
from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine
from opendbc.car import create_button_events, structs
from opendbc.car import Bus, create_button_events, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.hyundai.hyundaicanfd import CanBus
from opendbc.car.hyundai.values import HyundaiFlags, CAR, DBC, Buttons, CarControllerParams
@ -23,7 +23,7 @@ BUTTONS_DICT = {Buttons.RES_ACCEL: ButtonType.accelCruise, Buttons.SET_DECEL: Bu
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
self.cruise_buttons: deque = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES)
self.main_buttons: deque = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES)
@ -57,9 +57,12 @@ class CarState(CarStateBase):
self.params = CarControllerParams(CP)
def update(self, cp, cp_cam, *_) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
if self.CP.flags & HyundaiFlags.CANFD:
return self.update_canfd(cp, cp_cam)
return self.update_canfd(can_parsers)
ret = structs.CarState()
cp_cruise = cp_cam if self.CP.flags & HyundaiFlags.CAMERA_SCC else cp
@ -177,7 +180,10 @@ class CarState(CarStateBase):
return ret
def update_canfd(self, cp, cp_cam) -> structs.CarState:
def update_canfd(self, can_parsers) -> structs.CarState:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
ret = structs.CarState()
self.is_metric = cp.vl["CRUISE_BUTTONS_ALT"]["DISTANCE_UNIT"] != 1
@ -263,11 +269,62 @@ class CarState(CarStateBase):
return ret
def get_can_parser(self, CP):
if CP.flags & HyundaiFlags.CANFD:
return self.get_can_parser_canfd(CP)
def get_can_parsers_canfd(self, CP):
pt_messages = [
("WHEEL_SPEEDS", 100),
("STEERING_SENSORS", 100),
("MDPS", 100),
("TCS", 50),
("CRUISE_BUTTONS_ALT", 50),
("BLINKERS", 4),
("DOORS_SEATBELTS", 4),
]
messages = [
if CP.flags & HyundaiFlags.EV:
pt_messages += [
("ACCELERATOR", 100),
("MANUAL_SPEED_LIMIT_ASSIST", 10),
]
else:
pt_messages += [
(self.gear_msg_canfd, 100),
(self.accelerator_msg_canfd, 100),
]
if not (CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS):
pt_messages += [
("CRUISE_BUTTONS", 50)
]
if CP.enableBsm:
pt_messages += [
("BLINDSPOTS_REAR_CORNERS", 20),
]
if not (CP.flags & HyundaiFlags.CANFD_CAMERA_SCC.value) and not CP.openpilotLongitudinalControl:
pt_messages += [
("SCC_CONTROL", 50),
]
cam_messages = []
if CP.flags & HyundaiFlags.CANFD_HDA2:
block_lfa_msg = "CAM_0x362" if CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING else "CAM_0x2a4"
cam_messages += [(block_lfa_msg, 20)]
elif CP.flags & HyundaiFlags.CANFD_CAMERA_SCC:
cam_messages += [
("SCC_CONTROL", 50),
]
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, CanBus(CP).ECAN),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, CanBus(CP).CAM),
}
def get_can_parsers(self, CP):
if CP.flags & HyundaiFlags.CANFD:
return self.get_can_parsers_canfd(CP)
pt_messages = [
# address, frequency
("MDPS12", 50),
("TCS11", 100),
@ -284,103 +341,48 @@ class CarState(CarStateBase):
]
if not CP.openpilotLongitudinalControl and not (CP.flags & HyundaiFlags.CAMERA_SCC):
messages += [
pt_messages += [
("SCC11", 50),
("SCC12", 50),
]
if CP.flags & HyundaiFlags.USE_FCA.value:
messages.append(("FCA11", 50))
pt_messages.append(("FCA11", 50))
if CP.enableBsm:
messages.append(("LCA11", 50))
pt_messages.append(("LCA11", 50))
if CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV):
messages.append(("E_EMS11", 50))
pt_messages.append(("E_EMS11", 50))
else:
messages += [
pt_messages += [
("EMS12", 100),
("EMS16", 100),
]
if CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV):
messages.append(("ELECT_GEAR", 20))
pt_messages.append(("ELECT_GEAR", 20))
elif CP.flags & HyundaiFlags.CLUSTER_GEARS:
pass
elif CP.flags & HyundaiFlags.TCU_GEARS:
messages.append(("TCU12", 100))
pt_messages.append(("TCU12", 100))
else:
messages.append(("LVR12", 100))
pt_messages.append(("LVR12", 100))
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0)
@staticmethod
def get_cam_can_parser(CP):
if CP.flags & HyundaiFlags.CANFD:
return CarState.get_cam_can_parser_canfd(CP)
messages = [
cam_messages = [
("LKAS11", 100)
]
if not CP.openpilotLongitudinalControl and CP.flags & HyundaiFlags.CAMERA_SCC:
messages += [
cam_messages += [
("SCC11", 50),
("SCC12", 50),
]
if CP.flags & HyundaiFlags.USE_FCA.value:
messages.append(("FCA11", 50))
cam_messages.append(("FCA11", 50))
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 2)
def get_can_parser_canfd(self, CP):
messages = [
("WHEEL_SPEEDS", 100),
("STEERING_SENSORS", 100),
("MDPS", 100),
("TCS", 50),
("CRUISE_BUTTONS_ALT", 50),
("BLINKERS", 4),
("DOORS_SEATBELTS", 4),
]
if CP.flags & HyundaiFlags.EV:
messages += [
("ACCELERATOR", 100),
("MANUAL_SPEED_LIMIT_ASSIST", 10),
]
else:
messages += [
(self.gear_msg_canfd, 100),
(self.accelerator_msg_canfd, 100),
]
if not (CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS):
messages += [
("CRUISE_BUTTONS", 50)
]
if CP.enableBsm:
messages += [
("BLINDSPOTS_REAR_CORNERS", 20),
]
if not (CP.flags & HyundaiFlags.CANFD_CAMERA_SCC.value) and not CP.openpilotLongitudinalControl:
messages += [
("SCC_CONTROL", 50),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus(CP).ECAN)
@staticmethod
def get_cam_can_parser_canfd(CP):
messages = []
if CP.flags & HyundaiFlags.CANFD_HDA2:
block_lfa_msg = "CAM_0x362" if CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING else "CAM_0x2a4"
messages += [(block_lfa_msg, 20)]
elif CP.flags & HyundaiFlags.CANFD_CAMERA_SCC:
messages += [
("SCC_CONTROL", 50),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus(CP).CAM)
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, 0),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, 2),
}

View File

@ -1,5 +1,5 @@
from panda import Panda
from opendbc.car import get_safety_config, structs
from opendbc.car import Bus, get_safety_config, structs
from opendbc.car.hyundai.hyundaicanfd import CanBus
from opendbc.car.hyundai.values import HyundaiFlags, CAR, DBC, CAMERA_SCC_CAR, CANFD_RADAR_SCC_CAR, \
CANFD_UNSUPPORTED_LONGITUDINAL_CAR, \
@ -100,7 +100,7 @@ class CarInterface(CarInterfaceBase):
# Common longitudinal control setup
ret.radarUnavailable = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint]["radar"] is None
ret.radarUnavailable = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint][Bus.radar] is None
ret.openpilotLongitudinalControl = experimental_long and ret.experimentalLongitudinalAvailable
ret.pcmCruise = not ret.openpilotLongitudinalControl
ret.startingState = True

View File

@ -1,7 +1,7 @@
import math
from opendbc.can.parser import CANParser
from opendbc.car import structs
from opendbc.car import Bus, structs
from opendbc.car.interfaces import RadarInterfaceBase
from opendbc.car.hyundai.values import DBC
@ -11,11 +11,11 @@ RADAR_MSG_COUNT = 32
# POC for parsing corner radars: https://github.com/commaai/openpilot/pull/24221/
def get_radar_can_parser(CP):
if DBC[CP.carFingerprint]['radar'] is None:
if Bus.radar not in DBC[CP.carFingerprint]:
return None
messages = [(f"RADAR_TRACK_{addr:x}", 50) for addr in range(RADAR_START_ADDR, RADAR_START_ADDR + RADAR_MSG_COUNT)]
return CANParser(DBC[CP.carFingerprint]['radar'], messages, 1)
return CANParser(DBC[CP.carFingerprint][Bus.radar], messages, 1)
class RadarInterface(RadarInterfaceBase):

View File

@ -3,7 +3,7 @@ from dataclasses import dataclass, field
from enum import Enum, IntFlag
from panda import uds
from opendbc.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from opendbc.car import Bus, CarSpecs, DbcDict, PlatformConfig, Platforms
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
@ -117,11 +117,11 @@ class HyundaiCarDocs(CarDocs):
@dataclass
class HyundaiPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict("hyundai_kia_generic", None))
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: "hyundai_kia_generic"})
def init(self):
if self.flags & HyundaiFlags.MANDO_RADAR:
self.dbc_dict = dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated')
self.dbc_dict = {Bus.pt: "hyundai_kia_generic", Bus.radar: 'hyundai_kia_mando_front_radar_generated'}
if self.flags & HyundaiFlags.MIN_STEER_32_MPH:
self.specs = self.specs.override(minSteerSpeed=32 * CV.MPH_TO_MS)
@ -129,7 +129,7 @@ class HyundaiPlatformConfig(PlatformConfig):
@dataclass
class HyundaiCanFDPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict("hyundai_canfd", None))
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: "hyundai_canfd"})
def init(self):
self.flags |= HyundaiFlags.CANFD

View File

@ -17,6 +17,7 @@ from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.common.simple_kalman import KF1D, get_kalman_gain
from opendbc.car.common.numpy_fast import clip
from opendbc.car.values import PLATFORMS
from opendbc.can.parser import CANParser
GearShifter = structs.CarState.GearShifter
@ -92,15 +93,10 @@ class CarInterfaceBase(ABC):
self.v_ego_cluster_seen = False
self.CS: CarStateBase = CarState(CP)
self.cp = self.CS.get_can_parser(CP)
self.cp_cam = self.CS.get_cam_can_parser(CP)
self.cp_adas = self.CS.get_adas_can_parser(CP)
self.cp_body = self.CS.get_body_can_parser(CP)
self.cp_loopback = self.CS.get_loopback_can_parser(CP)
self.can_parsers = (self.cp, self.cp_cam, self.cp_adas, self.cp_body, self.cp_loopback)
self.can_parsers: dict[StrEnum, CANParser] = self.CS.get_can_parsers(CP)
dbc_name = "" if self.cp is None else self.cp.dbc_name
self.CC: CarControllerBase = CarController(dbc_name, CP)
dbc_names = {bus: cp.dbc_name for bus, cp in self.can_parsers.items()}
self.CC: CarControllerBase = CarController(dbc_names, CP)
def apply(self, c: structs.CarControl, now_nanos: int | None = None) -> tuple[structs.CarControl.Actuators, list[CanData]]:
if now_nanos is None:
@ -221,19 +217,19 @@ class CarInterfaceBase(ABC):
tune.torque.steeringAngleDeadzoneDeg = steering_angle_deadzone_deg
def _update(self) -> structs.CarState:
return self.CS.update(*self.can_parsers)
return self.CS.update(self.can_parsers)
def update(self, can_packets: list[tuple[int, list[CanData]]]) -> structs.CarState:
# parse can
for cp in self.can_parsers:
for cp in self.can_parsers.values():
if cp is not None:
cp.update_strings(can_packets)
# get CarState
ret = self._update()
ret.canValid = all(cp.can_valid for cp in self.can_parsers if cp is not None)
ret.canTimeout = any(cp.bus_timeout for cp in self.can_parsers if cp is not None)
ret.canValid = all(cp.can_valid for cp in self.can_parsers.values())
ret.canTimeout = any(cp.bus_timeout for cp in self.can_parsers.values())
if ret.vEgoCluster == 0.0 and not self.v_ego_cluster_seen:
ret.vEgoCluster = ret.vEgo
@ -293,7 +289,7 @@ class CarStateBase(ABC):
self.v_ego_kf = KF1D(x0=x0, A=A, C=C[0], K=K)
@abstractmethod
def update(self, cp, cp_cam, cp_adas, cp_body, cp_loopback) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
pass
def update_speed_kf(self, v_ego_raw):
@ -357,28 +353,12 @@ class CarStateBase(ABC):
return GEAR_SHIFTER_MAP.get(gear.upper(), GearShifter.unknown)
@staticmethod
def get_can_parser(CP):
return None
@staticmethod
def get_cam_can_parser(CP):
return None
@staticmethod
def get_adas_can_parser(CP):
return None
@staticmethod
def get_body_can_parser(CP):
return None
@staticmethod
def get_loopback_can_parser(CP):
return None
def get_can_parsers(CP) -> dict[StrEnum, CANParser]:
return {}
class CarControllerBase(ABC):
def __init__(self, dbc_name: str, CP: structs.CarParams):
def __init__(self, dbc_names: dict[StrEnum, str], CP: structs.CarParams):
self.CP = CP
self.frame = 0
self.secoc_key: bytes = b"00" * 16

View File

@ -1,5 +1,5 @@
from opendbc.can.packer import CANPacker
from opendbc.car import apply_driver_steer_torque_limits, structs
from opendbc.car import Bus, apply_driver_steer_torque_limits, structs
from opendbc.car.interfaces import CarControllerBase
from opendbc.car.mazda import mazdacan
from opendbc.car.mazda.values import CarControllerParams, Buttons
@ -8,10 +8,10 @@ VisualAlert = structs.CarControl.HUDControl.VisualAlert
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.apply_steer_last = 0
self.packer = CANPacker(dbc_name)
self.packer = CANPacker(dbc_names[Bus.pt])
self.brake_counter = 0
def update(self, CC, CS, now_nanos):

View File

@ -1,6 +1,6 @@
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import create_button_events, structs
from opendbc.car import Bus, create_button_events, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.interfaces import CarStateBase
from opendbc.car.mazda.values import DBC, LKAS_LIMITS, MazdaFlags
@ -12,7 +12,7 @@ class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
self.shifter_values = can_define.dv["GEAR"]["GEAR"]
self.crz_btns_counter = 0
@ -22,7 +22,9 @@ class CarState(CarStateBase):
self.distance_button = 0
def update(self, cp, cp_cam, *_) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
ret = structs.CarState()
@ -121,8 +123,8 @@ class CarState(CarStateBase):
return ret
@staticmethod
def get_can_parser(CP):
messages = [
def get_can_parsers(CP):
pt_messages = [
# sig_address, frequency
("BLINK_INFO", 10),
("STEER", 67),
@ -132,7 +134,7 @@ class CarState(CarStateBase):
]
if CP.flags & MazdaFlags.GEN1:
messages += [
pt_messages += [
("ENGINE_DATA", 100),
("CRZ_CTRL", 50),
("CRZ_EVENTS", 50),
@ -145,17 +147,15 @@ class CarState(CarStateBase):
("BSM", 10),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0)
@staticmethod
def get_cam_can_parser(CP):
messages = []
cam_messages = []
if CP.flags & MazdaFlags.GEN1:
messages += [
cam_messages += [
# sig_address, frequency
("CAM_LANEINFO", 2),
("CAM_LKAS", 16),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 2)
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, 0),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, 2),
}

View File

@ -1,7 +1,7 @@
from dataclasses import dataclass, field
from enum import IntFlag
from opendbc.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from opendbc.car import Bus, CarSpecs, DbcDict, PlatformConfig, Platforms
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarHarness, CarDocs, CarParts
@ -45,7 +45,7 @@ class MazdaFlags(IntFlag):
@dataclass
class MazdaPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('mazda_2017', None))
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: 'mazda_2017'})
flags: int = MazdaFlags.GEN1

View File

@ -1,6 +1,6 @@
from opendbc.can.packer import CANPacker
from opendbc.car.common.numpy_fast import clip
from opendbc.car import apply_std_steer_angle_limits, structs
from opendbc.car import Bus, apply_std_steer_angle_limits, structs
from opendbc.car.interfaces import CarControllerBase
from opendbc.car.nissan import nissancan
from opendbc.car.nissan.values import CAR, CarControllerParams
@ -9,14 +9,14 @@ VisualAlert = structs.CarControl.HUDControl.VisualAlert
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.car_fingerprint = CP.carFingerprint
self.lkas_max_torque = 0
self.apply_angle_last = 0
self.packer = CANPacker(dbc_name)
self.packer = CANPacker(dbc_names[Bus.pt])
def update(self, CC, CS, now_nanos):
actuators = CC.actuators

View File

@ -2,7 +2,7 @@ import copy
from collections import deque
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import create_button_events, structs
from opendbc.car import Bus, create_button_events, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.interfaces import CarStateBase
from opendbc.car.nissan.values import CAR, DBC, CarControllerParams
@ -15,7 +15,7 @@ TORQUE_SAMPLES = 12
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
self.lkas_hud_msg = {}
self.lkas_hud_info_msg = {}
@ -25,7 +25,11 @@ class CarState(CarStateBase):
self.distance_button = 0
def update(self, cp, cp_cam, cp_adas, *_) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
cp_adas = can_parsers[Bus.adas]
ret = structs.CarState()
prev_distance_button = self.distance_button
@ -130,8 +134,8 @@ class CarState(CarStateBase):
return ret
@staticmethod
def get_can_parser(CP):
messages = [
def get_can_parsers(CP):
pt_messages = [
# sig_address, frequency
("STEER_ANGLE_SENSOR", 100),
("WHEEL_SPEEDS_REAR", 50),
@ -143,14 +147,14 @@ class CarState(CarStateBase):
]
if CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL, CAR.NISSAN_ALTIMA):
messages += [
pt_messages += [
("GAS_PEDAL", 100),
("CRUISE_THROTTLE", 50),
("HUD", 25),
]
elif CP.carFingerprint in (CAR.NISSAN_LEAF, CAR.NISSAN_LEAF_IC):
messages += [
pt_messages += [
("BRAKE_PEDAL", 100),
("CRUISE_THROTTLE", 50),
("CANCEL_MSG", 50),
@ -159,28 +163,27 @@ class CarState(CarStateBase):
]
if CP.carFingerprint == CAR.NISSAN_ALTIMA:
messages += [
pt_messages += [
("CRUISE_STATE", 10),
("LKAS_SETTINGS", 10),
("PROPILOT_HUD", 50),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 1)
else:
pt_messages.append(("STEER_TORQUE_SENSOR", 100))
messages.append(("STEER_TORQUE_SENSOR", 100))
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0)
@staticmethod
def get_adas_can_parser(CP):
# this function generates lists for signal, messages and initial values
cam_messages = []
if CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL):
cam_messages.append(("PRO_PILOT", 100))
elif CP.carFingerprint == CAR.NISSAN_ALTIMA:
cam_messages.append(("STEER_TORQUE_SENSOR", 100))
if CP.carFingerprint == CAR.NISSAN_ALTIMA:
messages = [
adas_messages = [
("LKAS", 100),
("PRO_PILOT", 100),
]
else:
messages = [
adas_messages = [
("PROPILOT_HUD_INFO_MSG", 2),
("LKAS_SETTINGS", 10),
("CRUISE_STATE", 50),
@ -188,16 +191,8 @@ class CarState(CarStateBase):
("LKAS", 100),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 2)
@staticmethod
def get_cam_can_parser(CP):
messages = []
if CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL):
messages.append(("PRO_PILOT", 100))
elif CP.carFingerprint == CAR.NISSAN_ALTIMA:
messages.append(("STEER_TORQUE_SENSOR", 100))
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0)
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 1)
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, 1 if CP.carFingerprint == CAR.NISSAN_ALTIMA else 0),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, 0 if CP.carFingerprint == CAR.NISSAN_ALTIMA else 1),
Bus.adas: CANParser(DBC[CP.carFingerprint][Bus.pt], adas_messages, 2),
}

View File

@ -1,7 +1,7 @@
from dataclasses import dataclass, field
from panda import uds
from opendbc.car import AngleRateLimit, CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from opendbc.car import AngleRateLimit, Bus, CarSpecs, DbcDict, PlatformConfig, Platforms
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarDocs, CarHarness, CarParts
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
@ -37,7 +37,7 @@ class NissanCarSpecs(CarSpecs):
@dataclass
class NissanPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('nissan_x_trail_2017_generated', None))
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: 'nissan_x_trail_2017_generated'})
class CAR(Platforms):
@ -48,7 +48,7 @@ class CAR(Platforms):
NISSAN_LEAF = NissanPlatformConfig(
[NissanCarDocs("Nissan Leaf 2018-23", video_link="https://youtu.be/vaMbtAh_0cY")],
NissanCarSpecs(mass=1610, wheelbase=2.705),
dbc_dict('nissan_leaf_2018_generated', None),
{Bus.pt: 'nissan_leaf_2018_generated'},
)
# Leaf with ADAS ECU found behind instrument cluster instead of glovebox
# Currently the only known difference between them is the inverted seatbelt signal.

View File

@ -1,5 +1,5 @@
from opendbc.can.packer import CANPacker
from opendbc.car import apply_driver_steer_torque_limits, common_fault_avoidance, make_tester_present_msg
from opendbc.car import Bus, apply_driver_steer_torque_limits, common_fault_avoidance, make_tester_present_msg
from opendbc.car.common.numpy_fast import clip, interp
from opendbc.car.interfaces import CarControllerBase
from opendbc.car.subaru import subarucan
@ -12,15 +12,15 @@ MAX_STEER_RATE_FRAMES = 7 # tx control frames needed before torque can be cut
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.apply_steer_last = 0
self.cruise_button_prev = 0
self.steer_rate_counter = 0
self.p = CarControllerParams(CP)
self.packer = CANPacker(DBC[CP.carFingerprint]['pt'])
self.packer = CANPacker(DBC[CP.carFingerprint][Bus.pt])
def update(self, CC, CS, now_nanos):
actuators = CC.actuators

View File

@ -1,7 +1,7 @@
import copy
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import structs
from opendbc.car import Bus, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.interfaces import CarStateBase
from opendbc.car.subaru.values import DBC, CanBus, SubaruFlags
@ -11,25 +11,28 @@ from opendbc.car import CanSignalRateCalculator
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
self.shifter_values = can_define.dv["Transmission"]["Gear"]
self.angle_rate_calulator = CanSignalRateCalculator(50)
def update(self, cp, cp_cam, _, cp_body, __) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
cp_alt = can_parsers[Bus.alt]
ret = structs.CarState()
throttle_msg = cp.vl["Throttle"] if not (self.CP.flags & SubaruFlags.HYBRID) else cp_body.vl["Throttle_Hybrid"]
throttle_msg = cp.vl["Throttle"] if not (self.CP.flags & SubaruFlags.HYBRID) else cp_alt.vl["Throttle_Hybrid"]
ret.gas = throttle_msg["Throttle_Pedal"] / 255.
ret.gasPressed = ret.gas > 1e-5
if self.CP.flags & SubaruFlags.PREGLOBAL:
ret.brakePressed = cp.vl["Brake_Pedal"]["Brake_Pedal"] > 0
else:
cp_brakes = cp_body if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp
cp_brakes = cp_alt if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp
ret.brakePressed = cp_brakes.vl["Brake_Status"]["Brake"] == 1
cp_es_distance = cp_body if self.CP.flags & (SubaruFlags.GLOBAL_GEN2 | SubaruFlags.HYBRID) else cp_cam
cp_es_distance = cp_alt if self.CP.flags & (SubaruFlags.GLOBAL_GEN2 | SubaruFlags.HYBRID) else cp_cam
if not (self.CP.flags & SubaruFlags.HYBRID):
eyesight_fault = bool(cp_es_distance.vl["ES_Distance"]["Cruise_Fault"])
@ -39,7 +42,7 @@ class CarState(CarStateBase):
else:
ret.accFaulted = eyesight_fault
cp_wheels = cp_body if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp
cp_wheels = cp_alt if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp
ret.wheelSpeeds = self.get_wheel_speeds(
cp_wheels.vl["Wheel_Speeds"]["FL"],
cp_wheels.vl["Wheel_Speeds"]["FR"],
@ -58,7 +61,7 @@ class CarState(CarStateBase):
ret.leftBlindspot = (cp.vl["BSD_RCTA"]["L_ADJACENT"] == 1) or (cp.vl["BSD_RCTA"]["L_APPROACHING"] == 1)
ret.rightBlindspot = (cp.vl["BSD_RCTA"]["R_ADJACENT"] == 1) or (cp.vl["BSD_RCTA"]["R_APPROACHING"] == 1)
cp_transmission = cp_body if self.CP.flags & SubaruFlags.HYBRID else cp
cp_transmission = cp_alt if self.CP.flags & SubaruFlags.HYBRID else cp
can_gear = int(cp_transmission.vl["Transmission"]["Gear"])
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(can_gear, None))
@ -74,7 +77,7 @@ class CarState(CarStateBase):
steer_threshold = 75 if self.CP.flags & SubaruFlags.PREGLOBAL else 80
ret.steeringPressed = abs(ret.steeringTorque) > steer_threshold
cp_cruise = cp_body if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp
cp_cruise = cp_alt if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp
if self.CP.flags & SubaruFlags.HYBRID:
ret.cruiseState.enabled = cp_cam.vl["ES_DashStatus"]['Cruise_Activated'] != 0
ret.cruiseState.available = cp_cam.vl["ES_DashStatus"]['Cruise_On'] != 0
@ -105,9 +108,9 @@ class CarState(CarStateBase):
(cp_cam.vl["ES_LKAS_State"]["LKAS_Alert"] == 2)
self.es_lkas_state_msg = copy.copy(cp_cam.vl["ES_LKAS_State"])
cp_es_brake = cp_body if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp_cam
cp_es_brake = cp_alt if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp_cam
self.es_brake_msg = copy.copy(cp_es_brake.vl["ES_Brake"])
cp_es_status = cp_body if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp_cam
cp_es_status = cp_alt if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp_cam
# TODO: Hybrid cars don't have ES_Distance, need a replacement
if not (self.CP.flags & SubaruFlags.HYBRID):
@ -164,8 +167,8 @@ class CarState(CarStateBase):
return messages
@staticmethod
def get_can_parser(CP):
messages = [
def get_can_parsers(CP):
pt_messages = [
# sig_address, frequency
("Dashlights", 10),
("Steering_Torque", 50),
@ -174,55 +177,50 @@ class CarState(CarStateBase):
]
if not (CP.flags & SubaruFlags.HYBRID):
messages += [
pt_messages += [
("Throttle", 100),
("Transmission", 100)
]
if CP.enableBsm:
messages.append(("BSD_RCTA", 17))
pt_messages.append(("BSD_RCTA", 17))
if not (CP.flags & SubaruFlags.PREGLOBAL):
if not (CP.flags & SubaruFlags.GLOBAL_GEN2):
messages += CarState.get_common_global_body_messages(CP)
pt_messages += CarState.get_common_global_body_messages(CP)
else:
messages += CarState.get_common_preglobal_body_messages()
pt_messages += CarState.get_common_preglobal_body_messages()
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus.main)
@staticmethod
def get_cam_can_parser(CP):
if CP.flags & SubaruFlags.PREGLOBAL:
messages = [
cam_messages = [
("ES_DashStatus", 20),
("ES_Distance", 20),
]
else:
messages = [
cam_messages = [
("ES_DashStatus", 10),
("ES_LKAS_State", 10),
]
if not (CP.flags & SubaruFlags.GLOBAL_GEN2):
messages += CarState.get_common_global_es_messages(CP)
cam_messages += CarState.get_common_global_es_messages(CP)
if CP.flags & SubaruFlags.SEND_INFOTAINMENT:
messages.append(("ES_Infotainment", 10))
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus.camera)
@staticmethod
def get_body_can_parser(CP):
messages = []
cam_messages.append(("ES_Infotainment", 10))
alt_messages = []
if CP.flags & SubaruFlags.GLOBAL_GEN2:
messages += CarState.get_common_global_body_messages(CP)
messages += CarState.get_common_global_es_messages(CP)
alt_messages += CarState.get_common_global_body_messages(CP)
alt_messages += CarState.get_common_global_es_messages(CP)
if CP.flags & SubaruFlags.HYBRID:
messages += [
alt_messages += [
("Throttle_Hybrid", 40),
("Transmission", 100)
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus.alt)
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, CanBus.main),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, CanBus.camera),
Bus.alt: CANParser(DBC[CP.carFingerprint][Bus.pt], alt_messages, CanBus.alt)
}

View File

@ -2,7 +2,7 @@ from dataclasses import dataclass, field
from enum import Enum, IntFlag
from panda import uds
from opendbc.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from opendbc.car import Bus, CarSpecs, DbcDict, PlatformConfig, Platforms
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Tool, Column
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16
@ -104,11 +104,11 @@ class SubaruCarDocs(CarDocs):
@dataclass
class SubaruPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('subaru_global_2017_generated', None))
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: 'subaru_global_2017_generated'})
def init(self):
if self.flags & SubaruFlags.HYBRID:
self.dbc_dict = dbc_dict('subaru_global_2020_hybrid_generated', None)
self.dbc_dict = {Bus.pt: 'subaru_global_2020_hybrid_generated'}
@dataclass
@ -171,25 +171,25 @@ class CAR(Platforms):
SUBARU_FORESTER_PREGLOBAL = SubaruPlatformConfig(
[SubaruCarDocs("Subaru Forester 2017-18")],
CarSpecs(mass=1568, wheelbase=2.67, steerRatio=20),
dbc_dict('subaru_forester_2017_generated', None),
{Bus.pt: 'subaru_forester_2017_generated'},
flags=SubaruFlags.PREGLOBAL,
)
SUBARU_LEGACY_PREGLOBAL = SubaruPlatformConfig(
[SubaruCarDocs("Subaru Legacy 2015-18")],
CarSpecs(mass=1568, wheelbase=2.67, steerRatio=12.5),
dbc_dict('subaru_outback_2015_generated', None),
{Bus.pt: 'subaru_outback_2015_generated'},
flags=SubaruFlags.PREGLOBAL,
)
SUBARU_OUTBACK_PREGLOBAL = SubaruPlatformConfig(
[SubaruCarDocs("Subaru Outback 2015-17")],
SUBARU_FORESTER_PREGLOBAL.specs,
dbc_dict('subaru_outback_2015_generated', None),
{Bus.pt: 'subaru_outback_2015_generated'},
flags=SubaruFlags.PREGLOBAL,
)
SUBARU_OUTBACK_PREGLOBAL_2018 = SubaruPlatformConfig(
[SubaruCarDocs("Subaru Outback 2018-19")],
SUBARU_FORESTER_PREGLOBAL.specs,
dbc_dict('subaru_outback_2019_generated', None),
{Bus.pt: 'subaru_outback_2019_generated'},
flags=SubaruFlags.PREGLOBAL,
)
# Angle LKAS

View File

@ -1,21 +1,19 @@
from opendbc.car.common.numpy_fast import clip
from opendbc.can.packer import CANPacker
from opendbc.car import apply_std_steer_angle_limits
from opendbc.car import Bus, apply_std_steer_angle_limits
from opendbc.car.interfaces import CarControllerBase
from opendbc.car.tesla.teslacan import TeslaCAN
from opendbc.car.tesla.values import CarControllerParams
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
self.CP = CP
self.frame = 0
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.apply_angle_last = 0
self.packer = CANPacker(dbc_name)
self.packer = CANPacker(dbc_names[Bus.party])
self.tesla_can = TeslaCAN(self.packer)
def update(self, CC, CS, now_nanos):
actuators = CC.actuators
can_sends = []

View File

@ -1,7 +1,7 @@
import copy
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import structs
from opendbc.car import Bus, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.interfaces import CarStateBase
from opendbc.car.tesla.values import DBC, CANBUS, GEAR_MAP
@ -11,32 +11,34 @@ ButtonType = structs.CarState.ButtonEvent.Type
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
self.can_define = CANDefine(DBC[CP.carFingerprint]['pt'])
self.can_define = CANDefine(DBC[CP.carFingerprint][Bus.party])
self.hands_on_level = 0
self.das_control = None
def update(self, cp, cp_cam, *_) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
cp_party = can_parsers[Bus.party]
cp_ap_party = can_parsers[Bus.ap_party]
ret = structs.CarState()
# Vehicle speed
ret.vEgoRaw = cp.vl["DI_speed"]["DI_vehicleSpeed"] * CV.KPH_TO_MS
ret.vEgoRaw = cp_party.vl["DI_speed"]["DI_vehicleSpeed"] * CV.KPH_TO_MS
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw)
# Gas pedal
pedal_status = cp.vl["DI_systemStatus"]["DI_accelPedalPos"]
pedal_status = cp_party.vl["DI_systemStatus"]["DI_accelPedalPos"]
ret.gas = pedal_status / 100.0
ret.gasPressed = (pedal_status > 0)
# Brake pedal
ret.brake = 0
ret.brakePressed = cp.vl["IBST_status"]["IBST_driverBrakeApply"] == 2
ret.brakePressed = cp_party.vl["IBST_status"]["IBST_driverBrakeApply"] == 2
# Steering wheel
epas_status = cp.vl["EPAS3S_sysStatus"]
epas_status = cp_party.vl["EPAS3S_sysStatus"]
self.hands_on_level = epas_status["EPAS3S_handsOnLevel"]
ret.steeringAngleDeg = -epas_status["EPAS3S_internalSAS"]
ret.steeringRateDeg = -cp_cam.vl["SCCM_steeringAngleSensor"]["SCCM_steeringAngleSpeed"]
ret.steeringRateDeg = -cp_ap_party.vl["SCCM_steeringAngleSensor"]["SCCM_steeringAngleSpeed"]
ret.steeringTorque = -epas_status["EPAS3S_torsionBarTorque"]
ret.steeringPressed = self.hands_on_level > 0
@ -45,48 +47,48 @@ class CarState(CarStateBase):
ret.steerFaultTemporary = eac_status == "EAC_INHIBITED"
# Cruise state
cruise_state = self.can_define.dv["DI_state"]["DI_cruiseState"].get(int(cp.vl["DI_state"]["DI_cruiseState"]), None)
speed_units = self.can_define.dv["DI_state"]["DI_speedUnits"].get(int(cp.vl["DI_state"]["DI_speedUnits"]), None)
cruise_state = self.can_define.dv["DI_state"]["DI_cruiseState"].get(int(cp_party.vl["DI_state"]["DI_cruiseState"]), None)
speed_units = self.can_define.dv["DI_state"]["DI_speedUnits"].get(int(cp_party.vl["DI_state"]["DI_speedUnits"]), None)
ret.cruiseState.enabled = cruise_state in ("ENABLED", "STANDSTILL", "OVERRIDE", "PRE_FAULT", "PRE_CANCEL")
if speed_units == "KPH":
ret.cruiseState.speed = cp.vl["DI_state"]["DI_digitalSpeed"] * CV.KPH_TO_MS
ret.cruiseState.speed = cp_party.vl["DI_state"]["DI_digitalSpeed"] * CV.KPH_TO_MS
elif speed_units == "MPH":
ret.cruiseState.speed = cp.vl["DI_state"]["DI_digitalSpeed"] * CV.MPH_TO_MS
ret.cruiseState.speed = cp_party.vl["DI_state"]["DI_digitalSpeed"] * CV.MPH_TO_MS
ret.cruiseState.available = cruise_state == "STANDBY" or ret.cruiseState.enabled
ret.cruiseState.standstill = False # This needs to be false, since we can resume from stop without sending anything special
ret.standstill = cruise_state == "STANDSTILL"
# Gear
ret.gearShifter = GEAR_MAP[self.can_define.dv["DI_systemStatus"]["DI_gear"].get(int(cp.vl["DI_systemStatus"]["DI_gear"]), "DI_GEAR_INVALID")]
ret.gearShifter = GEAR_MAP[self.can_define.dv["DI_systemStatus"]["DI_gear"].get(int(cp_party.vl["DI_systemStatus"]["DI_gear"]), "DI_GEAR_INVALID")]
# Doors
ret.doorOpen = cp.vl["UI_warning"]["anyDoorOpen"] == 1
ret.doorOpen = cp_party.vl["UI_warning"]["anyDoorOpen"] == 1
# Blinkers
ret.leftBlinker = cp.vl["UI_warning"]["leftBlinkerOn"] != 0
ret.rightBlinker = cp.vl["UI_warning"]["rightBlinkerOn"] != 0
ret.leftBlinker = cp_party.vl["UI_warning"]["leftBlinkerOn"] != 0
ret.rightBlinker = cp_party.vl["UI_warning"]["rightBlinkerOn"] != 0
# Seatbelt
ret.seatbeltUnlatched = cp.vl["UI_warning"]["buckleStatus"] != 1
ret.seatbeltUnlatched = cp_party.vl["UI_warning"]["buckleStatus"] != 1
# Blindspot
ret.leftBlindspot = cp_cam.vl["DAS_status"]["DAS_blindSpotRearLeft"] != 0
ret.rightBlindspot = cp_cam.vl["DAS_status"]["DAS_blindSpotRearRight"] != 0
ret.leftBlindspot = cp_ap_party.vl["DAS_status"]["DAS_blindSpotRearLeft"] != 0
ret.rightBlindspot = cp_ap_party.vl["DAS_status"]["DAS_blindSpotRearRight"] != 0
# AEB
ret.stockAeb = cp_cam.vl["DAS_control"]["DAS_aebEvent"] == 1
ret.stockAeb = cp_ap_party.vl["DAS_control"]["DAS_aebEvent"] == 1
# Buttons # ToDo: add Gap adjust button
# Messages needed by carcontroller
self.das_control = copy.copy(cp_cam.vl["DAS_control"])
self.das_control = copy.copy(cp_ap_party.vl["DAS_control"])
return ret
@staticmethod
def get_can_parser(CP):
messages = [
def get_can_parsers(CP):
party_messages = [
# sig_address, frequency
("DI_speed", 50),
("DI_systemStatus", 100),
@ -96,14 +98,13 @@ class CarState(CarStateBase):
("UI_warning", 10)
]
return CANParser(DBC[CP.carFingerprint]['pt'], messages, CANBUS.party)
@staticmethod
def get_cam_can_parser(CP):
messages = [
ap_party_messages = [
("DAS_control", 25),
("DAS_status", 2),
("SCCM_steeringAngleSensor", 100),
]
return CANParser(DBC[CP.carFingerprint]['pt'], messages, CANBUS.autopilot_party)
return {
Bus.party: CANParser(DBC[CP.carFingerprint][Bus.party], party_messages, CANBUS.party),
Bus.ap_party: CANParser(DBC[CP.carFingerprint][Bus.party], ap_party_messages, CANBUS.autopilot_party)
}

View File

@ -1,22 +1,23 @@
from enum import IntFlag
from opendbc.car.structs import CarParams
from opendbc.car import structs
from opendbc.car import AngleRateLimit, CarSpecs, PlatformConfig, Platforms, dbc_dict
from opendbc.car import Bus, structs
from opendbc.car import AngleRateLimit, CarSpecs, PlatformConfig, Platforms
from opendbc.car.docs_definitions import CarDocs
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
Ecu = CarParams.Ecu
class CAR(Platforms):
TESLA_MODEL_3 = PlatformConfig(
[CarDocs("Tesla Model 3", "All")],
CarSpecs(mass=1899., wheelbase=2.875, steerRatio=12.0),
dbc_dict('tesla_model3_party', None)
{Bus.party: 'tesla_model3_party'},
)
TESLA_MODEL_Y = PlatformConfig(
[CarDocs("Tesla Model Y", "All")],
CarSpecs(mass=2072., wheelbase=2.890, steerRatio=12.0),
dbc_dict('tesla_model3_party', None)
{Bus.party: 'tesla_model3_party'},
)

View File

@ -9,7 +9,7 @@ class TestPlatformConfigs:
assert platform.config._frozen
if platform != "MOCK":
assert "pt" in platform.config.dbc_dict
assert len(platform.config.dbc_dict) > 0
assert len(platform.config.platform_str) > 0
assert name == platform.config.platform_str

View File

@ -1,5 +1,5 @@
import math
from opendbc.car import carlog, apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, \
from opendbc.car import Bus, carlog, apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, \
make_tester_present_msg, rate_limit, structs, ACCELERATION_DUE_TO_GRAVITY, DT_CTRL
from opendbc.car.can_definitions import CanData
from opendbc.car.common.filter_simple import FirstOrderFilter
@ -36,8 +36,8 @@ MAX_LTA_DRIVER_TORQUE_ALLOWANCE = 150 # slightly above steering pressed allows
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.params = CarControllerParams(self.CP)
self.last_steer = 0
self.last_angle = 0
@ -50,7 +50,7 @@ class CarController(CarControllerBase):
self.pcm_accel_compensation = FirstOrderFilter(0, 0.5, DT_CTRL * 3)
self.permit_braking = True
self.packer = CANPacker(dbc_name)
self.packer = CANPacker(dbc_names[Bus.pt])
self.accel = 0
self.prev_accel = 0

View File

@ -2,7 +2,7 @@ import copy
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import DT_CTRL, create_button_events, structs
from opendbc.car import Bus, DT_CTRL, create_button_events, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.common.filter_simple import FirstOrderFilter
from opendbc.car.common.numpy_fast import mean
@ -28,7 +28,7 @@ PERM_STEER_FAULTS = (3, 17)
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
self.eps_torque_scale = EPS_SCALE[CP.carFingerprint] / 100.
self.cluster_speed_hyst_gap = CV.KPH_TO_MS / 2.
self.cluster_min_speed = CV.KPH_TO_MS / 2.
@ -53,7 +53,10 @@ class CarState(CarStateBase):
self.pcm_accel_net = 0.0
self.secoc_synchronization = None
def update(self, cp, cp_cam, *_) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
ret = structs.CarState()
cp_acc = cp_cam if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) else cp
@ -202,8 +205,8 @@ class CarState(CarStateBase):
return ret
@staticmethod
def get_can_parser(CP):
messages = [
def get_can_parsers(CP):
pt_messages = [
("LIGHT_STALK", 1),
("BLINKERS_STATE", 0.15),
("BODY_CONTROL_STATE", 3),
@ -219,63 +222,61 @@ class CarState(CarStateBase):
]
if CP.flags & ToyotaFlags.SECOC.value:
messages += [
pt_messages += [
("GEAR_PACKET_HYBRID", 60),
("SECOC_SYNCHRONIZATION", 10),
("GAS_PEDAL", 42),
]
else:
if CP.carFingerprint not in [CAR.TOYOTA_MIRAI]:
messages.append(("ENGINE_RPM", 42))
pt_messages.append(("ENGINE_RPM", 42))
messages += [
pt_messages += [
("GEAR_PACKET", 1),
]
if CP.carFingerprint in (TSS2_CAR - SECOC_CAR - {CAR.LEXUS_NX_TSS2, CAR.TOYOTA_ALPHARD_TSS2, CAR.LEXUS_IS_TSS2}):
messages.append(("CLUTCH", 15))
pt_messages.append(("CLUTCH", 15))
if CP.carFingerprint in UNSUPPORTED_DSU_CAR:
messages.append(("DSU_CRUISE", 5))
messages.append(("PCM_CRUISE_ALT", 1))
pt_messages.append(("DSU_CRUISE", 5))
pt_messages.append(("PCM_CRUISE_ALT", 1))
else:
messages.append(("PCM_CRUISE_2", 33))
pt_messages.append(("PCM_CRUISE_2", 33))
if CP.enableBsm:
messages.append(("BSM", 1))
pt_messages.append(("BSM", 1))
if CP.carFingerprint in RADAR_ACC_CAR and not CP.flags & ToyotaFlags.DISABLE_RADAR.value:
messages += [
pt_messages += [
("PCS_HUD", 1),
("ACC_CONTROL", 33),
]
if CP.carFingerprint not in (TSS2_CAR - RADAR_ACC_CAR) and not CP.enableDsu and not CP.flags & ToyotaFlags.DISABLE_RADAR.value:
messages += [
pt_messages += [
("PRE_COLLISION", 33),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0)
@staticmethod
def get_cam_can_parser(CP):
messages = []
cam_messages = []
if CP.carFingerprint != CAR.TOYOTA_PRIUS_V:
messages += [
cam_messages += [
("LKAS_HUD", 1),
]
if CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR):
messages += [
cam_messages += [
("ACC_CONTROL", 33),
("PCS_HUD", 1),
]
# TODO: Figure out new layout of the PRE_COLLISION message
if not CP.flags & ToyotaFlags.SECOC.value:
messages += [
cam_messages += [
("PRE_COLLISION", 33),
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 2)
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, 0),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, 2),
}

View File

@ -1,6 +1,6 @@
from panda import Panda
from panda import uds
from opendbc.car import structs, get_safety_config
from opendbc.car import Bus, structs, get_safety_config
from opendbc.car.toyota.values import Ecu, CAR, DBC, ToyotaFlags, CarControllerParams, TSS2_CAR, RADAR_ACC_CAR, NO_DSU_CAR, \
MIN_ACC_SPEED, EPS_SCALE, UNSUPPORTED_DSU_CAR, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR
from opendbc.car.disable_ecu import disable_ecu
@ -21,7 +21,7 @@ class CarInterface(CarInterfaceBase):
ret.safetyConfigs[0].safetyParam = EPS_SCALE[candidate]
# BRAKE_MODULE is on a different address for these cars
if DBC[candidate]["pt"] == "toyota_new_mc_pt_generated":
if DBC[candidate][Bus.pt] == "toyota_new_mc_pt_generated":
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_TOYOTA_ALT_BRAKE
if ret.flags & ToyotaFlags.SECOC.value:
@ -101,7 +101,7 @@ class CarInterface(CarInterfaceBase):
# No radar dbc for cars without DSU which are not TSS 2.0
# TODO: make an adas dbc file for dsu-less models
ret.radarUnavailable = DBC[candidate]['radar'] is None or candidate in (NO_DSU_CAR - TSS2_CAR)
ret.radarUnavailable = Bus.radar not in DBC[candidate] or candidate in (NO_DSU_CAR - TSS2_CAR)
# since we don't yet parse radar on TSS2/TSS-P radar-based ACC cars, gate longitudinal behind experimental toggle
if candidate in (RADAR_ACC_CAR | NO_DSU_CAR):

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3
from opendbc.can.parser import CANParser
from opendbc.car import Bus
from opendbc.car.structs import RadarData
from opendbc.car.toyota.values import DBC, TSS2_CAR
from opendbc.car.interfaces import RadarInterfaceBase
@ -17,7 +18,7 @@ def _create_radar_can_parser(car_fingerprint):
msg_b_n = len(RADAR_B_MSGS)
messages = list(zip(RADAR_A_MSGS + RADAR_B_MSGS, [20] * (msg_a_n + msg_b_n), strict=True))
return CANParser(DBC[car_fingerprint]['radar'], messages, 1)
return CANParser(DBC[car_fingerprint][Bus.radar], messages, 1)
class RadarInterface(RadarInterfaceBase):
def __init__(self, CP):

View File

@ -1,5 +1,6 @@
from hypothesis import given, settings, strategies as st
from opendbc.car import Bus
from opendbc.car.structs import CarParams
from opendbc.car.fw_versions import build_fw_dict
from opendbc.car.toyota.fingerprints import FW_VERSIONS
@ -29,7 +30,7 @@ class TestToyotaInterfaces:
# like looking up certain signals only in this DBC
for car_model, dbc in DBC.items():
if car_model in TSS2_CAR and car_model not in SECOC_CAR:
assert dbc["pt"] == "toyota_nodsu_pt_generated"
assert dbc[Bus.pt] == "toyota_nodsu_pt_generated"
def test_essential_ecus(self, subtests):
# Asserts standard ECUs exist for each platform

View File

@ -3,7 +3,7 @@ from collections import defaultdict
from dataclasses import dataclass, field
from enum import Enum, IntFlag
from opendbc.car import CarSpecs, PlatformConfig, Platforms, AngleRateLimit, dbc_dict
from opendbc.car import Bus, CarSpecs, PlatformConfig, Platforms, AngleRateLimit
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarFootnote, CarDocs, Column, CarParts, CarHarness
@ -73,6 +73,8 @@ class ToyotaCarDocs(CarDocs):
package: str = "All"
car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.toyota_a]))
def dbc_dict(pt, radar):
return {Bus.pt: pt, Bus.radar: radar}
@dataclass
class ToyotaTSS2PlatformConfig(PlatformConfig):
@ -82,7 +84,7 @@ class ToyotaTSS2PlatformConfig(PlatformConfig):
self.flags |= ToyotaFlags.TSS2 | ToyotaFlags.NO_STOP_TIMER | ToyotaFlags.NO_DSU
if self.flags & ToyotaFlags.RADAR_ACC:
self.dbc_dict = dbc_dict('toyota_nodsu_pt_generated', None)
self.dbc_dict = {Bus.pt: 'toyota_nodsu_pt_generated'}
class CAR(Platforms):

View File

@ -1,5 +1,5 @@
from opendbc.can.packer import CANPacker
from opendbc.car import DT_CTRL, apply_driver_steer_torque_limits, structs
from opendbc.car import Bus, DT_CTRL, apply_driver_steer_torque_limits, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.common.numpy_fast import clip
from opendbc.car.interfaces import CarControllerBase
@ -11,11 +11,11 @@ LongCtrlState = structs.CarControl.Actuators.LongControlState
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
self.CCP = CarControllerParams(CP)
self.CCS = pqcan if CP.flags & VolkswagenFlags.PQ else mqbcan
self.packer_pt = CANPacker(dbc_name)
self.packer_pt = CANPacker(dbc_names[Bus.pt])
self.ext_bus = CANBUS.pt if CP.networkLocation == structs.CarParams.NetworkLocation.fwdCamera else CANBUS.cam
self.apply_steer_last = 0

View File

@ -1,6 +1,6 @@
import numpy as np
from opendbc.can.parser import CANParser
from opendbc.car import structs
from opendbc.car import Bus, structs
from opendbc.car.interfaces import CarStateBase
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.volkswagen.values import DBC, CANBUS, NetworkLocation, TransmissionType, GearShifter, \
@ -32,8 +32,9 @@ class CarState(CarStateBase):
return button_events
def update(self, pt_cp, cam_cp, *_) -> structs.CarState:
def update(self, can_parsers) -> structs.CarState:
pt_cp = can_parsers[Bus.pt]
cam_cp = can_parsers[Bus.cam]
ext_cp = pt_cp if self.CP.networkLocation == NetworkLocation.fwdCamera else cam_cp
if self.CP.flags & VolkswagenFlags.PQ:
@ -266,11 +267,11 @@ class CarState(CarStateBase):
return temp_fault, perm_fault
@staticmethod
def get_can_parser(CP):
def get_can_parsers(CP):
if CP.flags & VolkswagenFlags.PQ:
return CarState.get_can_parser_pq(CP)
return CarState.get_can_parsers_pq(CP)
messages = [
pt_messages = [
# sig_address, frequency
("LWI_01", 100), # From J500 Steering Assist with integrated sensors
("LH_EPS_03", 100), # From J500 Steering Assist with integrated sensors
@ -290,46 +291,41 @@ class CarState(CarStateBase):
]
if CP.transmissionType == TransmissionType.automatic:
messages.append(("Getriebe_11", 20)) # From J743 Auto transmission control module
pt_messages.append(("Getriebe_11", 20)) # From J743 Auto transmission control module
elif CP.transmissionType == TransmissionType.direct:
messages.append(("Motor_EV_01", 10)) # From J??? unknown EV control module
pt_messages.append(("Motor_EV_01", 10)) # From J??? unknown EV control module
if CP.networkLocation == NetworkLocation.fwdCamera:
# Radars are here on CANBUS.pt
messages += MqbExtraSignals.fwd_radar_messages
pt_messages += MqbExtraSignals.fwd_radar_messages
if CP.enableBsm:
messages += MqbExtraSignals.bsm_radar_messages
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CANBUS.pt)
@staticmethod
def get_cam_can_parser(CP):
if CP.flags & VolkswagenFlags.PQ:
return CarState.get_cam_can_parser_pq(CP)
messages = []
pt_messages += MqbExtraSignals.bsm_radar_messages
cam_messages = []
if CP.flags & VolkswagenFlags.STOCK_HCA_PRESENT:
messages += [
cam_messages += [
("HCA_01", 1), # From R242 Driver assistance camera, 50Hz if steering/1Hz if not
]
if CP.networkLocation == NetworkLocation.fwdCamera:
messages += [
cam_messages += [
# sig_address, frequency
("LDW_02", 10) # From R242 Driver assistance camera
]
else:
# Radars are here on CANBUS.cam
messages += MqbExtraSignals.fwd_radar_messages
cam_messages += MqbExtraSignals.fwd_radar_messages
if CP.enableBsm:
messages += MqbExtraSignals.bsm_radar_messages
cam_messages += MqbExtraSignals.bsm_radar_messages
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CANBUS.cam)
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, CANBUS.pt),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, CANBUS.cam),
}
@staticmethod
def get_can_parser_pq(CP):
messages = [
def get_can_parsers_pq(CP):
pt_messages = [
# sig_address, frequency
("Bremse_1", 100), # From J104 ABS/ESP controller
("Bremse_3", 100), # From J104 ABS/ESP controller
@ -347,36 +343,33 @@ class CarState(CarStateBase):
]
if CP.transmissionType == TransmissionType.automatic:
messages += [("Getriebe_1", 100)] # From J743 Auto transmission control module
pt_messages += [("Getriebe_1", 100)] # From J743 Auto transmission control module
elif CP.transmissionType == TransmissionType.manual:
messages += [("Motor_1", 100)] # From J623 Engine control module
pt_messages += [("Motor_1", 100)] # From J623 Engine control module
if CP.networkLocation == NetworkLocation.fwdCamera:
# Extended CAN devices other than the camera are here on CANBUS.pt
messages += PqExtraSignals.fwd_radar_messages
pt_messages += PqExtraSignals.fwd_radar_messages
if CP.enableBsm:
messages += PqExtraSignals.bsm_radar_messages
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CANBUS.pt)
@staticmethod
def get_cam_can_parser_pq(CP):
messages = []
pt_messages += PqExtraSignals.bsm_radar_messages
cam_messages = []
if CP.networkLocation == NetworkLocation.fwdCamera:
messages += [
cam_messages += [
# sig_address, frequency
("LDW_Status", 10) # From R242 Driver assistance camera
]
if CP.networkLocation == NetworkLocation.gateway:
# Radars are here on CANBUS.cam
messages += PqExtraSignals.fwd_radar_messages
cam_messages += PqExtraSignals.fwd_radar_messages
if CP.enableBsm:
messages += PqExtraSignals.bsm_radar_messages
cam_messages += PqExtraSignals.bsm_radar_messages
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CANBUS.cam)
return {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, CANBUS.pt),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, CANBUS.cam),
}
class MqbExtraSignals:

View File

@ -4,7 +4,7 @@ from enum import Enum, IntFlag, StrEnum
from panda import uds
from opendbc.can.can_define import CANDefine
from opendbc.car import dbc_dict, CarSpecs, DbcDict, PlatformConfig, Platforms
from opendbc.car import Bus, CarSpecs, DbcDict, PlatformConfig, Platforms
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car import structs
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \
@ -40,7 +40,7 @@ class CarControllerParams:
ACCEL_MIN = -3.5 # 3.5 m/s max deceleration
def __init__(self, CP):
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
if CP.flags & VolkswagenFlags.PQ:
self.LDW_STEP = 5 # LDW_1 message frequency 20Hz
@ -142,7 +142,7 @@ class VolkswagenFlags(IntFlag):
@dataclass
class VolkswagenMQBPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('vw_mqb_2010', None))
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: 'vw_mqb_2010'})
# Volkswagen uses the VIN WMI and chassis code to match in the absence of the comma power
# on camera-integrated cars, as we lose too many ECUs to reliably identify the vehicle
chassis_codes: set[str] = field(default_factory=set)
@ -151,7 +151,7 @@ class VolkswagenMQBPlatformConfig(PlatformConfig):
@dataclass
class VolkswagenPQPlatformConfig(VolkswagenMQBPlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('vw_golf_mk4', None))
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: 'vw_golf_mk4'})
def init(self):
self.flags |= VolkswagenFlags.PQ