mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-03 20:42:09 +08:00
cabana: add option to suppress already known signals (#28106)
* suppress using static mask * use mask in updateLastMsgsTo * store mask in cabana::Msg * update mask in the right places * actually build mask * restore setting * less diff old-commit-hash: b53f748a1a328e63dff0a404114c5210eeaf2282
This commit is contained in:
@@ -13,6 +13,30 @@ std::vector<const cabana::Signal*> cabana::Msg::getSignals() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cabana::Msg::updateMask() {
|
||||
mask.clear();
|
||||
for (int i = 0; i < size; i++) {
|
||||
mask.push_back(0x00);
|
||||
}
|
||||
|
||||
for (auto &sig : sigs) {
|
||||
int i = sig.msb / 8;
|
||||
int bits = sig.size;
|
||||
while (i >= 0 && i < size && bits > 0) {
|
||||
int lsb = (int)(sig.lsb / 8) == i ? sig.lsb : i * 8;
|
||||
int msb = (int)(sig.msb / 8) == i ? sig.msb : (i + 1) * 8 - 1;
|
||||
|
||||
int sz = msb - lsb + 1;
|
||||
int shift = (lsb - (i * 8));
|
||||
|
||||
mask[i] |= ((1ULL << sz) - 1) << shift;
|
||||
|
||||
bits -= size;
|
||||
i = sig.is_little_endian ? i - 1 : i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cabana::Signal::updatePrecision() {
|
||||
precision = std::max(num_decimals(factor), num_decimals(offset));
|
||||
}
|
||||
|
||||
@@ -65,6 +65,9 @@ namespace cabana {
|
||||
uint32_t size;
|
||||
QList<cabana::Signal> sigs;
|
||||
|
||||
QList<uint8_t> mask;
|
||||
void updateMask();
|
||||
|
||||
std::vector<const cabana::Signal*> getSignals() const;
|
||||
const cabana::Signal *sig(const QString &sig_name) const {
|
||||
auto it = std::find_if(sigs.begin(), sigs.end(), [&](auto &s) { return s.name == sig_name; });
|
||||
|
||||
@@ -55,6 +55,7 @@ void DBCFile::open(const QString &content) {
|
||||
sig.is_little_endian = s.is_little_endian;
|
||||
sig.updatePrecision();
|
||||
}
|
||||
m.updateMask();
|
||||
}
|
||||
parseExtraInfo(content);
|
||||
|
||||
@@ -103,6 +104,7 @@ bool DBCFile::writeContents(const QString &fn) {
|
||||
cabana::Signal *DBCFile::addSignal(const MessageId &id, const cabana::Signal &sig) {
|
||||
if (auto m = const_cast<cabana::Msg *>(msg(id.address))) {
|
||||
m->sigs.push_back(sig);
|
||||
m->updateMask();
|
||||
return &m->sigs.last();
|
||||
}
|
||||
|
||||
@@ -113,6 +115,7 @@ cabana::Signal *DBCFile::addSignal(const MessageId &id, const cabana::Signal &si
|
||||
if (auto m = const_cast<cabana::Msg *>(msg(id))) {
|
||||
if (auto s = (cabana::Signal *)m->sig(sig_name)) {
|
||||
*s = sig;
|
||||
m->updateMask();
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -135,6 +138,7 @@ void DBCFile::removeSignal(const MessageId &id, const QString &sig_name) {
|
||||
auto it = std::find_if(m->sigs.begin(), m->sigs.end(), [&](auto &s) { return s.name == sig_name; });
|
||||
if (it != m->sigs.end()) {
|
||||
m->sigs.erase(it);
|
||||
m->updateMask();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,6 +171,15 @@ QString DBCFile::newSignalName(const MessageId &id) {
|
||||
return name;
|
||||
}
|
||||
|
||||
const QList<uint8_t>& DBCFile::mask(const MessageId &id) const {
|
||||
const cabana::Msg *m = msg(id);
|
||||
if (m != nullptr) {
|
||||
return m->mask;
|
||||
} else {
|
||||
return empty_mask;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<uint32_t, cabana::Msg> DBCFile::getMessages() {
|
||||
return msgs;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ public:
|
||||
QString newMsgName(const MessageId &id);
|
||||
QString newSignalName(const MessageId &id);
|
||||
|
||||
const QList<uint8_t>& mask(const MessageId &id) const;
|
||||
|
||||
std::map<uint32_t, cabana::Msg> getMessages();
|
||||
const cabana::Msg *msg(const MessageId &id) const;
|
||||
const cabana::Msg *msg(uint32_t address) const;
|
||||
@@ -58,4 +60,5 @@ private:
|
||||
void parseExtraInfo(const QString &content);
|
||||
std::map<uint32_t, cabana::Msg> msgs;
|
||||
QString name_;
|
||||
QList<uint8_t> empty_mask;
|
||||
};
|
||||
|
||||
@@ -188,6 +188,15 @@ QString DBCManager::newSignalName(const MessageId &id) {
|
||||
return dbc_file->newSignalName(id);
|
||||
}
|
||||
|
||||
const QList<uint8_t>& DBCManager::mask(const MessageId &id) const {
|
||||
auto sources_dbc_file = findDBCFile(id);
|
||||
if (!sources_dbc_file) {
|
||||
return empty_mask;
|
||||
}
|
||||
auto [_, dbc_file] = *sources_dbc_file;
|
||||
return dbc_file->mask(id);
|
||||
}
|
||||
|
||||
std::map<MessageId, cabana::Msg> DBCManager::getMessages(uint8_t source) {
|
||||
std::map<MessageId, cabana::Msg> ret;
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ public:
|
||||
QString newMsgName(const MessageId &id);
|
||||
QString newSignalName(const MessageId &id);
|
||||
|
||||
const QList<uint8_t>& mask(const MessageId &id) const;
|
||||
|
||||
std::map<MessageId, cabana::Msg> getMessages(uint8_t source);
|
||||
const cabana::Msg *msg(const MessageId &id) const;
|
||||
const cabana::Msg* msg(uint8_t source, const QString &name);
|
||||
@@ -57,6 +59,7 @@ public:
|
||||
|
||||
private:
|
||||
SourceSet sources;
|
||||
QList<uint8_t> empty_mask;
|
||||
|
||||
public slots:
|
||||
void updateSources(const SourceSet &s);
|
||||
|
||||
@@ -138,6 +138,7 @@ std::deque<HistoryLogModel::Message> HistoryLogModel::fetchData(InputIt first, I
|
||||
}
|
||||
|
||||
std::deque<HistoryLogModel::Message> HistoryLogModel::fetchData(uint64_t from_time, uint64_t min_time) {
|
||||
const QList<uint8_t> mask;
|
||||
const auto &events = can->events(msg_id);
|
||||
const auto freq = can->lastMessage(msg_id).freq;
|
||||
const bool update_colors = !display_signals_mode || sigs.empty();
|
||||
@@ -150,7 +151,7 @@ std::deque<HistoryLogModel::Message> HistoryLogModel::fetchData(uint64_t from_ti
|
||||
auto msgs = fetchData(first, events.rend(), min_time);
|
||||
if (update_colors && (min_time > 0 || messages.empty())) {
|
||||
for (auto it = msgs.rbegin(); it != msgs.rend(); ++it) {
|
||||
hex_colors.compute(it->data.data(), it->data.size(), it->mono_time / (double)1e9, speed, freq);
|
||||
hex_colors.compute(it->data.data(), it->data.size(), it->mono_time / (double)1e9, speed, mask, freq);
|
||||
it->colors = hex_colors.colors;
|
||||
}
|
||||
}
|
||||
@@ -163,7 +164,7 @@ std::deque<HistoryLogModel::Message> HistoryLogModel::fetchData(uint64_t from_ti
|
||||
auto msgs = fetchData(first, events.cend(), 0);
|
||||
if (update_colors) {
|
||||
for (auto it = msgs.begin(); it != msgs.end(); ++it) {
|
||||
hex_colors.compute(it->data.data(), it->data.size(), it->mono_time / (double)1e9, speed, freq);
|
||||
hex_colors.compute(it->data.data(), it->data.size(), it->mono_time / (double)1e9, speed, mask, freq);
|
||||
it->colors = hex_colors.colors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,9 @@ MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) {
|
||||
suppress_clear = new QPushButton();
|
||||
suppress_layout->addWidget(suppress_add);
|
||||
suppress_layout->addWidget(suppress_clear);
|
||||
QCheckBox *suppress_defined_signals = new QCheckBox(tr("Suppress Defined Signals"), this);
|
||||
suppress_defined_signals->setChecked(settings.suppress_defined_signals);
|
||||
suppress_layout->addWidget(suppress_defined_signals);
|
||||
main_layout->addLayout(suppress_layout);
|
||||
|
||||
// signals/slots
|
||||
@@ -61,6 +64,9 @@ MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) {
|
||||
view->setUniformRowHeights(!settings.multiple_lines_bytes);
|
||||
model->sortMessages();
|
||||
});
|
||||
QObject::connect(suppress_defined_signals, &QCheckBox::stateChanged, [=](int state) {
|
||||
settings.suppress_defined_signals = (state == Qt::Checked);
|
||||
});
|
||||
QObject::connect(can, &AbstractStream::msgsReceived, model, &MessageListModel::msgsReceived);
|
||||
QObject::connect(can, &AbstractStream::streamStarted, this, &MessagesWidget::reset);
|
||||
QObject::connect(dbc(), &DBCManager::DBCFileChanged, model, &MessageListModel::sortMessages);
|
||||
|
||||
@@ -38,6 +38,7 @@ void Settings::save() {
|
||||
s.setValue("log_livestream", log_livestream);
|
||||
s.setValue("log_path", log_path);
|
||||
s.setValue("drag_direction", drag_direction);
|
||||
s.setValue("suppress_defined_signals", suppress_defined_signals);
|
||||
}
|
||||
|
||||
void Settings::load() {
|
||||
@@ -61,6 +62,7 @@ void Settings::load() {
|
||||
log_livestream = s.value("log_livestream", true).toBool();
|
||||
log_path = s.value("log_path").toString();
|
||||
drag_direction = (Settings::DragDirection)s.value("drag_direction", 0).toInt();
|
||||
suppress_defined_signals = s.value("suppress_defined_signals", false).toBool();
|
||||
if (log_path.isEmpty()) {
|
||||
log_path = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/cabana_live_stream/";
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
int sparkline_range = 15; // 15 seconds
|
||||
bool multiple_lines_bytes = true;
|
||||
bool log_livestream = true;
|
||||
bool suppress_defined_signals = false;
|
||||
QString log_path;
|
||||
QString last_dir;
|
||||
QString last_route_dir;
|
||||
|
||||
@@ -27,7 +27,8 @@ void AbstractStream::updateMessages(QHash<MessageId, CanData> *messages) {
|
||||
}
|
||||
|
||||
void AbstractStream::updateEvent(const MessageId &id, double sec, const uint8_t *data, uint8_t size) {
|
||||
all_msgs[id].compute((const char *)data, size, sec, getSpeed());
|
||||
QList<uint8_t> mask = settings.suppress_defined_signals ? dbc()->mask(id) : QList<uint8_t>();
|
||||
all_msgs[id].compute((const char *)data, size, sec, getSpeed(), mask);
|
||||
if (!new_msgs->contains(id)) {
|
||||
new_msgs->insert(id, {});
|
||||
}
|
||||
@@ -67,10 +68,11 @@ void AbstractStream::updateLastMsgsTo(double sec) {
|
||||
auto it = std::lower_bound(ev.crbegin(), ev.crend(), last_ts, [](auto e, uint64_t ts) {
|
||||
return e->mono_time > ts;
|
||||
});
|
||||
QList<uint8_t> mask = settings.suppress_defined_signals ? dbc()->mask(id) : QList<uint8_t>();
|
||||
if (it != ev.crend()) {
|
||||
double ts = (*it)->mono_time / 1e9 - routeStartTime();
|
||||
auto &m = all_msgs[id];
|
||||
m.compute((const char *)(*it)->dat, (*it)->size, ts, getSpeed());
|
||||
m.compute((const char *)(*it)->dat, (*it)->size, ts, getSpeed(), mask);
|
||||
m.count = std::distance(it, ev.crend());
|
||||
m.freq = m.count / std::max(1.0, ts);
|
||||
}
|
||||
@@ -153,7 +155,7 @@ static inline QColor blend(const QColor &a, const QColor &b) {
|
||||
return QColor((a.red() + b.red()) / 2, (a.green() + b.green()) / 2, (a.blue() + b.blue()) / 2, (a.alpha() + b.alpha()) / 2);
|
||||
}
|
||||
|
||||
void CanData::compute(const char *can_data, const int size, double current_sec, double playback_speed, uint32_t in_freq) {
|
||||
void CanData::compute(const char *can_data, const int size, double current_sec, double playback_speed, const QList<uint8_t> &mask, uint32_t in_freq) {
|
||||
ts = current_sec;
|
||||
++count;
|
||||
freq = in_freq == 0 ? count / std::max(1.0, current_sec) : in_freq;
|
||||
@@ -171,8 +173,9 @@ void CanData::compute(const char *can_data, const int size, double current_sec,
|
||||
const QColor &greyish_blue = !lighter ? GREYISH_BLUE : GREYISH_BLUE_LIGHTER;
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
const uint8_t last = dat[i];
|
||||
const uint8_t cur = can_data[i];
|
||||
const uint8_t mask_byte = (i < mask.size()) ? (~mask[i]) : 0xff;
|
||||
const uint8_t last = dat[i] & mask_byte;
|
||||
const uint8_t cur = can_data[i] & mask_byte;
|
||||
const int delta = cur - last;
|
||||
|
||||
if (last != cur) {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "tools/replay/replay.h"
|
||||
|
||||
struct CanData {
|
||||
void compute(const char *dat, const int size, double current_sec, double playback_speed, uint32_t in_freq = 0);
|
||||
void compute(const char *dat, const int size, double current_sec, double playback_speed, const QList<uint8_t> &mask, uint32_t in_freq = 0);
|
||||
|
||||
double ts = 0.;
|
||||
uint32_t count = 0;
|
||||
|
||||
Reference in New Issue
Block a user