Skip to content

Commit

Permalink
build message lookup table in dbc
Browse files Browse the repository at this point in the history
  • Loading branch information
deanlee committed Sep 6, 2023
1 parent 5ebf73e commit ef4e1c3
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 41 deletions.
3 changes: 1 addition & 2 deletions can/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,10 @@ class CANPacker {
private:
const DBC *dbc = NULL;
std::map<std::pair<uint32_t, std::string>, Signal> signal_lookup;
std::map<uint32_t, Msg> message_lookup;
std::map<uint32_t, uint32_t> counters;

public:
CANPacker(const std::string& dbc_name);
std::vector<uint8_t> pack(uint32_t address, const std::vector<SignalPackValue> &values);
std::pair<uint32_t, std::vector<uint8_t>> pack(const std::string &name_or_address, const std::vector<SignalPackValue> &values);
Msg* lookup_message(uint32_t address);
};
4 changes: 2 additions & 2 deletions can/common.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,5 @@ cdef extern from "common.h":
void update_strings(vector[string]&, vector[SignalValue]&, bool) except +

cdef cppclass CANPacker:
CANPacker(string)
vector[uint8_t] pack(uint32_t, vector[SignalPackValue]&)
CANPacker(string) except +
pair[uint32_t, vector[uint8_t]] pack(const string&, vector[SignalPackValue]&)
6 changes: 5 additions & 1 deletion can/common_dbc.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#include <cstddef>
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>

#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
Expand Down Expand Up @@ -61,6 +61,10 @@ struct DBC {
std::string name;
std::vector<Msg> msgs;
std::vector<Val> vals;
std::unordered_map<uint32_t, const Msg*> address_to_msg;
std::unordered_map<std::string, const Msg*> name_to_msg;

const Msg *findMessage(const std::string &name_or_address) const;
};

typedef struct ChecksumState {
Expand Down
14 changes: 14 additions & 0 deletions can/dbc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ DBC* dbc_parse_from_stream(const std::string &dbc_name, std::istream &stream, Ch

for (auto& m : dbc->msgs) {
m.sigs = signals[m.address];
dbc->address_to_msg[m.address] = &m;
dbc->name_to_msg[m.name] = &m;
}
for (auto& v : dbc->vals) {
v.sigs = signals[v.address];
Expand Down Expand Up @@ -256,3 +258,15 @@ std::vector<std::string> get_dbc_names() {
}
return dbcs;
}

const Msg* DBC::findMessage(const std::string& name_or_address) const {
auto it = name_to_msg.find(name_or_address);
if (it != name_to_msg.end()) return it->second;

try {
uint32_t address = std::stoul(name_or_address);
return address_to_msg.at(address);
} catch (std::exception& ex) {
return nullptr;
}
}
18 changes: 12 additions & 6 deletions can/packer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,25 @@ void set_value(std::vector<uint8_t> &msg, const Signal &sig, int64_t ival) {

CANPacker::CANPacker(const std::string& dbc_name) {
dbc = dbc_lookup(dbc_name);
assert(dbc);
if (!dbc) {
throw std::runtime_error("Can't find DBC: " + dbc_name);
}

for (const auto& msg : dbc->msgs) {
message_lookup[msg.address] = msg;
for (const auto& sig : msg.sigs) {
signal_lookup[std::make_pair(msg.address, std::string(sig.name))] = sig;
}
}
init_crc_lookup_tables();
}

std::vector<uint8_t> CANPacker::pack(uint32_t address, const std::vector<SignalPackValue> &signals) {
std::vector<uint8_t> ret(message_lookup[address].size, 0);
std::pair<uint32_t, std::vector<uint8_t>> CANPacker::pack(const std::string &name_or_address, const std::vector<SignalPackValue> &signals) {
auto msg = dbc->findMessage(name_or_address);
if (!msg) {
throw std::runtime_error("Can't find message: " + name_or_address);
}
uint32_t address = msg->address;
std::vector<uint8_t> ret(msg->size, 0);

// set all values for all given signal/value pairs
bool counter_set = false;
Expand Down Expand Up @@ -89,10 +95,10 @@ std::vector<uint8_t> CANPacker::pack(uint32_t address, const std::vector<SignalP
}
}

return ret;
return std::make_pair(address, ret);
}

// This function has a definition in common.h and is used in PlotJuggler
Msg* CANPacker::lookup_message(uint32_t address) {
return &message_lookup[address];
return (Msg*)dbc->address_to_msg.at(address);
}
35 changes: 5 additions & 30 deletions can/packer_pyx.pyx
Original file line number Diff line number Diff line change
@@ -1,49 +1,24 @@
# 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

from .common cimport SignalPackValue

cdef class CANPacker:
cdef:
cpp_CANPacker *packer
const DBC *dbc
map[string, int] name_to_address
cdef cpp_CANPacker *packer

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

cdef vector[uint8_t] pack(self, addr, values):
cpdef make_can_msg(self, name_or_addr, bus, 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]
ret = self.packer.pack(name_or_addr, values_thing)
return [ret.first, 0, (<char *>ret.second.data())[:ret.second.size()], bus]

0 comments on commit ef4e1c3

Please sign in to comment.