mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-07-07 22:12:05 +08:00
e0ab166ed3
f1e69a6cf Fix wrong message size in Chrysler 54482cfb0 Fix GM message signal sizes 4e796e06d Fix wrong message sizes in Nissan fb6c1ee2b Better GEAR signal tracking the gear stick rather than the gear box (#257) d7a2efbbd Raw angle signal data for easy checksum calc, and one less gear bit (#254) 7456061a7 add checksum check to can parser for subaru 7f3b1774d Chrysler: calculate checksum in can packer/parser (#255) 0c0215516 Rename BYTE_ to SET_ME_X (#253) 1efe437cf Add values for a static 0xe5 (honda bosch) (#250) 7dffe0bd9 Create DBC for HRV (#248) b69398525 Add LFAHDA message to hyundai a57e7ddbd CANPacker: Subaru checksum support (#241) 36c471e59 Fixed signals order and added new signals for subaru global (#221) 7b5a1fcc1 BMW 2008-2013 (#230) cc09af763 Add RPM signal (#216) 47db9238f Add SWA_01 message detail and CRC support for VW MQB (#236) c98fe2ab9 Fixed signal unknown1 overlapping the button bits (#239) 572261ee3 Rear Cross Traffic Alert 044730aeb Speed limit signs 87b1a21fb Pedals/gear, gas pedal scale value ce78044d8 Tracking the steer angle with LKAS signal 7f19ab415 Introduce the new mazda 3 2019/2020 dbc e58520619 traffic sign speed limit 00bad5ee7 Speed Auto High Beam Traffic signs 9d080ea42 Nissan leaf (#238) 50fbbe739 nissan x trail cleanup (#237) git-subtree-dir: opendbc git-subtree-split: f1e69a6cf91cdaf1b8008d73f6fbb6634fbbeb42
127 lines
4.4 KiB
Python
Executable File
127 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from __future__ import print_function
|
|
import os
|
|
import sys
|
|
|
|
import jinja2
|
|
|
|
from collections import Counter
|
|
from opendbc.can.dbc import dbc
|
|
|
|
def process(in_fn, out_fn):
|
|
dbc_name = os.path.split(out_fn)[-1].replace('.cc', '')
|
|
#print("processing %s: %s -> %s" % (dbc_name, in_fn, out_fn))
|
|
|
|
template_fn = os.path.join(os.path.dirname(__file__), "dbc_template.cc")
|
|
|
|
with open(template_fn, "r") as template_f:
|
|
template = jinja2.Template(template_f.read(), trim_blocks=True, lstrip_blocks=True)
|
|
|
|
can_dbc = dbc(in_fn)
|
|
|
|
msgs = [(address, msg_name, msg_size, sorted(msg_sigs, key=lambda s: s.name not in ("COUNTER", "CHECKSUM"))) # process counter and checksums first
|
|
for address, ((msg_name, msg_size), msg_sigs) in sorted(can_dbc.msgs.items()) if msg_sigs]
|
|
|
|
def_vals = {a: sorted(set(b)) for a, b in can_dbc.def_vals.items()} # remove duplicates
|
|
def_vals = sorted(def_vals.items())
|
|
|
|
if can_dbc.name.startswith(("honda_", "acura_")):
|
|
checksum_type = "honda"
|
|
checksum_size = 4
|
|
counter_size = 2
|
|
checksum_start_bit = 3
|
|
counter_start_bit = 5
|
|
little_endian = False
|
|
elif can_dbc.name.startswith(("toyota_", "lexus_")):
|
|
checksum_type = "toyota"
|
|
checksum_size = 8
|
|
counter_size = None
|
|
checksum_start_bit = 7
|
|
counter_start_bit = None
|
|
little_endian = False
|
|
elif can_dbc.name.startswith(("vw_", "volkswagen_", "audi_", "seat_", "skoda_")):
|
|
checksum_type = "volkswagen"
|
|
checksum_size = 8
|
|
counter_size = 4
|
|
checksum_start_bit = 0
|
|
counter_start_bit = 0
|
|
little_endian = True
|
|
elif can_dbc.name.startswith(("subaru_")):
|
|
checksum_type = "subaru"
|
|
checksum_size = 8
|
|
counter_size = None
|
|
checksum_start_bit = 0
|
|
counter_start_bit = None
|
|
little_endian = True
|
|
elif can_dbc.name.startswith(("chrysler_")):
|
|
checksum_type = "chrysler"
|
|
checksum_size = 8
|
|
counter_size = None
|
|
checksum_start_bit = 7
|
|
counter_start_bit = None
|
|
little_endian = False
|
|
else:
|
|
checksum_type = None
|
|
checksum_size = None
|
|
counter_size = None
|
|
checksum_start_bit = None
|
|
counter_start_bit = None
|
|
little_endian = None
|
|
|
|
# sanity checks on expected COUNTER and CHECKSUM rules, as packer and parser auto-compute those signals
|
|
for address, msg_name, msg_size, sigs in msgs:
|
|
dbc_msg_name = dbc_name + " " + msg_name
|
|
for sig in sigs:
|
|
if checksum_type is not None:
|
|
# checksum rules
|
|
if sig.name == "CHECKSUM":
|
|
if sig.size != checksum_size:
|
|
sys.exit("%s: CHECKSUM is not %d bits long" % (dbc_msg_name, checksum_size))
|
|
if sig.start_bit % 8 != checksum_start_bit:
|
|
sys.exit("%s: CHECKSUM starts at wrong bit" % dbc_msg_name)
|
|
if little_endian != sig.is_little_endian:
|
|
sys.exit("%s: CHECKSUM has wrong endianess" % dbc_msg_name)
|
|
# counter rules
|
|
if sig.name == "COUNTER":
|
|
if counter_size is not None and sig.size != counter_size:
|
|
sys.exit("%s: COUNTER is not %d bits long" % (dbc_msg_name, counter_size))
|
|
if counter_start_bit is not None and sig.start_bit % 8 != counter_start_bit:
|
|
print(counter_start_bit, sig.start_bit)
|
|
sys.exit("%s: COUNTER starts at wrong bit" % dbc_msg_name)
|
|
if little_endian != sig.is_little_endian:
|
|
sys.exit("%s: COUNTER has wrong endianess" % dbc_msg_name)
|
|
# pedal rules
|
|
if address in [0x200, 0x201]:
|
|
if sig.name == "COUNTER_PEDAL" and sig.size != 4:
|
|
sys.exit("%s: PEDAL COUNTER is not 4 bits long" % dbc_msg_name)
|
|
if sig.name == "CHECKSUM_PEDAL" and sig.size != 8:
|
|
sys.exit("%s: PEDAL CHECKSUM is not 8 bits long" % dbc_msg_name)
|
|
|
|
# Fail on duplicate message names
|
|
c = Counter([msg_name for address, msg_name, msg_size, sigs in msgs])
|
|
for name, count in c.items():
|
|
if count > 1:
|
|
sys.exit("%s: Duplicate message name in DBC file %s" % (dbc_name, name))
|
|
|
|
parser_code = template.render(dbc=can_dbc, checksum_type=checksum_type, msgs=msgs, def_vals=def_vals, len=len)
|
|
|
|
with open(out_fn, "w") as out_f:
|
|
out_f.write(parser_code)
|
|
|
|
def main():
|
|
if len(sys.argv) != 3:
|
|
print("usage: %s dbc_directory output_filename" % (sys.argv[0],))
|
|
sys.exit(0)
|
|
|
|
dbc_dir = sys.argv[1]
|
|
out_fn = sys.argv[2]
|
|
|
|
dbc_name = os.path.split(out_fn)[-1].replace('.cc', '')
|
|
in_fn = os.path.join(dbc_dir, dbc_name + '.dbc')
|
|
|
|
process(in_fn, out_fn)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|