mirror of https://github.com/rusefi/opendbc.git
teach the packer how to count (#669)
* teach the packer how to count * fix tests * same as checksum * little test
This commit is contained in:
parent
72d3f935e6
commit
387dcf9628
|
@ -87,9 +87,10 @@ 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, int counter);
|
||||
std::vector<uint8_t> pack(uint32_t address, const std::vector<SignalPackValue> &values);
|
||||
Msg* lookup_message(uint32_t address);
|
||||
};
|
||||
|
|
|
@ -82,4 +82,4 @@ cdef extern from "common.h":
|
|||
|
||||
cdef cppclass CANPacker:
|
||||
CANPacker(string)
|
||||
vector[uint8_t] pack(uint32_t, vector[SignalPackValue], int counter)
|
||||
vector[uint8_t] pack(uint32_t, vector[SignalPackValue])
|
||||
|
|
|
@ -40,10 +40,12 @@ CANPacker::CANPacker(const std::string& dbc_name) {
|
|||
init_crc_lookup_tables();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> CANPacker::pack(uint32_t address, const std::vector<SignalPackValue> &signals, int counter) {
|
||||
std::vector<uint8_t> CANPacker::pack(uint32_t address, const std::vector<SignalPackValue> &signals) {
|
||||
std::vector<uint8_t> ret(message_lookup[address].size, 0);
|
||||
|
||||
// set all values for all given signal/value pairs
|
||||
bool counter_set = false;
|
||||
bool checksum_set = false;
|
||||
for (const auto& sigval : signals) {
|
||||
auto sig_it = signal_lookup.find(std::make_pair(address, sigval.name));
|
||||
if (sig_it == signal_lookup.end()) {
|
||||
|
@ -57,24 +59,30 @@ std::vector<uint8_t> CANPacker::pack(uint32_t address, const std::vector<SignalP
|
|||
if (ival < 0) {
|
||||
ival = (1ULL << sig.size) + ival;
|
||||
}
|
||||
|
||||
set_value(ret, sig, ival);
|
||||
|
||||
counter_set = counter_set || (sigval.name == "COUNTER");
|
||||
checksum_set = checksum_set || (sigval.name == "CHECKSUM");
|
||||
if (counter_set) {
|
||||
counters[address] = sigval.value;
|
||||
}
|
||||
}
|
||||
|
||||
// set message counter
|
||||
if (counter >= 0){
|
||||
auto sig_it = signal_lookup.find(std::make_pair(address, "COUNTER"));
|
||||
if (sig_it == signal_lookup.end()) {
|
||||
WARN("COUNTER not defined\n");
|
||||
return ret;
|
||||
auto sig_it_counter = signal_lookup.find(std::make_pair(address, "COUNTER"));
|
||||
if (!counter_set && sig_it_counter != signal_lookup.end()) {
|
||||
const auto& sig = sig_it_counter->second;
|
||||
|
||||
if (counters.find(address) == counters.end()) {
|
||||
counters[address] = 0;
|
||||
}
|
||||
const auto& sig = sig_it->second;
|
||||
set_value(ret, sig, counter);
|
||||
set_value(ret, sig, counters[address]);
|
||||
counters[address] = (counters[address] + 1) % (1 << sig.size);
|
||||
}
|
||||
|
||||
// set message checksum
|
||||
auto sig_it_checksum = signal_lookup.find(std::make_pair(address, "CHECKSUM"));
|
||||
if (sig_it_checksum != signal_lookup.end()) {
|
||||
if (!checksum_set && sig_it_checksum != signal_lookup.end()) {
|
||||
const auto &sig = sig_it_checksum->second;
|
||||
if (sig.calc_checksum != nullptr) {
|
||||
unsigned int checksum = sig.calc_checksum(address, sig, ret);
|
||||
|
|
|
@ -30,7 +30,7 @@ cdef class CANPacker:
|
|||
self.name_to_address_and_size[string(msg.name)] = (msg.address, msg.size)
|
||||
self.address_to_size[msg.address] = msg.size
|
||||
|
||||
cdef vector[uint8_t] pack(self, addr, values, counter):
|
||||
cdef vector[uint8_t] pack(self, addr, values):
|
||||
cdef vector[SignalPackValue] values_thing
|
||||
values_thing.reserve(len(values))
|
||||
cdef SignalPackValue spv
|
||||
|
@ -40,9 +40,9 @@ cdef class CANPacker:
|
|||
spv.value = value
|
||||
values_thing.push_back(spv)
|
||||
|
||||
return self.packer.pack(addr, values_thing, counter)
|
||||
return self.packer.pack(addr, values_thing)
|
||||
|
||||
cpdef make_can_msg(self, name_or_addr, bus, values, counter=-1):
|
||||
cpdef make_can_msg(self, name_or_addr, bus, values):
|
||||
cdef int addr, size
|
||||
if type(name_or_addr) == int:
|
||||
addr = name_or_addr
|
||||
|
@ -50,5 +50,5 @@ cdef class CANPacker:
|
|||
else:
|
||||
addr, size = self.name_to_address_and_size[name_or_addr.encode('utf8')]
|
||||
|
||||
cdef vector[uint8_t] val = self.pack(addr, values, counter)
|
||||
cdef vector[uint8_t] val = self.pack(addr, values)
|
||||
return [addr, 0, (<char *>&val[0])[:size], bus]
|
||||
|
|
|
@ -32,10 +32,10 @@ class TestCanChecksums(unittest.TestCase):
|
|||
checksum_std = [11, 10, 9, 8]
|
||||
checksum_ext = [4, 3, 2, 1]
|
||||
|
||||
for idx, (std, ext) in enumerate(zip(checksum_std, checksum_ext)):
|
||||
for std, ext in zip(checksum_std, checksum_ext):
|
||||
msgs = [
|
||||
packer.make_can_msg("LKAS_HUD", 0, values, idx),
|
||||
packer.make_can_msg("LKAS_HUD_A", 0, values, idx),
|
||||
packer.make_can_msg("LKAS_HUD", 0, values),
|
||||
packer.make_can_msg("LKAS_HUD_A", 0, values),
|
||||
]
|
||||
can_strings = [can_list_to_can_capnp(msgs), ]
|
||||
parser.update_strings(can_strings)
|
||||
|
|
|
@ -45,6 +45,39 @@ class TestCanParserPacker(unittest.TestCase):
|
|||
self.assertEqual(bus, b)
|
||||
self.assertEqual(dat[0], i)
|
||||
|
||||
def test_packer_counter(self):
|
||||
signals = [
|
||||
("COUNTER", "CAN_FD_MESSAGE"),
|
||||
]
|
||||
checks = [("CAN_FD_MESSAGE", 0), ]
|
||||
packer = CANPacker(TEST_DBC)
|
||||
parser = CANParser(TEST_DBC, signals, checks, 0)
|
||||
|
||||
# packer should increment the counter
|
||||
for i in range(1000):
|
||||
msg = packer.make_can_msg("CAN_FD_MESSAGE", 0, {})
|
||||
dat = can_list_to_can_capnp([msg, ])
|
||||
parser.update_string(dat)
|
||||
self.assertEqual(parser.vl["CAN_FD_MESSAGE"]["COUNTER"], i % 256)
|
||||
|
||||
# setting COUNTER should override
|
||||
for _ in range(100):
|
||||
cnt = random.randint(0, 255)
|
||||
msg = packer.make_can_msg("CAN_FD_MESSAGE", 0, {
|
||||
"COUNTER": cnt,
|
||||
})
|
||||
dat = can_list_to_can_capnp([msg, ])
|
||||
parser.update_string(dat)
|
||||
self.assertEqual(parser.vl["CAN_FD_MESSAGE"]["COUNTER"], cnt)
|
||||
|
||||
# then, should resume counting from the override value
|
||||
cnt = parser.vl["CAN_FD_MESSAGE"]["COUNTER"]
|
||||
for i in range(100):
|
||||
msg = packer.make_can_msg("CAN_FD_MESSAGE", 0, {})
|
||||
dat = can_list_to_can_capnp([msg, ])
|
||||
parser.update_string(dat)
|
||||
self.assertEqual(parser.vl["CAN_FD_MESSAGE"]["COUNTER"], (cnt + i) % 256)
|
||||
|
||||
def test_parser_can_valid(self):
|
||||
signals = [
|
||||
("COUNTER", "CAN_FD_MESSAGE"),
|
||||
|
@ -89,18 +122,15 @@ class TestCanParserPacker(unittest.TestCase):
|
|||
packer = CANPacker(TEST_DBC)
|
||||
parser = CANParser(TEST_DBC, signals, checks, 0)
|
||||
|
||||
idx = 0
|
||||
|
||||
for steer in range(-256, 255):
|
||||
for active in (1, 0):
|
||||
v1 = {
|
||||
"STEER_TORQUE": steer,
|
||||
"STEER_TORQUE_REQUEST": active,
|
||||
}
|
||||
m1 = packer.make_can_msg("STEERING_CONTROL", 0, v1, idx)
|
||||
m1 = packer.make_can_msg("STEERING_CONTROL", 0, v1)
|
||||
|
||||
v2 = {
|
||||
"COUNTER": idx % 256,
|
||||
"SIGNED": steer,
|
||||
"64_BIT_LE": random.randint(0, 100),
|
||||
"64_BIT_BE": random.randint(0, 100),
|
||||
|
@ -120,7 +150,6 @@ class TestCanParserPacker(unittest.TestCase):
|
|||
for sig in ("STEER_TORQUE", "STEER_TORQUE_REQUEST", "COUNTER", "CHECKSUM"):
|
||||
self.assertEqual(parser.vl["STEERING_CONTROL"][sig], parser.vl[228][sig])
|
||||
|
||||
idx += 1
|
||||
|
||||
def test_scale_offset(self):
|
||||
"""Test that both scale and offset are correctly preserved"""
|
||||
|
@ -134,16 +163,14 @@ class TestCanParserPacker(unittest.TestCase):
|
|||
parser = CANParser(dbc_file, signals, checks, 0)
|
||||
packer = CANPacker(dbc_file)
|
||||
|
||||
idx = 0
|
||||
for brake in range(0, 100):
|
||||
values = {"USER_BRAKE": brake}
|
||||
msgs = packer.make_can_msg("VSA_STATUS", 0, values, idx)
|
||||
msgs = packer.make_can_msg("VSA_STATUS", 0, values)
|
||||
bts = can_list_to_can_capnp([msgs])
|
||||
|
||||
parser.update_string(bts)
|
||||
|
||||
self.assertAlmostEqual(parser.vl["VSA_STATUS"]["USER_BRAKE"], brake)
|
||||
idx += 1
|
||||
|
||||
def test_subaru(self):
|
||||
# Subuaru is little endian
|
||||
|
@ -162,7 +189,6 @@ class TestCanParserPacker(unittest.TestCase):
|
|||
packer = CANPacker(dbc_file)
|
||||
|
||||
idx = 0
|
||||
|
||||
for steer in range(-256, 255):
|
||||
for active in [1, 0]:
|
||||
values = {
|
||||
|
@ -171,7 +197,7 @@ class TestCanParserPacker(unittest.TestCase):
|
|||
"SET_1": 1
|
||||
}
|
||||
|
||||
msgs = packer.make_can_msg("ES_LKAS", 0, values, idx)
|
||||
msgs = packer.make_can_msg("ES_LKAS", 0, values)
|
||||
bts = can_list_to_can_capnp([msgs])
|
||||
parser.update_string(bts)
|
||||
|
||||
|
@ -179,7 +205,6 @@ class TestCanParserPacker(unittest.TestCase):
|
|||
self.assertAlmostEqual(parser.vl["ES_LKAS"]["LKAS_Request"], active)
|
||||
self.assertAlmostEqual(parser.vl["ES_LKAS"]["SET_1"], 1)
|
||||
self.assertAlmostEqual(parser.vl["ES_LKAS"]["COUNTER"], idx % 16)
|
||||
|
||||
idx += 1
|
||||
|
||||
def test_bus_timeout(self):
|
||||
|
@ -243,7 +268,7 @@ class TestCanParserPacker(unittest.TestCase):
|
|||
for frame, brake_vals in enumerate((user_brake_vals[:half_idx], user_brake_vals[half_idx:])):
|
||||
for user_brake in brake_vals:
|
||||
values = {"USER_BRAKE": user_brake}
|
||||
can_msgs[frame].append(packer.make_can_msg("VSA_STATUS", 0, values, idx))
|
||||
can_msgs[frame].append(packer.make_can_msg("VSA_STATUS", 0, values))
|
||||
idx += 1
|
||||
|
||||
can_strings = [can_list_to_can_capnp(msgs) for msgs in can_msgs]
|
||||
|
|
Loading…
Reference in New Issue