openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

129 lines
4.3 KiB

#include "opendbc/can/common.h"
#undef INFO
#include "catch2/catch.hpp"
#include "tools/replay/logreader.h"
#include "tools/cabana/dbc/dbcmanager.h"
#include "tools/cabana/streams/abstractstream.h"
// demo route, first segment
const std::string TEST_RLOG_URL = "https://commadata2.blob.core.windows.net/commadata2/a2a0ccea32023010/2023-07-27--13-01-19/0/rlog.bz2";
TEST_CASE("DBCFile::generateDBC") {
QString fn = QString("%1/%2.dbc").arg(OPENDBC_FILE_PATH, "tesla_can");
DBCFile dbc_origin(fn);
DBCFile dbc_from_generated("", dbc_origin.generateDBC());
REQUIRE(dbc_origin.msgCount() == dbc_from_generated.msgCount());
auto &msgs = dbc_origin.getMessages();
auto &new_msgs = dbc_from_generated.getMessages();
for (auto &[id, m] : msgs) {
auto &new_m = new_msgs.at(id);
REQUIRE(m.name == new_m.name);
REQUIRE(m.size == new_m.size);
REQUIRE(m.getSignals().size() == new_m.getSignals().size());
auto sigs = m.getSignals();
auto new_sigs = new_m.getSignals();
for (int i = 0; i < sigs.size(); ++i) {
REQUIRE(*sigs[i] == *new_sigs[i]);
}
}
}
TEST_CASE("Parse can messages") {
DBCManager dbc(nullptr);
dbc.open({0}, "toyota_new_mc_pt_generated");
CANParser can_parser(0, "toyota_new_mc_pt_generated", {}, {});
LogReader log;
REQUIRE(log.load(TEST_RLOG_URL, nullptr, {}, true));
REQUIRE(log.events.size() > 0);
for (auto e : log.events) {
if (e->which == cereal::Event::Which::CAN) {
std::map<std::pair<uint32_t, QString>, std::vector<double>> values_1;
for (const auto &c : e->event.getCan()) {
const auto msg = dbc.msg({.source = c.getSrc(), .address = c.getAddress()});
if (c.getSrc() == 0 && msg) {
for (auto sig : msg->getSignals()) {
double val = get_raw_value((uint8_t *)c.getDat().begin(), c.getDat().size(), *sig);
values_1[{c.getAddress(), sig->name}].push_back(val);
}
}
}
can_parser.UpdateCans(e->mono_time, e->event.getCan());
std::vector<SignalValue> values_2;
can_parser.query_latest(values_2);
for (auto &[key, v1] : values_1) {
bool found = false;
for (auto &v2 : values_2) {
if (v2.address == key.first && key.second == v2.name.c_str()) {
REQUIRE(v2.all_values.size() == v1.size());
REQUIRE(v2.all_values == v1);
found = true;
break;
}
}
REQUIRE(found);
}
}
}
}
TEST_CASE("Parse dbc") {
QString content = R"(
BO_ 160 message_1: 8 EON
SG_ signal_1 : 0|12@1+ (1,0) [0|4095] "unit" XXX
SG_ signal_2 : 12|1@1+ (1.0,0.0) [0.0|1] "" XXX
BO_ 162 message_1: 8 XXX
SG_ signal_1 M : 0|12@1+ (1,0) [0|4095] "unit" XXX
SG_ signal_2 M4 : 12|1@1+ (1.0,0.0) [0.0|1] "" XXX
VAL_ 160 signal_1 0 "disabled" 1.2 "initializing" 2 "fault";
CM_ BO_ 160 "message comment" ;
CM_ SG_ 160 signal_1 "signal comment";
CM_ SG_ 160 signal_2 "multiple line comment
1
2
";)";
DBCFile file("", content);
auto msg = file.msg(160);
REQUIRE(msg != nullptr);
REQUIRE(msg->name == "message_1");
REQUIRE(msg->size == 8);
REQUIRE(msg->comment == "message comment");
REQUIRE(msg->sigs.size() == 2);
REQUIRE(msg->transmitter == "EON");
REQUIRE(file.msg("message_1") != nullptr);
auto sig_1 = msg->sigs[0];
REQUIRE(sig_1->name == "signal_1");
REQUIRE(sig_1->start_bit == 0);
REQUIRE(sig_1->size == 12);
REQUIRE(sig_1->min == 0);
REQUIRE(sig_1->max == 4095);
REQUIRE(sig_1->unit == "unit");
REQUIRE(sig_1->comment == "signal comment");
REQUIRE(sig_1->receiver_name == "XXX");
REQUIRE(sig_1->val_desc.size() == 3);
REQUIRE(sig_1->val_desc[0] == std::pair<double, QString>{0, "disabled"});
REQUIRE(sig_1->val_desc[1] == std::pair<double, QString>{1.2, "initializing"});
REQUIRE(sig_1->val_desc[2] == std::pair<double, QString>{2, "fault"});
auto &sig_2 = msg->sigs[1];
REQUIRE(sig_2->comment == "multiple line comment\n1\n2");
// multiplexed signals
msg = file.msg(162);
REQUIRE(msg != nullptr);
REQUIRE(msg->sigs.size() == 2);
REQUIRE(msg->sigs[0]->type == cabana::Signal::Type::Multiplexor);
REQUIRE(msg->sigs[1]->type == cabana::Signal::Type::Multiplexed);
REQUIRE(msg->sigs[1]->multiplex_value == 4);
REQUIRE(msg->sigs[1]->start_bit == 12);
REQUIRE(msg->sigs[1]->size == 1);
REQUIRE(msg->sigs[1]->receiver_name == "XXX");
}