cabana: DBCManager only expose methods/signals through MessageId (#27540)

pull/27585/head
Willem Melching 2 years ago committed by GitHub
parent b591b0c764
commit 0afd3bab34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      tools/cabana/chartswidget.cc
  2. 4
      tools/cabana/chartswidget.h
  3. 22
      tools/cabana/dbcmanager.cc
  4. 38
      tools/cabana/dbcmanager.h
  5. 5
      tools/cabana/detailwidget.cc
  6. 1
      tools/cabana/detailwidget.h
  7. 4
      tools/cabana/mainwin.cc
  8. 13
      tools/cabana/signaledit.cc
  9. 4
      tools/cabana/signaledit.h
  10. 5
      tools/cabana/streams/abstractstream.cc
  11. 2
      tools/cabana/streams/abstractstream.h
  12. 12
      tools/cabana/tests/test_cabana.cc
  13. 5
      tools/cabana/tools/findsimilarbits.cc

@ -421,8 +421,8 @@ void ChartView::signalUpdated(const cabana::Signal *sig) {
} }
} }
void ChartView::msgUpdated(uint32_t address) { void ChartView::msgUpdated(MessageId id) {
if (std::any_of(sigs.begin(), sigs.end(), [=](auto &s) { return s.msg_id.address == address; })) if (std::any_of(sigs.begin(), sigs.end(), [=](auto &s) { return s.msg_id == id; }))
updateTitle(); updateTitle();
} }

@ -57,11 +57,11 @@ signals:
void axisYLabelWidthChanged(int w); void axisYLabelWidthChanged(int w);
private slots: private slots:
void msgUpdated(uint32_t address);
void signalUpdated(const cabana::Signal *sig); void signalUpdated(const cabana::Signal *sig);
void manageSeries(); void manageSeries();
void handleMarkerClicked(); void handleMarkerClicked();
void msgRemoved(uint32_t address) { removeIf([=](auto &s) { return s.msg_id.address == address; }); } void msgUpdated(MessageId id);
void msgRemoved(MessageId id) { removeIf([=](auto &s) { return s.msg_id == id; }); }
void signalRemoved(const cabana::Signal *sig) { removeIf([=](auto &s) { return s.sig == sig; }); } void signalRemoved(const cabana::Signal *sig) { removeIf([=](auto &s) { return s.sig == sig; }); }
private: private:

@ -144,19 +144,31 @@ void DBCManager::updateMsg(const MessageId &id, const QString &name, uint32_t si
auto &m = msgs[id.address]; auto &m = msgs[id.address];
m.name = name; m.name = name;
m.size = size; m.size = size;
emit msgUpdated(id.address);
// This DBC applies to all active sources, emit for every source
for (uint8_t source : sources) {
emit msgUpdated({.source = source, .address = id.address});
}
} }
void DBCManager::removeMsg(const MessageId &id) { void DBCManager::removeMsg(const MessageId &id) {
msgs.erase(id.address); msgs.erase(id.address);
emit msgRemoved(id.address);
// This DBC applies to all active sources, emit for every source
for (uint8_t source : sources) {
emit msgRemoved({.source = source, .address = id.address});
}
} }
void DBCManager::addSignal(const MessageId &id, const cabana::Signal &sig) { void DBCManager::addSignal(const MessageId &id, const cabana::Signal &sig) {
if (auto m = const_cast<cabana::Msg *>(msg(id.address))) { if (auto m = const_cast<cabana::Msg *>(msg(id.address))) {
m->sigs.push_back(sig); m->sigs.push_back(sig);
auto s = &m->sigs.last(); auto s = &m->sigs.last();
emit signalAdded(id.address, s);
// This DBC applies to all active sources, emit for every source
for (uint8_t source : sources) {
emit signalAdded({.source = source, .address = id.address}, s);
}
} }
} }
@ -192,6 +204,10 @@ QStringList DBCManager::signalNames() {
return ret; return ret;
} }
void DBCManager::updateSources(const QSet<uint8_t> &s) {
sources = s;
}
DBCManager *dbc() { DBCManager *dbc() {
static DBCManager dbc_manager(nullptr); static DBCManager dbc_manager(nullptr);
return &dbc_manager; return &dbc_manager;

@ -5,6 +5,8 @@
#include <QMetaType> #include <QMetaType>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QSet>
#include <QDebug>
#include "tools/cabana/dbc.h" #include "tools/cabana/dbc.h"
@ -20,30 +22,52 @@ public:
void addSignal(const MessageId &id, const cabana::Signal &sig); void addSignal(const MessageId &id, const cabana::Signal &sig);
void updateSignal(const MessageId &id, const QString &sig_name, const cabana::Signal &sig); void updateSignal(const MessageId &id, const QString &sig_name, const cabana::Signal &sig);
void removeSignal(const MessageId &id, const QString &sig_name); void removeSignal(const MessageId &id, const QString &sig_name);
inline int msgCount() const { return msgs.size(); }
inline QString name() const { return name_; } inline QString name() const { return name_; }
void updateMsg(const MessageId &id, const QString &name, uint32_t size); void updateMsg(const MessageId &id, const QString &name, uint32_t size);
void removeMsg(const MessageId &id); void removeMsg(const MessageId &id);
inline const std::map<uint32_t, cabana::Msg> &messages() const { return msgs; } inline std::map<MessageId, cabana::Msg> getMessages(uint8_t source) {
std::map<MessageId, cabana::Msg> ret;
for (auto &[address, msg] : msgs) {
MessageId id = {.source = source, .address = address};
ret[id] = msg;
}
return ret;
}
inline const cabana::Msg *msg(const MessageId &id) const { return msg(id.address); } inline const cabana::Msg *msg(const MessageId &id) const { return msg(id.address); }
inline const cabana::Msg *msg(uint32_t address) const { inline const cabana::Msg* msg(uint8_t source, const QString &name) {
auto it = msgs.find(address); for (auto &[_, msg] : msgs) {
return it != msgs.end() ? &it->second : nullptr; if (msg.name == name) {
return &msg;
}
}
return nullptr;
} }
QStringList signalNames(); QStringList signalNames();
public slots:
void updateSources(const QSet<uint8_t> &s);
signals: signals:
void signalAdded(uint32_t address, const cabana::Signal *sig); void signalAdded(MessageId id, const cabana::Signal *sig);
void signalRemoved(const cabana::Signal *sig); void signalRemoved(const cabana::Signal *sig);
void signalUpdated(const cabana::Signal *sig); void signalUpdated(const cabana::Signal *sig);
void msgUpdated(uint32_t address); void msgUpdated(MessageId id);
void msgRemoved(uint32_t address); void msgRemoved(MessageId id);
void DBCFileChanged(); void DBCFileChanged();
private: private:
void parseExtraInfo(const QString &content); void parseExtraInfo(const QString &content);
std::map<uint32_t, cabana::Msg> msgs; std::map<uint32_t, cabana::Msg> msgs;
QString name_; QString name_;
QSet<uint8_t> sources;
inline const cabana::Msg *msg(uint32_t address) const {
auto it = msgs.find(address);
return it != msgs.end() ? &it->second : nullptr;
}
}; };
DBCManager *dbc(); DBCManager *dbc();

@ -177,7 +177,7 @@ void DetailWidget::removeMsg() {
// EditMessageDialog // EditMessageDialog
EditMessageDialog::EditMessageDialog(const MessageId &msg_id, const QString &title, int size, QWidget *parent) EditMessageDialog::EditMessageDialog(const MessageId &msg_id, const QString &title, int size, QWidget *parent)
: original_name(title), QDialog(parent) { : original_name(title), msg_id(msg_id), QDialog(parent) {
setWindowTitle(tr("Edit message: %1").arg(msg_id.toString())); setWindowTitle(tr("Edit message: %1").arg(msg_id.toString()));
QFormLayout *form_layout = new QFormLayout(this); QFormLayout *form_layout = new QFormLayout(this);
@ -207,8 +207,7 @@ void EditMessageDialog::validateName(const QString &text) {
bool valid = text.compare(UNTITLED, Qt::CaseInsensitive) != 0; bool valid = text.compare(UNTITLED, Qt::CaseInsensitive) != 0;
error_label->setVisible(false); error_label->setVisible(false);
if (!text.isEmpty() && valid && text != original_name) { if (!text.isEmpty() && valid && text != original_name) {
valid = std::none_of(dbc()->messages().begin(), dbc()->messages().end(), valid = dbc()->msg(msg_id.source, text) == nullptr;
[&text](auto &m) { return m.second.name == text; });
if (!valid) { if (!valid) {
error_label->setText(tr("Name already exists")); error_label->setText(tr("Name already exists"));
error_label->setVisible(true); error_label->setVisible(true);

@ -15,6 +15,7 @@ public:
EditMessageDialog(const MessageId &msg_id, const QString &title, int size, QWidget *parent); EditMessageDialog(const MessageId &msg_id, const QString &title, int size, QWidget *parent);
void validateName(const QString &text); void validateName(const QString &text);
MessageId msg_id;
QString original_name; QString original_name;
QDialogButtonBox *btn_box; QDialogButtonBox *btn_box;
QLineEdit *name_edit; QLineEdit *name_edit;

@ -42,6 +42,7 @@ MainWindow::MainWindow() : QMainWindow() {
messages_widget->restoreHeaderState(settings.message_header_state); messages_widget->restoreHeaderState(settings.message_header_state);
qRegisterMetaType<uint64_t>("uint64_t"); qRegisterMetaType<uint64_t>("uint64_t");
qRegisterMetaType<QSet<uint8_t>>("QSet<uint8_t>");
qRegisterMetaType<ReplyMsgType>("ReplyMsgType"); qRegisterMetaType<ReplyMsgType>("ReplyMsgType");
installMessageHandler([this](ReplyMsgType type, const std::string msg) { installMessageHandler([this](ReplyMsgType type, const std::string msg) {
// use queued connection to recv the log messages from replay. // use queued connection to recv the log messages from replay.
@ -70,6 +71,7 @@ MainWindow::MainWindow() : QMainWindow() {
QObject::connect(can, &AbstractStream::streamStarted, this, &MainWindow::loadDBCFromFingerprint); QObject::connect(can, &AbstractStream::streamStarted, this, &MainWindow::loadDBCFromFingerprint);
QObject::connect(can, &AbstractStream::eventsMerged, this, &MainWindow::updateStatus); QObject::connect(can, &AbstractStream::eventsMerged, this, &MainWindow::updateStatus);
QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &MainWindow::DBCFileChanged); QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &MainWindow::DBCFileChanged);
QObject::connect(can, &AbstractStream::sourcesUpdated, dbc(), &DBCManager::updateSources);
QObject::connect(UndoStack::instance(), &QUndoStack::cleanChanged, this, &MainWindow::undoStackCleanChanged); QObject::connect(UndoStack::instance(), &QUndoStack::cleanChanged, this, &MainWindow::undoStackCleanChanged);
QObject::connect(UndoStack::instance(), &QUndoStack::indexChanged, this, &MainWindow::undoStackIndexChanged); QObject::connect(UndoStack::instance(), &QUndoStack::indexChanged, this, &MainWindow::undoStackIndexChanged);
QObject::connect(&settings, &Settings::changed, this, &MainWindow::updateStatus); QObject::connect(&settings, &Settings::changed, this, &MainWindow::updateStatus);
@ -310,7 +312,7 @@ void MainWindow::loadDBCFromClipboard() {
QString dbc_str = QGuiApplication::clipboard()->text(); QString dbc_str = QGuiApplication::clipboard()->text();
QString error; QString error;
bool ret = dbc()->open("clipboard", dbc_str, &error); bool ret = dbc()->open("clipboard", dbc_str, &error);
if (ret && dbc()->messages().size() > 0) { if (ret && dbc()->msgCount() > 0) {
QMessageBox::information(this, tr("Load From Clipboard"), tr("DBC Successfully Loaded!")); QMessageBox::information(this, tr("Load From Clipboard"), tr("DBC Successfully Loaded!"));
} else { } else {
QMessageBox msg_box(QMessageBox::Warning, tr("Failed to load DBC from clipboard"), tr("Make sure that you paste the text with correct format.")); QMessageBox msg_box(QMessageBox::Warning, tr("Failed to load DBC from clipboard"), tr("Make sure that you paste the text with correct format."));

@ -239,8 +239,7 @@ void SignalModel::addSignal(int start_bit, int size, bool little_endian) {
auto msg = dbc()->msg(msg_id); auto msg = dbc()->msg(msg_id);
for (int i = 0; !msg; ++i) { for (int i = 0; !msg; ++i) {
QString name = QString("NEW_MSG_") + QString::number(msg_id.address, 16).toUpper(); QString name = QString("NEW_MSG_") + QString::number(msg_id.address, 16).toUpper();
if (i > 0) name += QString("_%1").arg(i); if (!dbc()->msg(msg_id.source, name)) {
if (std::none_of(dbc()->messages().begin(), dbc()->messages().end(), [&](auto &m) { return m.second.name == name; })) {
UndoStack::push(new EditMsgCommand(msg_id, name, can->lastMessage(msg_id).dat.size())); UndoStack::push(new EditMsgCommand(msg_id, name, can->lastMessage(msg_id).dat.size()));
msg = dbc()->msg(msg_id); msg = dbc()->msg(msg_id);
} }
@ -265,14 +264,14 @@ void SignalModel::removeSignal(const cabana::Signal *sig) {
UndoStack::push(new RemoveSigCommand(msg_id, sig)); UndoStack::push(new RemoveSigCommand(msg_id, sig));
} }
void SignalModel::handleMsgChanged(uint32_t address) { void SignalModel::handleMsgChanged(MessageId id) {
if (address == msg_id.address) { if (id == msg_id) {
refresh(); refresh();
} }
} }
void SignalModel::handleSignalAdded(uint32_t address, const cabana::Signal *sig) { void SignalModel::handleSignalAdded(MessageId id, const cabana::Signal *sig) {
if (address == msg_id.address) { if (id == msg_id) {
int i = 0; int i = 0;
for (; i < root->children.size(); ++i) { for (; i < root->children.size(); ++i) {
if (sig->start_bit < root->children[i]->sig->start_bit) break; if (sig->start_bit < root->children[i]->sig->start_bit) break;
@ -442,7 +441,7 @@ SignalView::SignalView(ChartsWidget *charts, QWidget *parent) : charts(charts),
QObject::connect(model, &QAbstractItemModel::modelReset, this, &SignalView::rowsChanged); QObject::connect(model, &QAbstractItemModel::modelReset, this, &SignalView::rowsChanged);
QObject::connect(model, &QAbstractItemModel::rowsInserted, this, &SignalView::rowsChanged); QObject::connect(model, &QAbstractItemModel::rowsInserted, this, &SignalView::rowsChanged);
QObject::connect(model, &QAbstractItemModel::rowsRemoved, this, &SignalView::rowsChanged); QObject::connect(model, &QAbstractItemModel::rowsRemoved, this, &SignalView::rowsChanged);
QObject::connect(dbc(), &DBCManager::signalAdded, [this](uint32_t address, const cabana::Signal *sig) { selectSignal(sig); }); QObject::connect(dbc(), &DBCManager::signalAdded, [this](MessageId id, const cabana::Signal *sig) { selectSignal(sig); });
setWhatsThis(tr(R"( setWhatsThis(tr(R"(
<b>Signal view</b><br /> <b>Signal view</b><br />

@ -48,10 +48,10 @@ public:
private: private:
void insertItem(SignalModel::Item *parent_item, int pos, const cabana::Signal *sig); void insertItem(SignalModel::Item *parent_item, int pos, const cabana::Signal *sig);
void handleSignalAdded(uint32_t address, const cabana::Signal *sig); void handleSignalAdded(MessageId id, const cabana::Signal *sig);
void handleSignalUpdated(const cabana::Signal *sig); void handleSignalUpdated(const cabana::Signal *sig);
void handleSignalRemoved(const cabana::Signal *sig); void handleSignalRemoved(const cabana::Signal *sig);
void handleMsgChanged(uint32_t address); void handleMsgChanged(MessageId id);
void refresh(); void refresh();
void updateState(const QHash<MessageId, CanData> *msgs); void updateState(const QHash<MessageId, CanData> *msgs);

@ -39,6 +39,11 @@ bool AbstractStream::updateEvent(const Event *event) {
data.colors = tracker.colors; data.colors = tracker.colors;
data.last_change_t = tracker.last_change_t; data.last_change_t = tracker.last_change_t;
data.bit_change_counts = tracker.bit_change_counts; data.bit_change_counts = tracker.bit_change_counts;
if (!sources.contains(id.source)) {
sources.insert(id.source);
emit sourcesUpdated(sources);
}
} }
double ts = millis_since_boot(); double ts = millis_since_boot();

@ -52,9 +52,11 @@ signals:
void updated(); void updated();
void msgsReceived(const QHash<MessageId, CanData> *); void msgsReceived(const QHash<MessageId, CanData> *);
void received(QHash<MessageId, CanData> *); void received(QHash<MessageId, CanData> *);
void sourcesUpdated(const QSet<uint8_t> &s);
public: public:
QHash<MessageId, CanData> can_msgs; QHash<MessageId, CanData> can_msgs;
QSet<uint8_t> sources;
protected: protected:
void process(QHash<MessageId, CanData> *); void process(QHash<MessageId, CanData> *);

@ -15,11 +15,11 @@ TEST_CASE("DBCManager::generateDBC") {
DBCManager dbc_from_generated(nullptr); DBCManager dbc_from_generated(nullptr);
dbc_from_generated.open("", dbc_origin.generateDBC()); dbc_from_generated.open("", dbc_origin.generateDBC());
auto &msgs = dbc_origin.messages(); REQUIRE(dbc_origin.msgCount() == dbc_from_generated.msgCount());
auto &new_msgs = dbc_from_generated.messages(); auto msgs = dbc_origin.getMessages(0);
REQUIRE(msgs.size() == new_msgs.size()); auto new_msgs = dbc_from_generated.getMessages(0);
for (auto &[address, m] : msgs) { for (auto &[id, m] : msgs) {
auto &new_m = new_msgs.at(address); auto &new_m = new_msgs.at(id);
REQUIRE(m.name == new_m.name); REQUIRE(m.name == new_m.name);
REQUIRE(m.size == new_m.size); REQUIRE(m.size == new_m.size);
REQUIRE(m.getSignals().size() == new_m.getSignals().size()); REQUIRE(m.getSignals().size() == new_m.getSignals().size());
@ -43,7 +43,7 @@ TEST_CASE("Parse can messages") {
if (e->which == cereal::Event::Which::CAN) { if (e->which == cereal::Event::Which::CAN) {
std::map<std::pair<uint32_t, QString>, std::vector<double>> values_1; std::map<std::pair<uint32_t, QString>, std::vector<double>> values_1;
for (const auto &c : e->event.getCan()) { for (const auto &c : e->event.getCan()) {
const auto msg = dbc.msg(c.getAddress()); const auto msg = dbc.msg({.source = c.getSrc(), .address = c.getAddress()});
if (c.getSrc() == 0 && msg) { if (c.getSrc() == 0 && msg) {
for (auto sig : msg->getSignals()) { for (auto sig : msg->getSignals()) {
double val = get_raw_value((uint8_t *)c.getDat().begin(), c.getDat().size(), *sig); double val = get_raw_value((uint8_t *)c.getDat().begin(), c.getDat().size(), *sig);

@ -29,8 +29,9 @@ FindSimilarBitsDlg::FindSimilarBitsDlg(QWidget *parent) : QDialog(parent, Qt::Wi
bus_combo->setCurrentIndex(0); bus_combo->setCurrentIndex(0);
msg_cb = new QComboBox(this); msg_cb = new QComboBox(this);
for (auto &[address, msg] : dbc()->messages()) { // TODO: update when bus_combo changes
msg_cb->addItem(msg.name, address); for (auto &[id, msg] : dbc()->getMessages(0)) {
msg_cb->addItem(msg.name, id.address);
} }
msg_cb->model()->sort(0); msg_cb->model()->sort(0);
msg_cb->setCurrentIndex(0); msg_cb->setCurrentIndex(0);

Loading…
Cancel
Save