mirror of https://github.com/commaai/openpilot.git
cabana: DBCManager only expose methods/signals through MessageId (#27540)
old-commit-hash: 0afd3bab34
This commit is contained in:
parent
da54ce208f
commit
918bad4847
|
@ -421,8 +421,8 @@ void ChartView::signalUpdated(const cabana::Signal *sig) {
|
|||
}
|
||||
}
|
||||
|
||||
void ChartView::msgUpdated(uint32_t address) {
|
||||
if (std::any_of(sigs.begin(), sigs.end(), [=](auto &s) { return s.msg_id.address == address; }))
|
||||
void ChartView::msgUpdated(MessageId id) {
|
||||
if (std::any_of(sigs.begin(), sigs.end(), [=](auto &s) { return s.msg_id == id; }))
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
|
|
|
@ -57,11 +57,11 @@ signals:
|
|||
void axisYLabelWidthChanged(int w);
|
||||
|
||||
private slots:
|
||||
void msgUpdated(uint32_t address);
|
||||
void signalUpdated(const cabana::Signal *sig);
|
||||
void manageSeries();
|
||||
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; }); }
|
||||
|
||||
private:
|
||||
|
|
|
@ -144,19 +144,31 @@ void DBCManager::updateMsg(const MessageId &id, const QString &name, uint32_t si
|
|||
auto &m = msgs[id.address];
|
||||
m.name = name;
|
||||
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) {
|
||||
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) {
|
||||
if (auto m = const_cast<cabana::Msg *>(msg(id.address))) {
|
||||
m->sigs.push_back(sig);
|
||||
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;
|
||||
}
|
||||
|
||||
void DBCManager::updateSources(const QSet<uint8_t> &s) {
|
||||
sources = s;
|
||||
}
|
||||
|
||||
DBCManager *dbc() {
|
||||
static DBCManager dbc_manager(nullptr);
|
||||
return &dbc_manager;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <QMetaType>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QSet>
|
||||
#include <QDebug>
|
||||
|
||||
#include "tools/cabana/dbc.h"
|
||||
|
||||
|
@ -20,30 +22,52 @@ public:
|
|||
void addSignal(const MessageId &id, 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);
|
||||
inline int msgCount() const { return msgs.size(); }
|
||||
|
||||
inline QString name() const { return name_; }
|
||||
void updateMsg(const MessageId &id, const QString &name, uint32_t size);
|
||||
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(uint32_t address) const {
|
||||
auto it = msgs.find(address);
|
||||
return it != msgs.end() ? &it->second : nullptr;
|
||||
inline const cabana::Msg* msg(uint8_t source, const QString &name) {
|
||||
for (auto &[_, msg] : msgs) {
|
||||
if (msg.name == name) {
|
||||
return &msg;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
QStringList signalNames();
|
||||
|
||||
public slots:
|
||||
void updateSources(const QSet<uint8_t> &s);
|
||||
|
||||
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 signalUpdated(const cabana::Signal *sig);
|
||||
void msgUpdated(uint32_t address);
|
||||
void msgRemoved(uint32_t address);
|
||||
void msgUpdated(MessageId id);
|
||||
void msgRemoved(MessageId id);
|
||||
void DBCFileChanged();
|
||||
|
||||
private:
|
||||
void parseExtraInfo(const QString &content);
|
||||
std::map<uint32_t, cabana::Msg> msgs;
|
||||
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();
|
||||
|
|
|
@ -177,7 +177,7 @@ void DetailWidget::removeMsg() {
|
|||
// EditMessageDialog
|
||||
|
||||
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()));
|
||||
QFormLayout *form_layout = new QFormLayout(this);
|
||||
|
||||
|
@ -207,8 +207,7 @@ void EditMessageDialog::validateName(const QString &text) {
|
|||
bool valid = text.compare(UNTITLED, Qt::CaseInsensitive) != 0;
|
||||
error_label->setVisible(false);
|
||||
if (!text.isEmpty() && valid && text != original_name) {
|
||||
valid = std::none_of(dbc()->messages().begin(), dbc()->messages().end(),
|
||||
[&text](auto &m) { return m.second.name == text; });
|
||||
valid = dbc()->msg(msg_id.source, text) == nullptr;
|
||||
if (!valid) {
|
||||
error_label->setText(tr("Name already exists"));
|
||||
error_label->setVisible(true);
|
||||
|
|
|
@ -15,6 +15,7 @@ public:
|
|||
EditMessageDialog(const MessageId &msg_id, const QString &title, int size, QWidget *parent);
|
||||
void validateName(const QString &text);
|
||||
|
||||
MessageId msg_id;
|
||||
QString original_name;
|
||||
QDialogButtonBox *btn_box;
|
||||
QLineEdit *name_edit;
|
||||
|
|
|
@ -42,6 +42,7 @@ MainWindow::MainWindow() : QMainWindow() {
|
|||
messages_widget->restoreHeaderState(settings.message_header_state);
|
||||
|
||||
qRegisterMetaType<uint64_t>("uint64_t");
|
||||
qRegisterMetaType<QSet<uint8_t>>("QSet<uint8_t>");
|
||||
qRegisterMetaType<ReplyMsgType>("ReplyMsgType");
|
||||
installMessageHandler([this](ReplyMsgType type, const std::string msg) {
|
||||
// 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::eventsMerged, this, &MainWindow::updateStatus);
|
||||
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::indexChanged, this, &MainWindow::undoStackIndexChanged);
|
||||
QObject::connect(&settings, &Settings::changed, this, &MainWindow::updateStatus);
|
||||
|
@ -310,7 +312,7 @@ void MainWindow::loadDBCFromClipboard() {
|
|||
QString dbc_str = QGuiApplication::clipboard()->text();
|
||||
QString 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!"));
|
||||
} else {
|
||||
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);
|
||||
for (int i = 0; !msg; ++i) {
|
||||
QString name = QString("NEW_MSG_") + QString::number(msg_id.address, 16).toUpper();
|
||||
if (i > 0) name += QString("_%1").arg(i);
|
||||
if (std::none_of(dbc()->messages().begin(), dbc()->messages().end(), [&](auto &m) { return m.second.name == name; })) {
|
||||
if (!dbc()->msg(msg_id.source, name)) {
|
||||
UndoStack::push(new EditMsgCommand(msg_id, name, can->lastMessage(msg_id).dat.size()));
|
||||
msg = dbc()->msg(msg_id);
|
||||
}
|
||||
|
@ -265,14 +264,14 @@ void SignalModel::removeSignal(const cabana::Signal *sig) {
|
|||
UndoStack::push(new RemoveSigCommand(msg_id, sig));
|
||||
}
|
||||
|
||||
void SignalModel::handleMsgChanged(uint32_t address) {
|
||||
if (address == msg_id.address) {
|
||||
void SignalModel::handleMsgChanged(MessageId id) {
|
||||
if (id == msg_id) {
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void SignalModel::handleSignalAdded(uint32_t address, const cabana::Signal *sig) {
|
||||
if (address == msg_id.address) {
|
||||
void SignalModel::handleSignalAdded(MessageId id, const cabana::Signal *sig) {
|
||||
if (id == msg_id) {
|
||||
int i = 0;
|
||||
for (; i < root->children.size(); ++i) {
|
||||
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::rowsInserted, 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"(
|
||||
<b>Signal view</b><br />
|
||||
|
|
|
@ -48,10 +48,10 @@ public:
|
|||
|
||||
private:
|
||||
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 handleSignalRemoved(const cabana::Signal *sig);
|
||||
void handleMsgChanged(uint32_t address);
|
||||
void handleMsgChanged(MessageId id);
|
||||
void refresh();
|
||||
void updateState(const QHash<MessageId, CanData> *msgs);
|
||||
|
||||
|
|
|
@ -39,6 +39,11 @@ bool AbstractStream::updateEvent(const Event *event) {
|
|||
data.colors = tracker.colors;
|
||||
data.last_change_t = tracker.last_change_t;
|
||||
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();
|
||||
|
|
|
@ -52,9 +52,11 @@ signals:
|
|||
void updated();
|
||||
void msgsReceived(const QHash<MessageId, CanData> *);
|
||||
void received(QHash<MessageId, CanData> *);
|
||||
void sourcesUpdated(const QSet<uint8_t> &s);
|
||||
|
||||
public:
|
||||
QHash<MessageId, CanData> can_msgs;
|
||||
QSet<uint8_t> sources;
|
||||
|
||||
protected:
|
||||
void process(QHash<MessageId, CanData> *);
|
||||
|
|
|
@ -15,11 +15,11 @@ TEST_CASE("DBCManager::generateDBC") {
|
|||
DBCManager dbc_from_generated(nullptr);
|
||||
dbc_from_generated.open("", dbc_origin.generateDBC());
|
||||
|
||||
auto &msgs = dbc_origin.messages();
|
||||
auto &new_msgs = dbc_from_generated.messages();
|
||||
REQUIRE(msgs.size() == new_msgs.size());
|
||||
for (auto &[address, m] : msgs) {
|
||||
auto &new_m = new_msgs.at(address);
|
||||
REQUIRE(dbc_origin.msgCount() == dbc_from_generated.msgCount());
|
||||
auto msgs = dbc_origin.getMessages(0);
|
||||
auto new_msgs = dbc_from_generated.getMessages(0);
|
||||
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());
|
||||
|
@ -43,7 +43,7 @@ TEST_CASE("Parse can messages") {
|
|||
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(c.getAddress());
|
||||
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);
|
||||
|
|
|
@ -29,8 +29,9 @@ FindSimilarBitsDlg::FindSimilarBitsDlg(QWidget *parent) : QDialog(parent, Qt::Wi
|
|||
bus_combo->setCurrentIndex(0);
|
||||
|
||||
msg_cb = new QComboBox(this);
|
||||
for (auto &[address, msg] : dbc()->messages()) {
|
||||
msg_cb->addItem(msg.name, address);
|
||||
// TODO: update when bus_combo changes
|
||||
for (auto &[id, msg] : dbc()->getMessages(0)) {
|
||||
msg_cb->addItem(msg.name, id.address);
|
||||
}
|
||||
msg_cb->model()->sort(0);
|
||||
msg_cb->setCurrentIndex(0);
|
||||
|
|
Loading…
Reference in New Issue