mirror of
https://github.com/infiniteCable2/opendbc.git
synced 2026-06-08 02:44:40 +08:00
Merge branch 'upstream/master' into sync-20260425
This commit is contained in:
2
.github/workflows/car_diff.yml
vendored
2
.github/workflows/car_diff.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: tests.yml
|
||||
workflow_conclusion: ''
|
||||
pr: ${{ github.event.number }}
|
||||
commit: ${{ github.event.pull_request.head.sha }}
|
||||
name: car_diff_${{ github.event.number }}
|
||||
path: .
|
||||
allow_forks: true
|
||||
|
||||
28
RELEASES.md
28
RELEASES.md
@@ -1,3 +1,31 @@
|
||||
Version 0.3.1 (2026-04-22)
|
||||
========================
|
||||
* Ship DBCs, capnp schemas, and torque data in the wheel
|
||||
|
||||
Version 0.3.0 (2026-04-22)
|
||||
========================
|
||||
* Supported car count: 345 → 397
|
||||
* Tesla Model 3, Model Y, and Model X (HW3 and HW4) support thanks to lukasloetkolben and greatgitsby!
|
||||
* Rivian R1S and R1T (Gen 1 and Gen 2) support thanks to lukasloetkolben!
|
||||
* Porsche Macan and Audi Q5 (VW MLB) support thanks to jyoung8607 and Dennis-NL!
|
||||
* VW MEB (ID.x) architecture support thanks to jyoung8607!
|
||||
* PSA AEE2010_R3 platform support thanks to elkoled!
|
||||
* Honda Accord 2023-25, CR-V 2023-25, Pilot 2023-25, Passport 2026, and Acura MDX 2025 support thanks to vanillagorillaa and MVL!
|
||||
* Honda Odyssey 2021-25 support thanks to csouers and MVL!
|
||||
* Acura TLX 2021 support thanks to MVL!
|
||||
* Honda City 2023 support thanks to vanillagorillaa and drFritz!
|
||||
* Honda N-Box 2018 support thanks to miettal!
|
||||
* Ford F-150, F-150 Hybrid, Mach-E, and Ranger support
|
||||
* Ford Escape 2023-24 and Kuga 2024 support thanks to incognitojam!
|
||||
* Hyundai Nexo 2021 support thanks to sunnyhaibin!
|
||||
* Kia K7 2017 support thanks to royjr!
|
||||
* Lexus LS 2018 support thanks to Hacheoy!
|
||||
* Lexus RC 2023 support thanks to nelsonjchen!
|
||||
* CANParser and CANPacker rewritten in pure Python — the installed package is pure Python, no compilation required
|
||||
* Safety code, `isotp.py`/`ccp.py`/`xcp.py`, and `vehicle_model.py` moved into opendbc from panda/openpilot — opendbc is now the self-contained car API package
|
||||
* `mull` replaced with a faster custom mutation test runner
|
||||
* Safety hardening: per-brand message-block config, missing RX checks, relay-malfunction config
|
||||
|
||||
Version 0.2.1 (2025-02-10)
|
||||
========================
|
||||
* Fix missing files making car/ package not importable
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import unittest
|
||||
|
||||
from opendbc.can import CANDefine
|
||||
from opendbc.can.tests import ALL_DBCS
|
||||
|
||||
|
||||
class TestCANDefine:
|
||||
class TestCANDefine(unittest.TestCase):
|
||||
def test_civic(self):
|
||||
|
||||
dbc_file = "honda_civic_touring_2016_can_generated"
|
||||
@@ -20,8 +22,8 @@ class TestCANDefine:
|
||||
0: 'NORMAL'}
|
||||
}
|
||||
|
||||
def test_all_dbcs(self, subtests):
|
||||
def test_all_dbcs(self):
|
||||
# Asserts no exceptions on all DBCs
|
||||
for dbc in ALL_DBCS:
|
||||
with subtests.test(dbc=dbc):
|
||||
with self.subTest(dbc=dbc):
|
||||
CANDefine(dbc)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import re
|
||||
import unittest
|
||||
|
||||
from opendbc.car.honda.fingerprints import FW_VERSIONS
|
||||
from opendbc.car.honda.values import HONDA_BOSCH, HONDA_BOSCH_TJA_CONTROL
|
||||
@@ -6,7 +7,7 @@ from opendbc.car.honda.values import HONDA_BOSCH, HONDA_BOSCH_TJA_CONTROL
|
||||
HONDA_FW_VERSION_RE = br"[A-Z0-9]{5}(-|,)[A-Z0-9]{3}(-|,)[A-Z0-9]{4}(\x00){2}$"
|
||||
|
||||
|
||||
class TestHondaFingerprint:
|
||||
class TestHondaFingerprint(unittest.TestCase):
|
||||
def test_fw_version_format(self):
|
||||
# Asserts all FW versions follow an expected format
|
||||
for fw_by_ecu in FW_VERSIONS.values():
|
||||
|
||||
@@ -23,6 +23,12 @@ MAX_ANGLE = 85
|
||||
MAX_ANGLE_FRAMES = 89
|
||||
MAX_ANGLE_CONSECUTIVE_FRAMES = 2
|
||||
|
||||
# On some HKG CAN and CAN FD non-CANFD_ALT_BUTTONS, the cancel button (CF_Clu_CruiseSwState / CRUISE_BUTTONS = 4) is
|
||||
# a pause/resume toggle, not a dedicated cancel. Firing it mid-brake inadvertently can cause a re-enable attempt
|
||||
# and triggers the "SCC Conditions Not Met" alert. Delaying the button send lets factory SCC disengage
|
||||
# naturally on brake press. We send ~100 ms later if it fails to do so, or if we want to cancel for another reason.
|
||||
CANCEL_BUTTON_DELAY_FRAMES = 10
|
||||
|
||||
|
||||
def process_hud_alert(enabled, fingerprint, hud_control):
|
||||
sys_warning = (hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw))
|
||||
@@ -66,6 +72,7 @@ class CarController(CarControllerBase, EsccCarController, LeadDataCarController,
|
||||
self.apply_torque_last = 0
|
||||
self.car_fingerprint = CP.carFingerprint
|
||||
self.last_button_frame = 0
|
||||
self.cancel_counter = 0
|
||||
|
||||
def update(self, CC, CC_SP, CS, now_nanos):
|
||||
EsccCarController.update(self, CS)
|
||||
@@ -113,6 +120,10 @@ class CarController(CarControllerBase, EsccCarController, LeadDataCarController,
|
||||
if self.CP.flags & HyundaiFlags.CANFD_ENABLE_BLINKERS:
|
||||
can_sends.append(make_tester_present_msg(0x7b1, self.CAN.ECAN, suppress_response=True))
|
||||
|
||||
# Delay the cancel button send so the brake can disengage factory SCC first.
|
||||
# Reset whenever openpilot is no longer requesting cancel.
|
||||
self.cancel_counter = self.cancel_counter + 1 if CC.cruiseControl.cancel else 0
|
||||
|
||||
# *** CAN/CAN FD specific ***
|
||||
if self.CP.flags & HyundaiFlags.CANFD:
|
||||
can_sends.extend(self.create_canfd_msgs(apply_steer_req, apply_torque, set_speed_in_units, accel,
|
||||
@@ -151,7 +162,7 @@ class CarController(CarControllerBase, EsccCarController, LeadDataCarController,
|
||||
|
||||
# Button messages
|
||||
if not self.CP.openpilotLongitudinalControl:
|
||||
if CC.cruiseControl.cancel:
|
||||
if self.cancel_counter > CANCEL_BUTTON_DELAY_FRAMES:
|
||||
can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP))
|
||||
elif CC.cruiseControl.resume:
|
||||
# send resume at a max freq of 10Hz
|
||||
@@ -220,10 +231,11 @@ class CarController(CarControllerBase, EsccCarController, LeadDataCarController,
|
||||
if (self.frame - self.last_button_frame) * DT_CTRL > 0.25:
|
||||
# cruise cancel
|
||||
if CC.cruiseControl.cancel:
|
||||
# Here we send ACC message to cancel, not buttons. Don't delay
|
||||
if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS:
|
||||
can_sends.append(hyundaicanfd.create_acc_cancel(self.packer, self.CP, self.CAN, CS.cruise_info))
|
||||
self.last_button_frame = self.frame
|
||||
else:
|
||||
elif self.cancel_counter > CANCEL_BUTTON_DELAY_FRAMES:
|
||||
for _ in range(20):
|
||||
can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter + 1, Buttons.CANCEL))
|
||||
self.last_button_frame = self.frame
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import unittest
|
||||
|
||||
from opendbc.car.rivian.fingerprints import FW_VERSIONS
|
||||
from opendbc.car.rivian.values import CAR, FW_QUERY_CONFIG, WMI, ModelLine, ModelYear
|
||||
|
||||
|
||||
class TestRivian:
|
||||
def test_custom_fuzzy_fingerprinting(self, subtests):
|
||||
class TestRivian(unittest.TestCase):
|
||||
def test_custom_fuzzy_fingerprinting(self):
|
||||
for platform in CAR:
|
||||
with subtests.test(platform=platform.name):
|
||||
with self.subTest(platform=platform.name):
|
||||
for wmi in WMI:
|
||||
for line in ModelLine:
|
||||
for year in ModelYear:
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import unittest
|
||||
|
||||
from opendbc.car.subaru.fingerprints import FW_VERSIONS
|
||||
|
||||
|
||||
class TestSubaruFingerprint:
|
||||
class TestSubaruFingerprint(unittest.TestCase):
|
||||
def test_fw_version_format(self):
|
||||
for platform, fws_per_ecu in FW_VERSIONS.items():
|
||||
for (ecu, _, _), fws in fws_per_ecu.items():
|
||||
|
||||
@@ -12,6 +12,7 @@ FW_VERSIONS = {
|
||||
b'TeM3_E014p10_0.0.0 (16),E014.17.00',
|
||||
b'TeM3_E014p10_0.0.0 (16),EL014.17.00',
|
||||
b'TeM3_ES014p11_0.0.0 (25),ES014.19.0',
|
||||
b'TeM3_E014p10_0.0.0 (24),E014.20.2',
|
||||
b'TeMYG4_DCS_Update_0.0.0 (13),E4014.28.1',
|
||||
b'TeMYG4_DCS_Update_0.0.0 (9),E4014.26.0',
|
||||
b'TeMYG4_Legacy3Y_0.0.0 (2),E4015.02.0',
|
||||
@@ -24,12 +25,14 @@ FW_VERSIONS = {
|
||||
b'TeMYG4_Main_0.0.0 (77),E4HP015.04.5',
|
||||
b'TeMYG4_Main_0.0.0 (78),E4HP015.05.0',
|
||||
b'TeMYG4_SingleECU_0.0.0 (33),E4S014.27',
|
||||
b'TeMYG4_Main_0.0.0 (78),E4H015.05.0',
|
||||
],
|
||||
},
|
||||
CAR.TESLA_MODEL_Y: {
|
||||
(Ecu.eps, 0x730, None): [
|
||||
b'TeM3_E014p10_0.0.0 (16),Y002.18.00',
|
||||
b'TeM3_E014p10_0.0.0 (16),YP002.18.00',
|
||||
b'TeM3_E014p10_0.0.0 (24),YP002.21.2',
|
||||
b'TeM3_ES014p11_0.0.0 (16),YS002.17',
|
||||
b'TeM3_ES014p11_0.0.0 (25),YS002.19.0',
|
||||
b'TeMYG4_DCS_Update_0.0.0 (13),Y4002.27.1',
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import re
|
||||
import unittest
|
||||
|
||||
from opendbc.car import gen_empty_fingerprint
|
||||
from opendbc.car.structs import CarParams
|
||||
from opendbc.car.tesla.interface import CarInterface
|
||||
@@ -7,23 +10,80 @@ from opendbc.car.tesla.values import CAR, FSD_14_FW
|
||||
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
# Fields prefixed unknown_* we observe structurally but don't know the meaning of.
|
||||
# Only `platform` has evidence-backed semantic meaning (matches car_model in FW_VERSIONS).
|
||||
#
|
||||
# unknown_prefix is everything before the comma; we don't split it because we don't know what its
|
||||
# parts mean, but observed shape is: <family>_<package>_<triplet> (<build>), e.g.
|
||||
# TeMYG4 _ Main _ 0.0.0 (78) or TeM3 _ SP_XP002p2 _ 0.0.0 (23)
|
||||
# family package triplet build family package triplet build
|
||||
#
|
||||
# After the comma, the version string decomposes into:
|
||||
# platform : E/Y/X = car model (Model 3 / Y / X). The only field with known meaning.
|
||||
# variant_code : differentiator WITHIN a platform — hardware/trim/calibration bits packed
|
||||
# into <digit?><letters?><3-digit series>, e.g. '4HP015', '4003', 'L014',
|
||||
# 'PR003'. We don't fully know what the parts mean individually, but the
|
||||
# whole string identifies a specific variant within the car model.
|
||||
# software_major/minor : numeric components after the first '.' — conventional release numbers.
|
||||
# minor is optional (e.g. 'E4S014.27' has no minor).
|
||||
#
|
||||
# Suspected (not confirmed): for M3/MY, `TeM3_*` outer + no-leading-digit variant_code == HW3, and
|
||||
# `TeMYG4_*` outer + leading-'4' variant_code == HW4 (the 'G4' in TeMYG4 likely denotes Gen 4).
|
||||
#
|
||||
# Example full parse of 'TeMYG4_Main_0.0.0 (78),E4HP015.05.0':
|
||||
# unknown_prefix='TeMYG4_Main_0.0.0 (78)'
|
||||
# platform=E variant_code=4HP015 software_major=05 software_minor=0
|
||||
FW_RE = re.compile(
|
||||
rb'^(?P<unknown_prefix>.+),' +
|
||||
rb'(?P<platform>[EYX])' +
|
||||
rb'(?P<variant_code>\d?[A-Z]*\d{3})' +
|
||||
rb'\.(?P<software_major>\d+)' +
|
||||
rb'(?:\.(?P<software_minor>\d+))?$'
|
||||
)
|
||||
|
||||
class TestTeslaFingerprint:
|
||||
def test_fsd_14_fw(self):
|
||||
PLATFORM_TO_CAR = {
|
||||
b'E': CAR.TESLA_MODEL_3,
|
||||
b'Y': CAR.TESLA_MODEL_Y,
|
||||
b'X': CAR.TESLA_MODEL_X,
|
||||
}
|
||||
|
||||
# Hypothesized FSD 14 profile, in terms of variant_code bookends (given software_major >= 4):
|
||||
# M3: variant_code starts with '4H', ends with '015'
|
||||
# MY: variant_code starts with '4', ends with '003'
|
||||
# Older series (M3 '014', MY '002') are never FSD 14.
|
||||
FSD_14_FW_RULE = {
|
||||
CAR.TESLA_MODEL_3: (b'4H', b'015'),
|
||||
CAR.TESLA_MODEL_Y: (b'4', b'003'),
|
||||
}
|
||||
|
||||
|
||||
class TestTeslaFingerprint(unittest.TestCase):
|
||||
def test_fw_platform_code(self):
|
||||
# Every EPS FW must parse and its platform letter must match the car it's filed under.
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
for fw in ecus.get((Ecu.eps, 0x730, None), []):
|
||||
_, _, version = fw.partition(b',')
|
||||
is_fsd_14 = fw in FSD_14_FW.get(car_model, [])
|
||||
m = FW_RE.match(fw)
|
||||
|
||||
if car_model == CAR.TESLA_MODEL_3:
|
||||
# Model 3: FSD 14 FW has 'P' in the Highland suffix (E4HP vs E4H)
|
||||
assert is_fsd_14 == version.startswith(b'E4HP'), f"{fw}"
|
||||
elif car_model == CAR.TESLA_MODEL_Y:
|
||||
# Model Y: FSD 14 FW is Y4x version >= 003.04
|
||||
prefix, _, ver = version.partition(b'.')
|
||||
y4_003 = prefix.startswith(b'Y4') and prefix.endswith(b'003') # Y4=HW4, 003=version series (002 is never FSD 14)
|
||||
high_version = y4_003 and int(ver.split(b'.')[0]) >= 4
|
||||
assert is_fsd_14 == high_version, f"{fw}"
|
||||
assert m is not None, f"Unparsable FW: {fw}"
|
||||
assert PLATFORM_TO_CAR[m['platform']] == car_model, f"Platform letter {m['platform']!r} != {car_model.value}: {fw}"
|
||||
|
||||
def test_fsd_14_fw(self):
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
if car_model not in FSD_14_FW_RULE:
|
||||
continue
|
||||
|
||||
variant_prefix, variant_suffix = FSD_14_FW_RULE[car_model]
|
||||
for fw in ecus.get((Ecu.eps, 0x730, None), []):
|
||||
m = FW_RE.match(fw)
|
||||
assert m is not None, f"Unparsable FW: {fw}"
|
||||
|
||||
is_fsd_14 = fw in FSD_14_FW.get(car_model, [])
|
||||
expected = (
|
||||
m['variant_code'].startswith(variant_prefix)
|
||||
and m['variant_code'].endswith(variant_suffix)
|
||||
and int(m['software_major']) >= 4
|
||||
)
|
||||
assert is_fsd_14 == expected, f"{fw}"
|
||||
|
||||
def test_radar_detection(self):
|
||||
# Test radar availability detection for cars with radar DBC defined
|
||||
|
||||
@@ -85,6 +85,7 @@ FSD_14_FW = {
|
||||
b'TeMYG4_Main_0.0.0 (77),E4HP015.04.5',
|
||||
b'TeMYG4_Main_0.0.0 (78),E4HP015.05.0',
|
||||
b'TeMYG4_Main_0.0.0 (77),E4H015.04.5',
|
||||
b'TeMYG4_Main_0.0.0 (78),E4H015.05.0',
|
||||
],
|
||||
CAR.TESLA_MODEL_Y: [
|
||||
b'TeMYG4_Legacy3Y_0.0.0 (6),Y4003.04.0',
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import unittest
|
||||
|
||||
from hypothesis import given, settings, strategies as st
|
||||
|
||||
from opendbc.car import Bus
|
||||
@@ -16,7 +18,7 @@ def check_fw_version(fw_version: bytes) -> bool:
|
||||
return b'?' not in fw_version and b'!' not in fw_version
|
||||
|
||||
|
||||
class TestToyotaInterfaces:
|
||||
class TestToyotaInterfaces(unittest.TestCase):
|
||||
def test_car_sets(self):
|
||||
assert len(ANGLE_CONTROL_CAR - TSS2_CAR) == 0
|
||||
assert len(RADAR_ACC_CAR - TSS2_CAR) == 0
|
||||
@@ -32,11 +34,11 @@ class TestToyotaInterfaces:
|
||||
if car_model in TSS2_CAR and car_model not in SECOC_CAR:
|
||||
assert dbc[Bus.pt] == "toyota_nodsu_pt_generated"
|
||||
|
||||
def test_essential_ecus(self, subtests):
|
||||
def test_essential_ecus(self):
|
||||
# Asserts standard ECUs exist for each platform
|
||||
common_ecus = {Ecu.fwdRadar, Ecu.fwdCamera}
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with subtests.test(car_model=car_model.value):
|
||||
with self.subTest(car_model=car_model.value):
|
||||
present_ecus = {ecu[0] for ecu in ecus}
|
||||
missing_ecus = common_ecus - present_ecus
|
||||
assert len(missing_ecus) == 0
|
||||
@@ -52,19 +54,19 @@ class TestToyotaInterfaces:
|
||||
assert Ecu.eps in present_ecus
|
||||
|
||||
|
||||
class TestToyotaFingerprint:
|
||||
def test_non_essential_ecus(self, subtests):
|
||||
class TestToyotaFingerprint(unittest.TestCase):
|
||||
def test_non_essential_ecus(self):
|
||||
# Ensures only the cars that have multiple engine ECUs are in the engine non-essential ECU list
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with subtests.test(car_model=car_model.value):
|
||||
with self.subTest(car_model=car_model.value):
|
||||
engine_ecus = {ecu for ecu in ecus if ecu[0] == Ecu.engine}
|
||||
assert (len(engine_ecus) > 1) == (car_model in FW_QUERY_CONFIG.non_essential_ecus[Ecu.engine]), \
|
||||
f"Car model unexpectedly {'not ' if len(engine_ecus) > 1 else ''}in non-essential list"
|
||||
|
||||
def test_valid_fw_versions(self, subtests):
|
||||
def test_valid_fw_versions(self):
|
||||
# Asserts all FW versions are valid
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with subtests.test(car_model=car_model.value):
|
||||
with self.subTest(car_model=car_model.value):
|
||||
for fws in ecus.values():
|
||||
for fw in fws:
|
||||
assert check_fw_version(fw), fw
|
||||
@@ -78,10 +80,10 @@ class TestToyotaFingerprint:
|
||||
fws = data.draw(fw_strategy)
|
||||
get_platform_codes(fws)
|
||||
|
||||
def test_platform_code_ecus_available(self, subtests):
|
||||
def test_platform_code_ecus_available(self):
|
||||
# Asserts ECU keys essential for fuzzy fingerprinting are available on all platforms
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with subtests.test(car_model=car_model.value):
|
||||
with self.subTest(car_model=car_model.value):
|
||||
for platform_code_ecu in PLATFORM_CODE_ECUS:
|
||||
if platform_code_ecu == Ecu.eps and car_model in (CAR.TOYOTA_PRIUS_V, CAR.LEXUS_CTH,):
|
||||
continue
|
||||
@@ -89,14 +91,14 @@ class TestToyotaFingerprint:
|
||||
continue
|
||||
assert platform_code_ecu in [e[0] for e in ecus]
|
||||
|
||||
def test_fw_format(self, subtests):
|
||||
def test_fw_format(self):
|
||||
# Asserts:
|
||||
# - every supported ECU FW version returns one platform code
|
||||
# - every supported ECU FW version has a part number
|
||||
# - expected parsing of ECU sub-versions
|
||||
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with subtests.test(car_model=car_model.value):
|
||||
with self.subTest(car_model=car_model.value):
|
||||
for ecu, fws in ecus.items():
|
||||
if ecu[0] not in PLATFORM_CODE_ECUS:
|
||||
continue
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "opendbc"
|
||||
version = "0.2.1"
|
||||
version = "0.3.1"
|
||||
description = "a Python API for your car"
|
||||
license = "MIT"
|
||||
authors = [{ name = "Vehicle Researcher", email = "user@comma.ai" }]
|
||||
@@ -18,7 +18,6 @@ dependencies = [
|
||||
|
||||
[project.optional-dependencies]
|
||||
testing = [
|
||||
"comma-car-segments @ https://huggingface.co/datasets/commaai/commaCarSegments/resolve/main/dist/comma_car_segments-0.1.0-py3-none-any.whl",
|
||||
"cffi",
|
||||
"tree-sitter",
|
||||
"tree-sitter-c",
|
||||
@@ -33,7 +32,6 @@ testing = [
|
||||
"lefthook",
|
||||
"cpplint",
|
||||
"codespell",
|
||||
"cppcheck @ git+https://github.com/commaai/dependencies.git@release-cppcheck#subdirectory=cppcheck",
|
||||
]
|
||||
docs = [
|
||||
"Jinja2",
|
||||
@@ -42,6 +40,15 @@ examples = [
|
||||
"inputs",
|
||||
]
|
||||
|
||||
# Dependency groups (PEP 735) are not included in the published wheel.
|
||||
# Direct URL dependencies must live here because PyPI rejects uploads whose
|
||||
# `Requires-Dist` contains direct URLs.
|
||||
[dependency-groups]
|
||||
testing = [
|
||||
"comma-car-segments @ https://huggingface.co/datasets/commaai/commaCarSegments/resolve/main/dist/comma_car_segments-0.1.0-py3-none-any.whl",
|
||||
"cppcheck @ git+https://github.com/commaai/dependencies.git@release-cppcheck#subdirectory=cppcheck",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
@@ -127,4 +134,6 @@ too-many-positional-arguments = "ignore"
|
||||
include-package-data = true
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
"opendbc.safety" = ["*.h", "board/*.h", "board/drivers/*.h", "modes/*.h"]
|
||||
"opendbc.car" = ["**/*.capnp", "**/*.toml"]
|
||||
"opendbc.dbc" = ["**/*.dbc"]
|
||||
"opendbc.safety" = ["*.h", "modes/*.h"]
|
||||
|
||||
2
setup.sh
2
setup.sh
@@ -18,5 +18,5 @@ if ! command -v uv &>/dev/null; then
|
||||
fi
|
||||
|
||||
export UV_PROJECT_ENVIRONMENT="$BASEDIR/.venv"
|
||||
uv sync --all-extras --inexact
|
||||
uv sync --all-extras --all-groups --inexact
|
||||
source "$PYTHONPATH/.venv/bin/activate"
|
||||
|
||||
18
uv.lock
generated
18
uv.lock
generated
@@ -382,7 +382,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "opendbc"
|
||||
version = "0.2.1"
|
||||
version = "0.3.1"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "numpy" },
|
||||
@@ -401,8 +401,6 @@ examples = [
|
||||
testing = [
|
||||
{ name = "cffi" },
|
||||
{ name = "codespell" },
|
||||
{ name = "comma-car-segments" },
|
||||
{ name = "cppcheck" },
|
||||
{ name = "cpplint" },
|
||||
{ name = "gcovr" },
|
||||
{ name = "hypothesis" },
|
||||
@@ -415,12 +413,16 @@ testing = [
|
||||
{ name = "zstandard" },
|
||||
]
|
||||
|
||||
[package.dev-dependencies]
|
||||
testing = [
|
||||
{ name = "comma-car-segments" },
|
||||
{ name = "cppcheck" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "cffi", marker = "extra == 'testing'" },
|
||||
{ name = "codespell", marker = "extra == 'testing'" },
|
||||
{ name = "comma-car-segments", marker = "extra == 'testing'", url = "https://huggingface.co/datasets/commaai/commaCarSegments/resolve/main/dist/comma_car_segments-0.1.0-py3-none-any.whl" },
|
||||
{ name = "cppcheck", marker = "extra == 'testing'", git = "https://github.com/commaai/dependencies.git?subdirectory=cppcheck&rev=release-cppcheck" },
|
||||
{ name = "cpplint", marker = "extra == 'testing'" },
|
||||
{ name = "gcovr", marker = "extra == 'testing'" },
|
||||
{ name = "hypothesis", marker = "extra == 'testing'", specifier = "==6.47.*" },
|
||||
@@ -440,6 +442,12 @@ requires-dist = [
|
||||
]
|
||||
provides-extras = ["testing", "docs", "examples"]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
testing = [
|
||||
{ name = "comma-car-segments", url = "https://huggingface.co/datasets/commaai/commaCarSegments/resolve/main/dist/comma_car_segments-0.1.0-py3-none-any.whl" },
|
||||
{ name = "cppcheck", git = "https://github.com/commaai/dependencies.git?subdirectory=cppcheck&rev=release-cppcheck" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pycapnp"
|
||||
version = "2.1.0"
|
||||
|
||||
Reference in New Issue
Block a user