mirror of https://github.com/rusefi/opendbc.git
CANParser: add field for all updated values (#548)
* add updated field * rename to updated * draft * clean up * function for resetting * *minor* refactor * clean up names * keep track of updated vals in the cc parser * remove extra lines * remove ts * match parser_pyx * cleaner to just call the cpp function as we don't need to aggregate updated values * draft * some tests * fix test * clean up clean up * test clean up * add clarifying comments * Revert "remove ts" This reverts commit fd4558289d6667a42ab41c4511b0d8fe54eb7fc8. * fix order * use vals * fix dup
This commit is contained in:
parent
6b57a33def
commit
da47fe5e45
|
@ -32,6 +32,7 @@ public:
|
|||
|
||||
std::vector<Signal> parse_sigs;
|
||||
std::vector<double> vals;
|
||||
std::vector<std::vector<double>> updated_vals;
|
||||
|
||||
uint16_t ts;
|
||||
uint64_t seen;
|
||||
|
@ -69,7 +70,7 @@ public:
|
|||
#endif
|
||||
void UpdateCans(uint64_t sec, const capnp::DynamicStruct::Reader& cans);
|
||||
void UpdateValid(uint64_t sec);
|
||||
std::vector<SignalValue> query_latest();
|
||||
std::vector<SignalValue> update_vl();
|
||||
};
|
||||
|
||||
class CANPacker {
|
||||
|
|
|
@ -63,6 +63,7 @@ cdef extern from "common_dbc.h":
|
|||
uint16_t ts
|
||||
const char* name
|
||||
double value
|
||||
vector[double] updated_values
|
||||
|
||||
cdef struct SignalPackValue:
|
||||
string name
|
||||
|
@ -76,7 +77,7 @@ cdef extern from "common.h":
|
|||
bool can_valid
|
||||
CANParser(int, string, vector[MessageParseOptions], vector[SignalParseOptions])
|
||||
void update_string(string, bool)
|
||||
vector[SignalValue] query_latest()
|
||||
vector[SignalValue] update_vl()
|
||||
|
||||
cdef cppclass CANPacker:
|
||||
CANPacker(string)
|
||||
|
|
|
@ -26,7 +26,8 @@ struct SignalValue {
|
|||
uint32_t address;
|
||||
uint16_t ts;
|
||||
const char* name;
|
||||
double value;
|
||||
double value; // latest value
|
||||
std::vector<double> updated_values; // values updated this cycle
|
||||
};
|
||||
|
||||
enum SignalType {
|
||||
|
|
|
@ -83,6 +83,7 @@ bool MessageState::parse(uint64_t sec, uint16_t ts_, uint8_t * dat) {
|
|||
}
|
||||
|
||||
vals[i] = tmp * sig.factor + sig.offset;
|
||||
updated_vals[i].push_back(vals[i]);
|
||||
}
|
||||
ts = ts_;
|
||||
seen = sec;
|
||||
|
@ -90,7 +91,6 @@ bool MessageState::parse(uint64_t sec, uint16_t ts_, uint8_t * dat) {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MessageState::update_counter_generic(int64_t v, int cnt_size) {
|
||||
uint8_t old_counter = counter;
|
||||
counter = v;
|
||||
|
@ -148,6 +148,7 @@ CANParser::CANParser(int abus, const std::string& dbc_name,
|
|||
if (sig->type != SignalType::DEFAULT) {
|
||||
state.parse_sigs.push_back(*sig);
|
||||
state.vals.push_back(0);
|
||||
state.updated_vals.push_back({});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,6 +162,7 @@ CANParser::CANParser(int abus, const std::string& dbc_name,
|
|||
&& sig->type == SignalType::DEFAULT) {
|
||||
state.parse_sigs.push_back(*sig);
|
||||
state.vals.push_back(0);
|
||||
state.updated_vals.push_back({});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -189,6 +191,7 @@ CANParser::CANParser(int abus, const std::string& dbc_name, bool ignore_checksum
|
|||
const Signal *sig = &msg->sigs[j];
|
||||
state.parse_sigs.push_back(*sig);
|
||||
state.vals.push_back(0);
|
||||
state.updated_vals.push_back({});
|
||||
}
|
||||
|
||||
message_states[state.address] = state;
|
||||
|
@ -280,12 +283,11 @@ void CANParser::UpdateValid(uint64_t sec) {
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<SignalValue> CANParser::query_latest() {
|
||||
std::vector<SignalValue> CANParser::update_vl() {
|
||||
std::vector<SignalValue> ret;
|
||||
|
||||
for (const auto& kv : message_states) {
|
||||
const auto& state = kv.second;
|
||||
if (last_sec != 0 && state.seen != last_sec) continue;
|
||||
for (auto& kv : message_states) {
|
||||
auto& state = kv.second;
|
||||
|
||||
for (int i=0; i<state.parse_sigs.size(); i++) {
|
||||
const Signal &sig = state.parse_sigs[i];
|
||||
|
@ -294,7 +296,9 @@ std::vector<SignalValue> CANParser::query_latest() {
|
|||
.ts = state.ts,
|
||||
.name = sig.name,
|
||||
.value = state.vals[i],
|
||||
.updated_values = state.updated_vals[i],
|
||||
});
|
||||
state.updated_vals[i].clear(); // reset updated values for next cycle
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ cdef class CANParser:
|
|||
string dbc_name
|
||||
dict vl
|
||||
dict ts
|
||||
dict updated
|
||||
bool can_valid
|
||||
int can_invalid_cnt
|
||||
|
||||
|
@ -43,6 +44,7 @@ cdef class CANParser:
|
|||
raise RuntimeError(f"Can't find DBC: {dbc_name}")
|
||||
self.vl = {}
|
||||
self.ts = {}
|
||||
self.updated = {}
|
||||
|
||||
self.can_invalid_cnt = CAN_INVALID_CNT
|
||||
|
||||
|
@ -58,6 +60,8 @@ cdef class CANParser:
|
|||
self.vl[name] = {}
|
||||
self.ts[msg.address] = {}
|
||||
self.ts[name] = {}
|
||||
self.updated[msg.address] = {}
|
||||
self.updated[name] = {}
|
||||
|
||||
# Convert message names into addresses
|
||||
for i in range(len(signals)):
|
||||
|
@ -106,13 +110,13 @@ cdef class CANParser:
|
|||
cdef string sig_name
|
||||
cdef unordered_set[uint32_t] updated_val
|
||||
|
||||
can_values = self.can.query_latest()
|
||||
can_values = self.can.update_vl()
|
||||
valid = self.can.can_valid
|
||||
|
||||
# Update invalid flag
|
||||
self.can_invalid_cnt += 1
|
||||
if valid:
|
||||
self.can_invalid_cnt = 0
|
||||
self.can_invalid_cnt = 0
|
||||
self.can_valid = self.can_invalid_cnt < CAN_INVALID_CNT
|
||||
|
||||
for cv in can_values:
|
||||
|
@ -121,12 +125,16 @@ cdef class CANParser:
|
|||
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[cv.address][cv_name] = cv.ts
|
||||
self.ts[name][cv_name] = cv.ts
|
||||
|
||||
updated_val.insert(cv.address)
|
||||
self.updated[cv.address][cv_name] = cv.updated_values
|
||||
self.updated[name][cv_name] = cv.updated_values
|
||||
|
||||
if cv.updated_values.size():
|
||||
updated_val.insert(cv.address)
|
||||
|
||||
return updated_val
|
||||
|
||||
|
@ -135,13 +143,10 @@ cdef class CANParser:
|
|||
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)
|
||||
self.can.update_string(s, sendcan)
|
||||
|
||||
return updated_vals
|
||||
return self.update_vl()
|
||||
|
||||
cdef class CANDefine():
|
||||
cdef:
|
||||
|
|
|
@ -119,6 +119,32 @@ class TestCanParserPacker(unittest.TestCase):
|
|||
|
||||
idx += 1
|
||||
|
||||
def test_updated(self):
|
||||
"""Test updated value dict"""
|
||||
dbc_file = "honda_civic_touring_2016_can_generated"
|
||||
|
||||
signals = [("USER_BRAKE", "VSA_STATUS")]
|
||||
checks = [("VSA_STATUS", 50)]
|
||||
|
||||
parser = CANParser(dbc_file, signals, checks, 0)
|
||||
packer = CANPacker(dbc_file)
|
||||
|
||||
# Make sure nothing is updated
|
||||
self.assertEqual(len(parser.updated["VSA_STATUS"]["USER_BRAKE"]), 0)
|
||||
|
||||
# Ensure CANParser holds the values of any duplicate messages
|
||||
user_brake_vals = [4, 5, 6, 7]
|
||||
msgs = []
|
||||
for user_brake in user_brake_vals:
|
||||
values = {"USER_BRAKE": user_brake}
|
||||
msgs.append(packer.make_can_msg("VSA_STATUS", 0, values))
|
||||
|
||||
parser.update_strings([can_list_to_can_capnp(msgs)])
|
||||
updated = parser.updated["VSA_STATUS"]["USER_BRAKE"]
|
||||
|
||||
self.assertEqual(updated, user_brake_vals)
|
||||
self.assertEqual(updated[-1], parser.vl["VSA_STATUS"]["USER_BRAKE"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in New Issue