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

4
#include "MainWindow.h"
Gus Grubba's avatar
Gus Grubba committed
5
#ifndef NO_SERIAL_LINK
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 13
#include "SettingsManager.h"
#include "AppSettings.h"
Don Gagne's avatar
Don Gagne committed
14
#include "LinkManager.h"
15
#include "QGCQFileDialog.h"
16
#include "QGCMessageBox.h"
17

18 19 20 21 22
QGCMAVLinkLogPlayer::QGCMAVLinkLogPlayer(QWidget *parent)
    : QWidget           (parent)
    , _replayLink       (NULL)
    , _lastCurrentTime  (0)
    , _ui               (new Ui::QGCMAVLinkLogPlayer)
Gus Grubba's avatar
Gus Grubba committed
23
{
Don Gagne's avatar
Don Gagne committed
24 25
    _ui->setupUi(this);
    _ui->horizontalLayout->setAlignment(Qt::AlignTop);
26

27
    // Setup buttons
Don Gagne's avatar
Don Gagne committed
28 29 30 31
    connect(_ui->selectFileButton,  &QPushButton::clicked,      this, &QGCMAVLinkLogPlayer::_selectLogFileForPlayback);
    connect(_ui->playButton,        &QPushButton::clicked,      this, &QGCMAVLinkLogPlayer::_playPauseToggle);
    connect(_ui->positionSlider,    &QSlider::valueChanged,     this, &QGCMAVLinkLogPlayer::_setPlayheadFromSlider);
    connect(_ui->positionSlider,    &QSlider::sliderPressed,    this, &QGCMAVLinkLogPlayer::_pause);
Gus Grubba's avatar
Gus Grubba committed
32

33 34 35 36 37 38 39 40
#if 0
    // Speed slider is removed from 3.0 release. Too broken to fix.
    connect(_ui->speedSlider, &QSlider::valueChanged, this, &QGCMAVLinkLogPlayer::_setAccelerationFromSlider);
    _ui->speedSlider->setMinimum(-100);
    _ui->speedSlider->setMaximum(100);
    _ui->speedSlider->setValue(0);
#endif

Don Gagne's avatar
Don Gagne committed
41
    _enablePlaybackControls(false);
Gus Grubba's avatar
Gus Grubba committed
42

Don Gagne's avatar
Don Gagne committed
43 44
    _ui->positionSlider->setMinimum(0);
    _ui->positionSlider->setMaximum(100);
Gus Grubba's avatar
Gus Grubba committed
45

46 47
}

Don Gagne's avatar
Don Gagne committed
48
QGCMAVLinkLogPlayer::~QGCMAVLinkLogPlayer()
49
{
Don Gagne's avatar
Don Gagne committed
50
    delete _ui;
51 52
}

Don Gagne's avatar
Don Gagne committed
53
void QGCMAVLinkLogPlayer::_playPauseToggle(void)
54
{
Don Gagne's avatar
Don Gagne committed
55 56 57 58
    if (_replayLink->isPlaying()) {
        _pause();
    } else {
        _replayLink->play();
59
    }
60 61
}

Don Gagne's avatar
Don Gagne committed
62
void QGCMAVLinkLogPlayer::_pause(void)
63
{
Don Gagne's avatar
Don Gagne committed
64
    _replayLink->pause();
65 66
}

Don Gagne's avatar
Don Gagne committed
67
void QGCMAVLinkLogPlayer::_selectLogFileForPlayback(void)
Lorenz Meier's avatar
Lorenz Meier committed
68
{
Don Gagne's avatar
Don Gagne committed
69
    // Disallow replay when any links are connected
70
    if (qgcApp()->toolbox()->multiVehicleManager()->activeVehicle()) {
71
        QGCMessageBox::information(tr("Log Replay"), tr("You must close all connections prior to replaying a log."));
Don Gagne's avatar
Don Gagne committed
72 73
        return;
    }
Gus Grubba's avatar
Gus Grubba committed
74

75
    QString logFilename = QGCQFileDialog::getOpenFileName(
76
        this,
Don Gagne's avatar
Don Gagne committed
77 78
        tr("Load Telemetry Log File"),
        qgcApp()->toolbox()->settingsManager()->appSettings()->telemetrySavePath(),
79
        tr("MAVLink Log Files (*.tlog);;All Files (*)"));
80

Don Gagne's avatar
Don Gagne committed
81 82
    if (logFilename.isEmpty()) {
        return;
83
    }
Gus Grubba's avatar
Gus Grubba committed
84

Don Gagne's avatar
Don Gagne committed
85 86 87 88
    LogReplayLinkConfiguration* linkConfig = new LogReplayLinkConfiguration(QString("Log Replay"));
    linkConfig->setLogFilename(logFilename);
    linkConfig->setName(linkConfig->logFilenameShort());
    _ui->logFileNameLabel->setText(linkConfig->logFilenameShort());
89 90 91 92

    LinkManager* linkMgr = qgcApp()->toolbox()->linkManager();
    SharedLinkConfigurationPointer sharedConfig = linkMgr->addConfiguration(linkConfig);
    _replayLink = (LogReplayLink*)qgcApp()->toolbox()->linkManager()->createConnectedLink(sharedConfig);
Gus Grubba's avatar
Gus Grubba committed
93

94 95 96 97 98 99
    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::currentLogTimeSecs,                this, &QGCMAVLinkLogPlayer::_setCurrentLogTime);
    connect(_replayLink, &LogReplayLink::disconnected,                      this, &QGCMAVLinkLogPlayer::_replayLinkDisconnected);
Gus Grubba's avatar
Gus Grubba committed
100

Don Gagne's avatar
Don Gagne committed
101
    _ui->positionSlider->setValue(0);
102
#if 0
Don Gagne's avatar
Don Gagne committed
103
    _ui->speedSlider->setValue(0);
104
#endif
105 106
}

Don Gagne's avatar
Don Gagne committed
107
void QGCMAVLinkLogPlayer::_playbackError(void)
108
{
Don Gagne's avatar
Don Gagne committed
109 110
    _ui->logFileNameLabel->setText("Error");
    _enablePlaybackControls(false);
111 112
}

Don Gagne's avatar
Don Gagne committed
113
QString QGCMAVLinkLogPlayer::_secondsToHMS(int seconds)
114
{
Don Gagne's avatar
Don Gagne committed
115 116 117 118 119
    int secondsPart  = seconds;
    int minutesPart  = secondsPart / 60;
    int hoursPart    = minutesPart / 60;
    secondsPart -= 60 * minutesPart;
    minutesPart -= 60 * hoursPart;
120

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

Don Gagne's avatar
Don Gagne committed
124 125 126 127
/// 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
128
{
Don Gagne's avatar
Don Gagne committed
129 130
    Q_UNUSED(logTimestamped);
    Q_UNUSED(binaryBaudRate);
Gus Grubba's avatar
Gus Grubba committed
131

132 133
    qDebug() << "_logFileStats" << logDurationSeconds;

Don Gagne's avatar
Don Gagne committed
134
    _logDurationSeconds = logDurationSeconds;
Gus Grubba's avatar
Gus Grubba committed
135

136
    _ui->logLengthTime->setText(_secondsToHMS(logDurationSeconds));
137 138
}

Don Gagne's avatar
Don Gagne committed
139 140
/// Signalled from LogReplayLink when replay starts
void QGCMAVLinkLogPlayer::_playbackStarted(void)
141
{
Don Gagne's avatar
Don Gagne committed
142 143 144
    _enablePlaybackControls(true);
    _ui->playButton->setChecked(true);
    _ui->playButton->setIcon(QIcon(":/res/Pause"));
Don Gagne's avatar
Don Gagne committed
145
    _ui->positionSlider->setEnabled(false);
146
}
147

Don Gagne's avatar
Don Gagne committed
148 149
/// Signalled from LogReplayLink when replay is paused
void QGCMAVLinkLogPlayer::_playbackPaused(void)
150
{
Don Gagne's avatar
Don Gagne committed
151 152
    _ui->playButton->setIcon(QIcon(":/res/Play"));
    _ui->playButton->setChecked(false);
Don Gagne's avatar
Don Gagne committed
153
    _ui->positionSlider->setEnabled(true);
154
}
155

Don Gagne's avatar
Don Gagne committed
156
void QGCMAVLinkLogPlayer::_playbackPercentCompleteChanged(int percentComplete)
157
{
Don Gagne's avatar
Don Gagne committed
158 159 160
    _ui->positionSlider->blockSignals(true);
    _ui->positionSlider->setValue(percentComplete);
    _ui->positionSlider->blockSignals(false);
161 162
}

Don Gagne's avatar
Don Gagne committed
163
void QGCMAVLinkLogPlayer::_setPlayheadFromSlider(int value)
164
{
Don Gagne's avatar
Don Gagne committed
165 166
    if (_replayLink) {
        _replayLink->movePlayhead(value);
167 168
    }
}
169

Don Gagne's avatar
Don Gagne committed
170
void QGCMAVLinkLogPlayer::_enablePlaybackControls(bool enabled)
171
{
Don Gagne's avatar
Don Gagne committed
172
    _ui->playButton->setEnabled(enabled);
173
#if 0
Don Gagne's avatar
Don Gagne committed
174
    _ui->speedSlider->setEnabled(enabled);
175
#endif
Don Gagne's avatar
Don Gagne committed
176
    _ui->positionSlider->setEnabled(enabled);
177
}
Don Gagne's avatar
Don Gagne committed
178

179
#if 0
Don Gagne's avatar
Don Gagne committed
180
void QGCMAVLinkLogPlayer::_setAccelerationFromSlider(int value)
Don Gagne's avatar
Don Gagne committed
181
{
dogmaphobic's avatar
dogmaphobic committed
182
    //qDebug() << value;
Don Gagne's avatar
Don Gagne committed
183 184 185
    if (_replayLink) {
        _replayLink->setAccelerationFactor(value);
    }
Gus Grubba's avatar
Gus Grubba committed
186

Don Gagne's avatar
Don Gagne committed
187
    // Factor: -100: 0.01x, 0: 1.0x, 100: 100x
Gus Grubba's avatar
Gus Grubba committed
188

Don Gagne's avatar
Don Gagne committed
189 190 191 192 193 194 195 196 197 198 199 200
    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;
    }
Gus Grubba's avatar
Gus Grubba committed
201

Don Gagne's avatar
Don Gagne committed
202
    _ui->speedLabel->setText(QString("Speed: %1X").arg(accelerationFactor, 5, 'f', 2, '0'));
Don Gagne's avatar
Don Gagne committed
203
}
204
#endif
Don Gagne's avatar
Don Gagne committed
205

Don Gagne's avatar
Don Gagne committed
206
void QGCMAVLinkLogPlayer::_replayLinkDisconnected(void)
Don Gagne's avatar
Don Gagne committed
207
{
Don Gagne's avatar
Don Gagne committed
208 209
    _enablePlaybackControls(false);
    _replayLink = NULL;
Don Gagne's avatar
Don Gagne committed
210
}
211 212 213 214 215 216 217 218

void QGCMAVLinkLogPlayer::_setCurrentLogTime(int secs)
{
    if (secs != _lastCurrentTime) {
        _lastCurrentTime = secs;
        _ui->logCurrentTime->setText(_secondsToHMS(secs));
    }
}