diff --git a/tools/cabana/binaryview.cc b/tools/cabana/binaryview.cc index ddad4cd446..a46c25bdfa 100644 --- a/tools/cabana/binaryview.cc +++ b/tools/cabana/binaryview.cc @@ -7,6 +7,8 @@ #include #include +#include + #include "tools/cabana/commands.h" #include "tools/cabana/streams/abstractstream.h" @@ -212,6 +214,19 @@ void BinaryViewModel::updateState() { for (int i = 0; i < binary.size(); ++i) { for (int j = 0; j < 8; ++j) { items[i * column_count + j].val = ((binary[i] >> (7 - j)) & 1) != 0 ? '1' : '0'; + + // Bit update frequency based highlighting + bool has_signal = items[i * column_count + j].sigs.size() > 0; + double offset = has_signal ? 50 : 0; + + double min_f = last_msg.bit_change_counts[i][7 - j] == 0 ? offset : offset + 25; + double max_f = 255.0; + + double factor = 0.25; + double scaler = max_f / log2(1.0 + factor); + + double alpha = std::clamp(offset + log2(1.0 + factor * (double)last_msg.bit_change_counts[i][7 - j] / (double)last_msg.count) * scaler, min_f, max_f); + items[i * column_count + j].bg_color.setAlpha(alpha); } hex[0] = toHex(binary[i] >> 4); hex[1] = toHex(binary[i] & 0xf); @@ -264,10 +279,18 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op painter->setPen(option.palette.color(QPalette::BrightText)); } else if (!item->sigs.isEmpty() && (!bin_view->selectionModel()->hasSelection() || !item->sigs.contains(bin_view->resize_sig))) { bool sig_hovered = item->sigs.contains(bin_view->hovered_sig); - painter->fillRect(option.rect, sig_hovered ? item->bg_color.darker(125) : item->bg_color); // 4/5x brightness + int min_alpha = item->sigs.contains(bin_view->hovered_sig) ? 255 : 50; + QColor bg = item->bg_color; + if (bg.alpha() < min_alpha) { + bg.setAlpha(min_alpha); + } + painter->fillRect(option.rect, sig_hovered ? bg.darker(125) : bg); // 4/5x brightness painter->setPen(sig_hovered ? option.palette.color(QPalette::BrightText) : Qt::black); + } else { + painter->fillRect(option.rect, item->bg_color); } + painter->drawText(option.rect, Qt::AlignCenter, item->val); if (item->is_msb || item->is_lsb) { painter->setFont(small_font); diff --git a/tools/cabana/binaryview.h b/tools/cabana/binaryview.h index f697ea28cb..d006672793 100644 --- a/tools/cabana/binaryview.h +++ b/tools/cabana/binaryview.h @@ -36,7 +36,7 @@ public: } struct Item { - QColor bg_color = QApplication::style()->standardPalette().color(QPalette::Base); + QColor bg_color = QColor(102, 86, 169, 0); bool is_msb = false; bool is_lsb = false; QString val = "-"; diff --git a/tools/cabana/streams/abstractstream.cc b/tools/cabana/streams/abstractstream.cc index 8a77e0eb39..94d653bcb0 100644 --- a/tools/cabana/streams/abstractstream.cc +++ b/tools/cabana/streams/abstractstream.cc @@ -34,6 +34,7 @@ bool AbstractStream::updateEvent(const Event *event) { change_trackers[id].compute(data.dat, data.ts, data.freq); data.colors = change_trackers[id].colors; data.last_change_t = change_trackers[id].last_change_t; + data.bit_change_counts = change_trackers[id].bit_change_counts; } double ts = millis_since_boot(); diff --git a/tools/cabana/streams/abstractstream.h b/tools/cabana/streams/abstractstream.h index 0dbb3d96a6..8c10d959cb 100644 --- a/tools/cabana/streams/abstractstream.h +++ b/tools/cabana/streams/abstractstream.h @@ -16,6 +16,7 @@ struct CanData { QByteArray dat; QVector colors; QVector last_change_t; + QVector> bit_change_counts; }; class AbstractStream : public QObject { diff --git a/tools/cabana/util.cc b/tools/cabana/util.cc index d978e4aa12..2806e175d7 100644 --- a/tools/cabana/util.cc +++ b/tools/cabana/util.cc @@ -18,6 +18,7 @@ void ChangeTracker::compute(const QByteArray &dat, double ts, uint32_t freq) { if (prev_dat.size() != dat.size()) { colors.resize(dat.size()); last_change_t.resize(dat.size()); + bit_change_counts.resize(dat.size()); std::fill(colors.begin(), colors.end(), QColor(0, 0, 0, 0)); std::fill(last_change_t.begin(), last_change_t.end(), ts); } else { @@ -39,6 +40,13 @@ void ChangeTracker::compute(const QByteArray &dat, double ts, uint32_t freq) { colors[i] = blend(colors[i], QColor(102, 86, 169, start_alpha / 2)); // Greyish/Blue } + // Track bit level changes + for (int bit = 0; bit < 8; bit++){ + if ((cur ^ last) & (1 << bit)) { + bit_change_counts[i][bit] += 1; + } + } + last_change_t[i] = ts; } else { // Fade out diff --git a/tools/cabana/util.h b/tools/cabana/util.h index af5032fd42..5d5b44d63c 100644 --- a/tools/cabana/util.h +++ b/tools/cabana/util.h @@ -17,6 +17,7 @@ public: QVector last_change_t; QVector colors; + QVector> bit_change_counts; private: const int periodic_threshold = 10;