Cabana: load DBC from car fingerprint (#26158)

* auto load DBC from fingerprint

* generate json in scons
old-commit-hash: 2ed51e3151
taco
Dean Lee 3 years ago committed by GitHub
parent 59eae58840
commit 03aefed64a
  1. 2
      tools/cabana/.gitignore
  2. 1
      tools/cabana/SConscript
  3. 24
      tools/cabana/generate_dbc_json.py
  4. 32
      tools/cabana/messageswidget.cc
  5. 7
      tools/cabana/messageswidget.h

@ -3,3 +3,5 @@ moc_*
_cabana _cabana
settings settings
car_fingerprint_to_dbc.json

@ -12,5 +12,6 @@ else:
qt_libs = ['qt_util', 'Qt5Charts'] + base_libs qt_libs = ['qt_util', 'Qt5Charts'] + base_libs
cabana_libs = [widgets, cereal, messaging, visionipc, replay_lib, opendbc,'avutil', 'avcodec', 'avformat', 'bz2', 'curl', 'yuv'] + qt_libs cabana_libs = [widgets, cereal, messaging, visionipc, replay_lib, opendbc,'avutil', 'avcodec', 'avformat', 'bz2', 'curl', 'yuv'] + qt_libs
qt_env.Execute('./generate_dbc_json.py --out car_fingerprint_to_dbc.json')
qt_env.Program('_cabana', ['cabana.cc', 'mainwin.cc', 'binaryview.cc', 'chartswidget.cc', 'historylog.cc', 'videowidget.cc', 'signaledit.cc', 'dbcmanager.cc', qt_env.Program('_cabana', ['cabana.cc', 'mainwin.cc', 'binaryview.cc', 'chartswidget.cc', 'historylog.cc', 'videowidget.cc', 'signaledit.cc', 'dbcmanager.cc',
'canmessages.cc', 'messageswidget.cc', 'detailwidget.cc'], LIBS=cabana_libs, FRAMEWORKS=base_frameworks) 'canmessages.cc', 'messageswidget.cc', 'detailwidget.cc'], LIBS=cabana_libs, FRAMEWORKS=base_frameworks)

@ -0,0 +1,24 @@
#!/usr/bin/env python3
import argparse
import json
from selfdrive.car.car_helpers import get_interface_attr
def generate_dbc_json() -> str:
all_cars_by_brand = get_interface_attr("CAR_INFO")
all_dbcs_by_brand = get_interface_attr("DBC")
dbc_map = {car: all_dbcs_by_brand[brand][car]['pt'] for brand, cars in all_cars_by_brand.items() for car in cars if car != 'mock'}
return json.dumps(dict(sorted(dbc_map.items())), indent=2)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Generate mapping for all car fingerprints to DBC names and outputs json file",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("--out", required=True, help="Generated json filepath")
args = parser.parse_args()
with open(args.out, 'w') as f:
f.write(generate_dbc_json())
print(f"Generated and written to {args.out}")

@ -68,9 +68,10 @@ MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) {
// signals/slots // signals/slots
QObject::connect(filter, &QLineEdit::textChanged, proxy_model, &QSortFilterProxyModel::setFilterFixedString); QObject::connect(filter, &QLineEdit::textChanged, proxy_model, &QSortFilterProxyModel::setFilterFixedString);
QObject::connect(can, &CANMessages::eventsMerged, this, &MessagesWidget::loadDBCFromFingerprint);
QObject::connect(can, &CANMessages::updated, model, &MessageListModel::updateState); QObject::connect(can, &CANMessages::updated, model, &MessageListModel::updateState);
QObject::connect(dbc_combo, SIGNAL(activated(const QString &)), SLOT(dbcSelectionChanged(const QString &))); QObject::connect(dbc_combo, SIGNAL(activated(const QString &)), SLOT(loadDBCFromName(const QString &)));
QObject::connect(load_from_paste, &QPushButton::clicked, this, &MessagesWidget::loadFromPaste); QObject::connect(load_from_paste, &QPushButton::clicked, this, &MessagesWidget::loadDBCFromPaste);
QObject::connect(save_btn, &QPushButton::clicked, [=]() { QObject::connect(save_btn, &QPushButton::clicked, [=]() {
// TODO: save DBC to file // TODO: save DBC to file
}); });
@ -80,17 +81,20 @@ MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) {
} }
}); });
// For test purpose QFile json_file("./car_fingerprint_to_dbc.json");
dbc_combo->setCurrentText("toyota_nodsu_pt_generated"); if(json_file.open(QIODevice::ReadOnly)) {
fingerprint_to_dbc = QJsonDocument::fromJson(json_file.readAll());
}
} }
void MessagesWidget::dbcSelectionChanged(const QString &dbc_file) { void MessagesWidget::loadDBCFromName(const QString &name) {
dbc()->open(dbc_file); dbc()->open(name);
// TODO: reset model? dbc_combo->setCurrentText(name);
table_widget->sortByColumn(0, Qt::AscendingOrder); // refresh model
model->updateState();
} }
void MessagesWidget::loadFromPaste() { void MessagesWidget::loadDBCFromPaste() {
LoadDBCDialog dlg(this); LoadDBCDialog dlg(this);
if (dlg.exec()) { if (dlg.exec()) {
dbc()->open("from paste", dlg.dbc_edit->toPlainText()); dbc()->open("from paste", dlg.dbc_edit->toPlainText());
@ -98,6 +102,16 @@ void MessagesWidget::loadFromPaste() {
} }
} }
void MessagesWidget::loadDBCFromFingerprint() {
auto fingerprint = can->carFingerprint();
if (!fingerprint.isEmpty() && dbc()->name().isEmpty()) {
auto dbc_name = fingerprint_to_dbc[fingerprint];
if (dbc_name != QJsonValue::Undefined) {
loadDBCFromName(dbc_name.toString());
}
}
}
// MessageListModel // MessageListModel
QVariant MessageListModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant MessageListModel::headerData(int section, Qt::Orientation orientation, int role) const {

@ -3,6 +3,7 @@
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <QComboBox> #include <QComboBox>
#include <QDialog> #include <QDialog>
#include <QJsonDocument>
#include <QTableView> #include <QTableView>
#include <QTextEdit> #include <QTextEdit>
@ -38,8 +39,9 @@ public:
MessagesWidget(QWidget *parent); MessagesWidget(QWidget *parent);
public slots: public slots:
void dbcSelectionChanged(const QString &dbc_file); void loadDBCFromName(const QString &name);
void loadFromPaste(); void loadDBCFromFingerprint();
void loadDBCFromPaste();
signals: signals:
void msgSelectionChanged(const QString &message_id); void msgSelectionChanged(const QString &message_id);
@ -48,4 +50,5 @@ protected:
QTableView *table_widget; QTableView *table_widget;
QComboBox *dbc_combo; QComboBox *dbc_combo;
MessageListModel *model; MessageListModel *model;
QJsonDocument fingerprint_to_dbc;
}; };

Loading…
Cancel
Save