cabana: fix panda stream issues (#32537)

fix segfault
pull/32584/head
Dean Lee 11 months ago committed by GitHub
parent 521ee46c47
commit 6b3d2b5a80
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      tools/cabana/streams/abstractstream.h
  2. 9
      tools/cabana/streams/livestream.cc
  3. 1
      tools/cabana/streams/livestream.h
  4. 29
      tools/cabana/streams/pandastream.cc
  5. 5
      tools/cabana/streams/pandastream.h
  6. 1
      tools/cabana/streams/socketcanstream.h
  7. 5
      tools/cabana/streamselector.cc
  8. 2
      tools/cabana/streamselector.h

@ -64,6 +64,7 @@ public:
AbstractStream(QObject *parent);
virtual ~AbstractStream() {}
virtual void start() = 0;
virtual void stop() {}
virtual bool liveStreaming() const { return true; }
virtual void seekTo(double ts) {}
virtual QString routeName() const = 0;
@ -128,11 +129,15 @@ private:
};
class AbstractOpenStreamWidget : public QWidget {
Q_OBJECT
public:
AbstractOpenStreamWidget(AbstractStream **stream, QWidget *parent = nullptr) : stream(stream), QWidget(parent) {}
virtual bool open() = 0;
virtual QString title() = 0;
signals:
void enableOpenButton(bool);
protected:
AbstractStream **stream = nullptr;
};

@ -42,6 +42,10 @@ LiveStream::LiveStream(QObject *parent) : AbstractStream(parent) {
QObject::connect(stream_thread, &QThread::finished, stream_thread, &QThread::deleteLater);
}
LiveStream::~LiveStream() {
stop();
}
void LiveStream::startUpdateTimer() {
update_timer.stop();
update_timer.start(1000.0 / settings.fps, this);
@ -55,11 +59,14 @@ void LiveStream::start() {
begin_date_time = QDateTime::currentDateTime();
}
LiveStream::~LiveStream() {
void LiveStream::stop() {
if (!stream_thread) return;
update_timer.stop();
stream_thread->requestInterruption();
stream_thread->quit();
stream_thread->wait();
stream_thread = nullptr;
}
// called in streamThread

@ -14,6 +14,7 @@ public:
LiveStream(QObject *parent);
virtual ~LiveStream();
void start() override;
void stop() override;
inline QDateTime beginDateTime() const { return begin_date_time; }
inline double routeStartTime() const override { return begin_event_ts / 1e9; }
void setSpeed(float speed) override { speed_ = speed; }

@ -6,12 +6,17 @@
#include <QMessageBox>
#include <QPushButton>
#include <QThread>
#include <QTimer>
PandaStream::PandaStream(QObject *parent, PandaStreamConfig config_) : config(config_), LiveStream(parent) {}
PandaStream::PandaStream(QObject *parent, PandaStreamConfig config_) : config(config_), LiveStream(parent) {
if (!connect()) {
throw std::runtime_error("Failed to connect to panda");
}
}
bool PandaStream::connect() {
try {
qDebug() << "Connecting to panda with serial" << config.serial;
qDebug() << "Connecting to panda " << config.serial;
panda.reset(new Panda(config.serial.toStdString()));
config.bus_config.resize(3);
qDebug() << "Connected";
@ -80,6 +85,13 @@ AbstractOpenStreamWidget *PandaStream::widget(AbstractStream **stream) {
OpenPandaWidget::OpenPandaWidget(AbstractStream **stream) : AbstractOpenStreamWidget(stream) {
form_layout = new QFormLayout(this);
if (can && dynamic_cast<PandaStream *>(can) != nullptr) {
form_layout->addWidget(new QLabel(tr("Already connected to %1.").arg(can->routeName())));
form_layout->addWidget(new QLabel("Close the current connection via [File menu -> Close Stream] before connecting to another Panda."));
QTimer::singleShot(0, [this]() { emit enableOpenButton(false); });
return;
}
QHBoxLayout *serial_layout = new QHBoxLayout();
serial_layout->addWidget(serial_edit = new QComboBox());
@ -116,6 +128,7 @@ void OpenPandaWidget::buildConfigForm() {
Panda panda(serial.toStdString());
has_fd = (panda.hw_type == cereal::PandaState::PandaType::RED_PANDA) || (panda.hw_type == cereal::PandaState::PandaType::RED_PANDA_V2);
} catch (const std::exception& e) {
qDebug() << "failed to open panda" << serial;
has_panda = false;
}
}
@ -170,13 +183,11 @@ void OpenPandaWidget::buildConfigForm() {
}
bool OpenPandaWidget::open() {
if (!config.serial.isEmpty()) {
auto panda_stream = std::make_unique<PandaStream>(qApp, config);
if (panda_stream->connect()) {
*stream = panda_stream.release();
try {
*stream = new PandaStream(qApp, config);
return true;
}
}
QMessageBox::warning(nullptr, tr("Warning"), tr("Failed to connect to panda"));
} catch (std::exception &e) {
QMessageBox::warning(nullptr, tr("Warning"), tr("Failed to connect to panda: '%1'").arg(e.what()));
return false;
}
}

@ -21,13 +21,14 @@ class PandaStream : public LiveStream {
Q_OBJECT
public:
PandaStream(QObject *parent, PandaStreamConfig config_ = {});
bool connect();
~PandaStream() { stop(); }
static AbstractOpenStreamWidget *widget(AbstractStream **stream);
inline QString routeName() const override {
return QString("Live Streaming From Panda %1").arg(config.serial);
return QString("Panda: %1").arg(config.serial);
}
protected:
bool connect();
void streamThread() override;
std::unique_ptr<Panda> panda;

@ -17,6 +17,7 @@ class SocketCanStream : public LiveStream {
Q_OBJECT
public:
SocketCanStream(QObject *parent, SocketCanStreamConfig config_ = {});
~SocketCanStream() { stop(); }
static AbstractOpenStreamWidget *widget(AbstractStream **stream);
static bool available();

@ -1,6 +1,5 @@
#include "tools/cabana/streamselector.h"
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QLabel>
#include <QPushButton>
@ -31,7 +30,7 @@ StreamSelector::StreamSelector(AbstractStream **stream, QWidget *parent) : QDial
line->setFrameStyle(QFrame::HLine | QFrame::Sunken);
layout->addWidget(line);
auto btn_box = new QDialogButtonBox(QDialogButtonBox::Open | QDialogButtonBox::Cancel);
btn_box = new QDialogButtonBox(QDialogButtonBox::Open | QDialogButtonBox::Cancel);
layout->addWidget(btn_box);
addStreamWidget(ReplayStream::widget(stream));
@ -60,4 +59,6 @@ StreamSelector::StreamSelector(AbstractStream **stream, QWidget *parent) : QDial
void StreamSelector::addStreamWidget(AbstractOpenStreamWidget *w) {
tab->addTab(w, w->title());
auto open_btn = btn_box->button(QDialogButtonBox::Open);
QObject::connect(w, &AbstractOpenStreamWidget::enableOpenButton, open_btn, &QPushButton::setEnabled);
}

@ -1,5 +1,6 @@
#pragma once
#include <QDialogButtonBox>
#include <QDialog>
#include <QLineEdit>
#include <QTabWidget>
@ -17,4 +18,5 @@ public:
private:
QLineEdit *dbc_file;
QTabWidget *tab;
QDialogButtonBox *btn_box;
};

Loading…
Cancel
Save