Skip to content

Commit

Permalink
cabana: support ECU node names (commaai#29897)
Browse files Browse the repository at this point in the history
* support display&edit node name

* cleanup

* set validator for Node name

* modify validator to support multiple receivers

* set default to XXX in updateMsg

* add DEFAULT_NODE_NAME

* Update tools/cabana/commands.h

---------

Co-authored-by: Shane Smiskol <shane@smiskol.com>
  • Loading branch information
deanlee and sshane authored Sep 15, 2023
1 parent 1410a11 commit c4df40a
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 35 deletions.
14 changes: 8 additions & 6 deletions tools/cabana/commands.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

// EditMsgCommand

EditMsgCommand::EditMsgCommand(const MessageId &id, const QString &name, int size, const QString &comment, QUndoCommand *parent)
: id(id), new_name(name), new_size(size), new_comment(comment), QUndoCommand(parent) {
EditMsgCommand::EditMsgCommand(const MessageId &id, const QString &name, int size,
const QString &node, const QString &comment, QUndoCommand *parent)
: id(id), new_name(name), new_size(size), new_node(node), new_comment(comment), QUndoCommand(parent) {
if (auto msg = dbc()->msg(id)) {
old_name = msg->name;
old_size = msg->size;
old_node = msg->transmitter;
old_comment = msg->comment;
setText(QObject::tr("edit message %1:%2").arg(name).arg(id.address));
} else {
Expand All @@ -20,11 +22,11 @@ void EditMsgCommand::undo() {
if (old_name.isEmpty())
dbc()->removeMsg(id);
else
dbc()->updateMsg(id, old_name, old_size, old_comment);
dbc()->updateMsg(id, old_name, old_size, old_node, old_comment);
}

void EditMsgCommand::redo() {
dbc()->updateMsg(id, new_name, new_size, new_comment);
dbc()->updateMsg(id, new_name, new_size, new_node, new_comment);
}

// RemoveMsgCommand
Expand All @@ -38,7 +40,7 @@ RemoveMsgCommand::RemoveMsgCommand(const MessageId &id, QUndoCommand *parent) :

void RemoveMsgCommand::undo() {
if (!message.name.isEmpty()) {
dbc()->updateMsg(id, message.name, message.size, message.comment);
dbc()->updateMsg(id, message.name, message.size, message.transmitter, message.comment);
for (auto s : message.getSignals())
dbc()->addSignal(id, *s);
}
Expand All @@ -64,7 +66,7 @@ void AddSigCommand::undo() {
void AddSigCommand::redo() {
if (auto msg = dbc()->msg(id); !msg) {
msg_created = true;
dbc()->updateMsg(id, dbc()->newMsgName(id), can->lastMessage(id).dat.size(), "");
dbc()->updateMsg(id, dbc()->newMsgName(id), can->lastMessage(id).dat.size(), "", "");
}
signal.name = dbc()->newSignalName(id);
signal.max = std::pow(2, signal.size) - 1;
Expand Down
5 changes: 3 additions & 2 deletions tools/cabana/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@

class EditMsgCommand : public QUndoCommand {
public:
EditMsgCommand(const MessageId &id, const QString &name, int size, const QString &comment, QUndoCommand *parent = nullptr);
EditMsgCommand(const MessageId &id, const QString &name, int size, const QString &node,
const QString &comment, QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;

private:
const MessageId id;
QString old_name, new_name, old_comment, new_comment;
QString old_name, new_name, old_comment, new_comment, old_node, new_node;
int old_size = 0, new_size = 0;
};

Expand Down
6 changes: 6 additions & 0 deletions tools/cabana/dbc/dbc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ QString cabana::Msg::newSignalName() {
}

void cabana::Msg::update() {
if (transmitter.isEmpty()) {
transmitter = DEFAULT_NODE_NAME;
}
mask.assign(size, 0x00);
multiplexor = nullptr;

Expand Down Expand Up @@ -125,6 +128,9 @@ void cabana::Msg::update() {

void cabana::Signal::update() {
updateMsbLsb(*this);
if (receiver_name.isEmpty()) {
receiver_name = DEFAULT_NODE_NAME;
}

float h = 19 * (float)lsb / 64.0;
h = fmod(h, 1.0);
Expand Down
1 change: 1 addition & 0 deletions tools/cabana/dbc/dbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "opendbc/can/common_dbc.h"

const QString UNTITLED = "untitled";
const QString DEFAULT_NODE_NAME = "XXX";

struct MessageId {
uint8_t source = 0;
Expand Down
8 changes: 5 additions & 3 deletions tools/cabana/dbc/dbcfile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ bool DBCFile::writeContents(const QString &fn) {
return false;
}

void DBCFile::updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &comment) {
void DBCFile::updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &node, const QString &comment) {
auto &m = msgs[id.address];
m.address = id.address;
m.name = name;
m.size = size;
m.transmitter = node.isEmpty() ? DEFAULT_NODE_NAME : node;
m.comment = comment;
}

Expand Down Expand Up @@ -198,7 +199,8 @@ void DBCFile::parse(const QString &content) {
QString DBCFile::generateDBC() {
QString dbc_string, signal_comment, message_comment, val_desc;
for (const auto &[address, m] : msgs) {
dbc_string += QString("BO_ %1 %2: %3 %4\n").arg(address).arg(m.name).arg(m.size).arg(m.transmitter.isEmpty() ? "XXX" : m.transmitter);
const QString transmitter = m.transmitter.isEmpty() ? DEFAULT_NODE_NAME : m.transmitter;
dbc_string += QString("BO_ %1 %2: %3 %4\n").arg(address).arg(m.name).arg(m.size).arg(transmitter);
if (!m.comment.isEmpty()) {
message_comment += QString("CM_ BO_ %1 \"%2\";\n").arg(address).arg(m.comment);
}
Expand All @@ -221,7 +223,7 @@ QString DBCFile::generateDBC() {
.arg(doubleToString(sig->min))
.arg(doubleToString(sig->max))
.arg(sig->unit)
.arg(sig->receiver_name.isEmpty() ? "XXX" : sig->receiver_name);
.arg(sig->receiver_name.isEmpty() ? DEFAULT_NODE_NAME : sig->receiver_name);
if (!sig->comment.isEmpty()) {
signal_comment += QString("CM_ SG_ %1 %2 \"%3\";\n").arg(address).arg(sig->name).arg(sig->comment);
}
Expand Down
2 changes: 1 addition & 1 deletion tools/cabana/dbc/dbcfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class DBCFile : public QObject {
void cleanupAutoSaveFile();
QString generateDBC();

void updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &comment);
void updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &node, const QString &comment);
inline void removeMsg(const MessageId &id) { msgs.erase(id.address); }

inline const std::map<uint32_t, cabana::Msg> &getMessages() const { return msgs; }
Expand Down
4 changes: 2 additions & 2 deletions tools/cabana/dbc/dbcmanager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ void DBCManager::removeSignal(const MessageId &id, const QString &sig_name) {
}
}

void DBCManager::updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &comment) {
void DBCManager::updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &node, const QString &comment) {
auto dbc_file = findDBCFile(id);
assert(dbc_file); // This should be impossible
dbc_file->updateMsg(id, name, size, comment);
dbc_file->updateMsg(id, name, size, node, comment);
emit msgUpdated(id);
}

Expand Down
2 changes: 1 addition & 1 deletion tools/cabana/dbc/dbcmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class DBCManager : public QObject {
void updateSignal(const MessageId &id, const QString &sig_name, const cabana::Signal &sig);
void removeSignal(const MessageId &id, const QString &sig_name);

void updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &comment);
void updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &node, const QString &comment);
void removeMsg(const MessageId &id);

QString newMsgName(const MessageId &id);
Expand Down
23 changes: 11 additions & 12 deletions tools/cabana/detailwidget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include <QFormLayout>
#include <QMenu>
#include <QMessageBox>

#include "tools/cabana/commands.h"
#include "tools/cabana/mainwin.h"
Expand Down Expand Up @@ -135,11 +134,12 @@ void DetailWidget::refresh() {
for (auto s : binary_view->getOverlappingSignals()) {
warnings.push_back(tr("%1 has overlapping bits.").arg(s->name));
}
name_label->setText(QString("%1 (%2)").arg(msgName(msg_id), msg->transmitter));
} else {
warnings.push_back(tr("Drag-Select in binary view to create new signal."));
name_label->setText(msgName(msg_id));
}
remove_btn->setEnabled(msg != nullptr);
name_label->setText(msgName(msg_id));

if (!warnings.isEmpty()) {
warning_label->setText(warnings.join('\n'));
Expand All @@ -164,8 +164,8 @@ void DetailWidget::editMsg() {
int size = msg ? msg->size : can->lastMessage(msg_id).dat.size();
EditMessageDialog dlg(msg_id, msgName(msg_id), size, this);
if (dlg.exec()) {
UndoStack::push(new EditMsgCommand(msg_id, dlg.name_edit->text().trimmed(),
dlg.size_spin->value(), dlg.comment_edit->toPlainText().trimmed()));
UndoStack::push(new EditMsgCommand(msg_id, dlg.name_edit->text().trimmed(), dlg.size_spin->value(),
dlg.node->text().trimmed(), dlg.comment_edit->toPlainText().trimmed()));
}
}

Expand All @@ -182,25 +182,24 @@ EditMessageDialog::EditMessageDialog(const MessageId &msg_id, const QString &tit

form_layout->addRow("", error_label = new QLabel);
error_label->setVisible(false);
name_edit = new QLineEdit(title, this);
form_layout->addRow(tr("Name"), name_edit = new QLineEdit(title, this));
name_edit->setValidator(new NameValidator(name_edit));
form_layout->addRow(tr("Name"), name_edit);

size_spin = new QSpinBox(this);
form_layout->addRow(tr("Size"), size_spin = new QSpinBox(this));
// TODO: limit the maximum?
size_spin->setMinimum(1);
size_spin->setValue(size);
form_layout->addRow(tr("Size"), size_spin);

form_layout->addRow(tr("Node"), node = new QLineEdit(this));
node->setValidator(new NameValidator(name_edit));
form_layout->addRow(tr("Comment"), comment_edit = new QTextEdit(this));
form_layout->addRow(btn_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel));

if (auto msg = dbc()->msg(msg_id)) {
node->setText(msg->transmitter);
comment_edit->setText(msg->comment);
}

btn_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
validateName(name_edit->text());
form_layout->addRow(btn_box);

setFixedWidth(parent->width() * 0.9);
connect(name_edit, &QLineEdit::textEdited, this, &EditMessageDialog::validateName);
connect(btn_box, &QDialogButtonBox::accepted, this, &QDialog::accept);
Expand Down
1 change: 1 addition & 0 deletions tools/cabana/detailwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class EditMessageDialog : public QDialog {
QString original_name;
QDialogButtonBox *btn_box;
QLineEdit *name_edit;
QLineEdit *node;
QTextEdit *comment_edit;
QLabel *error_label;
QSpinBox *size_spin;
Expand Down
16 changes: 10 additions & 6 deletions tools/cabana/signalview.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ SignalModel::SignalModel(QObject *parent) : root(new Item), QAbstractItemModel(p
void SignalModel::insertItem(SignalModel::Item *parent_item, int pos, const cabana::Signal *sig) {
Item *item = new Item{.sig = sig, .parent = parent_item, .title = sig->name, .type = Item::Sig};
parent_item->children.insert(pos, item);
QString titles[]{"Name", "Size", "Little Endian", "Signed", "Offset", "Factor", "Type", "Multiplex Value", "Extra Info",
QString titles[]{"Name", "Size", "Node", "Little Endian", "Signed", "Offset", "Factor", "Type", "Multiplex Value", "Extra Info",
"Unit", "Comment", "Minimum Value", "Maximum Value", "Value Descriptions"};
for (int i = 0; i < std::size(titles); ++i) {
item->children.push_back(new Item{.sig = sig, .parent = item, .title = titles[i], .type = (Item::Type)(i + Item::Name)});
Expand Down Expand Up @@ -134,6 +134,7 @@ QVariant SignalModel::data(const QModelIndex &index, int role) const {
case Item::Sig: return item->sig_val;
case Item::Name: return item->sig->name;
case Item::Size: return item->sig->size;
case Item::Node: return item->sig->receiver_name;
case Item::SignalType: return signalTypeToString(item->sig->type);
case Item::MultiplexValue: return item->sig->multiplex_value;
case Item::Offset: return doubleToString(item->sig->offset);
Expand Down Expand Up @@ -172,6 +173,7 @@ bool SignalModel::setData(const QModelIndex &index, const QVariant &value, int r
switch (item->type) {
case Item::Name: s.name = value.toString(); break;
case Item::Size: s.size = value.toInt(); break;
case Item::Node: s.receiver_name = value.toString().trimmed(); break;
case Item::SignalType: s.type = (cabana::Signal::Type)value.toInt(); break;
case Item::MultiplexValue: s.multiplex_value = value.toInt(); break;
case Item::Endian: s.is_little_endian = value.toBool(); break;
Expand All @@ -195,11 +197,11 @@ void SignalModel::showExtraInfo(const QModelIndex &index) {
if (item->type == Item::ExtraInfo) {
if (!item->parent->extra_expanded) {
item->parent->extra_expanded = true;
beginInsertRows(index.parent(), 7, 13);
beginInsertRows(index.parent(), Item::ExtraInfo - 2, Item::Desc - 2);
endInsertRows();
} else {
item->parent->extra_expanded = false;
beginRemoveRows(index.parent(), 7, 13);
beginRemoveRows(index.parent(), Item::ExtraInfo - 2, Item::Desc - 2);
endRemoveRows();
}
}
Expand Down Expand Up @@ -267,6 +269,7 @@ void SignalModel::handleSignalRemoved(const cabana::Signal *sig) {

SignalItemDelegate::SignalItemDelegate(QObject *parent) : QStyledItemDelegate(parent) {
name_validator = new NameValidator(this);
node_validator = new QRegExpValidator(QRegExp("^\\w+(,\\w+)*$"), this);
double_validator = new DoubleValidator(this);

label_font.setPointSize(8);
Expand Down Expand Up @@ -382,20 +385,21 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op

QWidget *SignalItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
auto item = (SignalModel::Item *)index.internalPointer();
if (item->type == SignalModel::Item::Name || item->type == SignalModel::Item::Offset ||
if (item->type == SignalModel::Item::Name || item->type == SignalModel::Item::Node || item->type == SignalModel::Item::Offset ||
item->type == SignalModel::Item::Factor || item->type == SignalModel::Item::MultiplexValue ||
item->type == SignalModel::Item::Min || item->type == SignalModel::Item::Max) {
QLineEdit *e = new QLineEdit(parent);
e->setFrame(false);
e->setValidator(item->type == SignalModel::Item::Name ? name_validator : double_validator);
if (item->type == SignalModel::Item::Name) e->setValidator(name_validator);
else if (item->type == SignalModel::Item::Node) e->setValidator(node_validator);
else e->setValidator(double_validator);

if (item->type == SignalModel::Item::Name) {
QCompleter *completer = new QCompleter(dbc()->signalNames());
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setFilterMode(Qt::MatchContains);
e->setCompleter(completer);
}

return e;
} else if (item->type == SignalModel::Item::Size) {
QSpinBox *spin = new QSpinBox(parent);
Expand Down
4 changes: 2 additions & 2 deletions tools/cabana/signalview.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class SignalModel : public QAbstractItemModel {
Q_OBJECT
public:
struct Item {
enum Type {Root, Sig, Name, Size, Endian, Signed, Offset, Factor, SignalType, MultiplexValue, ExtraInfo, Unit, Comment, Min, Max, Desc };
enum Type {Root, Sig, Name, Size, Node, Endian, Signed, Offset, Factor, SignalType, MultiplexValue, ExtraInfo, Unit, Comment, Min, Max, Desc };
~Item() { qDeleteAll(children); }
inline int row() { return parent->children.indexOf(this); }

Expand Down Expand Up @@ -87,7 +87,7 @@ class SignalItemDelegate : public QStyledItemDelegate {
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;

QValidator *name_validator, *double_validator;
QValidator *name_validator, *double_validator, *node_validator;
QFont label_font, minmax_font;
const int color_label_width = 18;
mutable QSize button_size;
Expand Down

0 comments on commit c4df40a

Please sign in to comment.