QGCMAVLinkLogPlayer.cc 5.96 KB
Newer Older
1
#include <QStandardPaths>
2
#include <QtEndian>
3

4
#include "MainWindow.h"
dogmaphobic's avatar
dogmaphobic committed
5
#ifndef __ios__
6
#include "SerialLink.h"
dogmaphobic's avatar
dogmaphobic committed
7
#endif
8
#include "QGCMAVLinkLogPlayer.h"
9
#include "QGC.h"
10
#include "ui_QGCMAVLinkLogPlayer.h"
Don Gagne's avatar
Don Gagne committed
11
#include "QGCApplication.h"
Don Gagne's avatar
Don Gagne committed
12
#include "LinkManager.h"
Don Gagne's avatar
Don Gagne committed
13
#include "QGCFileDialog.h"
14
#include "QGCMessageBox.h"
15

Don Gagne's avatar
Don Gagne committed
16
QGCMAVLinkLogPlayer::QGCMAVLinkLogPlayer(QWidget *parent) :
17
    QWidget(parent),
Don Gagne's avatar
Don Gagne committed
18 19
    _replayLink(NULL),
    _ui(new Ui::QGCMAVLinkLogPlayer)
Don Gagne's avatar
Don Gagne committed
20
{    
Don Gagne's avatar
Don Gagne committed
21 22
    _ui->setupUi(this);
    _ui->horizontalLayout->setAlignment(Qt::AlignTop);
23

24
    // Setup buttons
Don Gagne's avatar
Don Gagne committed
25 26 27 28 29
    connect(_ui->selectFileButton, &QPushButton::clicked, this, &QGCMAVLinkLogPlayer::_selectLogFileForPlayback);
    connect(_ui->playButton, &QPushButton::clicked, this, &QGCMAVLinkLogPlayer::_playPauseToggle);
    connect(_ui->speedSlider, &QSlider::valueChanged, this, &QGCMAVLinkLogPlayer::_setAccelerationFromSlider);
    connect(_ui->positionSlider, &QSlider::valueChanged, this, &QGCMAVLinkLogPlayer::_setPlayheadFromSlider);
    connect(_ui->positionSlider, &QSlider::sliderPressed, this, &QGCMAVLinkLogPlayer::_pause);
Don Gagne's avatar
Don Gagne committed
30
    
Don Gagne's avatar
Don Gagne committed
31
    _enablePlaybackControls(false);
Don Gagne's avatar
Don Gagne committed
32
    
Don Gagne's avatar
Don Gagne committed
33 34
    _ui->positionSlider->setMinimum(0);
    _ui->positionSlider->setMaximum(100);
Don Gagne's avatar
Don Gagne committed
35
    
Don Gagne's avatar
Don Gagne committed
36 37 38
    _ui->speedSlider->setMinimum(-100);
    _ui->speedSlider->setMaximum(100);
    _ui->speedSlider->setValue(0);
39 40
}

Don Gagne's avatar
Don Gagne committed
41
QGCMAVLinkLogPlayer::~QGCMAVLinkLogPlayer()
42
{
Don Gagne's avatar
Don Gagne committed
43
    delete _ui;
44 45
}

Don Gagne's avatar
Don Gagne committed
46
void QGCMAVLinkLogPlayer::_playPauseToggle(void)
47
{
Don Gagne's avatar
Don Gagne committed
48 49 50 51
    if (_replayLink->isPlaying()) {
        _pause();
    } else {
        _replayLink->play();
52
    }
53 54
}

Don Gagne's avatar
Don Gagne committed
55
void QGCMAVLinkLogPlayer::_pause(void)
56
{
Don Gagne's avatar
Don Gagne committed
57
    _replayLink->pause();
58 59
}

Don Gagne's avatar
Don Gagne committed
60
void QGCMAVLinkLogPlayer::_selectLogFileForPlayback(void)
Lorenz Meier's avatar
Lorenz Meier committed
61
{
Don Gagne's avatar
Don Gagne committed
62
    // Disallow replay when any links are connected
63
    if (qgcApp()->toolbox()->linkManager()->anyConnectedLinks()) {
64
        QGCMessageBox::information(tr("Log Replay"), tr("You must close all connections prior to replaying a log."));
Don Gagne's avatar
Don Gagne committed
65 66 67
        return;
    }
    
Don Gagne's avatar
Don Gagne committed
68
    QString logFilename = QGCFileDialog::getOpenFileName(
69 70 71
        this,
        tr("Load MAVLink Log File"),
        qgcApp()->mavlinkLogFilesLocation(),
72
        tr("MAVLink Log Files (*.mavlink);;All Files (*)"));
73

Don Gagne's avatar
Don Gagne committed
74 75
    if (logFilename.isEmpty()) {
        return;
76
    }
Don Gagne's avatar
Don Gagne committed
77 78 79 80 81 82 83
    
    LinkInterface* createConnectedLink(LinkConfiguration* config);
    
    LogReplayLinkConfiguration* linkConfig = new LogReplayLinkConfiguration(QString("Log Replay"));
    linkConfig->setLogFilename(logFilename);
    linkConfig->setName(linkConfig->logFilenameShort());
    _ui->logFileNameLabel->setText(linkConfig->logFilenameShort());
84
    _replayLink = (LogReplayLink*)qgcApp()->toolbox()->linkManager()->createConnectedLink(linkConfig);
Don Gagne's avatar
Don Gagne committed
85 86 87 88 89 90 91 92 93
    
    connect(_replayLink, &LogReplayLink::logFileStats, this, &QGCMAVLinkLogPlayer::_logFileStats);
    connect(_replayLink, &LogReplayLink::playbackStarted, this, &QGCMAVLinkLogPlayer::_playbackStarted);
    connect(_replayLink, &LogReplayLink::playbackPaused, this, &QGCMAVLinkLogPlayer::_playbackPaused);
    connect(_replayLink, &LogReplayLink::playbackPercentCompleteChanged, this, &QGCMAVLinkLogPlayer::_playbackPercentCompleteChanged);
    connect(_replayLink, &LogReplayLink::disconnected, this, &QGCMAVLinkLogPlayer::_replayLinkDisconnected);
    
    _ui->positionSlider->setValue(0);
    _ui->speedSlider->setValue(0);
94 95
}

Don Gagne's avatar
Don Gagne committed
96
void QGCMAVLinkLogPlayer::_playbackError(void)
97
{
Don Gagne's avatar
Don Gagne committed
98 99
    _ui->logFileNameLabel->setText("Error");
    _enablePlaybackControls(false);
100 101
}

Don Gagne's avatar
Don Gagne committed
102
QString QGCMAVLinkLogPlayer::_secondsToHMS(int seconds)
103
{
Don Gagne's avatar
Don Gagne committed
104 105 106 107 108
    int secondsPart  = seconds;
    int minutesPart  = secondsPart / 60;
    int hoursPart    = minutesPart / 60;
    secondsPart -= 60 * minutesPart;
    minutesPart -= 60 * hoursPart;
109

Don Gagne's avatar
Don Gagne committed
110
    return QString("%1h:%2m:%3s").arg(hoursPart, 2).arg(minutesPart, 2).arg(secondsPart, 2);
111 112
}

Don Gagne's avatar
Don Gagne committed
113 114 115 116
/// Signalled from LogReplayLink once log file information is known
void QGCMAVLinkLogPlayer::_logFileStats(bool    logTimestamped,         ///< true: timestamped log
                                        int     logDurationSeconds,     ///< Log duration
                                        int     binaryBaudRate)         ///< Baud rate for non-timestamped log
117
{
Don Gagne's avatar
Don Gagne committed
118 119 120 121 122 123
    Q_UNUSED(logTimestamped);
    Q_UNUSED(binaryBaudRate);
    
    _logDurationSeconds = logDurationSeconds;
    
    _ui->logStatsLabel->setText(_secondsToHMS(logDurationSeconds));
124 125
}

Don Gagne's avatar
Don Gagne committed
126 127
/// Signalled from LogReplayLink when replay starts
void QGCMAVLinkLogPlayer::_playbackStarted(void)
128
{
Don Gagne's avatar
Don Gagne committed
129 130 131
    _enablePlaybackControls(true);
    _ui->playButton->setChecked(true);
    _ui->playButton->setIcon(QIcon(":/res/Pause"));
132
}
133

Don Gagne's avatar
Don Gagne committed
134 135
/// Signalled from LogReplayLink when replay is paused
void QGCMAVLinkLogPlayer::_playbackPaused(void)
136
{
Don Gagne's avatar
Don Gagne committed
137 138
    _ui->playButton->setIcon(QIcon(":/res/Play"));
    _ui->playButton->setChecked(false);
139
}
140

Don Gagne's avatar
Don Gagne committed
141
void QGCMAVLinkLogPlayer::_playbackPercentCompleteChanged(int percentComplete)
142
{
Don Gagne's avatar
Don Gagne committed
143 144 145
    _ui->positionSlider->blockSignals(true);
    _ui->positionSlider->setValue(percentComplete);
    _ui->positionSlider->blockSignals(false);
146 147
}

Don Gagne's avatar
Don Gagne committed
148
void QGCMAVLinkLogPlayer::_setPlayheadFromSlider(int value)
149
{
Don Gagne's avatar
Don Gagne committed
150 151
    if (_replayLink) {
        _replayLink->movePlayhead(value);
152 153
    }
}
154

Don Gagne's avatar
Don Gagne committed
155
void QGCMAVLinkLogPlayer::_enablePlaybackControls(bool enabled)
156
{
Don Gagne's avatar
Don Gagne committed
157 158 159
    _ui->playButton->setEnabled(enabled);
    _ui->speedSlider->setEnabled(enabled);
    _ui->positionSlider->setEnabled(enabled);
160
}
Don Gagne's avatar
Don Gagne committed
161

Don Gagne's avatar
Don Gagne committed
162
void QGCMAVLinkLogPlayer::_setAccelerationFromSlider(int value)
Don Gagne's avatar
Don Gagne committed
163
{
Don Gagne's avatar
Don Gagne committed
164 165 166 167
    qDebug() << value;
    if (_replayLink) {
        _replayLink->setAccelerationFactor(value);
    }
Don Gagne's avatar
Don Gagne committed
168
    
Don Gagne's avatar
Don Gagne committed
169
    // Factor: -100: 0.01x, 0: 1.0x, 100: 100x
Don Gagne's avatar
Don Gagne committed
170
    
Don Gagne's avatar
Don Gagne committed
171 172 173 174 175 176 177 178 179 180 181 182
    float accelerationFactor;
    if (value < 0) {
        accelerationFactor = 0.01f;
        value -= -100;
        if (value > 0) {
            accelerationFactor *= (float)value;
        }
    } else if (value > 0) {
        accelerationFactor = 1.0f * (float)value;
    } else {
        accelerationFactor = 1.0f;
    }
Don Gagne's avatar
Don Gagne committed
183
    
Don Gagne's avatar
Don Gagne committed
184
    _ui->speedLabel->setText(QString("Speed: %1X").arg(accelerationFactor, 5, 'f', 2, '0'));
Don Gagne's avatar
Don Gagne committed
185 186
}

Don Gagne's avatar
Don Gagne committed
187
void QGCMAVLinkLogPlayer::_replayLinkDisconnected(void)
Don Gagne's avatar
Don Gagne committed
188
{
Don Gagne's avatar
Don Gagne committed
189 190 191
    _enablePlaybackControls(false);
    _replayLink = NULL;
}