30 changed files with 881 additions and 129 deletions
@ -0,0 +1,113 @@
@@ -0,0 +1,113 @@
|
||||
#include <QFileDialog> |
||||
#include <QMessageBox> |
||||
#include <QDesktopServices> |
||||
|
||||
#include "QGCMAVLinkLogPlayer.h" |
||||
#include "ui_QGCMAVLinkLogPlayer.h" |
||||
|
||||
QGCMAVLinkLogPlayer::QGCMAVLinkLogPlayer(MAVLinkProtocol* mavlink, QWidget *parent) : |
||||
QWidget(parent), |
||||
lineCounter(0), |
||||
totalLines(0), |
||||
startTime(0), |
||||
endTime(0), |
||||
currentTime(0), |
||||
mavlink(mavlink), |
||||
ui(new Ui::QGCMAVLinkLogPlayer) |
||||
{ |
||||
ui->setupUi(this); |
||||
ui->gridLayout->setAlignment(Qt::AlignTop); |
||||
|
||||
// Setup buttons
|
||||
connect(ui->selectFileButton, SIGNAL(clicked()), this, SLOT(selectLogFile())); |
||||
connect(ui->pauseButton, SIGNAL(clicked()), this, SLOT(pause())); |
||||
connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play())); |
||||
|
||||
} |
||||
|
||||
QGCMAVLinkLogPlayer::~QGCMAVLinkLogPlayer() |
||||
{ |
||||
delete ui; |
||||
} |
||||
|
||||
void QGCMAVLinkLogPlayer::play() |
||||
{ |
||||
if (logFile.isOpen()) |
||||
{ |
||||
ui->pauseButton->setChecked(false); |
||||
} |
||||
else |
||||
{ |
||||
ui->playButton->setChecked(false); |
||||
QMessageBox msgBox; |
||||
msgBox.setIcon(QMessageBox::Information); |
||||
msgBox.setText(tr("No logfile selected")); |
||||
msgBox.setInformativeText(tr("Please select first a MAVLink log file before playing it.")); |
||||
msgBox.setStandardButtons(QMessageBox::Ok); |
||||
msgBox.setDefaultButton(QMessageBox::Ok); |
||||
msgBox.exec(); |
||||
} |
||||
} |
||||
|
||||
void QGCMAVLinkLogPlayer::pause() |
||||
{ |
||||
ui->playButton->setChecked(false); |
||||
} |
||||
|
||||
void QGCMAVLinkLogPlayer::selectLogFile() |
||||
{ |
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Specify MAVLink log file name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("MAVLink Logfile (*.mavlink);;")); |
||||
|
||||
loadLogFile(fileName); |
||||
} |
||||
|
||||
void QGCMAVLinkLogPlayer::loadLogFile(const QString& file) |
||||
{ |
||||
logFile.setFileName(file); |
||||
|
||||
if (!logFile.open(QFile::ReadOnly)) |
||||
{ |
||||
QMessageBox msgBox; |
||||
msgBox.setIcon(QMessageBox::Critical); |
||||
msgBox.setText(tr("The selected logfile is unreadable")); |
||||
msgBox.setInformativeText(tr("Please make sure that the file %1 is readable or select a different file").arg(file)); |
||||
msgBox.setStandardButtons(QMessageBox::Ok); |
||||
msgBox.setDefaultButton(QMessageBox::Ok); |
||||
msgBox.exec(); |
||||
logFile.setFileName(""); |
||||
} |
||||
else |
||||
{ |
||||
ui->logFileNameLabel->setText(tr("%1").arg(file)); |
||||
} |
||||
} |
||||
|
||||
/**
|
||||
* This function is the "mainloop" of the log player, reading one line |
||||
* and adjusting the mainloop timer to read the next line in time. |
||||
* It might not perfectly match the timing of the log file, |
||||
* but it will never induce a static drift into the log file replay. |
||||
* For scientific logging, the use of onboard timestamps and the log |
||||
* functionality of the line chart plot is recommended. |
||||
*/ |
||||
void QGCMAVLinkLogPlayer::readLine() |
||||
{ |
||||
|
||||
// Ui update: Only every 20 messages
|
||||
// to prevent flickering and high CPU load
|
||||
|
||||
// Update status label
|
||||
// Update progress bar
|
||||
} |
||||
|
||||
void QGCMAVLinkLogPlayer::changeEvent(QEvent *e) |
||||
{ |
||||
QWidget::changeEvent(e); |
||||
switch (e->type()) { |
||||
case QEvent::LanguageChange: |
||||
ui->retranslateUi(this); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
} |
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
#ifndef QGCMAVLINKLOGPLAYER_H |
||||
#define QGCMAVLINKLOGPLAYER_H |
||||
|
||||
#include <QWidget> |
||||
#include <QFile> |
||||
|
||||
#include "MAVLinkProtocol.h" |
||||
|
||||
namespace Ui { |
||||
class QGCMAVLinkLogPlayer; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Replays MAVLink log files |
||||
* |
||||
* This class allows to replay MAVLink logs at varying speeds. |
||||
* captured flights can be replayed, shown to others and analyzed |
||||
* in-depth later on. |
||||
*/ |
||||
class QGCMAVLinkLogPlayer : public QWidget |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
explicit QGCMAVLinkLogPlayer(MAVLinkProtocol* mavlink, QWidget *parent = 0); |
||||
~QGCMAVLinkLogPlayer(); |
||||
|
||||
public slots: |
||||
/** @brief Replay the logfile */ |
||||
void play(); |
||||
/** @brief Pause the logfile */ |
||||
void pause(); |
||||
/** @brief Select logfile */ |
||||
void selectLogFile(); |
||||
/** @brief Load log file */ |
||||
void loadLogFile(const QString& file); |
||||
|
||||
protected: |
||||
int lineCounter; |
||||
int totalLines; |
||||
quint64 startTime; |
||||
quint64 endTime; |
||||
quint64 currentTime; |
||||
MAVLinkProtocol* mavlink; |
||||
QFile logFile; |
||||
QTimer loopTimer; |
||||
void changeEvent(QEvent *e); |
||||
void readLine(); |
||||
|
||||
private: |
||||
Ui::QGCMAVLinkLogPlayer *ui; |
||||
}; |
||||
|
||||
#endif // QGCMAVLINKLOGPLAYER_H
|
@ -0,0 +1,111 @@
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<ui version="4.0"> |
||||
<class>QGCMAVLinkLogPlayer</class> |
||||
<widget class="QWidget" name="QGCMAVLinkLogPlayer"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>0</x> |
||||
<y>0</y> |
||||
<width>407</width> |
||||
<height>144</height> |
||||
</rect> |
||||
</property> |
||||
<property name="windowTitle"> |
||||
<string>Form</string> |
||||
</property> |
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="1,10,10,1,1,0"> |
||||
<property name="horizontalSpacing"> |
||||
<number>12</number> |
||||
</property> |
||||
<item row="0" column="0" colspan="3"> |
||||
<widget class="QLabel" name="logFileNameLabel"> |
||||
<property name="text"> |
||||
<string>Please choose logfile</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="0" column="3" colspan="3"> |
||||
<widget class="QPushButton" name="selectFileButton"> |
||||
<property name="text"> |
||||
<string>Select File</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="1" column="1" colspan="5"> |
||||
<widget class="QSlider" name="speedSlider"> |
||||
<property name="minimum"> |
||||
<number>1</number> |
||||
</property> |
||||
<property name="maximum"> |
||||
<number>100</number> |
||||
</property> |
||||
<property name="value"> |
||||
<number>50</number> |
||||
</property> |
||||
<property name="sliderPosition"> |
||||
<number>50</number> |
||||
</property> |
||||
<property name="orientation"> |
||||
<enum>Qt::Horizontal</enum> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="3" column="0" colspan="3"> |
||||
<widget class="QLabel" name="logStatsLabel"> |
||||
<property name="text"> |
||||
<string>No logfile selected..</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="3" column="5"> |
||||
<widget class="QToolButton" name="pauseButton"> |
||||
<property name="text"> |
||||
<string>...</string> |
||||
</property> |
||||
<property name="icon"> |
||||
<iconset resource="../../mavground.qrc"> |
||||
<normaloff>:/images/actions/media-playback-pause.svg</normaloff>:/images/actions/media-playback-pause.svg</iconset> |
||||
</property> |
||||
<property name="checkable"> |
||||
<bool>true</bool> |
||||
</property> |
||||
<property name="checked"> |
||||
<bool>true</bool> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="4" column="0" colspan="6"> |
||||
<widget class="QProgressBar" name="progressBar"> |
||||
<property name="value"> |
||||
<number>0</number> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="1" column="0"> |
||||
<widget class="QLabel" name="speedLabel"> |
||||
<property name="text"> |
||||
<string>Speed</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="3" column="4"> |
||||
<widget class="QToolButton" name="playButton"> |
||||
<property name="text"> |
||||
<string>...</string> |
||||
</property> |
||||
<property name="icon"> |
||||
<iconset resource="../../mavground.qrc"> |
||||
<normaloff>:/images/actions/media-playback-start.svg</normaloff>:/images/actions/media-playback-start.svg</iconset> |
||||
</property> |
||||
<property name="checkable"> |
||||
<bool>true</bool> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
</widget> |
||||
<resources> |
||||
<include location="../../mavground.qrc"/> |
||||
</resources> |
||||
<connections/> |
||||
</ui> |
Loading…
Reference in new issue