Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cabana: miscellaneous bug fixes and enhancements #34297

Merged
merged 9 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tools/cabana/binaryview.cc
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
painter->fillRect(option.rect, item->bg_color);
}
auto color_role = item->sigs.contains(bin_view->hovered_sig) ? QPalette::BrightText : QPalette::Text;
painter->setPen(option.palette.color(color_role));
painter->setPen(option.palette.color(bin_view->is_message_active ? QPalette::Normal : QPalette::Disabled, color_role));
}

if (item->sigs.size() > 1) {
Expand Down
7 changes: 6 additions & 1 deletion tools/cabana/binaryview.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ class BinaryView : public QTableView {
void setMessage(const MessageId &message_id);
void highlight(const cabana::Signal *sig);
QSet<const cabana::Signal*> getOverlappingSignals() const;
inline void updateState() { model->updateState(); }
void updateState() { model->updateState(); }
void paintEvent(QPaintEvent *event) override {
is_message_active = can->isMessageActive(model->msg_id);
QTableView::paintEvent(event);
}
QSize minimumSizeHint() const override;
void setHeatmapLiveMode(bool live) { model->heatmap_live_mode = live; updateState(); }

Expand All @@ -93,6 +97,7 @@ class BinaryView : public QTableView {
QModelIndex anchor_index;
BinaryViewModel *model;
BinaryItemDelegate *delegate;
bool is_message_active = false;
const cabana::Signal *resize_sig = nullptr;
const cabana::Signal *hovered_sig = nullptr;
friend class BinaryItemDelegate;
Expand Down
2 changes: 2 additions & 0 deletions tools/cabana/chart/chart.cc
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,8 @@ void ChartView::setSeriesType(SeriesType type) {
}
updateSeriesPoints();
updateTitle();

menu->actions()[(int)type]->setChecked(true);
}
}

Expand Down
41 changes: 30 additions & 11 deletions tools/cabana/chart/chartswidget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) {
main_layout->setSpacing(0);

// toolbar
QToolBar *toolbar = new QToolBar(tr("Charts"), this);
toolbar = new QToolBar(tr("Charts"), this);
int icon_size = style()->pixelMetric(QStyle::PM_SmallIconSize);
toolbar->setIconSize({icon_size, icon_size});

Expand All @@ -34,6 +34,21 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) {
toolbar->addWidget(title_label = new QLabel());
title_label->setContentsMargins(0, 0, style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0);

auto chart_type_action = toolbar->addAction("");
QMenu *chart_type_menu = new QMenu(this);
auto types = std::array{tr("Line"), tr("Step"), tr("Scatter")};
for (int i = 0; i < types.size(); ++i) {
QString type_text = types[i];
chart_type_menu->addAction(type_text, this, [=]() {
settings.chart_series_type = i;
chart_type_action->setText("Type: " + type_text);
settingChanged();
});
}
chart_type_action->setText("Type: " + types[settings.chart_series_type]);
chart_type_action->setMenu(chart_type_menu);
qobject_cast<QToolButton *>(toolbar->widgetForAction(chart_type_action))->setPopupMode(QToolButton::InstantPopup);

QMenu *menu = new QMenu(this);
for (int i = 0; i < MAX_COLUMN_COUNT; ++i) {
menu->addAction(tr("%1").arg(i + 1), [=]() { setColumnCount(i + 1); });
Expand All @@ -42,13 +57,13 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) {
columns_action->setMenu(menu);
qobject_cast<QToolButton*>(toolbar->widgetForAction(columns_action))->setPopupMode(QToolButton::InstantPopup);

QLabel *stretch_label = new QLabel(this);
stretch_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
toolbar->addWidget(stretch_label);
QWidget *spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
toolbar->addWidget(spacer);

range_lb_action = toolbar->addWidget(range_lb = new QLabel(this));
range_slider = new LogSlider(1000, Qt::Horizontal, this);
range_slider->setMaximumWidth(200);
range_slider->setFixedWidth(150 * qApp->devicePixelRatio());
range_slider->setToolTip(tr("Set the chart range"));
range_slider->setRange(1, settings.max_cached_minutes * 60);
range_slider->setSingleStep(1);
Expand Down Expand Up @@ -121,10 +136,12 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) {
setIsDocked(true);
newTab();
qApp->installEventFilter(this);

setWhatsThis(tr(R"(
<b>Chart view</b><br />
<!-- TODO: add descprition here -->
<b>Chart View</b><br />
<b>Click</b>: Click to seek to a corresponding time.<br />
<b>Drag</b>: Zoom into the chart.<br />
<b>Shift + Drag</b>: Scrub through the chart to view values.<br />
<b>Right Mouse</b>: Open the context menu.<br />
)"));
}

Expand Down Expand Up @@ -219,7 +236,7 @@ void ChartsWidget::setIsDocked(bool docked) {

void ChartsWidget::updateToolBar() {
title_label->setText(tr("Charts: %1").arg(charts.size()));
columns_action->setText(tr("Column: %1").arg(column_count));
columns_action->setText(tr("Columns: %1").arg(column_count));
range_lb->setText(utils::formatSeconds(max_chart_range));

bool is_zoomed = can->timeRange().has_value();
Expand All @@ -241,7 +258,9 @@ void ChartsWidget::settingChanged() {
c->setTheme(theme);
}
}
range_slider->setRange(1, settings.max_cached_minutes * 60);
if (range_slider->maximum() != settings.max_cached_minutes * 60) {
range_slider->setRange(1, settings.max_cached_minutes * 60);
}
for (auto c : charts) {
c->setFixedHeight(settings.chart_height);
c->setSeriesType((SeriesType)settings.chart_series_type);
Expand Down Expand Up @@ -380,7 +399,7 @@ void ChartsWidget::doAutoScroll() {
}

QSize ChartsWidget::minimumSizeHint() const {
return QSize(CHART_MIN_WIDTH, QWidget::minimumSizeHint().height());
return QSize(CHART_MIN_WIDTH * 1.5 * qApp->devicePixelRatio(), QWidget::minimumSizeHint().height());
}

void ChartsWidget::newChart() {
Expand Down
2 changes: 2 additions & 0 deletions tools/cabana/chart/chartswidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <QLabel>
#include <QScrollArea>
#include <QTimer>
#include <QToolBar>
#include <QUndoCommand>
#include <QUndoStack>

Expand Down Expand Up @@ -88,6 +89,7 @@ public slots:
bool is_docked = true;
ToolButton *dock_btn;

QToolBar *toolbar;
QAction *undo_zoom_action;
QAction *redo_zoom_action;
QAction *reset_zoom_action;
Expand Down
4 changes: 2 additions & 2 deletions tools/cabana/dbc/dbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
#include <QMetaType>
#include <QString>


const QString UNTITLED = "untitled";
const QString DEFAULT_NODE_NAME = "XXX";
constexpr int CAN_MAX_DATA_BYTES = 64;

struct MessageId {
uint8_t source = 0;
uint32_t address = 0;

QString toString() const {
return QString("%1:%2").arg(source).arg(address, 1, 16);
return QString("%1:%2").arg(source).arg(QString::number(address, 16).toUpper());
}

bool operator==(const MessageId &other) const {
Expand Down
3 changes: 1 addition & 2 deletions tools/cabana/detailwidget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,7 @@ EditMessageDialog::EditMessageDialog(const MessageId &msg_id, const QString &tit
name_edit->setValidator(new NameValidator(name_edit));

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

form_layout->addRow(tr("Node"), node = new QLineEdit(this));
Expand Down
23 changes: 4 additions & 19 deletions tools/cabana/messageswidget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,6 @@

#include "tools/cabana/commands.h"

static bool isMessageActive(const MessageId &id) {
if (id.source == INVALID_SOURCE) {
return false;
}
// Check if the message is active based on time difference and frequency
const auto &m = can->lastMessage(id);
float delta = can->currentSec() - m.ts;

if (m.freq < std::numeric_limits<double>::epsilon()) {
return delta < 1.5;
}

return delta < (5.0 / m.freq) + (1.0 / settings.fps);
}

MessagesWidget::MessagesWidget(QWidget *parent) : menu(new QMenu(this)), QWidget(parent) {
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setContentsMargins(0, 0, 0, 0);
Expand Down Expand Up @@ -207,7 +192,7 @@ QVariant MessageListModel::data(const QModelIndex &index, int role) const {
switch (index.column()) {
case Column::NAME: return item.name;
case Column::SOURCE: return item.id.source != INVALID_SOURCE ? QString::number(item.id.source) : NA;
case Column::ADDRESS: return QString::number(item.id.address, 16);
case Column::ADDRESS: return toHexString(item.id.address);
case Column::NODE: return item.node;
case Column::FREQ: return item.id.source != INVALID_SOURCE ? getFreq(can->lastMessage(item.id).freq) : NA;
case Column::COUNT: return item.id.source != INVALID_SOURCE ? QString::number(can->lastMessage(item.id).count) : NA;
Expand Down Expand Up @@ -300,7 +285,7 @@ bool MessageListModel::match(const MessageListModel::Item &item) {
match = parseRange(txt, item.id.source);
break;
case Column::ADDRESS:
match = QString::number(item.id.address, 16).contains(txt, Qt::CaseInsensitive);
match = toHexString(item.id.address).contains(txt, Qt::CaseInsensitive);
match = match || parseRange(txt, item.id.address, 16);
break;
case Column::NODE:
Expand Down Expand Up @@ -335,7 +320,7 @@ bool MessageListModel::filterAndSort() {
std::vector<Item> items;
items.reserve(all_messages.size());
for (const auto &id : all_messages) {
if (show_inactive_messages || isMessageActive(id)) {
if (show_inactive_messages || can->isMessageActive(id)) {
auto msg = dbc()->msg(id);
Item item = {.id = id,
.name = msg ? msg->name : UNTITLED,
Expand Down Expand Up @@ -378,7 +363,7 @@ void MessageListModel::sort(int column, Qt::SortOrder order) {

void MessageView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
const auto &item = ((MessageListModel*)model())->items_[index.row()];
if (!isMessageActive(item.id)) {
if (!can->isMessageActive(item.id)) {
QStyleOptionViewItem custom_option = option;
custom_option.palette.setBrush(QPalette::Text, custom_option.palette.color(QPalette::Disabled, QPalette::Text));
auto color = QApplication::palette().color(QPalette::HighlightedText);
Expand Down
5 changes: 0 additions & 5 deletions tools/cabana/settings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,6 @@ SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) {

groupbox = new QGroupBox("Chart");
form_layout = new QFormLayout(groupbox);
form_layout->addRow(tr("Default Series Type"), chart_series_type = new QComboBox(this));
chart_series_type->addItems({tr("Line"), tr("Step Line"), tr("Scatter")});
chart_series_type->setCurrentIndex(settings.chart_series_type);

form_layout->addRow(tr("Chart Height"), chart_height = new QSpinBox(this));
chart_height->setRange(100, 500);
chart_height->setSingleStep(10);
Expand Down Expand Up @@ -132,7 +128,6 @@ void SettingsDlg::save() {
}
settings.fps = fps->value();
settings.max_cached_minutes = cached_minutes->value();
settings.chart_series_type = chart_series_type->currentIndex();
settings.chart_height = chart_height->value();
settings.log_livestream = log_livestream->isChecked();
settings.log_path = log_path->text();
Expand Down
2 changes: 1 addition & 1 deletion tools/cabana/signalview.cc
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ QWidget *SignalItemDelegate::createEditor(QWidget *parent, const QStyleOptionVie
} else if (item->type == SignalModel::Item::Size) {
QSpinBox *spin = new QSpinBox(parent);
spin->setFrame(false);
spin->setRange(1, 64);
spin->setRange(1, CAN_MAX_DATA_BYTES);
return spin;
} else if (item->type == SignalModel::Item::SignalType) {
QComboBox *c = new QComboBox(parent);
Expand Down
15 changes: 15 additions & 0 deletions tools/cabana/streams/abstractstream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,21 @@ const CanData &AbstractStream::lastMessage(const MessageId &id) const {
return it != last_msgs.end() ? it->second : empty_data;
}

bool AbstractStream::isMessageActive(const MessageId &id) const {
if (id.source == INVALID_SOURCE) {
return false;
}
// Check if the message is active based on time difference and frequency
const auto &m = lastMessage(id);
float delta = currentSec() - m.ts;

if (m.freq < std::numeric_limits<double>::epsilon()) {
return delta < 1.5;
}

return delta < (5.0 / m.freq) + (1.0 / settings.fps);
}

void AbstractStream::updateLastMsgsTo(double sec) {
std::lock_guard lk(mutex_);
current_sec_ = sec;
Expand Down
1 change: 1 addition & 0 deletions tools/cabana/streams/abstractstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class AbstractStream : public QObject {
inline double toSeconds(uint64_t mono_time) const { return std::max(0.0, (mono_time - beginMonoTime()) / 1e9); }

inline const std::unordered_map<MessageId, CanData> &lastMessages() const { return last_msgs; }
bool isMessageActive(const MessageId &id) const;
inline const MessageEventsMap &eventsMap() const { return events_; }
inline const std::vector<const CanEvent *> &allEvents() const { return all_events_; }
const CanData &lastMessage(const MessageId &id) const;
Expand Down
1 change: 1 addition & 0 deletions tools/cabana/utils/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,4 @@ public slots:

int num_decimals(double num);
QString signalToolTip(const cabana::Signal *sig);
inline QString toHexString(int value) { return QString("0x%1").arg(QString::number(value, 16).toUpper(), 2, '0'); }
Loading
Loading