def run_test(test): dbcpath = dbcs.DBC_PATH if test == "delphi": dbc_read = dbc(os.path.join(dbcpath, "delphi_esr2_64.dbc")) st = "0021e7cd0000864d".decode("hex") msg = 1280 elif test == "nidec": dbc_read = dbc(os.path.join(dbcpath, "acura_ilx_2016_nidec.dbc")) st = "0118111100000000".decode("hex") msg = 0x301 elif test == "steer_status": dbc_read = dbc(os.path.join(dbcpath, "acura_ilx_2016_can.dbc")) st = "00000000000000".decode("hex") msg = 0x18f print(st) print('here', dbc_read.msgs[msg]) out = dbc_read.decode([msg, 0, st], debug=True)[1] print("out!!", out) encoded = dbc_read.encode(msg, out) print("compare") print(encoded.encode("hex")) print(st.encode("hex")) assert encoded == st
def __init__(self, dbc_f, signals, checks=None): ### input: # dbc_f : dbc file # signals : List of tuples (name, address, ival) where # - name is the signal name. # - address is the corresponding message address. # - ival is the initial value. # checks : List of pairs (address, frequency) where # - address is the message address of a message for which health should be # monitored. # - frequency is the frequency at which health should be monitored. checks = [] if checks is None else checks self.msgs_ck = set([check[0] for check in checks]) self.frqs = dict(checks) self.can_valid = False # start with False CAN assumption # list of received msg we want to monitor counter and checksum for # read dbc file self.can_dbc = dbc(os.path.join(opendbc.DBC_PATH, dbc_f)) # initialize variables to initial values self.vl = {} # signal values self.ts = {} # time stamp recorded in log self.ct = {} # current time stamp self.ok = {} # valid message? self.cn = {} # message counter self.cn_vl = {} # message counter mismatch value self.ck = {} # message checksum status for _, addr, _ in signals: self.vl[addr] = {} self.ts[addr] = {} self.ct[addr] = sec_since_boot() self.ok[addr] = True self.cn[addr] = 0 self.cn_vl[addr] = 0 self.ck[addr] = False for name, addr, ival in signals: self.vl[addr][name] = ival self.ts[addr][name] = 0 self._msgs = [s[1] for s in signals] self._sgs = [s[0] for s in signals] self._message_indices = defaultdict(list) for i, x in enumerate(self._msgs): self._message_indices[x].append(i)
from common.realtime import Ratekeeper import selfdrive.messaging as messaging from selfdrive.services import service_list from selfdrive.config import CruiseButtons from selfdrive.car.honda.hondacan import fix from selfdrive.car.honda.carstate import get_can_parser from selfdrive.boardd.boardd import can_capnp_to_can_list, can_list_to_can_capnp from selfdrive.car.honda.can_parser import CANParser from cereal import car from common.dbc import dbc acura = dbc(os.path.join(DBC_PATH, "acura_ilx_2016_can.dbc")) def fake_car_params(): ret = car.CarParams.new_message() # largely copied from honda ret.carName = "honda" ret.radarName = "nidec" ret.carFingerprint = "ACURA ILX 2016 ACURAWATCH PLUS" ret.enableSteer = True ret.enableBrake = True ret.enableGas = True ret.enableCruise = False
from opendbc import DBC_PATH from common.realtime import Ratekeeper from selfdrive.config import Conversions as CV import selfdrive.messaging as messaging from selfdrive.services import service_list from selfdrive.car.honda.hondacan import fix from common.fingerprints import HONDA as CAR from selfdrive.car.honda.carstate import get_can_signals from selfdrive.boardd.boardd import can_capnp_to_can_list, can_list_to_can_capnp from selfdrive.car.honda.old_can_parser import CANParser from selfdrive.car.honda.interface import CarInterface from common.dbc import dbc honda = dbc( os.path.join(DBC_PATH, "honda_civic_touring_2016_can_generated.dbc")) # Trick: set 0x201 (interceptor) in fingerprints for gas is controlled like if there was an interceptor CP = CarInterface.get_params(CAR.CIVIC, {0x201}) def car_plant(pos, speed, grade, gas, brake): # vehicle parameters mass = 1700 aero_cd = 0.3 force_peak = mass * 3. force_brake_peak = -mass * 10. #1g power_peak = 100000 # 100kW speed_base = power_peak / force_peak rolling_res = 0.01 g = 9.81
import jinja2 from collections import Counter from common.dbc import dbc if len(sys.argv) != 3: print "usage: %s dbc_path struct_path" % (sys.argv[0], ) sys.exit(0) dbc_fn = sys.argv[1] out_fn = sys.argv[2] template_fn = os.path.join(os.path.dirname(__file__), "dbc_template.cc") can_dbc = dbc(dbc_fn) with open(template_fn, "r") as template_f: template = jinja2.Template(template_f.read(), trim_blocks=True, lstrip_blocks=True) 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.iteritems()) if msg_sigs ] if can_dbc.name.startswith("honda") or can_dbc.name.startswith("acura"):
def main(): if len(sys.argv) != 3: print "usage: %s dbc_directory output_directory" % (sys.argv[0], ) sys.exit(0) dbc_dir = sys.argv[1] out_dir = sys.argv[2] template_fn = os.path.join(os.path.dirname(__file__), "dbc_template.cc") template_mtime = os.path.getmtime(template_fn) this_file_mtime = os.path.getmtime(__file__) with open(template_fn, "r") as template_f: template = jinja2.Template(template_f.read(), trim_blocks=True, lstrip_blocks=True) for dbc_path in glob.iglob(os.path.join(dbc_dir, "*.dbc")): dbc_mtime = os.path.getmtime(dbc_path) dbc_fn = os.path.split(dbc_path)[1] dbc_name = os.path.splitext(dbc_fn)[0] can_dbc = dbc(dbc_path) out_fn = os.path.join(os.path.dirname(__file__), out_dir, dbc_name + ".cc") if os.path.exists(out_fn): out_mtime = os.path.getmtime(out_fn) else: out_mtime = 0 if dbc_mtime < out_mtime and template_mtime < out_mtime and this_file_mtime < out_mtime: continue #skip output is newer than template and dbc 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(six.iteritems(can_dbc.msgs)) if msg_sigs ] def_vals = {a: set(b) for a, b in can_dbc.def_vals.items()} #remove duplicates def_vals = [(address, sig) for address, sig in sorted(six.iteritems(def_vals))] if can_dbc.name.startswith("honda") or can_dbc.name.startswith( "acura"): checksum_type = "honda" checksum_size = 4 elif can_dbc.name.startswith("toyota") or can_dbc.name.startswith( "lexus"): checksum_type = "toyota" checksum_size = 8 else: checksum_type = None for address, msg_name, msg_size, sigs in msgs: for sig in sigs: if checksum_type is not None and sig.name == "CHECKSUM": if sig.size != checksum_size: sys.exit("CHECKSUM is not %d bits longs %s" % (checksum_size, msg_name)) if checksum_type == "honda" and sig.start_bit % 8 != 3: sys.exit("CHECKSUM starts at wrong bit %s" % msg_name) if checksum_type == "toyota" and sig.start_bit % 8 != 7: sys.exit("CHECKSUM starts at wrong bit %s" % msg_name) if checksum_type == "honda" and sig.name == "COUNTER": if sig.size != 2: sys.exit("COUNTER is not 2 bits longs %s" % msg_name) if sig.start_bit % 8 != 5: sys.exit("COUNTER starts at wrong bit %s" % msg_name) if address in [0x200, 0x201]: if sig.name == "COUNTER_PEDAL" and sig.size != 4: sys.exit("PEDAL COUNTER is not 4 bits longs %s" % msg_name) if sig.name == "CHECKSUM_PEDAL" and sig.size != 8: sys.exit("PEDAL CHECKSUM is not 8 bits longs %s" % 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("Duplicate message name in DBC file %s" % 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_directory" % (sys.argv[0], )) sys.exit(0) dbc_dir = sys.argv[1] out_dir = sys.argv[2] template_fn = os.path.join(os.path.dirname(__file__), "dbc_template.cc") template_mtime = os.path.getmtime(template_fn) this_file_mtime = os.path.getmtime(__file__) with open(template_fn, "r") as template_f: template = jinja2.Template(template_f.read(), trim_blocks=True, lstrip_blocks=True) for dbc_path in glob.iglob(os.path.join(dbc_dir, "*.dbc")): dbc_mtime = os.path.getmtime(dbc_path) dbc_fn = os.path.split(dbc_path)[1] dbc_name = os.path.splitext(dbc_fn)[0] can_dbc = dbc(dbc_path) out_fn = os.path.join(os.path.dirname(__file__), out_dir, dbc_name + ".cc") if os.path.exists(out_fn): out_mtime = os.path.getmtime(out_fn) else: out_mtime = 0 if dbc_mtime < out_mtime and template_mtime < out_mtime and this_file_mtime < out_mtime: continue #skip output is newer than template and dbc 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: 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 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)