Merge remote-tracking branch 'commaai/master' into ford-platform-codes

pull/31124/head
Cameron Clough 2 years ago
commit be72ef3219
  1. 4
      selfdrive/car/__init__.py
  2. 1
      selfdrive/car/ford/tests/test_ford.py
  3. 50
      selfdrive/car/ford/values.py
  4. 2
      selfdrive/car/gm/values.py
  5. 19
      selfdrive/car/interfaces.py
  6. 2
      selfdrive/car/subaru/values.py
  7. 6
      selfdrive/car/tests/test_fw_fingerprint.py
  8. 3
      selfdrive/car/toyota/fingerprints.py
  9. 6
      selfdrive/car/volkswagen/values.py
  10. 1
      system/hardware/tici/amplifier.py
  11. 6
      system/hardware/tici/hardware.h

@ -246,7 +246,7 @@ class CanSignalRateCalculator:
CarInfos = CarInfo | list[CarInfo] CarInfos = CarInfo | list[CarInfo]
@dataclass(kw_only=True) @dataclass(frozen=True, kw_only=True)
class CarSpecs: class CarSpecs:
mass: float mass: float
wheelbase: float wheelbase: float
@ -256,7 +256,7 @@ class CarSpecs:
minEnableSpeed: float = field(default=-1.) minEnableSpeed: float = field(default=-1.)
@dataclass(order=True) @dataclass(frozen=True, order=True)
class PlatformConfig: class PlatformConfig:
platform_str: str platform_str: str
car_info: CarInfos car_info: CarInfos

@ -20,6 +20,7 @@ ECU_ADDRESSES = {
Ecu.fwdCamera: 0x706, # Image Processing Module A (IPMA) Ecu.fwdCamera: 0x706, # Image Processing Module A (IPMA)
Ecu.engine: 0x7E0, # Powertrain Control Module (PCM) Ecu.engine: 0x7E0, # Powertrain Control Module (PCM)
Ecu.shiftByWire: 0x732, # Gear Shift Module (GSM) Ecu.shiftByWire: 0x732, # Gear Shift Module (GSM)
Ecu.debug: 0x7D0, # Accessory Protocol Interface Module (APIM)
} }

@ -3,11 +3,12 @@ from collections import defaultdict
from dataclasses import dataclass, field from dataclasses import dataclass, field
from enum import Enum from enum import Enum
import panda.python.uds as uds
from cereal import car from cereal import car
from openpilot.selfdrive.car import AngleRateLimit, CarSpecs, dbc_dict, DbcDict, PlatformConfig, Platforms from openpilot.selfdrive.car import AngleRateLimit, CarSpecs, dbc_dict, DbcDict, PlatformConfig, Platforms
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column, \ from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column, \
Device Device
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, LiveFwVersions, OfflineFwVersions, Request, StdQueries from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, LiveFwVersions, OfflineFwVersions, Request, StdQueries, p16
Ecu = car.CarParams.Ecu Ecu = car.CarParams.Ecu
@ -65,7 +66,7 @@ class FordCarInfo(CarInfo):
self.car_parts = CarParts([Device.threex, harness]) self.car_parts = CarParts([Device.threex, harness])
@dataclass @dataclass(frozen=True)
class FordPlatformConfig(PlatformConfig): 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: dbc_dict('ford_lincoln_base_pt', RADAR.DELPHI_MRR))
@ -142,7 +143,6 @@ class CAR(Platforms):
CANFD_CAR = {CAR.F_150_MK14, CAR.F_150_LIGHTNING_MK1, CAR.MUSTANG_MACH_E_MK1} CANFD_CAR = {CAR.F_150_MK14, CAR.F_150_LIGHTNING_MK1, CAR.MUSTANG_MACH_E_MK1}
# FW response contains a combined software and part number # FW response contains a combined software and part number
# A-Z except no I, O or W # A-Z except no I, O or W
# e.g. NZ6A-14C204-AAA # e.g. NZ6A-14C204-AAA
@ -234,9 +234,37 @@ def match_fw_to_car_fuzzy(live_fw_versions: LiveFwVersions, offline_fw_versions:
return candidates return candidates
# All of these ECUs must be present and are expected to have platform codes we can match # All of these ECUs must be present and are expected to have platform codes we can match
PLATFORM_CODE_ECUS = (Ecu.abs, Ecu.fwdCamera, Ecu.fwdRadar, Ecu.eps) PLATFORM_CODE_ECUS = (Ecu.abs, Ecu.fwdCamera, Ecu.fwdRadar, Ecu.eps)
DATA_IDENTIFIER_FORD_ASBUILT = 0xDE
ASBUILT_BLOCKS: list[tuple[int, list]] = [
(1, [Ecu.debug, Ecu.fwdCamera, Ecu.eps]),
(2, [Ecu.abs, Ecu.debug, Ecu.eps]),
(3, [Ecu.abs, Ecu.debug, Ecu.eps]),
(4, [Ecu.debug, Ecu.fwdCamera]),
(5, [Ecu.debug]),
(6, [Ecu.debug]),
(7, [Ecu.debug]),
(8, [Ecu.debug]),
(9, [Ecu.debug]),
(16, [Ecu.debug, Ecu.fwdCamera]),
(18, [Ecu.fwdCamera]),
(20, [Ecu.fwdCamera]),
(21, [Ecu.fwdCamera]),
]
def ford_asbuilt_block_request(block_id: int):
return bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + p16(DATA_IDENTIFIER_FORD_ASBUILT + block_id - 1)
def ford_asbuilt_block_response(block_id: int):
return bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40]) + p16(DATA_IDENTIFIER_FORD_ASBUILT + block_id - 1)
FW_QUERY_CONFIG = FwQueryConfig( FW_QUERY_CONFIG = FwQueryConfig(
requests=[ requests=[
# CAN and CAN FD queries are combined. # CAN and CAN FD queries are combined.
@ -244,19 +272,29 @@ FW_QUERY_CONFIG = FwQueryConfig(
Request( Request(
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.MANUFACTURER_SOFTWARE_VERSION_REQUEST], [StdQueries.TESTER_PRESENT_REQUEST, StdQueries.MANUFACTURER_SOFTWARE_VERSION_REQUEST],
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.MANUFACTURER_SOFTWARE_VERSION_RESPONSE], [StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.MANUFACTURER_SOFTWARE_VERSION_RESPONSE],
whitelist_ecus=[Ecu.abs, Ecu.debug, Ecu.engine, Ecu.eps, Ecu.fwdCamera, Ecu.fwdRadar, Ecu.shiftByWire],
logging=True, logging=True,
), ),
Request( Request(
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.MANUFACTURER_SOFTWARE_VERSION_REQUEST], [StdQueries.TESTER_PRESENT_REQUEST, StdQueries.MANUFACTURER_SOFTWARE_VERSION_REQUEST],
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.MANUFACTURER_SOFTWARE_VERSION_RESPONSE], [StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.MANUFACTURER_SOFTWARE_VERSION_RESPONSE],
whitelist_ecus=[Ecu.abs, Ecu.debug, Ecu.engine, Ecu.eps, Ecu.fwdCamera, Ecu.fwdRadar, Ecu.shiftByWire],
bus=0, bus=0,
auxiliary=True, auxiliary=True,
), ),
*[Request(
[StdQueries.TESTER_PRESENT_REQUEST, ford_asbuilt_block_request(block_id)],
[StdQueries.TESTER_PRESENT_RESPONSE, ford_asbuilt_block_response(block_id)],
whitelist_ecus=ecus,
bus=0,
logging=True,
) for block_id, ecus in ASBUILT_BLOCKS],
], ],
extra_ecus=[ extra_ecus=[
# We are unlikely to get a response from the PCM from behind the gateway (Ecu.engine, 0x7e0, None), # Powertrain Control Module
(Ecu.engine, 0x7e0, None), # Note: We are unlikely to get a response from behind the gateway
(Ecu.shiftByWire, 0x732, None), (Ecu.shiftByWire, 0x732, None), # Gear Shift Module
(Ecu.debug, 0x7d0, None), # Accessory Protocol Interface Module
], ],
# Custom fuzzy fingerprinting function using platform codes, part numbers and software versions # Custom fuzzy fingerprinting function using platform codes, part numbers and software versions
match_fw_to_car_fuzzy=match_fw_to_car_fuzzy, match_fw_to_car_fuzzy=match_fw_to_car_fuzzy,

@ -79,7 +79,7 @@ class GMCarInfo(CarInfo):
self.footnotes.append(Footnote.OBD_II) self.footnotes.append(Footnote.OBD_II)
@dataclass @dataclass(frozen=True)
class GMPlatformConfig(PlatformConfig): 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: dbc_dict('gm_global_a_powertrain_generated', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis'))

@ -4,7 +4,7 @@ import numpy as np
import tomllib import tomllib
from abc import abstractmethod, ABC from abc import abstractmethod, ABC
from enum import StrEnum from enum import StrEnum
from typing import Any, NamedTuple, cast from typing import Any, NamedTuple
from collections.abc import Callable from collections.abc import Callable
from cereal import car from cereal import car
@ -13,7 +13,7 @@ from openpilot.common.conversions import Conversions as CV
from openpilot.common.simple_kalman import KF1D, get_kalman_gain from openpilot.common.simple_kalman import KF1D, get_kalman_gain
from openpilot.common.numpy_fast import clip from openpilot.common.numpy_fast import clip
from openpilot.common.realtime import DT_CTRL from openpilot.common.realtime import DT_CTRL
from openpilot.selfdrive.car import PlatformConfig, apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, STD_CARGO_KG from openpilot.selfdrive.car import apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, STD_CARGO_KG
from openpilot.selfdrive.car.values import Platform from openpilot.selfdrive.car.values import Platform
from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX, get_friction from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX, get_friction
from openpilot.selfdrive.controls.lib.events import Events from openpilot.selfdrive.controls.lib.events import Events
@ -113,14 +113,13 @@ class CarInterfaceBase(ABC):
ret = CarInterfaceBase.get_std_params(candidate) ret = CarInterfaceBase.get_std_params(candidate)
if hasattr(candidate, "config"): if hasattr(candidate, "config"):
platform_config = cast(PlatformConfig, candidate.config) if candidate.config.specs is not None:
if platform_config.specs is not None: ret.mass = candidate.config.specs.mass
ret.mass = platform_config.specs.mass ret.wheelbase = candidate.config.specs.wheelbase
ret.wheelbase = platform_config.specs.wheelbase ret.steerRatio = candidate.config.specs.steerRatio
ret.steerRatio = platform_config.specs.steerRatio ret.centerToFront = ret.wheelbase * candidate.config.specs.centerToFrontRatio
ret.centerToFront = ret.wheelbase * platform_config.specs.centerToFrontRatio ret.minEnableSpeed = candidate.config.specs.minEnableSpeed
ret.minEnableSpeed = platform_config.specs.minEnableSpeed ret.minSteerSpeed = candidate.config.specs.minSteerSpeed
ret.minSteerSpeed = platform_config.specs.minSteerSpeed
ret = cls._get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs) ret = cls._get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs)

@ -89,7 +89,7 @@ class SubaruCarInfo(CarInfo):
self.footnotes.append(Footnote.EXP_LONG) self.footnotes.append(Footnote.EXP_LONG)
@dataclass @dataclass(frozen=True)
class SubaruPlatformConfig(PlatformConfig): class SubaruPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('subaru_global_2017_generated', None)) dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('subaru_global_2017_generated', None))

@ -263,13 +263,13 @@ class TestFwFingerprintTiming(unittest.TestCase):
print(f'get_vin {name} case, query time={self.total_time / self.N} seconds') print(f'get_vin {name} case, query time={self.total_time / self.N} seconds')
def test_fw_query_timing(self): def test_fw_query_timing(self):
total_ref_time = {1: 6.5, 2: 7.4} total_ref_time = {1: 7.8, 2: 8.7}
brand_ref_times = { brand_ref_times = {
1: { 1: {
'gm': 0.5, 'gm': 0.5,
'body': 0.1, 'body': 0.1,
'chrysler': 0.3, 'chrysler': 0.3,
'ford': 0.2, 'ford': 1.5,
'honda': 0.55, 'honda': 0.55,
'hyundai': 1.05, 'hyundai': 1.05,
'mazda': 0.1, 'mazda': 0.1,
@ -280,7 +280,7 @@ class TestFwFingerprintTiming(unittest.TestCase):
'volkswagen': 0.65, 'volkswagen': 0.65,
}, },
2: { 2: {
'ford': 0.3, 'ford': 1.6,
'hyundai': 1.85, 'hyundai': 1.85,
} }
} }

@ -573,6 +573,7 @@ FW_VERSIONS = {
b'\x018821F6201400\x00\x00\x00\x00', b'\x018821F6201400\x00\x00\x00\x00',
], ],
(Ecu.fwdCamera, 0x750, 0x6d): [ (Ecu.fwdCamera, 0x750, 0x6d): [
b'\x028646F12010C0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00',
b'\x028646F12010D0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', b'\x028646F12010D0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00',
b'\x028646F1201100\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', b'\x028646F1201100\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00',
b'\x028646F1201200\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', b'\x028646F1201200\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00',
@ -843,6 +844,7 @@ FW_VERSIONS = {
b'8965B47023\x00\x00\x00\x00\x00\x00', b'8965B47023\x00\x00\x00\x00\x00\x00',
b'8965B47050\x00\x00\x00\x00\x00\x00', b'8965B47050\x00\x00\x00\x00\x00\x00',
b'8965B47060\x00\x00\x00\x00\x00\x00', b'8965B47060\x00\x00\x00\x00\x00\x00',
b'8965B47070\x00\x00\x00\x00\x00\x00',
], ],
(Ecu.abs, 0x7b0, None): [ (Ecu.abs, 0x7b0, None): [
b'F152647290\x00\x00\x00\x00\x00\x00', b'F152647290\x00\x00\x00\x00\x00\x00',
@ -1024,6 +1026,7 @@ FW_VERSIONS = {
b'\x02896634A13000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'\x02896634A13000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x02896634A13001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', b'\x02896634A13001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00',
b'\x02896634A13101\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', b'\x02896634A13101\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00',
b'\x02896634A13201\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00',
b'\x02896634A14001\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', b'\x02896634A14001\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00',
b'\x02896634A14001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', b'\x02896634A14001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00',
b'\x02896634A14101\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', b'\x02896634A14101\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00',

@ -112,15 +112,15 @@ class CANBUS:
class VolkswagenFlags(IntFlag): class VolkswagenFlags(IntFlag):
STOCK_HCA_PRESENT = 1 STOCK_HCA_PRESENT = 1
@dataclass @dataclass(frozen=True)
class VolkswagenMQBPlatformConfig(PlatformConfig): class VolkswagenMQBPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('vw_mqb_2010', None)) dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('vw_mqb_2010', None))
@dataclass @dataclass(frozen=True)
class VolkswagenPQPlatformConfig(PlatformConfig): class VolkswagenPQPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('vw_golf_mk4', None)) dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('vw_golf_mk4', None))
@dataclass(kw_only=True) @dataclass(frozen=True, kw_only=True)
class VolkswagenCarSpecs(CarSpecs): class VolkswagenCarSpecs(CarSpecs):
steerRatio: float = field(default=15.6) steerRatio: float = field(default=15.6)

@ -97,6 +97,7 @@ CONFIGS = {
AmpConfig("Right DAC input mixer: DAI2 right", 0b1, 0x22, 0, 0b00000001), AmpConfig("Right DAC input mixer: DAI2 right", 0b1, 0x22, 0, 0b00000001),
AmpConfig("Volume adjustment smoothing disabled", 0b1, 0x49, 6, 0b01000000), AmpConfig("Volume adjustment smoothing disabled", 0b1, 0x49, 6, 0b01000000),
], ],
"mici": [],
} }
class Amplifier: class Amplifier:

@ -20,12 +20,12 @@ public:
} }
static std::string get_name() { static std::string get_name() {
std::string devicetree_model = util::read_file("/sys/firmware/devicetree/base/model"); std::string model = util::read_file("/sys/firmware/devicetree/base/model");
return (devicetree_model.find("tizi") != std::string::npos) ? "tizi" : "tici"; return model.substr(std::string("comma ").size());
} }
static cereal::InitData::DeviceType get_device_type() { static cereal::InitData::DeviceType get_device_type() {
return (get_name() == "tizi") ? cereal::InitData::DeviceType::TIZI : cereal::InitData::DeviceType::TICI; return (get_name() == "tizi") ? cereal::InitData::DeviceType::TIZI : (get_name() == "mici" ? cereal::InitData::DeviceType::MICI : cereal::InitData::DeviceType::TICI);
} }
static int get_voltage() { return std::atoi(util::read_file("/sys/class/hwmon/hwmon1/in1_input").c_str()); } static int get_voltage() { return std::atoi(util::read_file("/sys/class/hwmon/hwmon1/in1_input").c_str()); }

Loading…
Cancel
Save