wip
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
from opendbc.can.parser_pyx import CANDefine # pylint: disable=no-name-in-module, import-error
|
||||
assert CANDefine
|
||||
@@ -1,75 +0,0 @@
|
||||
# distutils: language = c++
|
||||
# cython: language_level=3
|
||||
|
||||
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t
|
||||
from libcpp cimport bool
|
||||
from libcpp.pair cimport pair
|
||||
from libcpp.string cimport string
|
||||
from libcpp.vector cimport vector
|
||||
|
||||
|
||||
ctypedef unsigned int (*calc_checksum_type)(uint32_t, const Signal&, const vector[uint8_t] &)
|
||||
|
||||
cdef extern from "common_dbc.h":
|
||||
ctypedef enum SignalType:
|
||||
DEFAULT,
|
||||
COUNTER,
|
||||
HONDA_CHECKSUM,
|
||||
TOYOTA_CHECKSUM,
|
||||
PEDAL_CHECKSUM,
|
||||
VOLKSWAGEN_MQB_CHECKSUM,
|
||||
XOR_CHECKSUM,
|
||||
SUBARU_CHECKSUM,
|
||||
CHRYSLER_CHECKSUM
|
||||
HKG_CAN_FD_CHECKSUM,
|
||||
|
||||
cdef struct Signal:
|
||||
string name
|
||||
int start_bit, msb, lsb, size
|
||||
bool is_signed
|
||||
double factor, offset
|
||||
bool is_little_endian
|
||||
SignalType type
|
||||
calc_checksum_type calc_checksum
|
||||
|
||||
cdef struct Msg:
|
||||
string name
|
||||
uint32_t address
|
||||
unsigned int size
|
||||
vector[Signal] sigs
|
||||
|
||||
cdef struct Val:
|
||||
string name
|
||||
uint32_t address
|
||||
string def_val
|
||||
vector[Signal] sigs
|
||||
|
||||
cdef struct DBC:
|
||||
string name
|
||||
vector[Msg] msgs
|
||||
vector[Val] vals
|
||||
|
||||
cdef struct SignalValue:
|
||||
uint32_t address
|
||||
uint64_t ts_nanos
|
||||
string name
|
||||
double value
|
||||
vector[double] all_values
|
||||
|
||||
cdef struct SignalPackValue:
|
||||
string name
|
||||
double value
|
||||
|
||||
|
||||
cdef extern from "common.h":
|
||||
cdef const DBC* dbc_lookup(const string) except +
|
||||
|
||||
cdef cppclass CANParser:
|
||||
bool can_valid
|
||||
bool bus_timeout
|
||||
CANParser(int, string, vector[pair[uint32_t, int]]) except +
|
||||
void update_strings(vector[string]&, vector[SignalValue]&, bool) except +
|
||||
|
||||
cdef cppclass CANPacker:
|
||||
CANPacker(string)
|
||||
vector[uint8_t] pack(uint32_t, vector[SignalPackValue]&)
|
||||
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
from opendbc.can.packer_pyx import CANPacker # pylint: disable=no-name-in-module, import-error
|
||||
assert CANPacker
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,53 +0,0 @@
|
||||
# distutils: language = c++
|
||||
# cython: c_string_encoding=ascii, language_level=3
|
||||
|
||||
from libc.stdint cimport uint8_t
|
||||
from libcpp.vector cimport vector
|
||||
from libcpp.map cimport map
|
||||
from libcpp.string cimport string
|
||||
|
||||
from .common cimport CANPacker as cpp_CANPacker
|
||||
from .common cimport dbc_lookup, SignalPackValue, DBC
|
||||
|
||||
|
||||
cdef class CANPacker:
|
||||
cdef:
|
||||
cpp_CANPacker *packer
|
||||
const DBC *dbc
|
||||
map[string, int] name_to_address
|
||||
|
||||
def __init__(self, dbc_name):
|
||||
self.dbc = dbc_lookup(dbc_name)
|
||||
if not self.dbc:
|
||||
raise RuntimeError(f"Can't lookup {dbc_name}")
|
||||
|
||||
self.packer = new cpp_CANPacker(dbc_name)
|
||||
for i in range(self.dbc[0].msgs.size()):
|
||||
msg = self.dbc[0].msgs[i]
|
||||
self.name_to_address[string(msg.name)] = msg.address
|
||||
|
||||
def __dealloc__(self):
|
||||
if self.packer:
|
||||
del self.packer
|
||||
|
||||
cdef vector[uint8_t] pack(self, addr, values):
|
||||
cdef vector[SignalPackValue] values_thing
|
||||
values_thing.reserve(len(values))
|
||||
cdef SignalPackValue spv
|
||||
|
||||
for name, value in values.iteritems():
|
||||
spv.name = name.encode("utf8")
|
||||
spv.value = value
|
||||
values_thing.push_back(spv)
|
||||
|
||||
return self.packer.pack(addr, values_thing)
|
||||
|
||||
cpdef make_can_msg(self, name_or_addr, bus, values):
|
||||
cdef int addr
|
||||
if isinstance(name_or_addr, int):
|
||||
addr = name_or_addr
|
||||
else:
|
||||
addr = self.name_to_address[name_or_addr.encode("utf8")]
|
||||
|
||||
cdef vector[uint8_t] val = self.pack(addr, values)
|
||||
return [addr, 0, (<char *>&val[0])[:val.size()], bus]
|
||||
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
from opendbc.can.parser_pyx import CANParser, CANDefine # pylint: disable=no-name-in-module, import-error
|
||||
assert CANParser, CANDefine
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,146 +0,0 @@
|
||||
# distutils: language = c++
|
||||
# cython: c_string_encoding=ascii, language_level=3
|
||||
|
||||
from cython.operator cimport dereference as deref, preincrement as preinc
|
||||
from libcpp.pair cimport pair
|
||||
from libcpp.string cimport string
|
||||
from libcpp.vector cimport vector
|
||||
from libcpp.unordered_set cimport unordered_set
|
||||
from libc.stdint cimport uint32_t
|
||||
|
||||
from .common cimport CANParser as cpp_CANParser
|
||||
from .common cimport dbc_lookup, SignalValue, DBC
|
||||
|
||||
import numbers
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
cdef class CANParser:
|
||||
cdef:
|
||||
cpp_CANParser *can
|
||||
const DBC *dbc
|
||||
vector[SignalValue] can_values
|
||||
|
||||
cdef readonly:
|
||||
dict vl
|
||||
dict vl_all
|
||||
dict ts_nanos
|
||||
string dbc_name
|
||||
|
||||
def __init__(self, dbc_name, messages, bus=0):
|
||||
self.dbc_name = dbc_name
|
||||
self.dbc = dbc_lookup(dbc_name)
|
||||
if not self.dbc:
|
||||
raise RuntimeError(f"Can't find DBC: {dbc_name}")
|
||||
|
||||
self.vl = {}
|
||||
self.vl_all = {}
|
||||
self.ts_nanos = {}
|
||||
msg_name_to_address = {}
|
||||
address_to_msg_name = {}
|
||||
|
||||
for i in range(self.dbc[0].msgs.size()):
|
||||
msg = self.dbc[0].msgs[i]
|
||||
name = msg.name.decode("utf8")
|
||||
|
||||
msg_name_to_address[name] = msg.address
|
||||
address_to_msg_name[msg.address] = name
|
||||
|
||||
# Convert message names into addresses and check existence in DBC
|
||||
cdef vector[pair[uint32_t, int]] message_v
|
||||
for i in range(len(messages)):
|
||||
c = messages[i]
|
||||
address = c[0] if isinstance(c[0], numbers.Number) else msg_name_to_address.get(c[0])
|
||||
if address not in address_to_msg_name:
|
||||
raise RuntimeError(f"could not find message {repr(c[0])} in DBC {self.dbc_name}")
|
||||
message_v.push_back((address, c[1]))
|
||||
|
||||
name = address_to_msg_name[address]
|
||||
self.vl[address] = {}
|
||||
self.vl[name] = self.vl[address]
|
||||
self.vl_all[address] = {}
|
||||
self.vl_all[name] = self.vl_all[address]
|
||||
self.ts_nanos[address] = {}
|
||||
self.ts_nanos[name] = self.ts_nanos[address]
|
||||
|
||||
self.can = new cpp_CANParser(bus, dbc_name, message_v)
|
||||
self.update_strings([])
|
||||
|
||||
def __dealloc__(self):
|
||||
if self.can:
|
||||
del self.can
|
||||
|
||||
def update_strings(self, strings, sendcan=False):
|
||||
for v in self.vl_all.values():
|
||||
for l in v.values(): # no-cython-lint
|
||||
l.clear()
|
||||
|
||||
cdef vector[SignalValue] new_vals
|
||||
cdef unordered_set[uint32_t] updated_addrs
|
||||
|
||||
self.can.update_strings(strings, new_vals, sendcan)
|
||||
cdef vector[SignalValue].iterator it = new_vals.begin()
|
||||
cdef SignalValue* cv
|
||||
while it != new_vals.end():
|
||||
cv = &deref(it)
|
||||
# Cast char * directly to unicode
|
||||
cv_name = <unicode>cv.name
|
||||
self.vl[cv.address][cv_name] = cv.value
|
||||
self.vl_all[cv.address][cv_name] = cv.all_values
|
||||
self.ts_nanos[cv.address][cv_name] = cv.ts_nanos
|
||||
updated_addrs.insert(cv.address)
|
||||
preinc(it)
|
||||
|
||||
return updated_addrs
|
||||
|
||||
@property
|
||||
def can_valid(self):
|
||||
return self.can.can_valid
|
||||
|
||||
@property
|
||||
def bus_timeout(self):
|
||||
return self.can.bus_timeout
|
||||
|
||||
|
||||
cdef class CANDefine():
|
||||
cdef:
|
||||
const DBC *dbc
|
||||
|
||||
cdef public:
|
||||
dict dv
|
||||
string dbc_name
|
||||
|
||||
def __init__(self, dbc_name):
|
||||
self.dbc_name = dbc_name
|
||||
self.dbc = dbc_lookup(dbc_name)
|
||||
if not self.dbc:
|
||||
raise RuntimeError(f"Can't find DBC: '{dbc_name}'")
|
||||
|
||||
address_to_msg_name = {}
|
||||
|
||||
for i in range(self.dbc[0].msgs.size()):
|
||||
msg = self.dbc[0].msgs[i]
|
||||
name = msg.name.decode("utf8")
|
||||
address = msg.address
|
||||
address_to_msg_name[address] = name
|
||||
|
||||
dv = defaultdict(dict)
|
||||
|
||||
for i in range(self.dbc[0].vals.size()):
|
||||
val = self.dbc[0].vals[i]
|
||||
|
||||
sgname = val.name.decode("utf8")
|
||||
def_val = val.def_val.decode("utf8")
|
||||
address = val.address
|
||||
msgname = address_to_msg_name[address]
|
||||
|
||||
# separate definition/value pairs
|
||||
def_val = def_val.split()
|
||||
values = [int(v) for v in def_val[::2]]
|
||||
defs = def_val[1::2]
|
||||
|
||||
# two ways to lookup: address or msg name
|
||||
dv[address][sgname] = dict(zip(values, defs))
|
||||
dv[msgname][sgname] = dv[address][sgname]
|
||||
|
||||
self.dv = dict(dv)
|
||||
Binary file not shown.
Reference in New Issue
Block a user