mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-21 11:54:15 +01:00
Merge branch 'thread/OP-1119_Flight_Side_Logs_Plugin' into next
This commit is contained in:
commit
1d6df555eb
@ -4,12 +4,14 @@
|
|||||||
|
|
||||||
LogFile::LogFile(QObject *parent) :
|
LogFile::LogFile(QObject *parent) :
|
||||||
QIODevice(parent),
|
QIODevice(parent),
|
||||||
lastTimeStamp(0),
|
m_lastTimeStamp(0),
|
||||||
lastPlayed(0),
|
m_lastPlayed(0),
|
||||||
timeOffset(0),
|
m_timeOffset(0),
|
||||||
playbackSpeed(1.0)
|
m_playbackSpeed(1.0),
|
||||||
|
m_nextTimeStamp(0),
|
||||||
|
m_useProvidedTimeStamp(false)
|
||||||
{
|
{
|
||||||
connect(&timer, SIGNAL(timeout()), this, SLOT(timerFired()));
|
connect(&m_timer, SIGNAL(timeout()), this, SLOT(timerFired()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,8 +22,8 @@ LogFile::LogFile(QObject *parent) :
|
|||||||
bool LogFile::open(OpenMode mode)
|
bool LogFile::open(OpenMode mode)
|
||||||
{
|
{
|
||||||
// start a timer for playback
|
// start a timer for playback
|
||||||
myTime.restart();
|
m_myTime.restart();
|
||||||
if (file.isOpen()) {
|
if (m_file.isOpen()) {
|
||||||
// We end up here when doing a replay, because the connection
|
// We end up here when doing a replay, because the connection
|
||||||
// manager will also try to open the QIODevice, even though we just
|
// manager will also try to open the QIODevice, even though we just
|
||||||
// opened it after selecting the file, which happens before the
|
// opened it after selecting the file, which happens before the
|
||||||
@ -29,8 +31,8 @@ bool LogFile::open(OpenMode mode)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.open(mode) == false) {
|
if (m_file.open(mode) == false) {
|
||||||
qDebug() << "Unable to open " << file.fileName() << " for logging";
|
qDebug() << "Unable to open " << m_file.fileName() << " for logging";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,25 +51,27 @@ void LogFile::close()
|
|||||||
{
|
{
|
||||||
emit aboutToClose();
|
emit aboutToClose();
|
||||||
|
|
||||||
if (timer.isActive()) {
|
if (m_timer.isActive()) {
|
||||||
timer.stop();
|
m_timer.stop();
|
||||||
}
|
}
|
||||||
file.close();
|
m_file.close();
|
||||||
QIODevice::close();
|
QIODevice::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 LogFile::writeData(const char *data, qint64 dataSize)
|
qint64 LogFile::writeData(const char *data, qint64 dataSize)
|
||||||
{
|
{
|
||||||
if (!file.isWritable()) {
|
if (!m_file.isWritable()) {
|
||||||
return dataSize;
|
return dataSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 timeStamp = myTime.elapsed();
|
// If m_nextTimeStamp != -1 then use this timestamp instead of the timer
|
||||||
|
// This is used when saving logs from on-board logging
|
||||||
|
quint32 timeStamp = m_useProvidedTimeStamp ? m_nextTimeStamp : m_myTime.elapsed();
|
||||||
|
|
||||||
file.write((char *)&timeStamp, sizeof(timeStamp));
|
m_file.write((char *)&timeStamp, sizeof(timeStamp));
|
||||||
file.write((char *)&dataSize, sizeof(dataSize));
|
m_file.write((char *)&dataSize, sizeof(dataSize));
|
||||||
|
|
||||||
qint64 written = file.write(data, dataSize);
|
qint64 written = m_file.write(data, dataSize);
|
||||||
if (written != -1) {
|
if (written != -1) {
|
||||||
emit bytesWritten(written);
|
emit bytesWritten(written);
|
||||||
}
|
}
|
||||||
@ -77,36 +81,36 @@ qint64 LogFile::writeData(const char *data, qint64 dataSize)
|
|||||||
|
|
||||||
qint64 LogFile::readData(char *data, qint64 maxSize)
|
qint64 LogFile::readData(char *data, qint64 maxSize)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
qint64 toRead = qMin(maxSize, (qint64)dataBuffer.size());
|
qint64 toRead = qMin(maxSize, (qint64)m_dataBuffer.size());
|
||||||
|
|
||||||
memcpy(data, dataBuffer.data(), toRead);
|
memcpy(data, m_dataBuffer.data(), toRead);
|
||||||
dataBuffer.remove(0, toRead);
|
m_dataBuffer.remove(0, toRead);
|
||||||
return toRead;
|
return toRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 LogFile::bytesAvailable() const
|
qint64 LogFile::bytesAvailable() const
|
||||||
{
|
{
|
||||||
return dataBuffer.size();
|
return m_dataBuffer.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogFile::timerFired()
|
void LogFile::timerFired()
|
||||||
{
|
{
|
||||||
qint64 dataSize;
|
qint64 dataSize;
|
||||||
|
|
||||||
if (file.bytesAvailable() > 4) {
|
if (m_file.bytesAvailable() > 4) {
|
||||||
int time;
|
int time;
|
||||||
time = myTime.elapsed();
|
time = m_myTime.elapsed();
|
||||||
|
|
||||||
// TODO: going back in time will be a problem
|
// TODO: going back in time will be a problem
|
||||||
while ((lastPlayed + ((time - timeOffset) * playbackSpeed) > lastTimeStamp)) {
|
while ((m_lastPlayed + ((time - m_timeOffset) * m_playbackSpeed) > m_lastTimeStamp)) {
|
||||||
lastPlayed += ((time - timeOffset) * playbackSpeed);
|
m_lastPlayed += ((time - m_timeOffset) * m_playbackSpeed);
|
||||||
if (file.bytesAvailable() < sizeof(dataSize)) {
|
if (m_file.bytesAvailable() < sizeof(dataSize)) {
|
||||||
stopReplay();
|
stopReplay();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.read((char *)&dataSize, sizeof(dataSize));
|
m_file.read((char *)&dataSize, sizeof(dataSize));
|
||||||
|
|
||||||
if (dataSize < 1 || dataSize > (1024 * 1024)) {
|
if (dataSize < 1 || dataSize > (1024 * 1024)) {
|
||||||
qDebug() << "Error: Logfile corrupted! Unlikely packet size: " << dataSize << "\n";
|
qDebug() << "Error: Logfile corrupted! Unlikely packet size: " << dataSize << "\n";
|
||||||
@ -114,34 +118,34 @@ void LogFile::timerFired()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.bytesAvailable() < dataSize) {
|
if (m_file.bytesAvailable() < dataSize) {
|
||||||
stopReplay();
|
stopReplay();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex.lock();
|
m_mutex.lock();
|
||||||
dataBuffer.append(file.read(dataSize));
|
m_dataBuffer.append(m_file.read(dataSize));
|
||||||
mutex.unlock();
|
m_mutex.unlock();
|
||||||
|
|
||||||
emit readyRead();
|
emit readyRead();
|
||||||
|
|
||||||
if (file.bytesAvailable() < sizeof(lastTimeStamp)) {
|
if (m_file.bytesAvailable() < sizeof(m_lastTimeStamp)) {
|
||||||
stopReplay();
|
stopReplay();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int save = lastTimeStamp;
|
int save = m_lastTimeStamp;
|
||||||
file.read((char *)&lastTimeStamp, sizeof(lastTimeStamp));
|
m_file.read((char *)&m_lastTimeStamp, sizeof(m_lastTimeStamp));
|
||||||
// some validity checks
|
// some validity checks
|
||||||
if (lastTimeStamp < save // logfile goes back in time
|
if (m_lastTimeStamp < save // logfile goes back in time
|
||||||
|| (lastTimeStamp - save) > (60 * 60 * 1000)) { // gap of more than 60 minutes)
|
|| (m_lastTimeStamp - save) > (60 * 60 * 1000)) { // gap of more than 60 minutes)
|
||||||
qDebug() << "Error: Logfile corrupted! Unlikely timestamp " << lastTimeStamp << " after " << save << "\n";
|
qDebug() << "Error: Logfile corrupted! Unlikely timestamp " << m_lastTimeStamp << " after " << save << "\n";
|
||||||
stopReplay();
|
stopReplay();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeOffset = time;
|
m_timeOffset = time;
|
||||||
time = myTime.elapsed();
|
time = m_myTime.elapsed();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stopReplay();
|
stopReplay();
|
||||||
@ -150,13 +154,13 @@ void LogFile::timerFired()
|
|||||||
|
|
||||||
bool LogFile::startReplay()
|
bool LogFile::startReplay()
|
||||||
{
|
{
|
||||||
dataBuffer.clear();
|
m_dataBuffer.clear();
|
||||||
myTime.restart();
|
m_myTime.restart();
|
||||||
timeOffset = 0;
|
m_timeOffset = 0;
|
||||||
lastPlayed = 0;
|
m_lastPlayed = 0;
|
||||||
file.read((char *)&lastTimeStamp, sizeof(lastTimeStamp));
|
m_file.read((char *)&m_lastTimeStamp, sizeof(m_lastTimeStamp));
|
||||||
timer.setInterval(10);
|
m_timer.setInterval(10);
|
||||||
timer.start();
|
m_timer.start();
|
||||||
emit replayStarted();
|
emit replayStarted();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -170,11 +174,11 @@ bool LogFile::stopReplay()
|
|||||||
|
|
||||||
void LogFile::pauseReplay()
|
void LogFile::pauseReplay()
|
||||||
{
|
{
|
||||||
timer.stop();
|
m_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogFile::resumeReplay()
|
void LogFile::resumeReplay()
|
||||||
{
|
{
|
||||||
timeOffset = myTime.elapsed();
|
m_timeOffset = m_myTime.elapsed();
|
||||||
timer.start();
|
m_timer.start();
|
||||||
}
|
}
|
@ -7,22 +7,22 @@
|
|||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include "uavobjectmanager.h"
|
#include <QFile>
|
||||||
#include <math.h>
|
#include "utils_global.h"
|
||||||
|
|
||||||
class LogFile : public QIODevice {
|
class QTCREATOR_UTILS_EXPORT LogFile : public QIODevice {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit LogFile(QObject *parent = 0);
|
explicit LogFile(QObject *parent = 0);
|
||||||
qint64 bytesAvailable() const;
|
qint64 bytesAvailable() const;
|
||||||
qint64 bytesToWrite()
|
qint64 bytesToWrite()
|
||||||
{
|
{
|
||||||
return file.bytesToWrite();
|
return m_file.bytesToWrite();
|
||||||
};
|
};
|
||||||
bool open(OpenMode mode);
|
bool open(OpenMode mode);
|
||||||
void setFileName(QString name)
|
void setFileName(QString name)
|
||||||
{
|
{
|
||||||
file.setFileName(name);
|
m_file.setFileName(name);
|
||||||
};
|
};
|
||||||
void close();
|
void close();
|
||||||
qint64 writeData(const char *data, qint64 dataSize);
|
qint64 writeData(const char *data, qint64 dataSize);
|
||||||
@ -30,12 +30,21 @@ public:
|
|||||||
|
|
||||||
bool startReplay();
|
bool startReplay();
|
||||||
bool stopReplay();
|
bool stopReplay();
|
||||||
|
void useProvidedTimeStamp(bool useProvidedTimeStamp)
|
||||||
|
{
|
||||||
|
m_useProvidedTimeStamp = useProvidedTimeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNextTimeStamp(quint32 nextTimestamp)
|
||||||
|
{
|
||||||
|
m_nextTimeStamp = nextTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setReplaySpeed(double val)
|
void setReplaySpeed(double val)
|
||||||
{
|
{
|
||||||
playbackSpeed = val;
|
m_playbackSpeed = val;
|
||||||
qDebug() << "Playback speed is now" << playbackSpeed;
|
qDebug() << "Playback speed is now" << m_playbackSpeed;
|
||||||
};
|
};
|
||||||
void pauseReplay();
|
void pauseReplay();
|
||||||
void resumeReplay();
|
void resumeReplay();
|
||||||
@ -49,17 +58,21 @@ signals:
|
|||||||
void replayFinished();
|
void replayFinished();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QByteArray dataBuffer;
|
QByteArray m_dataBuffer;
|
||||||
QTimer timer;
|
QTimer m_timer;
|
||||||
QTime myTime;
|
QTime m_myTime;
|
||||||
QFile file;
|
QFile m_file;
|
||||||
qint32 lastTimeStamp;
|
qint32 m_lastTimeStamp;
|
||||||
qint32 lastPlayed;
|
qint32 m_lastPlayed;
|
||||||
QMutex mutex;
|
QMutex m_mutex;
|
||||||
|
|
||||||
|
|
||||||
int timeOffset;
|
int m_timeOffset;
|
||||||
double playbackSpeed;
|
double m_playbackSpeed;
|
||||||
|
|
||||||
|
private:
|
||||||
|
quint32 m_nextTimeStamp;
|
||||||
|
bool m_useProvidedTimeStamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LOGFILE_H
|
#endif // LOGFILE_H
|
@ -54,7 +54,8 @@ SOURCES += reloadpromptutils.cpp \
|
|||||||
mytabwidget.cpp \
|
mytabwidget.cpp \
|
||||||
cachedsvgitem.cpp \
|
cachedsvgitem.cpp \
|
||||||
svgimageprovider.cpp \
|
svgimageprovider.cpp \
|
||||||
hostosinfo.cpp
|
hostosinfo.cpp \
|
||||||
|
logfile.cpp
|
||||||
|
|
||||||
SOURCES += xmlconfig.cpp
|
SOURCES += xmlconfig.cpp
|
||||||
|
|
||||||
@ -111,7 +112,8 @@ HEADERS += utils_global.h \
|
|||||||
mytabwidget.h \
|
mytabwidget.h \
|
||||||
cachedsvgitem.h \
|
cachedsvgitem.h \
|
||||||
svgimageprovider.h \
|
svgimageprovider.h \
|
||||||
hostosinfo.h
|
hostosinfo.h \
|
||||||
|
logfile.h
|
||||||
|
|
||||||
|
|
||||||
HEADERS += xmlconfig.h
|
HEADERS += xmlconfig.h
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
<plugin name="FlightLog" version="1.0.0" compatVersion="1.0.0">
|
||||||
|
<vendor>The OpenPilot Project</vendor>
|
||||||
|
<copyright>(C) 2013 OpenPilot Project</copyright>
|
||||||
|
<license>The GNU Public License (GPL) Version 3</license>
|
||||||
|
<description>A plugin to manage flight side logs, viewing and downloading.</description>
|
||||||
|
<url>http://www.openpilot.org</url>
|
||||||
|
<dependencyList>
|
||||||
|
<dependency name="Core" version="1.0.0"/>
|
||||||
|
</dependencyList>
|
||||||
|
</plugin>
|
189
ground/openpilotgcs/src/plugins/flightlog/FlightLogDialog.qml
Normal file
189
ground/openpilotgcs/src/plugins/flightlog/FlightLogDialog.qml
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.0
|
||||||
|
import QtQuick.Layouts 1.0
|
||||||
|
|
||||||
|
import org.openpilot 1.0
|
||||||
|
|
||||||
|
import "functions.js" as Functions
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 600
|
||||||
|
height: 400
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 10
|
||||||
|
spacing: 10
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
border.width: 1
|
||||||
|
radius: 4
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.margins: 10
|
||||||
|
anchors.fill: parent
|
||||||
|
Text {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: "<b>" + qsTr("Log entries") + "</b>"
|
||||||
|
font.pixelSize: 12
|
||||||
|
}
|
||||||
|
TableView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
model: logManager.logEntries
|
||||||
|
|
||||||
|
itemDelegate: Text {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 2
|
||||||
|
anchors.leftMargin: 5
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: styleData.value
|
||||||
|
}
|
||||||
|
|
||||||
|
TableViewColumn {
|
||||||
|
role: "Flight"; title: qsTr("Flight"); width: 50;
|
||||||
|
delegate:
|
||||||
|
Text {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 2
|
||||||
|
anchors.leftMargin: 5
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: styleData.value + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
TableViewColumn {
|
||||||
|
role: "FlightTime"; title: qsTr("Time"); width: 80;
|
||||||
|
delegate:
|
||||||
|
Text {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 2
|
||||||
|
anchors.leftMargin: 5
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: Functions.millisToTime(styleData.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TableViewColumn {
|
||||||
|
role: "Type"; title: "Type"; width: 50;
|
||||||
|
delegate:
|
||||||
|
Text {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 2
|
||||||
|
anchors.leftMargin: 5
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: {
|
||||||
|
switch(styleData.value) {
|
||||||
|
case 0 : text: qsTr("Empty"); break;
|
||||||
|
case 1 : text: qsTr("Text"); break;
|
||||||
|
case 2 : text: qsTr("UAVO"); break;
|
||||||
|
default: text: qsTr("Unknown"); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
TableViewColumn { role: "LogString"; title: qsTr("Data"); width: 280}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.margins: 10
|
||||||
|
spacing: 10
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 10
|
||||||
|
Text {
|
||||||
|
id: totalFlights
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: "<b>" + qsTr("Flights recorded: ") + "</b>" + (logStatus.Flight + 1)
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
id: totalEntries
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: "<b>" + qsTr("Entries logged (free): ") + "</b>" +
|
||||||
|
logStatus.UsedSlots + " (" + logStatus.FreeSlots + ")"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 10
|
||||||
|
RowLayout {
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: "<b>" + qsTr("Flight to download:") + "</b>"
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: flightCombo
|
||||||
|
enabled: !logManager.disableControls
|
||||||
|
model: logManager.flightEntries
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: qsTr("Download logs")
|
||||||
|
enabled: !logManager.disableControls
|
||||||
|
activeFocusOnPress: true
|
||||||
|
onClicked: logManager.retrieveLogs(flightCombo.currentIndex - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 40
|
||||||
|
Button {
|
||||||
|
id: exportButton
|
||||||
|
enabled: !logManager.disableControls && !logManager.disableExport
|
||||||
|
text: qsTr("Export...")
|
||||||
|
activeFocusOnPress: true
|
||||||
|
onClicked: logManager.exportLogs()
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
id: exportRelativeTimeCB
|
||||||
|
enabled: !logManager.disableControls && !logManager.disableExport
|
||||||
|
text: qsTr("Adjust timestamps")
|
||||||
|
activeFocusOnPress: true
|
||||||
|
checked: logManager.adjustExportedTimestamps
|
||||||
|
onCheckedChanged: logManager.setAdjustExportedTimestamps(checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: clearButton
|
||||||
|
enabled: !logManager.disableControls
|
||||||
|
text: qsTr("Clear all logs")
|
||||||
|
activeFocusOnPress: true
|
||||||
|
onClicked: logManager.clearAllLogs()
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: cancelButton
|
||||||
|
enabled: logManager.disableControls
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
activeFocusOnPress: true
|
||||||
|
onClicked: logManager.cancelExportLogs()
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: okButton
|
||||||
|
enabled: !logManager.disableControls
|
||||||
|
text: qsTr("OK")
|
||||||
|
isDefault: true
|
||||||
|
activeFocusOnPress: true
|
||||||
|
onClicked: dialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
ground/openpilotgcs/src/plugins/flightlog/flightLog.qrc
Normal file
6
ground/openpilotgcs/src/plugins/flightlog/flightLog.qrc
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/flightlog">
|
||||||
|
<file>FlightLogDialog.qml</file>
|
||||||
|
<file>functions.js</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
25
ground/openpilotgcs/src/plugins/flightlog/flightlog.pro
Normal file
25
ground/openpilotgcs/src/plugins/flightlog/flightlog.pro
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
TEMPLATE = lib
|
||||||
|
TARGET = FlightLog
|
||||||
|
|
||||||
|
QT += qml quick
|
||||||
|
|
||||||
|
include(../../openpilotgcsplugin.pri)
|
||||||
|
include(../../plugins/coreplugin/coreplugin.pri)
|
||||||
|
include(../../plugins/uavobjects/uavobjects.pri)
|
||||||
|
include(../../plugins/uavtalk/uavtalk.pri)
|
||||||
|
|
||||||
|
HEADERS += flightlogplugin.h \
|
||||||
|
flightlogmanager.h \
|
||||||
|
flightlogdialog.h
|
||||||
|
SOURCES += flightlogplugin.cpp \
|
||||||
|
flightlogmanager.cpp \
|
||||||
|
flightlogdialog.cpp
|
||||||
|
|
||||||
|
OTHER_FILES += Flightlog.pluginspec \
|
||||||
|
FlightLogDialog.qml \
|
||||||
|
functions.js
|
||||||
|
|
||||||
|
FORMS +=
|
||||||
|
|
||||||
|
RESOURCES += \
|
||||||
|
flightLog.qrc
|
@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file flightlogdialog.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||||
|
* @addtogroup [Group]
|
||||||
|
* @{
|
||||||
|
* @addtogroup FlightLogDialog
|
||||||
|
* @{
|
||||||
|
* @brief [Brief]
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flightlogdialog.h"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include <QtQuick>
|
||||||
|
#include <QQuickView>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QQmlContext>
|
||||||
|
|
||||||
|
#include "flightlogmanager.h"
|
||||||
|
|
||||||
|
FlightLogDialog::FlightLogDialog(QWidget *parent, FlightLogManager *flightLogManager) :
|
||||||
|
QDialog(parent)
|
||||||
|
{
|
||||||
|
qmlRegisterType<ExtendedDebugLogEntry>("org.openpilot", 1, 0, "DebugLogEntry");
|
||||||
|
|
||||||
|
setWindowIcon(QIcon(":/core/images/openpilot_logo_32.png"));
|
||||||
|
setWindowTitle(tr("Manage flight side logs"));
|
||||||
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||||
|
setMinimumSize(600, 400);
|
||||||
|
|
||||||
|
QQuickView *view = new QQuickView();
|
||||||
|
view->rootContext()->setContextProperty("dialog", this);
|
||||||
|
view->rootContext()->setContextProperty("logStatus", flightLogManager->flightLogStatus());
|
||||||
|
view->rootContext()->setContextProperty("logManager", flightLogManager);
|
||||||
|
view->setResizeMode(QQuickView::SizeRootObjectToView);
|
||||||
|
view->setSource(QUrl("qrc:/flightlog/FlightLogDialog.qml"));
|
||||||
|
|
||||||
|
QWidget *container = QWidget::createWindowContainer(view);
|
||||||
|
container->setMinimumSize(600, 400);
|
||||||
|
container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
QVBoxLayout *lay = new QVBoxLayout();
|
||||||
|
lay->setContentsMargins(0, 0, 0, 0);
|
||||||
|
setLayout(lay);
|
||||||
|
layout()->addWidget(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
FlightLogDialog::~FlightLogDialog()
|
||||||
|
{}
|
15
ground/openpilotgcs/src/plugins/flightlog/flightlogdialog.h
Normal file
15
ground/openpilotgcs/src/plugins/flightlog/flightlogdialog.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef FLIGHTLOGDIALOG_H
|
||||||
|
#define FLIGHTLOGDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "flightlogmanager.h"
|
||||||
|
|
||||||
|
class FlightLogDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FlightLogDialog(QWidget *parent, FlightLogManager *flightLogManager);
|
||||||
|
~FlightLogDialog();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FLIGHTLOGDIALOG_H
|
311
ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.cpp
Normal file
311
ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.cpp
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file flightlogmanager.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||||
|
* @addtogroup [Group]
|
||||||
|
* @{
|
||||||
|
* @addtogroup FlightLogManager
|
||||||
|
* @{
|
||||||
|
* @brief [Brief]
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flightlogmanager.h"
|
||||||
|
#include "extensionsystem/pluginmanager.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
|
#include "debuglogcontrol.h"
|
||||||
|
#include "uavobjecthelper.h"
|
||||||
|
#include "uavtalk/uavtalk.h"
|
||||||
|
#include "utils/logfile.h"
|
||||||
|
|
||||||
|
FlightLogManager::FlightLogManager(QObject *parent) :
|
||||||
|
QObject(parent), m_disableControls(false),
|
||||||
|
m_disableExport(true), m_cancelDownload(false),
|
||||||
|
m_adjustExportedTimestamps(true)
|
||||||
|
{
|
||||||
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||||
|
|
||||||
|
m_objectManager = pm->getObject<UAVObjectManager>();
|
||||||
|
Q_ASSERT(m_objectManager);
|
||||||
|
|
||||||
|
m_flightLogControl = DebugLogControl::GetInstance(m_objectManager);
|
||||||
|
Q_ASSERT(m_flightLogControl);
|
||||||
|
|
||||||
|
m_flightLogStatus = DebugLogStatus::GetInstance(m_objectManager);
|
||||||
|
Q_ASSERT(m_flightLogStatus);
|
||||||
|
connect(m_flightLogStatus, SIGNAL(FlightChanged(quint16)), this, SLOT(updateFlightEntries(quint16)));
|
||||||
|
|
||||||
|
m_flightLogEntry = DebugLogEntry::GetInstance(m_objectManager);
|
||||||
|
Q_ASSERT(m_flightLogEntry);
|
||||||
|
|
||||||
|
updateFlightEntries(m_flightLogStatus->getFlight());
|
||||||
|
}
|
||||||
|
|
||||||
|
FlightLogManager::~FlightLogManager()
|
||||||
|
{
|
||||||
|
while (!m_logEntries.isEmpty()) {
|
||||||
|
delete m_logEntries.takeFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addLogEntries(QQmlListProperty<ExtendedDebugLogEntry> *list, ExtendedDebugLogEntry *entry)
|
||||||
|
{
|
||||||
|
Q_UNUSED(list);
|
||||||
|
Q_UNUSED(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
int countLogEntries(QQmlListProperty<ExtendedDebugLogEntry> *list)
|
||||||
|
{
|
||||||
|
return static_cast< QList<ExtendedDebugLogEntry *> *>(list->data)->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedDebugLogEntry *logEntryAt(QQmlListProperty<ExtendedDebugLogEntry> *list, int index)
|
||||||
|
{
|
||||||
|
return static_cast< QList<ExtendedDebugLogEntry *> *>(list->data)->at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearLogEntries(QQmlListProperty<ExtendedDebugLogEntry> *list)
|
||||||
|
{
|
||||||
|
return static_cast< QList<ExtendedDebugLogEntry *> *>(list->data)->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
QQmlListProperty<ExtendedDebugLogEntry> FlightLogManager::logEntries()
|
||||||
|
{
|
||||||
|
return QQmlListProperty<ExtendedDebugLogEntry>(this, &m_logEntries, &addLogEntries, &countLogEntries, &logEntryAt, &clearLogEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList FlightLogManager::flightEntries()
|
||||||
|
{
|
||||||
|
return m_flightEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightLogManager::clearAllLogs()
|
||||||
|
{
|
||||||
|
setDisableControls(true);
|
||||||
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
|
||||||
|
// Clear on flight side
|
||||||
|
UAVObjectUpdaterHelper updateHelper;
|
||||||
|
|
||||||
|
m_flightLogControl->setFlight(0);
|
||||||
|
m_flightLogControl->setEntry(0);
|
||||||
|
m_flightLogControl->setOperation(DebugLogControl::OPERATION_FORMATFLASH);
|
||||||
|
if (updateHelper.doObjectAndWait(m_flightLogControl, UAVTALK_TIMEOUT) == UAVObjectUpdaterHelper::SUCCESS) {
|
||||||
|
// Then empty locally
|
||||||
|
clearLogList();
|
||||||
|
}
|
||||||
|
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
setDisableControls(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightLogManager::clearLogList()
|
||||||
|
{
|
||||||
|
QList<ExtendedDebugLogEntry*> tmpList(m_logEntries);
|
||||||
|
m_logEntries.clear();
|
||||||
|
|
||||||
|
emit logEntriesChanged();
|
||||||
|
setDisableExport(true);
|
||||||
|
|
||||||
|
while (!tmpList.isEmpty()) {
|
||||||
|
delete tmpList.takeFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightLogManager::retrieveLogs(int flightToRetrieve)
|
||||||
|
{
|
||||||
|
setDisableControls(true);
|
||||||
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
m_cancelDownload = false;
|
||||||
|
UAVObjectUpdaterHelper updateHelper;
|
||||||
|
UAVObjectRequestHelper requestHelper;
|
||||||
|
|
||||||
|
clearLogList();
|
||||||
|
|
||||||
|
// Set up what to retrieve
|
||||||
|
int startFlight = (flightToRetrieve == -1) ? 0 : flightToRetrieve;
|
||||||
|
int endFlight = (flightToRetrieve == -1) ? m_flightLogStatus->getFlight() : flightToRetrieve;
|
||||||
|
|
||||||
|
// Prepare to send request for event retrieval
|
||||||
|
m_flightLogControl->setOperation(DebugLogControl::OPERATION_RETRIEVE);
|
||||||
|
for (int flight = startFlight; flight <= endFlight; flight++) {
|
||||||
|
m_flightLogControl->setFlight(flight);
|
||||||
|
bool gotLast = false;
|
||||||
|
int entry = 0;
|
||||||
|
while (!gotLast) {
|
||||||
|
// Send request for loading flight entry on flight side and wait for ack/nack
|
||||||
|
m_flightLogControl->setEntry(entry);
|
||||||
|
|
||||||
|
if (updateHelper.doObjectAndWait(m_flightLogControl, UAVTALK_TIMEOUT) == UAVObjectUpdaterHelper::SUCCESS &&
|
||||||
|
requestHelper.doObjectAndWait(m_flightLogEntry, UAVTALK_TIMEOUT) == UAVObjectUpdaterHelper::SUCCESS) {
|
||||||
|
if (m_flightLogEntry->getType() != DebugLogEntry::TYPE_EMPTY) {
|
||||||
|
// Ok, we retrieved the entry, and it was the correct one. clone it and add it to the list
|
||||||
|
ExtendedDebugLogEntry *logEntry = new ExtendedDebugLogEntry();
|
||||||
|
logEntry->setData(m_flightLogEntry->getData(), m_objectManager);
|
||||||
|
m_logEntries << logEntry;
|
||||||
|
|
||||||
|
// Increment to get next entry from flight side
|
||||||
|
entry++;
|
||||||
|
} else {
|
||||||
|
// We are done, not more entries on this flight
|
||||||
|
gotLast = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We failed for some reason
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (m_cancelDownload) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_cancelDownload) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_cancelDownload) {
|
||||||
|
clearLogList();
|
||||||
|
m_cancelDownload = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit logEntriesChanged();
|
||||||
|
setDisableExport(m_logEntries.count() == 0);
|
||||||
|
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
setDisableControls(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightLogManager::exportLogs()
|
||||||
|
{
|
||||||
|
if(m_logEntries.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setDisableControls(true);
|
||||||
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(NULL, tr("Save Log"),
|
||||||
|
tr("OP-%0.opl").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss")),
|
||||||
|
tr("OpenPilot Log (*.opl)"));
|
||||||
|
if (!fileName.isEmpty()) {
|
||||||
|
// Loop and create a new file for each flight.
|
||||||
|
fileName = fileName.replace(QString(".opl"), QString("%1.opl"));
|
||||||
|
int currentEntry = 0;
|
||||||
|
int currentFlight = 0;
|
||||||
|
quint32 adjustedBaseTime = 0;
|
||||||
|
// Continue until all entries are exported
|
||||||
|
while(currentEntry < m_logEntries.count()) {
|
||||||
|
|
||||||
|
if (m_adjustExportedTimestamps) {
|
||||||
|
adjustedBaseTime = m_logEntries[currentEntry]->getFlightTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current flight
|
||||||
|
currentFlight = m_logEntries[currentEntry]->getFlight();
|
||||||
|
|
||||||
|
LogFile logFile;
|
||||||
|
logFile.useProvidedTimeStamp(true);
|
||||||
|
|
||||||
|
// Set the file name to contain flight number
|
||||||
|
logFile.setFileName(fileName.arg(tr("_flight-%1").arg(currentFlight + 1)));
|
||||||
|
logFile.open(QIODevice::WriteOnly);
|
||||||
|
UAVTalk uavTalk(&logFile, m_objectManager);
|
||||||
|
|
||||||
|
// Export entries until no more available or flight changes
|
||||||
|
while(currentEntry < m_logEntries.count() && m_logEntries[currentEntry]->getFlight() == currentFlight) {
|
||||||
|
ExtendedDebugLogEntry* entry = m_logEntries[currentEntry];
|
||||||
|
|
||||||
|
// Only log uavobjects
|
||||||
|
if (entry->getType() == ExtendedDebugLogEntry::TYPE_UAVOBJECT) {
|
||||||
|
// Set timestamp that should be logged for this entry
|
||||||
|
logFile.setNextTimeStamp(entry->getFlightTime() - adjustedBaseTime);
|
||||||
|
|
||||||
|
// Use UAVTalk to log complete message to file
|
||||||
|
uavTalk.sendObject(entry->uavObject(), false, false);
|
||||||
|
qDebug() << entry->getFlightTime() - adjustedBaseTime << "=" << entry->toStringBrief();
|
||||||
|
}
|
||||||
|
currentEntry++;
|
||||||
|
}
|
||||||
|
|
||||||
|
logFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
setDisableControls(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightLogManager::cancelExportLogs()
|
||||||
|
{
|
||||||
|
m_cancelDownload = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightLogManager::updateFlightEntries(quint16 currentFlight)
|
||||||
|
{
|
||||||
|
Q_UNUSED(currentFlight);
|
||||||
|
|
||||||
|
int flights = m_flightLogStatus->getFlight();
|
||||||
|
if (m_flightEntries.count() == 0 || (m_flightEntries.count() - 1 != flights)) {
|
||||||
|
m_flightEntries.clear();
|
||||||
|
|
||||||
|
m_flightEntries << tr("All");
|
||||||
|
for(int i = 0; i <= flights; i++) {
|
||||||
|
m_flightEntries << QString::number(i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit flightEntriesChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedDebugLogEntry::ExtendedDebugLogEntry() : DebugLogEntry(),
|
||||||
|
m_object(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ExtendedDebugLogEntry::~ExtendedDebugLogEntry()
|
||||||
|
{
|
||||||
|
if (m_object) {
|
||||||
|
delete m_object;
|
||||||
|
m_object = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ExtendedDebugLogEntry::getLogString()
|
||||||
|
{
|
||||||
|
if (getType() == DebugLogEntry::TYPE_TEXT) {
|
||||||
|
return QString((const char *)getData().Data);
|
||||||
|
} else if (getType() == DebugLogEntry::TYPE_UAVOBJECT) {
|
||||||
|
return m_object->toString().replace("\n", " ").replace("\t", " ");
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtendedDebugLogEntry::setData(const DebugLogEntry::DataFields &data, UAVObjectManager *objectManager)
|
||||||
|
{
|
||||||
|
DebugLogEntry::setData(data);
|
||||||
|
if (getType() == DebugLogEntry::TYPE_UAVOBJECT) {
|
||||||
|
UAVDataObject *object = (UAVDataObject *)objectManager->getObject(getObjectID(), getInstanceID());
|
||||||
|
Q_ASSERT(object);
|
||||||
|
m_object = object->clone(getInstanceID());
|
||||||
|
m_object->unpack(getData().Data);
|
||||||
|
}
|
||||||
|
}
|
162
ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.h
Normal file
162
ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.h
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file flightlogmanager.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||||
|
* @addtogroup [Group]
|
||||||
|
* @{
|
||||||
|
* @addtogroup FlightLogManager
|
||||||
|
* @{
|
||||||
|
* @brief [Brief]
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLIGHTLOGMANAGER_H
|
||||||
|
#define FLIGHTLOGMANAGER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QList>
|
||||||
|
#include <QQmlListProperty>
|
||||||
|
#include <QSemaphore>
|
||||||
|
|
||||||
|
#include "uavobjectmanager.h"
|
||||||
|
#include "debuglogentry.h"
|
||||||
|
#include "debuglogstatus.h"
|
||||||
|
#include "debuglogcontrol.h"
|
||||||
|
|
||||||
|
class ExtendedDebugLogEntry : public DebugLogEntry {
|
||||||
|
Q_OBJECT Q_PROPERTY(QString LogString READ getLogString WRITE setLogString NOTIFY LogStringUpdated)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ExtendedDebugLogEntry();
|
||||||
|
~ExtendedDebugLogEntry();
|
||||||
|
|
||||||
|
QString getLogString();
|
||||||
|
UAVDataObject *uavObject()
|
||||||
|
{
|
||||||
|
return m_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setData(const DataFields& data, UAVObjectManager *objectManager);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setLogString(QString arg)
|
||||||
|
{
|
||||||
|
Q_UNUSED(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void LogStringUpdated(QString arg);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UAVDataObject *m_object;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FlightLogManager : public QObject {
|
||||||
|
Q_OBJECT Q_PROPERTY(DebugLogStatus *flightLogStatus READ flightLogStatus)
|
||||||
|
Q_PROPERTY(QQmlListProperty<ExtendedDebugLogEntry> logEntries READ logEntries NOTIFY logEntriesChanged)
|
||||||
|
Q_PROPERTY(QStringList flightEntries READ flightEntries NOTIFY flightEntriesChanged)
|
||||||
|
Q_PROPERTY(bool disableControls READ disableControls WRITE setDisableControls NOTIFY disableControlsChanged)
|
||||||
|
Q_PROPERTY(bool disableExport READ disableExport WRITE setDisableExport NOTIFY disableExportChanged)
|
||||||
|
Q_PROPERTY(bool adjustExportedTimestamps READ adjustExportedTimestamps WRITE setAdjustExportedTimestamps NOTIFY adjustExportedTimestampsChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FlightLogManager(QObject *parent = 0);
|
||||||
|
~FlightLogManager();
|
||||||
|
|
||||||
|
QQmlListProperty<ExtendedDebugLogEntry> logEntries();
|
||||||
|
QStringList flightEntries();
|
||||||
|
|
||||||
|
DebugLogStatus *flightLogStatus() const
|
||||||
|
{
|
||||||
|
return m_flightLogStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool disableControls() const
|
||||||
|
{
|
||||||
|
return m_disableControls;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool disableExport() const
|
||||||
|
{
|
||||||
|
return m_disableExport;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearLogList();
|
||||||
|
|
||||||
|
bool adjustExportedTimestamps() const
|
||||||
|
{
|
||||||
|
return m_adjustExportedTimestamps;
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void logEntriesChanged();
|
||||||
|
void flightEntriesChanged();
|
||||||
|
void disableControlsChanged(bool arg);
|
||||||
|
void disableExportChanged(bool arg);
|
||||||
|
|
||||||
|
void adjustExportedTimestampsChanged(bool arg);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void clearAllLogs();
|
||||||
|
void retrieveLogs(int flightToRetrieve = -1);
|
||||||
|
void exportLogs();
|
||||||
|
void cancelExportLogs();
|
||||||
|
|
||||||
|
void setDisableControls(bool arg)
|
||||||
|
{
|
||||||
|
if (m_disableControls != arg) {
|
||||||
|
m_disableControls = arg;
|
||||||
|
emit disableControlsChanged(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDisableExport(bool arg)
|
||||||
|
{
|
||||||
|
if (m_disableExport != arg) {
|
||||||
|
m_disableExport = arg;
|
||||||
|
emit disableExportChanged(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAdjustExportedTimestamps(bool arg)
|
||||||
|
{
|
||||||
|
if (m_adjustExportedTimestamps != arg) {
|
||||||
|
m_adjustExportedTimestamps = arg;
|
||||||
|
emit adjustExportedTimestampsChanged(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateFlightEntries(quint16 currentFlight);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UAVObjectManager *m_objectManager;
|
||||||
|
DebugLogControl *m_flightLogControl;
|
||||||
|
DebugLogStatus *m_flightLogStatus;
|
||||||
|
DebugLogEntry *m_flightLogEntry;
|
||||||
|
QList<ExtendedDebugLogEntry *> m_logEntries;
|
||||||
|
QStringList m_flightEntries;
|
||||||
|
|
||||||
|
static const int UAVTALK_TIMEOUT = 4000;
|
||||||
|
bool m_disableControls;
|
||||||
|
bool m_disableExport;
|
||||||
|
bool m_cancelDownload;
|
||||||
|
bool m_adjustExportedTimestamps;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FLIGHTLOGMANAGER_H
|
@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file flightlogplugin.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @brief A plugin to view and download flight side logs.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
#include "flightlogplugin.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QtPlugin>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
|
||||||
|
#include <coreplugin/coreconstants.h>
|
||||||
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <QKeySequence>
|
||||||
|
#include <coreplugin/modemanager.h>
|
||||||
|
|
||||||
|
#include "flightlogdialog.h"
|
||||||
|
|
||||||
|
FlightLogPlugin::FlightLogPlugin() : m_logDialog(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
FlightLogPlugin::~FlightLogPlugin()
|
||||||
|
{
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FlightLogPlugin::initialize(const QStringList & args, QString *errMsg)
|
||||||
|
{
|
||||||
|
Q_UNUSED(args);
|
||||||
|
Q_UNUSED(errMsg);
|
||||||
|
|
||||||
|
// Add Menu entry
|
||||||
|
Core::ActionManager *am = Core::ICore::instance()->actionManager();
|
||||||
|
Core::ActionContainer *ac = am->actionContainer(Core::Constants::M_TOOLS);
|
||||||
|
|
||||||
|
Core::Command *cmd = am->registerAction(new QAction(this),
|
||||||
|
"FlightLogPlugin.ShowFlightLogDialog",
|
||||||
|
QList<int>() <<
|
||||||
|
Core::Constants::C_GLOBAL_ID);
|
||||||
|
cmd->setDefaultKeySequence(QKeySequence("Ctrl+F"));
|
||||||
|
cmd->action()->setText(tr("Manage flight side logs..."));
|
||||||
|
|
||||||
|
Core::ModeManager::instance()->addAction(cmd, 1);
|
||||||
|
|
||||||
|
ac->menu()->addSeparator();
|
||||||
|
ac->appendGroup("FlightLogs");
|
||||||
|
ac->addAction(cmd, "FlightLogs");
|
||||||
|
|
||||||
|
connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(ShowLogManagementDialog()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightLogPlugin::ShowLogManagementDialog()
|
||||||
|
{
|
||||||
|
if (!m_logDialog) {
|
||||||
|
m_logDialog = new FlightLogDialog(0, new FlightLogManager());
|
||||||
|
connect(m_logDialog, SIGNAL(finished(int)), this, SLOT(LogManagementDialogClosed()));
|
||||||
|
m_logDialog->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightLogPlugin::LogManagementDialogClosed()
|
||||||
|
{
|
||||||
|
if (m_logDialog) {
|
||||||
|
m_logDialog->deleteLater();
|
||||||
|
m_logDialog = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightLogPlugin::extensionsInitialized()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void FlightLogPlugin::shutdown()
|
||||||
|
{
|
||||||
|
if (m_logDialog) {
|
||||||
|
m_logDialog->close();
|
||||||
|
LogManagementDialogClosed();
|
||||||
|
}
|
||||||
|
}
|
53
ground/openpilotgcs/src/plugins/flightlog/flightlogplugin.h
Normal file
53
ground/openpilotgcs/src/plugins/flightlog/flightlogplugin.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file flightlogplugin.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @brief A plugin to view and download flight side logs.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLIGHTLOGPLUGIN_H_
|
||||||
|
#define FLIGHTLOGPLUGIN_H_
|
||||||
|
|
||||||
|
#include <extensionsystem/iplugin.h>
|
||||||
|
#include "flightlogmanager.h"
|
||||||
|
#include "flightlogdialog.h"
|
||||||
|
|
||||||
|
class FlightLogPlugin : public ExtensionSystem::IPlugin {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PLUGIN_METADATA(IID "OpenPilot.FlightLog")
|
||||||
|
|
||||||
|
public:
|
||||||
|
FlightLogPlugin();
|
||||||
|
~FlightLogPlugin();
|
||||||
|
|
||||||
|
void extensionsInitialized();
|
||||||
|
bool initialize(const QStringList & arguments, QString *errorString);
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void ShowLogManagementDialog();
|
||||||
|
void LogManagementDialogClosed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FlightLogDialog *m_logDialog;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FLIGHTLOGPLUGIN_H_ */
|
20
ground/openpilotgcs/src/plugins/flightlog/functions.js
Normal file
20
ground/openpilotgcs/src/plugins/flightlog/functions.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
.pragma library
|
||||||
|
|
||||||
|
function millisToTime(ms) {
|
||||||
|
var secs = Math.floor(ms / 1000);
|
||||||
|
var msleft = ms % 1000;
|
||||||
|
var hours = Math.floor(secs / (60 * 60));
|
||||||
|
var divisor_for_minutes = secs % (60 * 60);
|
||||||
|
var minutes = Math.floor(divisor_for_minutes / 60);
|
||||||
|
var divisor_for_seconds = divisor_for_minutes % 60;
|
||||||
|
var seconds = Math.ceil(divisor_for_seconds);
|
||||||
|
return pad(hours, 2) + ":" + pad(minutes, 2) + ":" + pad(seconds, 2) + ":" + pad(msleft, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pad(number, length) {
|
||||||
|
var str = '' + number;
|
||||||
|
while (str.length < length) {
|
||||||
|
str = '0' + str;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
@ -1,25 +1,22 @@
|
|||||||
TEMPLATE = lib
|
TEMPLATE = lib
|
||||||
|
|
||||||
TARGET = LoggingGadget
|
TARGET = LoggingGadget
|
||||||
DEFINES += LOGGING_LIBRARY
|
DEFINES += LOGGING_LIBRARY
|
||||||
QT += svg
|
QT += svg
|
||||||
|
|
||||||
include(../../openpilotgcsplugin.pri)
|
include(../../openpilotgcsplugin.pri)
|
||||||
include(logging_dependencies.pri)
|
include(logging_dependencies.pri)
|
||||||
HEADERS += loggingplugin.h \
|
HEADERS += loggingplugin.h \
|
||||||
logfile.h \
|
|
||||||
logginggadgetwidget.h \
|
logginggadgetwidget.h \
|
||||||
logginggadget.h \
|
logginggadget.h \
|
||||||
logginggadgetfactory.h
|
logginggadgetfactory.h
|
||||||
# logginggadgetconfiguration.h
|
|
||||||
# logginggadgetoptionspage.h
|
|
||||||
|
|
||||||
SOURCES += loggingplugin.cpp \
|
SOURCES += loggingplugin.cpp \
|
||||||
logfile.cpp \
|
|
||||||
logginggadgetwidget.cpp \
|
logginggadgetwidget.cpp \
|
||||||
logginggadget.cpp \
|
logginggadget.cpp \
|
||||||
logginggadgetfactory.cpp
|
logginggadgetfactory.cpp
|
||||||
# logginggadgetconfiguration.cpp \
|
|
||||||
# logginggadgetoptionspage.cpp
|
|
||||||
OTHER_FILES += LoggingGadget.pluginspec
|
OTHER_FILES += LoggingGadget.pluginspec
|
||||||
|
|
||||||
FORMS += logging.ui
|
FORMS += logging.ui
|
||||||
# logginggadgetwidget.ui \
|
|
||||||
# loggingdialog.ui
|
|
||||||
|
@ -323,7 +323,7 @@ bool LoggingPlugin::initialize(const QStringList & args, QString *errMsg)
|
|||||||
QList<int>() <<
|
QList<int>() <<
|
||||||
Core::Constants::C_GLOBAL_ID);
|
Core::Constants::C_GLOBAL_ID);
|
||||||
cmd->setDefaultKeySequence(QKeySequence("Ctrl+L"));
|
cmd->setDefaultKeySequence(QKeySequence("Ctrl+L"));
|
||||||
cmd->action()->setText("Start logging...");
|
cmd->action()->setText(tr("Start logging..."));
|
||||||
|
|
||||||
ac->menu()->addSeparator();
|
ac->menu()->addSeparator();
|
||||||
ac->appendGroup("Logging");
|
ac->appendGroup("Logging");
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#include "uavobjectmanager.h"
|
#include "uavobjectmanager.h"
|
||||||
#include "gcstelemetrystats.h"
|
#include "gcstelemetrystats.h"
|
||||||
#include <uavtalk/uavtalk.h>
|
#include <uavtalk/uavtalk.h>
|
||||||
#include <logfile.h>
|
#include <utils/logfile.h>
|
||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
|
@ -244,3 +244,10 @@ plugin_setupwizard.depends += plugin_config
|
|||||||
plugin_setupwizard.depends += plugin_uploader
|
plugin_setupwizard.depends += plugin_uploader
|
||||||
SUBDIRS += plugin_setupwizard
|
SUBDIRS += plugin_setupwizard
|
||||||
|
|
||||||
|
# Flight Logs plugin
|
||||||
|
plugin_flightlog.subdir = flightlog
|
||||||
|
plugin_flightlog.depends = plugin_coreplugin
|
||||||
|
plugin_flightlog.depends += plugin_uavobjects
|
||||||
|
plugin_flightlog.depends += plugin_uavtalk
|
||||||
|
SUBDIRS += plugin_flightlog
|
||||||
|
|
||||||
|
100
ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.cpp
Normal file
100
ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file uavobjecthelper.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||||
|
* @addtogroup [Group]
|
||||||
|
* @{
|
||||||
|
* @addtogroup UAVObjectHelper
|
||||||
|
* @{
|
||||||
|
* @brief [Brief]
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uavobjecthelper.h"
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
AbstractUAVObjectHelper::AbstractUAVObjectHelper(QObject *parent) :
|
||||||
|
QObject(parent), m_transactionResult(false), m_transactionCompleted(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
AbstractUAVObjectHelper::Result AbstractUAVObjectHelper::doObjectAndWait(UAVObject *object, int timeout)
|
||||||
|
{
|
||||||
|
// Lock, we can't call this twice from different threads
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
|
||||||
|
m_object = object;
|
||||||
|
|
||||||
|
// Reset variables
|
||||||
|
m_transactionResult = false;
|
||||||
|
m_transactionCompleted = false;
|
||||||
|
|
||||||
|
// Create timer and connect it, connect object tx completed to local slot
|
||||||
|
QTimer timeoutTimer;
|
||||||
|
timeoutTimer.setSingleShot(true);
|
||||||
|
connect(&timeoutTimer, SIGNAL(timeout()), &m_eventLoop, SLOT(quit()));
|
||||||
|
connect(object, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(transactionCompleted(UAVObject *, bool)));
|
||||||
|
|
||||||
|
// Start timeout timer
|
||||||
|
timeoutTimer.start(timeout);
|
||||||
|
|
||||||
|
// Call the actual implementation in concrete subclass
|
||||||
|
doObjectAndWaitImpl();
|
||||||
|
|
||||||
|
// Wait if not completed
|
||||||
|
if (!m_transactionCompleted) {
|
||||||
|
m_eventLoop.exec();
|
||||||
|
}
|
||||||
|
timeoutTimer.stop();
|
||||||
|
|
||||||
|
// Disconnect
|
||||||
|
disconnect(object, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(transactionCompleted(UAVObject *, bool)));
|
||||||
|
disconnect(&timeoutTimer, SIGNAL(timeout()), &m_eventLoop, SLOT(quit()));
|
||||||
|
|
||||||
|
// Return result
|
||||||
|
if (!m_transactionCompleted) {
|
||||||
|
return TIMEOUT;
|
||||||
|
} else {
|
||||||
|
return m_transactionResult ? SUCCESS : FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractUAVObjectHelper::transactionCompleted(UAVObject *object, bool success)
|
||||||
|
{
|
||||||
|
Q_UNUSED(object)
|
||||||
|
|
||||||
|
// Set variables and quit event loop
|
||||||
|
m_transactionResult = success;
|
||||||
|
m_transactionCompleted = true;
|
||||||
|
m_eventLoop.quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
UAVObjectUpdaterHelper::UAVObjectUpdaterHelper(QObject *parent) : AbstractUAVObjectHelper(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void UAVObjectUpdaterHelper::doObjectAndWaitImpl()
|
||||||
|
{
|
||||||
|
m_object->updated();
|
||||||
|
}
|
||||||
|
|
||||||
|
UAVObjectRequestHelper::UAVObjectRequestHelper(QObject *parent) : AbstractUAVObjectHelper(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void UAVObjectRequestHelper::doObjectAndWaitImpl()
|
||||||
|
{
|
||||||
|
m_object->requestUpdate();
|
||||||
|
}
|
78
ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.h
Normal file
78
ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file uavobjecthelper.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||||
|
* @addtogroup [Group]
|
||||||
|
* @{
|
||||||
|
* @addtogroup UAVObjectHelper
|
||||||
|
* @{
|
||||||
|
* @brief [Brief]
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UAVOBJECTHELPER_H
|
||||||
|
#define UAVOBJECTHELPER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QEventLoop>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
|
||||||
|
#include "uavobject.h"
|
||||||
|
|
||||||
|
class UAVOBJECTS_EXPORT AbstractUAVObjectHelper : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit AbstractUAVObjectHelper(QObject *parent = 0);
|
||||||
|
|
||||||
|
enum Result { SUCCESS, FAIL, TIMEOUT };
|
||||||
|
Result doObjectAndWait(UAVObject *object, int timeout);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void doObjectAndWaitImpl() = 0;
|
||||||
|
UAVObject *m_object;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void transactionCompleted(UAVObject *object, bool success);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMutex m_mutex;
|
||||||
|
QEventLoop m_eventLoop;
|
||||||
|
bool m_transactionResult;
|
||||||
|
bool m_transactionCompleted;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UAVOBJECTS_EXPORT UAVObjectUpdaterHelper : public AbstractUAVObjectHelper {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit UAVObjectUpdaterHelper(QObject *parent = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void doObjectAndWaitImpl();
|
||||||
|
};
|
||||||
|
|
||||||
|
class UAVOBJECTS_EXPORT UAVObjectRequestHelper : public AbstractUAVObjectHelper {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit UAVObjectRequestHelper(QObject *parent = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void doObjectAndWaitImpl();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UAVOBJECTHELPER_H
|
@ -11,14 +11,16 @@ HEADERS += uavobjects_global.h \
|
|||||||
uavdataobject.h \
|
uavdataobject.h \
|
||||||
uavobjectfield.h \
|
uavobjectfield.h \
|
||||||
uavobjectsinit.h \
|
uavobjectsinit.h \
|
||||||
uavobjectsplugin.h
|
uavobjectsplugin.h \
|
||||||
|
uavobjecthelper.h
|
||||||
|
|
||||||
SOURCES += uavobject.cpp \
|
SOURCES += uavobject.cpp \
|
||||||
uavmetaobject.cpp \
|
uavmetaobject.cpp \
|
||||||
uavobjectmanager.cpp \
|
uavobjectmanager.cpp \
|
||||||
uavdataobject.cpp \
|
uavdataobject.cpp \
|
||||||
uavobjectfield.cpp \
|
uavobjectfield.cpp \
|
||||||
uavobjectsplugin.cpp
|
uavobjectsplugin.cpp \
|
||||||
|
uavobjecthelper.cpp
|
||||||
|
|
||||||
OTHER_FILES += UAVObjects.pluginspec
|
OTHER_FILES += UAVObjects.pluginspec
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user