mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-01 03:22:07 +08:00
07fbcc5dc2
4f82d01e gitignore
5cb83454 Honda FCM: diagnostic signals
d309cdce Added linter to opendbc (#203)
d452706f add requirements.txt
ec3b4595 deterministic dependency order
a265d351 Azure pipelines ci (#202)
bce9a2e1 packer depends on libdbc
5d5fdd6a no more python version of libdbc, everything through cython
541705bf move CANDefine to parser code
da25c52a add test for can define
0ba7926b unify can packer and parser
25d88009 consistent naming
a5c640a5 fix linter
be210fef remove obsolete make file
ffd9dca7 opendbc needs cereal
b559f63d remove more make
d0929496 seems to work now
41e80836 don't make
3254d1fc think scons works
eb78f6aa scons sort of working
0ef1e35d fix gitignore
e155e017 Can migration (#199)
3eded83a Honda: correct steering torque sensor sign to be consistent with standard convention (left+)
32f70e2f Fix outback endianness consistency (#196)
a7da471f Update subaru_outback_2015_eyesight.dbc (#195)
git-subtree-dir: opendbc
git-subtree-split: 4f82d01ebc78109888954d9807d320e3c27896fd
old-commit-hash: 683b6151ce
189 lines
4.8 KiB
Cython
189 lines
4.8 KiB
Cython
# distutils: language = c++
|
|
# cython: c_string_encoding=ascii, language_level=3
|
|
|
|
from libcpp.string cimport string
|
|
from libcpp.vector cimport vector
|
|
from libcpp cimport bool
|
|
from libcpp.unordered_set cimport unordered_set
|
|
from libc.stdint cimport uint32_t, uint64_t, uint16_t
|
|
from libcpp.map cimport map
|
|
|
|
from collections import defaultdict
|
|
|
|
from common cimport CANParser as cpp_CANParser
|
|
from common cimport SignalParseOptions, MessageParseOptions, dbc_lookup, SignalValue, DBC
|
|
|
|
|
|
from libcpp cimport bool
|
|
import os
|
|
import numbers
|
|
|
|
cdef int CAN_INVALID_CNT = 5
|
|
|
|
|
|
cdef class CANParser:
|
|
cdef:
|
|
cpp_CANParser *can
|
|
const DBC *dbc
|
|
map[string, uint32_t] msg_name_to_address
|
|
map[uint32_t, string] address_to_msg_name
|
|
vector[SignalValue] can_values
|
|
bool test_mode_enabled
|
|
|
|
cdef public:
|
|
string dbc_name
|
|
dict vl
|
|
dict ts
|
|
bool can_valid
|
|
int can_invalid_cnt
|
|
|
|
def __init__(self, dbc_name, signals, checks=None, bus=0):
|
|
if checks is None:
|
|
checks = []
|
|
|
|
self.can_valid = True
|
|
self.dbc_name = dbc_name
|
|
self.dbc = dbc_lookup(dbc_name)
|
|
self.vl = {}
|
|
self.ts = {}
|
|
|
|
self.can_invalid_cnt = CAN_INVALID_CNT
|
|
|
|
num_msgs = self.dbc[0].num_msgs
|
|
for i in range(num_msgs):
|
|
msg = self.dbc[0].msgs[i]
|
|
name = msg.name.decode('utf8')
|
|
|
|
self.msg_name_to_address[name] = msg.address
|
|
self.address_to_msg_name[msg.address] = name
|
|
self.vl[msg.address] = {}
|
|
self.vl[name] = {}
|
|
self.ts[msg.address] = {}
|
|
self.ts[name] = {}
|
|
|
|
# Convert message names into addresses
|
|
for i in range(len(signals)):
|
|
s = signals[i]
|
|
if not isinstance(s[1], numbers.Number):
|
|
name = s[1].encode('utf8')
|
|
s = (s[0], self.msg_name_to_address[name], s[2])
|
|
signals[i] = s
|
|
|
|
for i in range(len(checks)):
|
|
c = checks[i]
|
|
if not isinstance(c[0], numbers.Number):
|
|
name = c[0].encode('utf8')
|
|
c = (self.msg_name_to_address[name], c[1])
|
|
checks[i] = c
|
|
|
|
cdef vector[SignalParseOptions] signal_options_v
|
|
cdef SignalParseOptions spo
|
|
for sig_name, sig_address, sig_default in signals:
|
|
spo.address = sig_address
|
|
spo.name = sig_name
|
|
spo.default_value = sig_default
|
|
signal_options_v.push_back(spo)
|
|
|
|
message_options = dict((address, 0) for _, address, _ in signals)
|
|
message_options.update(dict(checks))
|
|
|
|
cdef vector[MessageParseOptions] message_options_v
|
|
cdef MessageParseOptions mpo
|
|
for msg_address, freq in message_options.items():
|
|
mpo.address = msg_address
|
|
mpo.check_frequency = freq
|
|
message_options_v.push_back(mpo)
|
|
|
|
self.can = new cpp_CANParser(bus, dbc_name, message_options_v, signal_options_v)
|
|
self.update_vl()
|
|
|
|
cdef unordered_set[uint32_t] update_vl(self):
|
|
cdef string sig_name
|
|
cdef unordered_set[uint32_t] updated_val
|
|
|
|
can_values = self.can.query_latest()
|
|
valid = self.can.can_valid
|
|
|
|
# Update invalid flag
|
|
self.can_invalid_cnt += 1
|
|
if valid:
|
|
self.can_invalid_cnt = 0
|
|
self.can_valid = self.can_invalid_cnt < CAN_INVALID_CNT
|
|
|
|
|
|
for cv in can_values:
|
|
# Cast char * directly to unicde
|
|
name = <unicode>self.address_to_msg_name[cv.address].c_str()
|
|
cv_name = <unicode>cv.name
|
|
|
|
self.vl[cv.address][cv_name] = cv.value
|
|
self.ts[cv.address][cv_name] = cv.ts
|
|
|
|
self.vl[name][cv_name] = cv.value
|
|
self.ts[name][cv_name] = cv.ts
|
|
|
|
updated_val.insert(cv.address)
|
|
|
|
return updated_val
|
|
|
|
def update_string(self, dat, sendcan=False):
|
|
self.can.update_string(dat, sendcan)
|
|
return self.update_vl()
|
|
|
|
def update_strings(self, strings, sendcan=False):
|
|
updated_vals = set()
|
|
|
|
for s in strings:
|
|
updated_val = self.update_string(s, sendcan)
|
|
updated_vals.update(updated_val)
|
|
|
|
return updated_vals
|
|
|
|
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)
|
|
|
|
num_vals = self.dbc[0].num_vals
|
|
|
|
address_to_msg_name = {}
|
|
|
|
num_msgs = self.dbc[0].num_msgs
|
|
for i in range(num_msgs):
|
|
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(num_vals):
|
|
val = self.dbc[0].vals[i]
|
|
|
|
sgname = val.name.decode('utf8')
|
|
address = val.address
|
|
def_val = val.def_val.decode('utf8')
|
|
|
|
#separate definition/value pairs
|
|
def_val = def_val.split()
|
|
values = [int(v) for v in def_val[::2]]
|
|
defs = def_val[1::2]
|
|
|
|
if address not in dv:
|
|
dv[address] = {}
|
|
msgname = address_to_msg_name[address]
|
|
dv[msgname] = {}
|
|
|
|
# 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)
|