cabana: add csv export (#30800)

export csv
old-commit-hash: 5f04517677
chrysler-long2
Dean Lee 1 year ago committed by GitHub
parent a3eafc8cd5
commit 8056fe5aff
  1. 3
      tools/cabana/SConscript
  2. 2
      tools/cabana/dbc/dbc.cc
  3. 16
      tools/cabana/historylog.cc
  4. 3
      tools/cabana/historylog.h
  5. 12
      tools/cabana/mainwin.cc
  6. 2
      tools/cabana/mainwin.h
  7. 2
      tools/cabana/settings.cc
  8. 2
      tools/cabana/streams/abstractstream.h
  9. 47
      tools/cabana/utils/export.cc
  10. 10
      tools/cabana/utils/export.h
  11. 2
      tools/cabana/utils/util.cc
  12. 0
      tools/cabana/utils/util.h
  13. 2
      tools/cabana/videowidget.h

@ -27,8 +27,9 @@ cabana_env.Depends(assets, Glob('/assets/*', exclude=[assets, assets_src, "asset
cabana_lib = cabana_env.Library("cabana_lib", ['mainwin.cc', 'streams/socketcanstream.cc', 'streams/pandastream.cc', 'streams/devicestream.cc', 'streams/livestream.cc', 'streams/abstractstream.cc', 'streams/replaystream.cc', 'binaryview.cc', 'historylog.cc', 'videowidget.cc', 'signalview.cc',
'dbc/dbc.cc', 'dbc/dbcfile.cc', 'dbc/dbcmanager.cc',
'utils/export.cc', 'utils/util.cc',
'chart/chartswidget.cc', 'chart/chart.cc', 'chart/signalselector.cc', 'chart/tiplabel.cc', 'chart/sparkline.cc',
'commands.cc', 'messageswidget.cc', 'streamselector.cc', 'settings.cc', 'util.cc', 'detailwidget.cc', 'tools/findsimilarbits.cc', 'tools/findsignal.cc'], LIBS=cabana_libs, FRAMEWORKS=base_frameworks)
'commands.cc', 'messageswidget.cc', 'streamselector.cc', 'settings.cc', 'detailwidget.cc', 'tools/findsimilarbits.cc', 'tools/findsignal.cc'], LIBS=cabana_libs, FRAMEWORKS=base_frameworks)
cabana_env.Program('cabana', ['cabana.cc', cabana_lib, assets], LIBS=cabana_libs, FRAMEWORKS=base_frameworks)
if GetOption('extras'):

@ -2,7 +2,7 @@
#include <algorithm>
#include "tools/cabana/util.h"
#include "tools/cabana/utils/util.h"
uint qHash(const MessageId &item) {
return qHash(item.source) ^ qHash(item.address);

@ -2,11 +2,12 @@
#include <functional>
#include <QFileDialog>
#include <QPainter>
#include <QPushButton>
#include <QVBoxLayout>
#include "tools/cabana/commands.h"
#include "tools/cabana/utils/export.h"
QVariant HistoryLogModel::data(const QModelIndex &index, int role) const {
const bool show_signals = display_signals_mode && sigs.size() > 0;
@ -220,6 +221,8 @@ LogsWidget::LogsWidget(QWidget *parent) : QFrame(parent) {
h->addWidget(filters_widget);
h->addStretch(0);
h->addWidget(dynamic_mode = new QCheckBox(tr("Dynamic")), 0, Qt::AlignRight);
ToolButton *export_btn = new ToolButton("filetype-csv", tr("Export to CSV file..."));
h->addWidget(export_btn, 0, Qt::AlignRight);
display_type_cb->addItems({"Signal", "Hex"});
display_type_cb->setToolTip(tr("Display signal value or raw hex value"));
@ -252,6 +255,7 @@ LogsWidget::LogsWidget(QWidget *parent) : QFrame(parent) {
QObject::connect(signals_cb, SIGNAL(activated(int)), this, SLOT(setFilter()));
QObject::connect(comp_box, SIGNAL(activated(int)), this, SLOT(setFilter()));
QObject::connect(value_edit, &QLineEdit::textChanged, this, &LogsWidget::setFilter);
QObject::connect(export_btn, &QToolButton::clicked, this, &LogsWidget::exportToCSV);
QObject::connect(can, &AbstractStream::seekedTo, model, &HistoryLogModel::refresh);
QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &LogsWidget::refresh);
QObject::connect(UndoStack::instance(), &QUndoStack::indexChanged, this, &LogsWidget::refresh);
@ -304,3 +308,13 @@ void LogsWidget::showEvent(QShowEvent *event) {
model->refresh();
}
}
void LogsWidget::exportToCSV() {
QString dir = QString("%1/%2_%3.csv").arg(settings.last_dir).arg(can->routeName()).arg(msgName(model->msg_id));
QString fn = QFileDialog::getSaveFileName(this, QString("Export %1 to CSV file").arg(msgName(model->msg_id)),
dir, tr("csv (*.csv)"));
if (!fn.isEmpty()) {
const bool export_signals = model->display_signals_mode && model->sigs.size() > 0;
export_signals ? utils::exportSignalsToCSV(fn, model->msg_id) : utils::exportToCSV(fn, model->msg_id);
}
}

@ -11,7 +11,7 @@
#include "tools/cabana/dbc/dbcmanager.h"
#include "tools/cabana/streams/abstractstream.h"
#include "tools/cabana/util.h"
#include "tools/cabana/utils/util.h"
class HeaderView : public QHeaderView {
public:
@ -80,6 +80,7 @@ public:
private slots:
void setFilter();
void exportToCSV();
private:
void refresh();

@ -22,6 +22,7 @@
#include "tools/cabana/commands.h"
#include "tools/cabana/streamselector.h"
#include "tools/cabana/tools/findsignal.h"
#include "tools/cabana/utils/export.h"
#include "tools/replay/replay.h"
MainWindow::MainWindow() : QMainWindow() {
@ -86,7 +87,9 @@ void MainWindow::createActions() {
QMenu *file_menu = menuBar()->addMenu(tr("&File"));
file_menu->addAction(tr("Open Stream..."), this, &MainWindow::openStream);
close_stream_act = file_menu->addAction(tr("Close stream"), this, &MainWindow::closeStream);
export_to_csv_act = file_menu->addAction(tr("Export to CSV..."), this, &MainWindow::exportToCSV);
close_stream_act->setEnabled(false);
export_to_csv_act->setEnabled(false);
file_menu->addSeparator();
file_menu->addAction(tr("New DBC File"), [this]() { newFile(); }, QKeySequence::New);
@ -270,6 +273,14 @@ void MainWindow::closeStream() {
statusBar()->showMessage(tr("stream closed"));
}
void MainWindow::exportToCSV() {
QString dir = QString("%1/%2.csv").arg(settings.last_dir).arg(can->routeName());
QString fn = QFileDialog::getSaveFileName(this, "Export stream to CSV file", dir, tr("csv (*.csv)"));
if (!fn.isEmpty()) {
utils::exportToCSV(fn);
}
}
void MainWindow::newFile(SourceSet s) {
closeFile(s);
dbc()->open(s, "", "");
@ -344,6 +355,7 @@ void MainWindow::changingStream() {
void MainWindow::streamStarted() {
bool has_stream = dynamic_cast<DummyStream *>(can) == nullptr;
close_stream_act->setEnabled(has_stream);
export_to_csv_act->setEnabled(has_stream);
tools_menu->setEnabled(has_stream);
createDockWidgets();

@ -29,6 +29,7 @@ public:
public slots:
void openStream();
void closeStream();
void exportToCSV();
void changingStream();
void streamStarted();
@ -94,6 +95,7 @@ protected:
QMenu *manage_dbcs_menu = nullptr;
QMenu *tools_menu = nullptr;
QAction *close_stream_act = nullptr;
QAction *export_to_csv_act = nullptr;
QAction *save_dbc = nullptr;
QAction *save_dbc_as = nullptr;
QAction *copy_dbc_to_clipboard = nullptr;

@ -10,7 +10,7 @@
#include <QStandardPaths>
#include <type_traits>
#include "tools/cabana/util.h"
#include "tools/cabana/utils/util.h"
Settings settings;

@ -12,7 +12,7 @@
#include "cereal/messaging/messaging.h"
#include "tools/cabana/dbc/dbcmanager.h"
#include "tools/cabana/util.h"
#include "tools/cabana/utils/util.h"
struct CanData {
void compute(const MessageId &msg_id, const uint8_t *dat, const int size, double current_sec,

@ -0,0 +1,47 @@
#include "tools/cabana/utils/export.h"
#include <QFile>
#include <QTextStream>
#include "tools/cabana/streams/abstractstream.h"
namespace utils {
void exportToCSV(const QString &file_name, std::optional<MessageId> msg_id) {
QFile file(file_name);
if (file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
const uint64_t start_time = can->routeStartTime();
QTextStream stream(&file);
stream << "time,addr,bus,data\n";
for (auto e : msg_id ? can->events(*msg_id) : can->allEvents()) {
stream << QString::number((e->mono_time / 1e9) - start_time, 'f', 2) << ","
<< "0x" << QString::number(e->address, 16) << "," << e->src << ","
<< "0x" << QByteArray::fromRawData((const char *)e->dat, e->size).toHex().toUpper() << "\n";
}
}
}
void exportSignalsToCSV(const QString &file_name, const MessageId &msg_id) {
QFile file(file_name);
if (auto msg = dbc()->msg(msg_id); msg && msg->sigs.size() && file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
QTextStream stream(&file);
stream << "time,addr,bus";
for (auto s : msg->sigs)
stream << "," << s->name;
stream << "\n";
const uint64_t start_time = can->routeStartTime();
for (auto e : can->events(msg_id)) {
stream << QString::number((e->mono_time / 1e9) - start_time, 'f', 2) << ","
<< "0x" << QString::number(e->address, 16) << "," << e->src;
for (auto s : msg->sigs) {
double value = 0;
s->getValue(e->dat, e->size, &value);
stream << "," << QString::number(value, 'f', s->precision);
}
stream << "\n";
}
}
}
} // namespace utils

@ -0,0 +1,10 @@
#pragma once
#include <optional>
#include "tools/cabana/dbc/dbcmanager.h"
namespace utils {
void exportToCSV(const QString &file_name, std::optional<MessageId> msg_id = std::nullopt);
void exportSignalsToCSV(const QString &file_name, const MessageId &msg_id);
} // namespace utils

@ -1,4 +1,4 @@
#include "tools/cabana/util.h"
#include "tools/cabana/utils/util.h"
#include <algorithm>
#include <csignal>

@ -10,7 +10,7 @@
#include <QTabBar>
#include "selfdrive/ui/qt/widgets/cameraview.h"
#include "tools/cabana/util.h"
#include "tools/cabana/utils/util.h"
#include "tools/replay/logreader.h"
struct AlertInfo {

Loading…
Cancel
Save