Skip to content

Commit

Permalink
Showing 8 changed files with 44 additions and 15 deletions.
5 changes: 5 additions & 0 deletions tools/cabana/streams/abstractstream.h
Original file line number Diff line number Diff line change
@@ -64,6 +64,7 @@ class AbstractStream : public QObject {
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 @@ class AbstractStream : public QObject {
};

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;
};
9 changes: 8 additions & 1 deletion tools/cabana/streams/livestream.cc
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions tools/cabana/streams/livestream.h
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ class LiveStream : public AbstractStream {
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; }
31 changes: 21 additions & 10 deletions tools/cabana/streams/pandastream.cc
Original file line number Diff line number Diff line change
@@ -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();
return true;
}
try {
*stream = new PandaStream(qApp, config);
return true;
} catch (std::exception &e) {
QMessageBox::warning(nullptr, tr("Warning"), tr("Failed to connect to panda: '%1'").arg(e.what()));
return false;
}
QMessageBox::warning(nullptr, tr("Warning"), tr("Failed to connect to panda"));
return false;
}
5 changes: 3 additions & 2 deletions tools/cabana/streams/pandastream.h
Original file line number Diff line number Diff line change
@@ -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;
1 change: 1 addition & 0 deletions tools/cabana/streams/socketcanstream.h
Original file line number Diff line number Diff line change
@@ -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();

5 changes: 3 additions & 2 deletions tools/cabana/streamselector.cc
Original file line number Diff line number Diff line change
@@ -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);
}
2 changes: 2 additions & 0 deletions tools/cabana/streamselector.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <QDialogButtonBox>
#include <QDialog>
#include <QLineEdit>
#include <QTabWidget>
@@ -17,4 +18,5 @@ class StreamSelector : public QDialog {
private:
QLineEdit *dbc_file;
QTabWidget *tab;
QDialogButtonBox *btn_box;
};

0 comments on commit 6b3d2b5

Please sign in to comment.