VW MQB: UDS fingerprinting support (#20271)
* FPv2 support for MQB * Comment touch-ups * Trim extra newlines * Add Atlas and Tiguan * Update submodule ref * Revert "Add Atlas and Tiguan" This reverts commitpull/20478/heada47bc1bca7
. * Curb my enthusiasm * Drop ABS/ESP from UDS fingerprinting for now * Use multi-query to grab SW build ID and parameterization * Resolve merge oops * Resolve merge conflicts * Make Ecu.fwdCamera optional for VW * Where'd that come from? * Propitiate process replay checks until ready for model dump * FW values for Audi A3 Prestige * Revert "Make Ecu.fwdCamera optional for VW" This reverts commit56852b99
* Don't try to FP fwdCamera for VW * Remove FW comments * Simplify RX offset handling * Corrected scoping for MQB trans detection * Add default response_offset * Remove explicit list of MQB vehicles for now * Deal with pylint warning * Clarify and simplify comments Co-authored-by: Comma Device <device@comma.ai> Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
parent
4d377851a3
commit
e7fc11c7fb
|
@ -56,50 +56,78 @@ HYUNDAI_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x4
|
|||
TOYOTA_VERSION_REQUEST = b'\x1a\x88\x01'
|
||||
TOYOTA_VERSION_RESPONSE = b'\x5a\x88\x01'
|
||||
|
||||
VOLKSWAGEN_VERSION_REQUEST_MULTI = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \
|
||||
p16(uds.DATA_IDENTIFIER_TYPE.VEHICLE_MANUFACTURER_SPARE_PART_NUMBER) + \
|
||||
p16(uds.DATA_IDENTIFIER_TYPE.VEHICLE_MANUFACTURER_ECU_SOFTWARE_VERSION_NUMBER) + \
|
||||
p16(uds.DATA_IDENTIFIER_TYPE.APPLICATION_DATA_IDENTIFICATION)
|
||||
VOLKSWAGEN_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40])
|
||||
|
||||
OBD_VERSION_REQUEST = b'\x09\x04'
|
||||
OBD_VERSION_RESPONSE = b'\x49\x04'
|
||||
|
||||
DEFAULT_RX_OFFSET = 0x8
|
||||
VOLKSWAGEN_RX_OFFSET = 0x6a
|
||||
|
||||
# supports subaddressing, request, response
|
||||
# brand, request, response, response offset
|
||||
REQUESTS = [
|
||||
# Hundai
|
||||
# Hyundai
|
||||
(
|
||||
"hyundai",
|
||||
[HYUNDAI_VERSION_REQUEST_SHORT],
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
DEFAULT_RX_OFFSET,
|
||||
),
|
||||
(
|
||||
"hyundai",
|
||||
[HYUNDAI_VERSION_REQUEST_LONG],
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
DEFAULT_RX_OFFSET,
|
||||
),
|
||||
(
|
||||
"hyundai",
|
||||
[HYUNDAI_VERSION_REQUEST_MULTI],
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
DEFAULT_RX_OFFSET,
|
||||
),
|
||||
# Honda
|
||||
(
|
||||
"honda",
|
||||
[UDS_VERSION_REQUEST],
|
||||
[UDS_VERSION_RESPONSE],
|
||||
DEFAULT_RX_OFFSET,
|
||||
),
|
||||
# Toyota
|
||||
(
|
||||
"toyota",
|
||||
[SHORT_TESTER_PRESENT_REQUEST, TOYOTA_VERSION_REQUEST],
|
||||
[SHORT_TESTER_PRESENT_RESPONSE, TOYOTA_VERSION_RESPONSE],
|
||||
DEFAULT_RX_OFFSET,
|
||||
),
|
||||
(
|
||||
"toyota",
|
||||
[SHORT_TESTER_PRESENT_REQUEST, OBD_VERSION_REQUEST],
|
||||
[SHORT_TESTER_PRESENT_RESPONSE, OBD_VERSION_RESPONSE],
|
||||
DEFAULT_RX_OFFSET,
|
||||
),
|
||||
(
|
||||
"toyota",
|
||||
[TESTER_PRESENT_REQUEST, DEFAULT_DIAGNOSTIC_REQUEST, EXTENDED_DIAGNOSTIC_REQUEST, UDS_VERSION_REQUEST],
|
||||
[TESTER_PRESENT_RESPONSE, DEFAULT_DIAGNOSTIC_RESPONSE, EXTENDED_DIAGNOSTIC_RESPONSE, UDS_VERSION_RESPONSE],
|
||||
)
|
||||
DEFAULT_RX_OFFSET,
|
||||
),
|
||||
# Volkswagen
|
||||
(
|
||||
"volkswagen",
|
||||
[VOLKSWAGEN_VERSION_REQUEST_MULTI],
|
||||
[VOLKSWAGEN_VERSION_RESPONSE],
|
||||
VOLKSWAGEN_RX_OFFSET,
|
||||
),
|
||||
(
|
||||
"volkswagen",
|
||||
[VOLKSWAGEN_VERSION_REQUEST_MULTI],
|
||||
[VOLKSWAGEN_VERSION_RESPONSE],
|
||||
DEFAULT_RX_OFFSET,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
@ -173,12 +201,12 @@ def get_fw_versions(logcan, sendcan, bus, extra=None, timeout=0.1, debug=False,
|
|||
fw_versions = {}
|
||||
for i, addr in enumerate(tqdm(addrs, disable=not progress)):
|
||||
for addr_chunk in chunks(addr):
|
||||
for brand, request, response in REQUESTS:
|
||||
for brand, request, response, response_offset in REQUESTS:
|
||||
try:
|
||||
addrs = [(a, s) for (b, a, s) in addr_chunk if b in (brand, 'any')]
|
||||
|
||||
if addrs:
|
||||
query = IsoTpParallelQuery(sendcan, logcan, bus, addrs, request, response, debug=debug)
|
||||
query = IsoTpParallelQuery(sendcan, logcan, bus, addrs, request, response, response_offset, debug=debug)
|
||||
t = 2 * timeout if i == 0 else timeout
|
||||
fw_versions.update(query.get_data(t))
|
||||
except Exception:
|
||||
|
|
|
@ -9,7 +9,7 @@ from panda.python.uds import CanClient, IsoTpMessage, FUNCTIONAL_ADDRS, get_rx_a
|
|||
|
||||
|
||||
class IsoTpParallelQuery():
|
||||
def __init__(self, sendcan, logcan, bus, addrs, request, response, functional_addr=False, debug=False):
|
||||
def __init__(self, sendcan, logcan, bus, addrs, request, response, response_offset=0x8, functional_addr=False, debug=False):
|
||||
self.sendcan = sendcan
|
||||
self.logcan = logcan
|
||||
self.bus = bus
|
||||
|
@ -25,7 +25,7 @@ class IsoTpParallelQuery():
|
|||
else:
|
||||
self.real_addrs.append((a, None))
|
||||
|
||||
self.msg_addrs = {tx_addr: get_rx_addr_for_tx_addr(tx_addr[0]) for tx_addr in self.real_addrs}
|
||||
self.msg_addrs = {tx_addr: get_rx_addr_for_tx_addr(tx_addr[0], rx_offset=response_offset) for tx_addr in self.real_addrs}
|
||||
self.msg_buffer = defaultdict(list)
|
||||
|
||||
def rx(self):
|
||||
|
|
|
@ -25,42 +25,47 @@ class CarInterface(CarInterfaceBase):
|
|||
# VW port is a community feature, since we don't own one to test
|
||||
ret.communityFeature = True
|
||||
|
||||
if candidate in [CAR.GOLF, CAR.AUDI_A3]:
|
||||
if True: # pylint: disable=using-constant-test
|
||||
# Set common MQB parameters that will apply globally
|
||||
ret.carName = "volkswagen"
|
||||
ret.radarOffCan = True
|
||||
ret.safetyModel = car.CarParams.SafetyModel.volkswagen
|
||||
ret.steerActuatorDelay = 0.05
|
||||
|
||||
# Additional common MQB parameters that may be overridden per-vehicle
|
||||
ret.steerRateCost = 1.0
|
||||
ret.steerActuatorDelay = 0.05 # Hopefully all MQB racks are similar here
|
||||
ret.steerLimitTimer = 0.4
|
||||
if 0xAD in fingerprint[0]:
|
||||
# Getriebe_11 detected: traditional automatic or DSG gearbox
|
||||
ret.transmissionType = TransmissionType.automatic
|
||||
elif 0x187 in fingerprint[0]:
|
||||
# EV_Gearshift detected: e-Golf or similar direct-drive electric
|
||||
ret.transmissionType = TransmissionType.direct
|
||||
else:
|
||||
# No trans message at all, must be a true stick-shift manual
|
||||
ret.transmissionType = TransmissionType.manual
|
||||
cloudlog.info("Detected transmission type: %s", ret.transmissionType)
|
||||
|
||||
ret.lateralTuning.pid.kpBP = [0.]
|
||||
ret.lateralTuning.pid.kiBP = [0.]
|
||||
# Global tuning defaults, can be overridden per-vehicle
|
||||
|
||||
ret.steerRateCost = 1.0
|
||||
ret.steerLimitTimer = 0.4
|
||||
ret.steerRatio = 15.6 # Let the params learner figure this out
|
||||
tire_stiffness_factor = 1.0 # Let the params learner figure this out
|
||||
ret.lateralTuning.pid.kpBP = [0.]
|
||||
ret.lateralTuning.pid.kiBP = [0.]
|
||||
ret.lateralTuning.pid.kf = 0.00006
|
||||
ret.lateralTuning.pid.kpV = [0.6]
|
||||
ret.lateralTuning.pid.kiV = [0.2]
|
||||
|
||||
# Per-chassis tuning values, override tuning defaults here if desired
|
||||
|
||||
if candidate in [CAR.AUDI_A3, CAR.GOLF]:
|
||||
# Temporarily carry forward old tuning values while we test vehicle identification
|
||||
ret.mass = 1500 + STD_CARGO_KG
|
||||
ret.wheelbase = 2.64
|
||||
ret.centerToFront = ret.wheelbase * 0.45
|
||||
ret.steerRatio = 15.6
|
||||
ret.lateralTuning.pid.kf = 0.00006
|
||||
ret.lateralTuning.pid.kpV = [0.6]
|
||||
ret.lateralTuning.pid.kiV = [0.2]
|
||||
tire_stiffness_factor = 1.0
|
||||
|
||||
ret.centerToFront = ret.wheelbase * 0.45
|
||||
|
||||
ret.enableCamera = True # Stock camera detection doesn't apply to VW
|
||||
|
||||
if 0xAD in fingerprint[0]:
|
||||
# Getriebe_11 detected: traditional automatic or DSG gearbox
|
||||
ret.transmissionType = TransmissionType.automatic
|
||||
elif 0x187 in fingerprint[0]:
|
||||
# EV_Gearshift detected: e-Golf or similar direct-drive electric
|
||||
ret.transmissionType = TransmissionType.direct
|
||||
else:
|
||||
# No trans message at all, must be a true stick-shift manual
|
||||
ret.transmissionType = TransmissionType.manual
|
||||
cloudlog.info("Detected transmission type: %s", ret.transmissionType)
|
||||
|
||||
# TODO: get actual value, for now starting with reasonable value for
|
||||
# civic and scaling by mass and wheelbase
|
||||
ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# flake8: noqa
|
||||
|
||||
from cereal import car
|
||||
from selfdrive.car import dbc_dict
|
||||
from cereal import car
|
||||
Ecu = car.CarParams.Ecu
|
||||
|
||||
class CarControllerParams:
|
||||
HCA_STEP = 2 # HCA_01 message frequency 50Hz
|
||||
|
@ -49,9 +50,13 @@ MQB_LDW_MESSAGES = {
|
|||
"laneAssistDeactivated": 10, # "Lane Assist deactivated." silent with persistent icon afterward
|
||||
}
|
||||
|
||||
# Check the 7th and 8th characters of the VIN before adding a new CAR. If the
|
||||
# chassis code is already listed below, don't add a new CAR, just add to the
|
||||
# FW_VERSIONS for that existing CAR.
|
||||
|
||||
class CAR:
|
||||
GOLF = "VOLKSWAGEN GOLF"
|
||||
AUDI_A3 = "AUDI A3"
|
||||
GOLF = "VOLKSWAGEN GOLF" # Chassis 5G/AU/BA/BE, Mk7 VW Golf and variants
|
||||
AUDI_A3 = "AUDI A3" # Chassis 8V/FF, Mk3 Audi A3 and variants
|
||||
|
||||
FINGERPRINTS = {
|
||||
CAR.GOLF: [{
|
||||
|
@ -62,6 +67,43 @@ FINGERPRINTS = {
|
|||
}],
|
||||
}
|
||||
|
||||
FW_VERSIONS = {
|
||||
CAR.AUDI_A3: {
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\xf1\x875G0906259L \xf1\x890002',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'\xf1\x870D9300013B \xf1\x894931',
|
||||
],
|
||||
(Ecu.srs, 0x715, None): [
|
||||
b'\xf1\x875Q0959655J \xf1\x890830\xf1\x82\023121111111211--261117141112231291163221',
|
||||
],
|
||||
(Ecu.eps, 0x712, None): [
|
||||
b'\xf1\x875Q0909144T \xf1\x891072\xf1\x82\00521G00807A1',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x757, None): [
|
||||
b'\xf1\x875Q0907572G \xf1\x890571',
|
||||
],
|
||||
},
|
||||
CAR.GOLF: {
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\xf1\x878V0906259P \xf1\x890001',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'\xf1\x870GC300012A \xf1\x891403',
|
||||
],
|
||||
(Ecu.srs, 0x715, None): [
|
||||
b'\xf1\x875Q0959655J \xf1\x890830\xf1\x82\x13271212111312--071104171838103891131211',
|
||||
],
|
||||
(Ecu.eps, 0x712, None): [
|
||||
b'\xf1\x873Q0909144L \xf1\x895081\xf1\x82\x0571A0JA15A1',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x757, None): [
|
||||
b'\xf1\x875Q0907572J \xf1\x890654',
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
DBC = {
|
||||
CAR.GOLF: dbc_dict('vw_mqb_2010', None),
|
||||
CAR.AUDI_A3: dbc_dict('vw_mqb_2010', None),
|
||||
|
|
Loading…
Reference in New Issue