Commit 771f2ace authored by pixhawk's avatar pixhawk

Merge branch 'dev-lin' of https://github.com/pixhawk/qgroundcontrol into dev

parents 980b976d 72f8399a
...@@ -338,6 +338,7 @@ QProgressBar { ...@@ -338,6 +338,7 @@ QProgressBar {
padding: 2px; padding: 2px;
color: #DDDDDF; color: #DDDDDF;
background-color: #111118; background-color: #111118;
height: 10px;
} }
QProgressBar:horizontal { QProgressBar:horizontal {
...@@ -398,3 +399,28 @@ QDialog { ...@@ -398,3 +399,28 @@ QDialog {
QTabBar::tab:selected { QTabBar::tab:selected {
border: 2px solid #379AC3; border: 2px solid #379AC3;
} }
QLabel {
background-color: transparent;
}
QLabel#toolBarNameLabel {
font: bold 16px;
color: #3C7B9E;
}
QLabel#toolBarModeLabel {
font: 12px;
}
QLabel#toolBarStateLabel {
font: 12px;
color: #3C7B9E;
}
QLabel#toolBarMessageLabel {
font: 12px;
font-style: italic;
color: #3C7B9E;
}
...@@ -127,6 +127,15 @@ MainWindow::MainWindow(QWidget *parent): ...@@ -127,6 +127,15 @@ MainWindow::MainWindow(QWidget *parent):
centerStack = new QStackedWidget(this); centerStack = new QStackedWidget(this);
setCentralWidget(centerStack); setCentralWidget(centerStack);
// Load Toolbar
toolBar = new QGCToolBar(this);
this->addToolBar(toolBar);
// Add actions
toolBar->addPerspectiveChangeAction(ui.actionOperatorsView);
toolBar->addPerspectiveChangeAction(ui.actionEngineersView);
toolBar->addPerspectiveChangeAction(ui.actionPilotsView);
toolBar->addPerspectiveChangeAction(ui.actionUnconnectedView);
buildCommonWidgets(); buildCommonWidgets();
connectCommonWidgets(); connectCommonWidgets();
...@@ -181,14 +190,6 @@ MainWindow::MainWindow(QWidget *parent): ...@@ -181,14 +190,6 @@ MainWindow::MainWindow(QWidget *parent):
fgLink = new QGCFlightGearLink(); fgLink = new QGCFlightGearLink();
fgLink->connectSimulation(); fgLink->connectSimulation();
// Load Toolbar
toolBar = new QGCToolBar(this);
this->addToolBar(toolBar);
// Add actions
toolBar->addPerspectiveChangeAction(ui.actionOperatorsView);
toolBar->addPerspectiveChangeAction(ui.actionEngineersView);
toolBar->addPerspectiveChangeAction(ui.actionPilotsView);
// Connect link // Connect link
if (autoReconnect) if (autoReconnect)
{ {
...@@ -408,7 +409,9 @@ void MainWindow::buildCommonWidgets() ...@@ -408,7 +409,9 @@ void MainWindow::buildCommonWidgets()
if (!logPlayerDockWidget) if (!logPlayerDockWidget)
{ {
logPlayerDockWidget = new QDockWidget(tr("MAVLink Log Player"), this); logPlayerDockWidget = new QDockWidget(tr("MAVLink Log Player"), this);
logPlayerDockWidget->setWidget( new QGCMAVLinkLogPlayer(mavlink, this) ); logPlayer = new QGCMAVLinkLogPlayer(mavlink, this);
toolBar->setLogPlayer(logPlayer);
logPlayerDockWidget->setWidget(logPlayer);
logPlayerDockWidget->setObjectName("MAVLINK_LOG_PLAYER_DOCKWIDGET"); logPlayerDockWidget->setObjectName("MAVLINK_LOG_PLAYER_DOCKWIDGET");
addTool(logPlayerDockWidget, tr("MAVLink Log Replay"), Qt::RightDockWidgetArea); addTool(logPlayerDockWidget, tr("MAVLink Log Replay"), Qt::RightDockWidgetArea);
} }
......
...@@ -75,6 +75,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -75,6 +75,7 @@ This file is part of the QGROUNDCONTROL project
#include "SlugsPadCameraControl.h" #include "SlugsPadCameraControl.h"
#include "UASControlParameters.h" #include "UASControlParameters.h"
#include "QGCFlightGearLink.h" #include "QGCFlightGearLink.h"
#include "QGCMAVLinkLogPlayer.h"
class QGCMapTool; class QGCMapTool;
...@@ -210,6 +211,17 @@ public slots: ...@@ -210,6 +211,17 @@ public slots:
*/ */
void showCentralWidget(); void showCentralWidget();
public:
QGCMAVLinkLogPlayer* getLogPlayer()
{
return logPlayer;
}
MAVLinkProtocol* getMAVLink()
{
return mavlink;
}
protected: protected:
MainWindow(QWidget *parent = 0); MainWindow(QWidget *parent = 0);
...@@ -342,6 +354,7 @@ protected: ...@@ -342,6 +354,7 @@ protected:
QPointer<QGCToolBar> toolBar; QPointer<QGCToolBar> toolBar;
QGCMAVLinkLogPlayer* logPlayer;
// Popup widgets // Popup widgets
JoystickWidget* joystickWidget; JoystickWidget* joystickWidget;
......
...@@ -20,6 +20,7 @@ QGCMAVLinkLogPlayer::QGCMAVLinkLogPlayer(MAVLinkProtocol* mavlink, QWidget *pare ...@@ -20,6 +20,7 @@ QGCMAVLinkLogPlayer::QGCMAVLinkLogPlayer(MAVLinkProtocol* mavlink, QWidget *pare
loopCounter(0), loopCounter(0),
mavlinkLogFormat(true), mavlinkLogFormat(true),
binaryBaudRate(57600), binaryBaudRate(57600),
isPlaying(false),
ui(new Ui::QGCMAVLinkLogPlayer) ui(new Ui::QGCMAVLinkLogPlayer)
{ {
ui->setupUi(this); ui->setupUi(this);
...@@ -33,8 +34,7 @@ QGCMAVLinkLogPlayer::QGCMAVLinkLogPlayer(MAVLinkProtocol* mavlink, QWidget *pare ...@@ -33,8 +34,7 @@ QGCMAVLinkLogPlayer::QGCMAVLinkLogPlayer(MAVLinkProtocol* mavlink, QWidget *pare
// Setup buttons // Setup buttons
connect(ui->selectFileButton, SIGNAL(clicked()), this, SLOT(selectLogFile())); connect(ui->selectFileButton, SIGNAL(clicked()), this, SLOT(selectLogFile()));
connect(ui->pauseButton, SIGNAL(clicked()), this, SLOT(pause())); connect(ui->playButton, SIGNAL(clicked()), this, SLOT(playPauseToggle()));
connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play()));
connect(ui->speedSlider, SIGNAL(valueChanged(int)), this, SLOT(setAccelerationFactorInt(int))); connect(ui->speedSlider, SIGNAL(valueChanged(int)), this, SLOT(setAccelerationFactorInt(int)));
connect(ui->positionSlider, SIGNAL(valueChanged(int)), this, SLOT(jumpToSliderVal(int))); connect(ui->positionSlider, SIGNAL(valueChanged(int)), this, SLOT(jumpToSliderVal(int)));
connect(ui->positionSlider, SIGNAL(sliderPressed()), this, SLOT(pause())); connect(ui->positionSlider, SIGNAL(sliderPressed()), this, SLOT(pause()));
...@@ -49,12 +49,37 @@ QGCMAVLinkLogPlayer::~QGCMAVLinkLogPlayer() ...@@ -49,12 +49,37 @@ QGCMAVLinkLogPlayer::~QGCMAVLinkLogPlayer()
delete ui; delete ui;
} }
void QGCMAVLinkLogPlayer::playPause(bool enabled)
{
if (enabled)
{
play();
}
else
{
pause();
}
}
void QGCMAVLinkLogPlayer::playPauseToggle()
{
if (isPlaying)
{
pause();
}
else
{
play();
}
}
void QGCMAVLinkLogPlayer::play() void QGCMAVLinkLogPlayer::play()
{ {
if (logFile.isOpen()) { if (logFile.isOpen())
ui->pauseButton->setChecked(false); {
ui->selectFileButton->setEnabled(false); ui->selectFileButton->setEnabled(false);
if (logLink) { if (logLink)
{
logLink->disconnect(); logLink->disconnect();
LinkManager::instance()->removeLink(logLink); LinkManager::instance()->removeLink(logLink);
delete logLink; delete logLink;
...@@ -62,9 +87,12 @@ void QGCMAVLinkLogPlayer::play() ...@@ -62,9 +87,12 @@ void QGCMAVLinkLogPlayer::play()
logLink = new MAVLinkSimulationLink(""); logLink = new MAVLinkSimulationLink("");
// Start timer // Start timer
if (mavlinkLogFormat) { if (mavlinkLogFormat)
{
loopTimer.start(1); loopTimer.start(1);
} else { }
else
{
// Read len bytes at a time // Read len bytes at a time
int len = 100; int len = 100;
// Calculate the number of times to read 100 bytes per second // Calculate the number of times to read 100 bytes per second
...@@ -73,7 +101,11 @@ void QGCMAVLinkLogPlayer::play() ...@@ -73,7 +101,11 @@ void QGCMAVLinkLogPlayer::play()
int interval = 1000 / ((binaryBaudRate / 10) / len); int interval = 1000 / ((binaryBaudRate / 10) / len);
loopTimer.start(interval*accelerationFactor); loopTimer.start(interval*accelerationFactor);
} }
} else { isPlaying = true;
ui->playButton->setIcon(QIcon(":images/actions/media-playback-pause.svg"));
}
else
{
ui->playButton->setChecked(false); ui->playButton->setChecked(false);
QMessageBox msgBox; QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Information); msgBox.setIcon(QMessageBox::Information);
...@@ -87,10 +119,12 @@ void QGCMAVLinkLogPlayer::play() ...@@ -87,10 +119,12 @@ void QGCMAVLinkLogPlayer::play()
void QGCMAVLinkLogPlayer::pause() void QGCMAVLinkLogPlayer::pause()
{ {
isPlaying = false;
loopTimer.stop(); loopTimer.stop();
ui->playButton->setChecked(false); ui->playButton->setIcon(QIcon(":images/actions/media-playback-start.svg"));
ui->selectFileButton->setEnabled(true); ui->selectFileButton->setEnabled(true);
if (logLink) { if (logLink)
{
logLink->disconnect(); logLink->disconnect();
LinkManager::instance()->removeLink(logLink); LinkManager::instance()->removeLink(logLink);
delete logLink; delete logLink;
...@@ -101,34 +135,39 @@ void QGCMAVLinkLogPlayer::pause() ...@@ -101,34 +135,39 @@ void QGCMAVLinkLogPlayer::pause()
bool QGCMAVLinkLogPlayer::reset(int packetIndex) bool QGCMAVLinkLogPlayer::reset(int packetIndex)
{ {
// Reset only for valid values // Reset only for valid values
if (packetIndex >= 0 && packetIndex <= logFile.size() - (packetLen+timeLen)) { const unsigned int packetSize = timeLen + packetLen;
if (packetIndex >= 0 && packetIndex*packetSize <= logFile.size() - packetSize)
{
bool result = true; bool result = true;
pause(); pause();
loopCounter = 0; loopCounter = 0;
logFile.reset(); logFile.reset();
if (!logFile.seek(packetIndex*(timeLen + packetLen))) {
if (!logFile.seek(packetIndex*packetSize))
{
// Fallback: Start from scratch // Fallback: Start from scratch
logFile.reset(); logFile.reset();
ui->logStatsLabel->setText(tr("Changing packet index failed, back to start.")); ui->logStatsLabel->setText(tr("Changing packet index failed, back to start."));
result = false; result = false;
} }
ui->pauseButton->setChecked(true); ui->playButton->setIcon(QIcon(":images/actions/media-playback-start.svg"));
ui->positionSlider->blockSignals(true); ui->positionSlider->blockSignals(true);
int sliderVal = (packetIndex / (double)(logFile.size()/(packetLen+timeLen))) * (ui->positionSlider->maximum() - ui->positionSlider->minimum()); int sliderVal = (packetIndex / (double)(logFile.size()/packetSize)) * (ui->positionSlider->maximum() - ui->positionSlider->minimum());
ui->positionSlider->setValue(sliderVal); ui->positionSlider->setValue(sliderVal);
ui->positionSlider->blockSignals(false); ui->positionSlider->blockSignals(false);
startTime = 0; startTime = 0;
return result; return result;
} else { }
else
{
return false; return false;
} }
} }
void QGCMAVLinkLogPlayer::selectLogFile() void QGCMAVLinkLogPlayer::selectLogFile()
{ {
QString fileName = QFileDialog::getOpenFileName(this, tr("Specify MAVLink log file name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("MAVLink or Binary Logfile (*.mavlink *.bin)")); QString fileName = QFileDialog::getOpenFileName(this, tr("Specify MAVLink log file name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("MAVLink or Binary Logfile (*.mavlink *.bin *.log)"));
loadLogFile(fileName); loadLogFile(fileName);
} }
...@@ -141,14 +180,18 @@ void QGCMAVLinkLogPlayer::setAccelerationFactorInt(int factor) ...@@ -141,14 +180,18 @@ void QGCMAVLinkLogPlayer::setAccelerationFactorInt(int factor)
float f = factor+1.0f; float f = factor+1.0f;
f -= 50.0f; f -= 50.0f;
if (f < 0.0f) { if (f < 0.0f)
{
accelerationFactor = 1.0f / (-f/2.0f); accelerationFactor = 1.0f / (-f/2.0f);
} else { }
else
{
accelerationFactor = 1+(f/2.0f); accelerationFactor = 1+(f/2.0f);
} }
// Update timer interval // Update timer interval
if (!mavlinkLogFormat) { if (!mavlinkLogFormat)
{
// Read len bytes at a time // Read len bytes at a time
int len = 100; int len = 100;
// Calculate the number of times to read 100 bytes per second // Calculate the number of times to read 100 bytes per second
...@@ -167,22 +210,27 @@ void QGCMAVLinkLogPlayer::setAccelerationFactorInt(int factor) ...@@ -167,22 +210,27 @@ void QGCMAVLinkLogPlayer::setAccelerationFactorInt(int factor)
void QGCMAVLinkLogPlayer::loadLogFile(const QString& file) void QGCMAVLinkLogPlayer::loadLogFile(const QString& file)
{ {
// Check if logging is still enabled // Check if logging is still enabled
if (mavlink->loggingEnabled()) { if (mavlink->loggingEnabled())
{
mavlink->enableLogging(false); mavlink->enableLogging(false);
MainWindow::instance()->showInfoMessage(tr("MAVLink Logging Stopped during Replay"), tr("MAVLink logging has been stopped during the log replay. To re-enable logging, use the link properties in the communication menu.")); MainWindow::instance()->showInfoMessage(tr("MAVLink Logging Stopped during Replay"), tr("MAVLink logging has been stopped during the log replay. To re-enable logging, use the link properties in the communication menu."));
} }
// Ensure that the playback process is stopped // Ensure that the playback process is stopped
if (logFile.isOpen()) { if (logFile.isOpen())
{
pause(); pause();
logFile.close(); logFile.close();
} }
logFile.setFileName(file); logFile.setFileName(file);
if (!logFile.open(QFile::ReadOnly)) { if (!logFile.open(QFile::ReadOnly))
{
MainWindow::instance()->showCriticalMessage(tr("The selected logfile is unreadable"), tr("Please make sure that the file %1 is readable or select a different file").arg(file)); MainWindow::instance()->showCriticalMessage(tr("The selected logfile is unreadable"), tr("Please make sure that the file %1 is readable or select a different file").arg(file));
logFile.setFileName(""); logFile.setFileName("");
} else { }
else
{
QFileInfo logFileInfo(file); QFileInfo logFileInfo(file);
logFile.reset(); logFile.reset();
startTime = 0; startTime = 0;
...@@ -191,7 +239,8 @@ void QGCMAVLinkLogPlayer::loadLogFile(const QString& file) ...@@ -191,7 +239,8 @@ void QGCMAVLinkLogPlayer::loadLogFile(const QString& file)
// Select if binary or MAVLink log format is used // Select if binary or MAVLink log format is used
mavlinkLogFormat = file.endsWith(".mavlink"); mavlinkLogFormat = file.endsWith(".mavlink");
if (mavlinkLogFormat) { if (mavlinkLogFormat)
{
// Get the time interval from the logfile // Get the time interval from the logfile
QByteArray timestamp = logFile.read(timeLen); QByteArray timestamp = logFile.read(timeLen);
...@@ -216,17 +265,21 @@ void QGCMAVLinkLogPlayer::loadLogFile(const QString& file) ...@@ -216,17 +265,21 @@ void QGCMAVLinkLogPlayer::loadLogFile(const QString& file)
QString timelabel = tr("%1h:%2m:%3s").arg(hours, 2).arg(minutes, 2).arg(seconds, 2); QString timelabel = tr("%1h:%2m:%3s").arg(hours, 2).arg(minutes, 2).arg(seconds, 2);
ui->logStatsLabel->setText(tr("%2 MB, %3 packets, %4").arg(logFileInfo.size()/1000000.0f, 0, 'f', 2).arg(logFileInfo.size()/(MAVLINK_MAX_PACKET_LEN+sizeof(quint64))).arg(timelabel)); ui->logStatsLabel->setText(tr("%2 MB, %3 packets, %4").arg(logFileInfo.size()/1000000.0f, 0, 'f', 2).arg(logFileInfo.size()/(MAVLINK_MAX_PACKET_LEN+sizeof(quint64))).arg(timelabel));
} else { }
else
{
// Load in binary mode // Load in binary mode
// Set baud rate if any present // Set baud rate if any present
QStringList parts = logFileInfo.baseName().split("_"); QStringList parts = logFileInfo.baseName().split("_");
if (parts.count() > 1) { if (parts.count() > 1)
{
bool ok; bool ok;
int rate = parts.last().toInt(&ok); int rate = parts.last().toInt(&ok);
// 9600 baud to 100 MBit // 9600 baud to 100 MBit
if (ok && (rate > 9600 && rate < 100000000)) { if (ok && (rate > 9600 && rate < 100000000))
{
// Accept this as valid baudrate // Accept this as valid baudrate
binaryBaudRate = rate; binaryBaudRate = rate;
} }
...@@ -256,8 +309,10 @@ void QGCMAVLinkLogPlayer::jumpToSliderVal(int slidervalue) ...@@ -256,8 +309,10 @@ void QGCMAVLinkLogPlayer::jumpToSliderVal(int slidervalue)
int packetIndex = (packetCount - 1) * (slidervalue / (double)(ui->positionSlider->maximum() - ui->positionSlider->minimum())); int packetIndex = (packetCount - 1) * (slidervalue / (double)(ui->positionSlider->maximum() - ui->positionSlider->minimum()));
// Do only accept valid jumps // Do only accept valid jumps
if (reset(packetIndex)) { if (reset(packetIndex))
if (mavlinkLogFormat) { {
if (mavlinkLogFormat)
{
ui->logStatsLabel->setText(tr("Jumped to packet %1").arg(packetIndex)); ui->logStatsLabel->setText(tr("Jumped to packet %1").arg(packetIndex));
} }
} }
...@@ -273,15 +328,18 @@ void QGCMAVLinkLogPlayer::jumpToSliderVal(int slidervalue) ...@@ -273,15 +328,18 @@ void QGCMAVLinkLogPlayer::jumpToSliderVal(int slidervalue)
*/ */
void QGCMAVLinkLogPlayer::logLoop() void QGCMAVLinkLogPlayer::logLoop()
{ {
if (mavlinkLogFormat) { if (mavlinkLogFormat)
{
bool ok; bool ok;
// First check initialization // First check initialization
if (startTime == 0) { if (startTime == 0)
{
QByteArray startBytes = logFile.read(timeLen); QByteArray startBytes = logFile.read(timeLen);
// Check if the correct number of bytes could be read // Check if the correct number of bytes could be read
if (startBytes.length() != timeLen) { if (startBytes.length() != timeLen)
{
ui->logStatsLabel->setText(tr("Error reading first %1 bytes").arg(timeLen)); ui->logStatsLabel->setText(tr("Error reading first %1 bytes").arg(timeLen));
MainWindow::instance()->showCriticalMessage(tr("Failed loading MAVLink Logfile"), tr("Error reading first %1 bytes from logfile. Got %2 instead of %1 bytes. Is the logfile readable?").arg(timeLen).arg(startBytes.length())); MainWindow::instance()->showCriticalMessage(tr("Failed loading MAVLink Logfile"), tr("Error reading first %1 bytes from logfile. Got %2 instead of %1 bytes. Is the logfile readable?").arg(timeLen).arg(startBytes.length()));
reset(); reset();
...@@ -296,7 +354,8 @@ void QGCMAVLinkLogPlayer::logLoop() ...@@ -296,7 +354,8 @@ void QGCMAVLinkLogPlayer::logLoop()
//qDebug() << "START TIME: " << startTime; //qDebug() << "START TIME: " << startTime;
// Check if these bytes could be correctly decoded // Check if these bytes could be correctly decoded
if (!ok) { if (!ok)
{
ui->logStatsLabel->setText(tr("Error decoding first timestamp, aborting.")); ui->logStatsLabel->setText(tr("Error decoding first timestamp, aborting."));
MainWindow::instance()->showCriticalMessage(tr("Failed loading MAVLink Logfile"), tr("Could not load initial timestamp from file %1. Is the file corrupted?").arg(logFile.fileName())); MainWindow::instance()->showCriticalMessage(tr("Failed loading MAVLink Logfile"), tr("Could not load initial timestamp from file %1. Is the file corrupted?").arg(logFile.fileName()));
reset(); reset();
...@@ -313,7 +372,8 @@ void QGCMAVLinkLogPlayer::logLoop() ...@@ -313,7 +372,8 @@ void QGCMAVLinkLogPlayer::logLoop()
emit bytesReady(logLink, packet); emit bytesReady(logLink, packet);
// Check if reached end of file before reading next timestamp // Check if reached end of file before reading next timestamp
if (chunk.length() < timeLen+packetLen || logFile.atEnd()) { if (chunk.length() < timeLen+packetLen || logFile.atEnd())
{
// Reached end of file // Reached end of file
reset(); reset();
...@@ -329,12 +389,15 @@ void QGCMAVLinkLogPlayer::logLoop() ...@@ -329,12 +389,15 @@ void QGCMAVLinkLogPlayer::logLoop()
// This is the timestamp of the next packet // This is the timestamp of the next packet
quint64 time = *((quint64*)(rawTime.constData())); quint64 time = *((quint64*)(rawTime.constData()));
ok = true; ok = true;
if (!ok) { if (!ok)
{
// Convert it to 64bit number // Convert it to 64bit number
QString status = tr("Time conversion error during log replay. Continuing.."); QString status = tr("Time conversion error during log replay. Continuing..");
ui->logStatsLabel->setText(status); ui->logStatsLabel->setText(status);
MainWindow::instance()->showStatusMessage(status); MainWindow::instance()->showStatusMessage(status);
} else { }
else
{
// Normal processing, passed all checks // Normal processing, passed all checks
// start timer to match time offset between // start timer to match time offset between
// this and next packet // this and next packet
...@@ -350,13 +413,18 @@ void QGCMAVLinkLogPlayer::logLoop() ...@@ -350,13 +413,18 @@ void QGCMAVLinkLogPlayer::logLoop()
//qDebug() << "nextExecutionTime:" << nextExecutionTime << "QGC START TIME:" << currentStartTime << "LOG START TIME:" << startTime; //qDebug() << "nextExecutionTime:" << nextExecutionTime << "QGC START TIME:" << currentStartTime << "LOG START TIME:" << startTime;
if (nextExecutionTime < 2) { if (nextExecutionTime < 2)
{
logLoop(); logLoop();
} else { }
else
{
loopTimer.start(nextExecutionTime); loopTimer.start(nextExecutionTime);
} }
} }
} else { }
else
{
// Binary format - read at fixed rate // Binary format - read at fixed rate
const int len = 100; const int len = 100;
QByteArray chunk = logFile.read(len); QByteArray chunk = logFile.read(len);
...@@ -365,7 +433,8 @@ void QGCMAVLinkLogPlayer::logLoop() ...@@ -365,7 +433,8 @@ void QGCMAVLinkLogPlayer::logLoop()
emit bytesReady(logLink, chunk); emit bytesReady(logLink, chunk);
// Check if reached end of file before reading next timestamp // Check if reached end of file before reading next timestamp
if (chunk.length() < len || logFile.atEnd()) { if (chunk.length() < len || logFile.atEnd())
{
// Reached end of file // Reached end of file
reset(); reset();
...@@ -380,7 +449,8 @@ void QGCMAVLinkLogPlayer::logLoop() ...@@ -380,7 +449,8 @@ void QGCMAVLinkLogPlayer::logLoop()
// Update status label // Update status label
// Update progress bar // Update progress bar
if (loopCounter % 40 == 0) { if (loopCounter % 40 == 0)
{
QFileInfo logFileInfo(logFile); QFileInfo logFileInfo(logFile);
int progress = (ui->positionSlider->maximum()-ui->positionSlider->minimum())*(logFile.pos()/static_cast<float>(logFileInfo.size())); int progress = (ui->positionSlider->maximum()-ui->positionSlider->minimum())*(logFile.pos()/static_cast<float>(logFileInfo.size()));
//qDebug() << "Progress:" << progress; //qDebug() << "Progress:" << progress;
...@@ -394,7 +464,8 @@ void QGCMAVLinkLogPlayer::logLoop() ...@@ -394,7 +464,8 @@ void QGCMAVLinkLogPlayer::logLoop()
void QGCMAVLinkLogPlayer::changeEvent(QEvent *e) void QGCMAVLinkLogPlayer::changeEvent(QEvent *e)
{ {
QWidget::changeEvent(e); QWidget::changeEvent(e);
switch (e->type()) { switch (e->type())
{
case QEvent::LanguageChange: case QEvent::LanguageChange:
ui->retranslateUi(this); ui->retranslateUi(this);
break; break;
......
...@@ -29,6 +29,10 @@ public: ...@@ -29,6 +29,10 @@ public:
~QGCMAVLinkLogPlayer(); ~QGCMAVLinkLogPlayer();
public slots: public slots:
/** @brief Toggle between play and pause */
void playPauseToggle();
/** @brief Play / pause the log */
void playPause(bool play);
/** @brief Replay the logfile */ /** @brief Replay the logfile */
void play(); void play();
/** @brief Pause the logfile */ /** @brief Pause the logfile */
...@@ -64,6 +68,7 @@ protected: ...@@ -64,6 +68,7 @@ protected:
int loopCounter; int loopCounter;
bool mavlinkLogFormat; bool mavlinkLogFormat;
int binaryBaudRate; int binaryBaudRate;
bool isPlaying;
static const int packetLen = MAVLINK_MAX_PACKET_LEN; static const int packetLen = MAVLINK_MAX_PACKET_LEN;
static const int timeLen = sizeof(quint64); static const int timeLen = sizeof(quint64);
void changeEvent(QEvent *e); void changeEvent(QEvent *e);
......
...@@ -75,32 +75,6 @@ ...@@ -75,32 +75,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="5">
<widget class="QToolButton" name="pauseButton">
<property name="toolTip">
<string>Pause the logfile</string>
</property>
<property name="statusTip">
<string>Pause the logfile</string>
</property>
<property name="whatsThis">
<string>Pause the logfile</string>
</property>
<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="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="speedLabel"> <widget class="QLabel" name="speedLabel">
<property name="toolTip"> <property name="toolTip">
...@@ -117,7 +91,23 @@ ...@@ -117,7 +91,23 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="4"> <item row="4" column="0" colspan="6">
<widget class="QSlider" name="positionSlider">
<property name="maximum">
<number>10000</number>
</property>
<property name="pageStep">
<number>100</number>
</property>
<property name="tracking">
<bool>false</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QToolButton" name="playButton"> <widget class="QToolButton" name="playButton">
<property name="toolTip"> <property name="toolTip">
<string>Start to replay the logfile</string> <string>Start to replay the logfile</string>
...@@ -132,7 +122,7 @@ ...@@ -132,7 +122,7 @@
<string>...</string> <string>...</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../mavground.qrc"> <iconset resource="../../qgroundcontrol.qrc">
<normaloff>:/images/actions/media-playback-start.svg</normaloff>:/images/actions/media-playback-start.svg</iconset> <normaloff>:/images/actions/media-playback-start.svg</normaloff>:/images/actions/media-playback-start.svg</iconset>
</property> </property>
<property name="checkable"> <property name="checkable">
...@@ -140,26 +130,10 @@ ...@@ -140,26 +130,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0" colspan="6">
<widget class="QSlider" name="positionSlider">
<property name="maximum">
<number>10000</number>
</property>
<property name="pageStep">
<number>100</number>
</property>
<property name="tracking">
<bool>false</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources> <resources>
<include location="../../mavground.qrc"/> <include location="../../qgroundcontrol.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>
...@@ -25,6 +25,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -25,6 +25,7 @@ This file is part of the QGROUNDCONTROL project
#include <QLabel> #include <QLabel>
#include "QGCToolBar.h" #include "QGCToolBar.h"
#include "UASManager.h" #include "UASManager.h"
#include "MainWindow.h"
QGCToolBar::QGCToolBar(QWidget *parent) : QGCToolBar::QGCToolBar(QWidget *parent) :
QToolBar(parent), QToolBar(parent),
...@@ -33,14 +34,93 @@ QGCToolBar::QGCToolBar(QWidget *parent) : ...@@ -33,14 +34,93 @@ QGCToolBar::QGCToolBar(QWidget *parent) :
mav(NULL) mav(NULL)
{ {
setObjectName("QGC_TOOLBAR"); setObjectName("QGC_TOOLBAR");
createCustomWidgets();
toggleLoggingAction = new QAction(QIcon(":"), "Logging", this);
toggleLoggingAction->setCheckable(true);
logReplayAction = new QAction(QIcon(":"), "Replay", this);
logReplayAction->setCheckable(true);
addSeparator();
addAction(toggleLoggingAction);
addAction(logReplayAction);
// CREATE TOOLBAR ITEMS
// Add internal actions
// Add MAV widget
symbolButton = new QToolButton(this);
toolBarNameLabel = new QLabel("------", this);
toolBarModeLabel = new QLabel("------", this);
toolBarModeLabel->setStyleSheet("QLabel { margin: 0px 4px; font: 16px; color: #3C7B9E; }");
toolBarStateLabel = new QLabel("------", this);
toolBarStateLabel->setStyleSheet("QLabel { margin: 0px 4px; font: 16px; color: #FEC654; }");
toolBarWpLabel = new QLabel("---", this);
toolBarDistLabel = new QLabel("--- ---- m", this);
toolBarMessageLabel = new QLabel("No system messages.", this);
toolBarBatteryBar = new QProgressBar(this);
toolBarBatteryBar->setStyleSheet("QProgressBar:horizontal { margin: 0px 8px; border: 1px solid #4A4A4F; border-radius: 4px; text-align: center; padding: 2px; color: #111111; background-color: #111118; height: 10px; } QProgressBar:horizontal QLabel { font-size: 9px; color: #111111; } QProgressBar::chunk { background-color: green; }");
toolBarBatteryBar->setMinimum(0);
toolBarBatteryBar->setMaximum(100);
toolBarBatteryBar->setMaximumWidth(200);
//symbolButton->setIcon(":");
symbolButton->setStyleSheet("QWidget { background-color: #050508; color: #DDDDDF; background-clip: border; } QToolButton { font-weight: bold; font-size: 12px; border: 0px solid #999999; border-radius: 5px; min-width:22px; max-width: 22px; min-height: 22px; max-height: 22px; padding: 0px; margin: 0px 0px 0px 20px; background-color: none; }");
addWidget(symbolButton);
addWidget(toolBarNameLabel);
addWidget(toolBarModeLabel);
addWidget(toolBarStateLabel);
addWidget(toolBarBatteryBar);
addWidget(toolBarWpLabel);
addWidget(toolBarDistLabel);
addWidget(toolBarMessageLabel);
//addWidget(new QSpacerItem(20, 0, QSizePolicy::Expanding));
// DONE INITIALIZING BUTTONS
setActiveUAS(UASManager::instance()->getActiveUAS()); setActiveUAS(UASManager::instance()->getActiveUAS());
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
} }
void QGCToolBar::setLogPlayer(QGCMAVLinkLogPlayer* player)
{
connect(toggleLoggingAction, SIGNAL(triggered(bool)), player, SLOT(playPause(bool)));
connect(logReplayAction, SIGNAL(triggered(bool)), this, SLOT(logging(bool)));
}
void QGCToolBar::logging(bool enabled)
{
// Stop logging in any case
MainWindow::instance()->getMAVLink()->enableLogging(false);
if (enabled)
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Specify MAVLink log file name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("MAVLink Logfile (*.mavlink *.log *.bin);;"));
if (!fileName.endsWith(".mavlink"))
{
fileName.append(".mavlink");
}
QFileInfo file(fileName);
if (file.exists() && !file.isWritable())
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(tr("The selected logfile is not writable"));
msgBox.setInformativeText(tr("Please make sure that the file %1 is writable or select a different file").arg(fileName));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
else
{
MainWindow::instance()->getMAVLink()->setLogfileName(fileName);
MainWindow::instance()->getMAVLink()->enableLogging(true);
}
}
}
void QGCToolBar::addPerspectiveChangeAction(QAction* action) void QGCToolBar::addPerspectiveChangeAction(QAction* action)
{ {
addAction(action); insertAction(toggleLoggingAction, action);
} }
void QGCToolBar::setActiveUAS(UASInterface* active) void QGCToolBar::setActiveUAS(UASInterface* active)
...@@ -56,6 +136,7 @@ void QGCToolBar::setActiveUAS(UASInterface* active) ...@@ -56,6 +136,7 @@ void QGCToolBar::setActiveUAS(UASInterface* active)
disconnect(mav, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString))); disconnect(mav, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString)));
disconnect(mav, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint))); disconnect(mav, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint)));
disconnect(mav, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(receiveTextMessage(int,int,int,QString))); disconnect(mav, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(receiveTextMessage(int,int,int,QString)));
disconnect(mav, SIGNAL(batteryChanged(UASInterface*,double,double,int)), this, SLOT(updateBatteryRemaining(UASInterface*,double,double,int)));
} }
// Connect new system // Connect new system
...@@ -65,61 +146,46 @@ void QGCToolBar::setActiveUAS(UASInterface* active) ...@@ -65,61 +146,46 @@ void QGCToolBar::setActiveUAS(UASInterface* active)
connect(active, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString))); connect(active, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString)));
connect(active, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint))); connect(active, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint)));
connect(active, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(receiveTextMessage(int,int,int,QString))); connect(active, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(receiveTextMessage(int,int,int,QString)));
connect(active, SIGNAL(batteryChanged(UASInterface*,double,double,int)), this, SLOT(updateBatteryRemaining(UASInterface*,double,double,int)));
// Update all values once // Update all values once
nameLabel->setText(mav->getUASName()); toolBarNameLabel->setText(mav->getUASName());
modeLabel->setText(mav->getShortMode()); toolBarNameLabel->setStyleSheet(QString("QLabel { font: bold 16px; color: %1; }").arg(mav->getColor().name()));
stateLabel->setText(mav->getShortState()); symbolButton->setStyleSheet(QString("QWidget { background-color: %1; color: #DDDDDF; background-clip: border; } QToolButton { font-weight: bold; font-size: 12px; border: 0px solid #999999; border-radius: 5px; min-width:22px; max-width: 22px; min-height: 22px; max-height: 22px; padding: 0px; margin: 0px 4px 0px 20px; background-color: none; }").arg(mav->getColor().name()));
// toolBarModeLabel->setStyleSheet("QLabel { font: 16px; color: #3C7B9E; }");
// toolBarStateLabel->setStyleSheet("QLabel { font: 16px; color: #FEC654; }");
toolBarModeLabel->setText(mav->getShortMode());
toolBarStateLabel->setText(mav->getShortState());
setSystemType(mav, mav->getSystemType()); setSystemType(mav, mav->getSystemType());
} }
void QGCToolBar::createCustomWidgets() void QGCToolBar::createCustomWidgets()
{ {
// Add internal actions
// Add MAV widget
symbolButton = new QToolButton(this);
nameLabel = new QLabel("------", this);
modeLabel = new QLabel("------", this);
stateLabel = new QLabel("------", this);
wpLabel = new QLabel("---", this);
distlabel = new QLabel("--- ---- m", this);
messageLabel = new QLabel("No system messages.", this);
//symbolButton->setIcon(":");
symbolButton->setStyleSheet("QWidget { background-color: #050508; color: #DDDDDF; background-clip: border; } QToolButton { font-weight: bold; font-size: 12px; border: 0px solid #999999; border-radius: 5px; min-width:22px; max-width: 22px; min-height: 22px; max-height: 22px; padding: 0px; margin: 0px; background-color: none; }");
addWidget(symbolButton);
addWidget(nameLabel);
addWidget(modeLabel);
addWidget(stateLabel);
addWidget(wpLabel);
addWidget(distlabel);
addWidget(messageLabel);
toggleLoggingAction = new QAction(QIcon(":"), "Start Logging", this); }
logReplayAction = new QAction(QIcon(":"), "Start Replay", this);
//addAction(toggleLoggingAction);
//addAction(logReplayAction);
addSeparator(); void QGCToolBar::updateBatteryRemaining(UASInterface* uas, double voltage, double percent, int seconds)
{
toolBarBatteryBar->setValue(percent);
} }
void QGCToolBar::updateState(UASInterface* system, QString name, QString description) void QGCToolBar::updateState(UASInterface* system, QString name, QString description)
{ {
Q_UNUSED(system); Q_UNUSED(system);
Q_UNUSED(description); Q_UNUSED(description);
stateLabel->setText(tr(" State: %1").arg(name)); toolBarStateLabel->setText(tr("%1").arg(name));
} }
void QGCToolBar::updateMode(int system, QString name, QString description) void QGCToolBar::updateMode(int system, QString name, QString description)
{ {
Q_UNUSED(system); Q_UNUSED(system);
Q_UNUSED(description); Q_UNUSED(description);
modeLabel->setText(tr(" Mode: %1").arg(name)); toolBarModeLabel->setText(tr("%1").arg(name));
} }
void QGCToolBar::updateName(const QString& name) void QGCToolBar::updateName(const QString& name)
{ {
nameLabel->setText(name); toolBarNameLabel->setText(name);
} }
/** /**
...@@ -163,7 +229,7 @@ void QGCToolBar::receiveTextMessage(int uasid, int componentid, int severity, QS ...@@ -163,7 +229,7 @@ void QGCToolBar::receiveTextMessage(int uasid, int componentid, int severity, QS
Q_UNUSED(uasid); Q_UNUSED(uasid);
Q_UNUSED(componentid); Q_UNUSED(componentid);
Q_UNUSED(severity); Q_UNUSED(severity);
messageLabel->setText(text); toolBarMessageLabel->setText(text);
} }
QGCToolBar::~QGCToolBar() QGCToolBar::~QGCToolBar()
......
...@@ -28,14 +28,16 @@ This file is part of the QGROUNDCONTROL project ...@@ -28,14 +28,16 @@ This file is part of the QGROUNDCONTROL project
#include <QAction> #include <QAction>
#include <QToolButton> #include <QToolButton>
#include <QLabel> #include <QLabel>
#include <QProgressBar>
#include "UASInterface.h" #include "UASInterface.h"
#include "QGCMAVLinkLogPlayer.h"
class QGCToolBar : public QToolBar class QGCToolBar : public QToolBar
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit QGCToolBar(QWidget *parent = 0); explicit QGCToolBar(QWidget* parent = 0);
void addPerspectiveChangeAction(QAction* action); void addPerspectiveChangeAction(QAction* action);
~QGCToolBar(); ~QGCToolBar();
...@@ -52,6 +54,12 @@ public slots: ...@@ -52,6 +54,12 @@ public slots:
void setSystemType(UASInterface* uas, unsigned int systemType); void setSystemType(UASInterface* uas, unsigned int systemType);
/** @brief Received system text message */ /** @brief Received system text message */
void receiveTextMessage(int uasid, int componentid, int severity, QString text); void receiveTextMessage(int uasid, int componentid, int severity, QString text);
/** @brief Start / stop logging */
void logging(bool enabled);
/** @brief Set log playing component */
void setLogPlayer(QGCMAVLinkLogPlayer* player);
/** @brief Update battery charge state */
void updateBatteryRemaining(UASInterface* uas, double voltage, double percent, int seconds);
protected: protected:
void createCustomWidgets(); void createCustomWidgets();
...@@ -60,12 +68,13 @@ protected: ...@@ -60,12 +68,13 @@ protected:
QAction* logReplayAction; QAction* logReplayAction;
UASInterface* mav; UASInterface* mav;
QToolButton* symbolButton; QToolButton* symbolButton;
QLabel* nameLabel; QLabel* toolBarNameLabel;
QLabel* modeLabel; QLabel* toolBarModeLabel;
QLabel* stateLabel; QLabel* toolBarStateLabel;
QLabel* wpLabel; QLabel* toolBarWpLabel;
QLabel* distlabel; QLabel* toolBarDistLabel;
QLabel* messageLabel; QLabel* toolBarMessageLabel;
QProgressBar* toolBarBatteryBar;
}; };
#endif // QGCTOOLBAR_H #endif // QGCTOOLBAR_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment