mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-03-15 07:29:15 +01:00
Merge branch 'next' into corvuscorax/OP-1022_AH_improvements_amorale
This commit is contained in:
commit
1b68f9fd04
@ -2491,6 +2491,17 @@
|
||||
</data>
|
||||
</default>
|
||||
</SystemHealthGadget>
|
||||
<TelemetryMonitorGadget>
|
||||
<default>
|
||||
<configInfo>
|
||||
<locked>true</locked>
|
||||
<version>0.0.0</version>
|
||||
</configInfo>
|
||||
<data>
|
||||
<diagram>%%DATAPATH%%diagrams/default/system-health.svg</diagram>
|
||||
</data>
|
||||
</default>
|
||||
</TelemetryMonitorGadget>
|
||||
<UAVObjectBrowser>
|
||||
<default>
|
||||
<configInfo>
|
||||
|
@ -4,12 +4,14 @@
|
||||
|
||||
LogFile::LogFile(QObject *parent) :
|
||||
QIODevice(parent),
|
||||
lastTimeStamp(0),
|
||||
lastPlayed(0),
|
||||
timeOffset(0),
|
||||
playbackSpeed(1.0)
|
||||
m_lastTimeStamp(0),
|
||||
m_lastPlayed(0),
|
||||
m_timeOffset(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)
|
||||
{
|
||||
// start a timer for playback
|
||||
myTime.restart();
|
||||
if (file.isOpen()) {
|
||||
m_myTime.restart();
|
||||
if (m_file.isOpen()) {
|
||||
// We end up here when doing a replay, because the connection
|
||||
// manager will also try to open the QIODevice, even though we just
|
||||
// opened it after selecting the file, which happens before the
|
||||
@ -29,8 +31,8 @@ bool LogFile::open(OpenMode mode)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (file.open(mode) == false) {
|
||||
qDebug() << "Unable to open " << file.fileName() << " for logging";
|
||||
if (m_file.open(mode) == false) {
|
||||
qDebug() << "Unable to open " << m_file.fileName() << " for logging";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -49,25 +51,27 @@ void LogFile::close()
|
||||
{
|
||||
emit aboutToClose();
|
||||
|
||||
if (timer.isActive()) {
|
||||
timer.stop();
|
||||
if (m_timer.isActive()) {
|
||||
m_timer.stop();
|
||||
}
|
||||
file.close();
|
||||
m_file.close();
|
||||
QIODevice::close();
|
||||
}
|
||||
|
||||
qint64 LogFile::writeData(const char *data, qint64 dataSize)
|
||||
{
|
||||
if (!file.isWritable()) {
|
||||
if (!m_file.isWritable()) {
|
||||
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));
|
||||
file.write((char *)&dataSize, sizeof(dataSize));
|
||||
m_file.write((char *)&timeStamp, sizeof(timeStamp));
|
||||
m_file.write((char *)&dataSize, sizeof(dataSize));
|
||||
|
||||
qint64 written = file.write(data, dataSize);
|
||||
qint64 written = m_file.write(data, dataSize);
|
||||
if (written != -1) {
|
||||
emit bytesWritten(written);
|
||||
}
|
||||
@ -77,36 +81,36 @@ qint64 LogFile::writeData(const char *data, qint64 dataSize)
|
||||
|
||||
qint64 LogFile::readData(char *data, qint64 maxSize)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
qint64 toRead = qMin(maxSize, (qint64)dataBuffer.size());
|
||||
QMutexLocker locker(&m_mutex);
|
||||
qint64 toRead = qMin(maxSize, (qint64)m_dataBuffer.size());
|
||||
|
||||
memcpy(data, dataBuffer.data(), toRead);
|
||||
dataBuffer.remove(0, toRead);
|
||||
memcpy(data, m_dataBuffer.data(), toRead);
|
||||
m_dataBuffer.remove(0, toRead);
|
||||
return toRead;
|
||||
}
|
||||
|
||||
qint64 LogFile::bytesAvailable() const
|
||||
{
|
||||
return dataBuffer.size();
|
||||
return m_dataBuffer.size();
|
||||
}
|
||||
|
||||
void LogFile::timerFired()
|
||||
{
|
||||
qint64 dataSize;
|
||||
|
||||
if (file.bytesAvailable() > 4) {
|
||||
if (m_file.bytesAvailable() > 4) {
|
||||
int time;
|
||||
time = myTime.elapsed();
|
||||
time = m_myTime.elapsed();
|
||||
|
||||
// TODO: going back in time will be a problem
|
||||
while ((lastPlayed + ((time - timeOffset) * playbackSpeed) > lastTimeStamp)) {
|
||||
lastPlayed += ((time - timeOffset) * playbackSpeed);
|
||||
if (file.bytesAvailable() < sizeof(dataSize)) {
|
||||
while ((m_lastPlayed + ((time - m_timeOffset) * m_playbackSpeed) > m_lastTimeStamp)) {
|
||||
m_lastPlayed += ((time - m_timeOffset) * m_playbackSpeed);
|
||||
if (m_file.bytesAvailable() < sizeof(dataSize)) {
|
||||
stopReplay();
|
||||
return;
|
||||
}
|
||||
|
||||
file.read((char *)&dataSize, sizeof(dataSize));
|
||||
m_file.read((char *)&dataSize, sizeof(dataSize));
|
||||
|
||||
if (dataSize < 1 || dataSize > (1024 * 1024)) {
|
||||
qDebug() << "Error: Logfile corrupted! Unlikely packet size: " << dataSize << "\n";
|
||||
@ -114,34 +118,34 @@ void LogFile::timerFired()
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.bytesAvailable() < dataSize) {
|
||||
if (m_file.bytesAvailable() < dataSize) {
|
||||
stopReplay();
|
||||
return;
|
||||
}
|
||||
|
||||
mutex.lock();
|
||||
dataBuffer.append(file.read(dataSize));
|
||||
mutex.unlock();
|
||||
m_mutex.lock();
|
||||
m_dataBuffer.append(m_file.read(dataSize));
|
||||
m_mutex.unlock();
|
||||
|
||||
emit readyRead();
|
||||
|
||||
if (file.bytesAvailable() < sizeof(lastTimeStamp)) {
|
||||
if (m_file.bytesAvailable() < sizeof(m_lastTimeStamp)) {
|
||||
stopReplay();
|
||||
return;
|
||||
}
|
||||
|
||||
int save = lastTimeStamp;
|
||||
file.read((char *)&lastTimeStamp, sizeof(lastTimeStamp));
|
||||
int save = m_lastTimeStamp;
|
||||
m_file.read((char *)&m_lastTimeStamp, sizeof(m_lastTimeStamp));
|
||||
// some validity checks
|
||||
if (lastTimeStamp < save // logfile goes back in time
|
||||
|| (lastTimeStamp - save) > (60 * 60 * 1000)) { // gap of more than 60 minutes)
|
||||
qDebug() << "Error: Logfile corrupted! Unlikely timestamp " << lastTimeStamp << " after " << save << "\n";
|
||||
if (m_lastTimeStamp < save // logfile goes back in time
|
||||
|| (m_lastTimeStamp - save) > (60 * 60 * 1000)) { // gap of more than 60 minutes)
|
||||
qDebug() << "Error: Logfile corrupted! Unlikely timestamp " << m_lastTimeStamp << " after " << save << "\n";
|
||||
stopReplay();
|
||||
return;
|
||||
}
|
||||
|
||||
timeOffset = time;
|
||||
time = myTime.elapsed();
|
||||
m_timeOffset = time;
|
||||
time = m_myTime.elapsed();
|
||||
}
|
||||
} else {
|
||||
stopReplay();
|
||||
@ -150,13 +154,13 @@ void LogFile::timerFired()
|
||||
|
||||
bool LogFile::startReplay()
|
||||
{
|
||||
dataBuffer.clear();
|
||||
myTime.restart();
|
||||
timeOffset = 0;
|
||||
lastPlayed = 0;
|
||||
file.read((char *)&lastTimeStamp, sizeof(lastTimeStamp));
|
||||
timer.setInterval(10);
|
||||
timer.start();
|
||||
m_dataBuffer.clear();
|
||||
m_myTime.restart();
|
||||
m_timeOffset = 0;
|
||||
m_lastPlayed = 0;
|
||||
m_file.read((char *)&m_lastTimeStamp, sizeof(m_lastTimeStamp));
|
||||
m_timer.setInterval(10);
|
||||
m_timer.start();
|
||||
emit replayStarted();
|
||||
return true;
|
||||
}
|
||||
@ -170,11 +174,11 @@ bool LogFile::stopReplay()
|
||||
|
||||
void LogFile::pauseReplay()
|
||||
{
|
||||
timer.stop();
|
||||
m_timer.stop();
|
||||
}
|
||||
|
||||
void LogFile::resumeReplay()
|
||||
{
|
||||
timeOffset = myTime.elapsed();
|
||||
timer.start();
|
||||
m_timeOffset = m_myTime.elapsed();
|
||||
m_timer.start();
|
||||
}
|
@ -7,22 +7,22 @@
|
||||
#include <QMutexLocker>
|
||||
#include <QDebug>
|
||||
#include <QBuffer>
|
||||
#include "uavobjectmanager.h"
|
||||
#include <math.h>
|
||||
#include <QFile>
|
||||
#include "utils_global.h"
|
||||
|
||||
class LogFile : public QIODevice {
|
||||
class QTCREATOR_UTILS_EXPORT LogFile : public QIODevice {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LogFile(QObject *parent = 0);
|
||||
qint64 bytesAvailable() const;
|
||||
qint64 bytesToWrite()
|
||||
{
|
||||
return file.bytesToWrite();
|
||||
return m_file.bytesToWrite();
|
||||
};
|
||||
bool open(OpenMode mode);
|
||||
void setFileName(QString name)
|
||||
{
|
||||
file.setFileName(name);
|
||||
m_file.setFileName(name);
|
||||
};
|
||||
void close();
|
||||
qint64 writeData(const char *data, qint64 dataSize);
|
||||
@ -30,12 +30,21 @@ public:
|
||||
|
||||
bool startReplay();
|
||||
bool stopReplay();
|
||||
void useProvidedTimeStamp(bool useProvidedTimeStamp)
|
||||
{
|
||||
m_useProvidedTimeStamp = useProvidedTimeStamp;
|
||||
}
|
||||
|
||||
void setNextTimeStamp(quint32 nextTimestamp)
|
||||
{
|
||||
m_nextTimeStamp = nextTimestamp;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void setReplaySpeed(double val)
|
||||
{
|
||||
playbackSpeed = val;
|
||||
qDebug() << "Playback speed is now" << playbackSpeed;
|
||||
m_playbackSpeed = val;
|
||||
qDebug() << "Playback speed is now" << m_playbackSpeed;
|
||||
};
|
||||
void pauseReplay();
|
||||
void resumeReplay();
|
||||
@ -49,17 +58,21 @@ signals:
|
||||
void replayFinished();
|
||||
|
||||
protected:
|
||||
QByteArray dataBuffer;
|
||||
QTimer timer;
|
||||
QTime myTime;
|
||||
QFile file;
|
||||
qint32 lastTimeStamp;
|
||||
qint32 lastPlayed;
|
||||
QMutex mutex;
|
||||
QByteArray m_dataBuffer;
|
||||
QTimer m_timer;
|
||||
QTime m_myTime;
|
||||
QFile m_file;
|
||||
qint32 m_lastTimeStamp;
|
||||
qint32 m_lastPlayed;
|
||||
QMutex m_mutex;
|
||||
|
||||
|
||||
int timeOffset;
|
||||
double playbackSpeed;
|
||||
int m_timeOffset;
|
||||
double m_playbackSpeed;
|
||||
|
||||
private:
|
||||
quint32 m_nextTimeStamp;
|
||||
bool m_useProvidedTimeStamp;
|
||||
};
|
||||
|
||||
#endif // LOGFILE_H
|
@ -54,7 +54,8 @@ SOURCES += reloadpromptutils.cpp \
|
||||
mytabwidget.cpp \
|
||||
cachedsvgitem.cpp \
|
||||
svgimageprovider.cpp \
|
||||
hostosinfo.cpp
|
||||
hostosinfo.cpp \
|
||||
logfile.cpp
|
||||
|
||||
SOURCES += xmlconfig.cpp
|
||||
|
||||
@ -111,7 +112,8 @@ HEADERS += utils_global.h \
|
||||
mytabwidget.h \
|
||||
cachedsvgitem.h \
|
||||
svgimageprovider.h \
|
||||
hostosinfo.h
|
||||
hostosinfo.h \
|
||||
logfile.h
|
||||
|
||||
|
||||
HEADERS += xmlconfig.h
|
||||
|
@ -48,9 +48,6 @@ ConnectionManager::ConnectionManager(Internal::MainWindow *mainWindow) :
|
||||
polling(true),
|
||||
m_mainWindow(mainWindow)
|
||||
{
|
||||
// monitor widget
|
||||
m_monitorWidget = new TelemetryMonitorWidget(this);
|
||||
|
||||
// device list
|
||||
m_availableDevList = new QComboBox;
|
||||
m_availableDevList->setMinimumWidth(120);
|
||||
@ -64,15 +61,14 @@ ConnectionManager::ConnectionManager(Internal::MainWindow *mainWindow) :
|
||||
// put everything together
|
||||
QHBoxLayout *layout = new QHBoxLayout;
|
||||
layout->setSpacing(5);
|
||||
layout->setContentsMargins(5, 2, 5, 2);
|
||||
// cheat a bit with the margin to "nicely" center things vertically
|
||||
layout->setContentsMargins(5, 0, 5, 4);
|
||||
setLayout(layout);
|
||||
|
||||
layout->addWidget(m_monitorWidget, 0, Qt::AlignVCenter);
|
||||
layout->addWidget(new QLabel(tr("Connections:")), 0, Qt::AlignVCenter);
|
||||
layout->addWidget(m_availableDevList, 0, Qt::AlignVCenter);
|
||||
layout->addWidget(m_connectBtn, 0, Qt::AlignVCenter);
|
||||
|
||||
setLayout(layout);
|
||||
|
||||
QObject::connect(m_connectBtn, SIGNAL(clicked()), this, SLOT(onConnectClicked()));
|
||||
QObject::connect(m_availableDevList, SIGNAL(currentIndexChanged(int)), this, SLOT(onDeviceSelectionChanged(int)));
|
||||
|
||||
@ -87,9 +83,6 @@ ConnectionManager::~ConnectionManager()
|
||||
{
|
||||
disconnectDevice();
|
||||
suspendPolling();
|
||||
if (m_monitorWidget) {
|
||||
delete m_monitorWidget;
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionManager::init()
|
||||
@ -100,6 +93,15 @@ void ConnectionManager::init()
|
||||
QObject::connect(ExtensionSystem::PluginManager::instance(), SIGNAL(aboutToRemoveObject(QObject *)), this, SLOT(aboutToRemoveObject(QObject *)));
|
||||
}
|
||||
|
||||
|
||||
// TODO needs documentation?
|
||||
void ConnectionManager::addWidget(QWidget *widget)
|
||||
{
|
||||
QHBoxLayout *l = (QHBoxLayout *)layout();
|
||||
|
||||
l->insertWidget(0, widget, 0, Qt::AlignVCenter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called when the user clicks the "Connect" button
|
||||
*/
|
||||
@ -133,11 +135,9 @@ bool ConnectionManager::connectDevice(DevListItem device)
|
||||
|
||||
// signal interested plugins that we connected to the device
|
||||
emit deviceConnected(io_dev);
|
||||
m_connectBtn->setText("Disconnect");
|
||||
m_availableDevList->setEnabled(false);
|
||||
|
||||
// tell the monitorwidget we're conneced
|
||||
m_monitorWidget->connect();
|
||||
m_connectBtn->setText(tr("Disconnect"));
|
||||
m_availableDevList->setEnabled(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -148,9 +148,6 @@ bool ConnectionManager::connectDevice(DevListItem device)
|
||||
*/
|
||||
bool ConnectionManager::disconnectDevice()
|
||||
{
|
||||
// tell the monitor widget we're disconnected
|
||||
m_monitorWidget->disconnect();
|
||||
|
||||
if (!m_ioDev) {
|
||||
// apparently we are already disconnected: this can
|
||||
// happen if a plugin tries to force a disconnect whereas
|
||||
@ -182,8 +179,10 @@ bool ConnectionManager::disconnectDevice()
|
||||
m_connectionDevice.connection = NULL;
|
||||
m_ioDev = NULL;
|
||||
|
||||
// signal interested plugins that we disconnected from the device
|
||||
emit deviceDisconnected();
|
||||
m_connectBtn->setText("Connect");
|
||||
|
||||
m_connectBtn->setText(tr("Connect"));
|
||||
m_availableDevList->setEnabled(true);
|
||||
|
||||
return true;
|
||||
@ -278,9 +277,6 @@ void ConnectionManager::telemetryConnected()
|
||||
if (reconnectCheck->isActive()) {
|
||||
reconnectCheck->stop();
|
||||
}
|
||||
|
||||
// tell the monitor we're connected
|
||||
m_monitorWidget->connect();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -297,17 +293,6 @@ void ConnectionManager::telemetryDisconnected()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tell the monitor we're disconnected
|
||||
m_monitorWidget->disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Slot called when the telemetry rates are updated
|
||||
*/
|
||||
void ConnectionManager::telemetryUpdated(double txRate, double rxRate)
|
||||
{
|
||||
m_monitorWidget->updateTelemetry(txRate, rxRate);
|
||||
}
|
||||
|
||||
void ConnectionManager::reconnectSlot()
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "generalsettings.h"
|
||||
#include "telemetrymonitorwidget.h"
|
||||
#include <coreplugin/iconnection.h>
|
||||
#include <QWidget>
|
||||
#include <QtCore/QVector>
|
||||
@ -104,6 +103,8 @@ public:
|
||||
return m_ioDev != 0;
|
||||
}
|
||||
|
||||
void addWidget(QWidget *widget);
|
||||
|
||||
bool connectDevice(DevListItem device);
|
||||
bool disconnectDevice();
|
||||
void suspendPolling();
|
||||
@ -123,7 +124,6 @@ signals:
|
||||
public slots:
|
||||
void telemetryConnected();
|
||||
void telemetryDisconnected();
|
||||
void telemetryUpdated(double txRate, double rxRate);
|
||||
|
||||
private slots:
|
||||
void objectAdded(QObject *obj);
|
||||
@ -144,9 +144,6 @@ protected:
|
||||
QLinkedList<DevListItem> m_devList;
|
||||
QList<IConnection *> m_connectionsList;
|
||||
|
||||
// tx/rx telemetry monitor
|
||||
TelemetryMonitorWidget *m_monitorWidget;
|
||||
|
||||
// currently connected connection plugin
|
||||
DevListItem m_connectionDevice;
|
||||
|
||||
|
@ -60,7 +60,6 @@
|
||||
<file>images/cog.png</file>
|
||||
<file>images/helpicon.svg</file>
|
||||
<file>images/cpu.png</file>
|
||||
<file>images/tx-rx.svg</file>
|
||||
<file>qml/images/tab.png</file>
|
||||
<file>qml/AboutDialog.qml</file>
|
||||
<file alias="qml/AuthorsModel.qml">../../../../../build/openpilotgcs-synthetics/AuthorsModel.qml</file>
|
||||
|
@ -70,8 +70,7 @@ SOURCES += mainwindow.cpp \
|
||||
uavgadgetdecorator.cpp \
|
||||
workspacesettings.cpp \
|
||||
uavconfiginfo.cpp \
|
||||
telemetrymonitorwidget.cpp \
|
||||
aboutdialog.cpp
|
||||
aboutdialog.cpp \
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
tabpositionindicator.h \
|
||||
@ -130,8 +129,8 @@ HEADERS += mainwindow.h \
|
||||
uavgadgetdecorator.h \
|
||||
workspacesettings.h \
|
||||
uavconfiginfo.h \
|
||||
authorsdialog.h \
|
||||
iconfigurableplugin.h \
|
||||
telemetrymonitorwidget.h \
|
||||
aboutdialog.h
|
||||
|
||||
FORMS += dialogs/settingsdialog.ui \
|
||||
|
@ -1,399 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="620.10828"
|
||||
height="82.577499"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="tx-rx.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.58"
|
||||
inkscape:cx="89.172147"
|
||||
inkscape:cy="14.870213"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="txrxBackground"
|
||||
showgrid="false"
|
||||
showguides="false"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="686"
|
||||
inkscape:window-x="200"
|
||||
inkscape:window-y="200"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
borderlayer="false"
|
||||
inkscape:showpageshadow="false"
|
||||
showborder="true">
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="5.047377,-45.228607"
|
||||
id="guide3775" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="184.31566,5.990903"
|
||||
id="guide3912" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="bg"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-154.70873,-502.60486)"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="g3963">
|
||||
<g
|
||||
id="txrxBackground"
|
||||
inkscape:label="#g3983">
|
||||
<rect
|
||||
style="fill:#333333;fill-rule:evenodd;stroke:#646464;stroke-width:2.57372737;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="rect2985"
|
||||
width="617.53455"
|
||||
height="80.003769"
|
||||
x="155.99559"
|
||||
y="503.89172"
|
||||
ry="12.840112" />
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke:none"
|
||||
id="rect3755-8"
|
||||
width="53.658535"
|
||||
height="25.938581"
|
||||
x="222.97562"
|
||||
y="512.58765"
|
||||
ry="12.969291" />
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke:none"
|
||||
id="rect3755-1-2"
|
||||
width="53.658535"
|
||||
height="25.169617"
|
||||
x="222.09756"
|
||||
y="548.42963"
|
||||
ry="12.584808" />
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke:none"
|
||||
id="rect3755-7-4"
|
||||
width="53.658535"
|
||||
height="25.938581"
|
||||
x="282.97562"
|
||||
y="512.58765"
|
||||
ry="12.969291" />
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke:none"
|
||||
id="rect3755-1-4-5"
|
||||
width="53.658535"
|
||||
height="25.169617"
|
||||
x="282.09756"
|
||||
y="548.42963"
|
||||
ry="12.584808" />
|
||||
<rect
|
||||
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3755-5"
|
||||
width="53.658535"
|
||||
height="25.938581"
|
||||
x="342.78049"
|
||||
y="512.58765"
|
||||
ry="12.969291" />
|
||||
<rect
|
||||
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3755-1-1"
|
||||
width="53.658535"
|
||||
height="25.169617"
|
||||
x="341.90244"
|
||||
y="548.42963"
|
||||
ry="12.584808" />
|
||||
<rect
|
||||
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3755-7-7"
|
||||
width="53.658535"
|
||||
height="25.938581"
|
||||
x="402.78049"
|
||||
y="512.58765"
|
||||
ry="12.969291" />
|
||||
<rect
|
||||
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3755-1-4-1"
|
||||
width="53.658535"
|
||||
height="25.169617"
|
||||
x="401.90244"
|
||||
y="548.42963"
|
||||
ry="12.584808" />
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke:none"
|
||||
id="rect3755-8-1"
|
||||
width="53.658535"
|
||||
height="25.938581"
|
||||
x="462.78049"
|
||||
y="512.58765"
|
||||
ry="12.969291" />
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke:none"
|
||||
id="rect3755-1-2-5"
|
||||
width="53.658535"
|
||||
height="25.169617"
|
||||
x="461.90244"
|
||||
y="548.42963"
|
||||
ry="12.584808" />
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke:none"
|
||||
id="rect3755-7-4-2"
|
||||
width="53.658535"
|
||||
height="25.938581"
|
||||
x="522.78052"
|
||||
y="512.58765"
|
||||
ry="12.969291" />
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke:none"
|
||||
id="rect3755-1-4-5-7"
|
||||
width="53.658535"
|
||||
height="25.169617"
|
||||
x="521.90247"
|
||||
y="548.42963"
|
||||
ry="12.584808" />
|
||||
<rect
|
||||
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3755-7-7-4"
|
||||
width="53.658535"
|
||||
height="25.938581"
|
||||
x="581.80487"
|
||||
y="513.30939"
|
||||
ry="12.969291" />
|
||||
<rect
|
||||
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3755-1-4-1-2"
|
||||
width="53.658535"
|
||||
height="25.169617"
|
||||
x="580.92682"
|
||||
y="549.13"
|
||||
ry="12.584808" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
|
||||
x="164.82353"
|
||||
y="538.24451"
|
||||
id="text3093"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3038"
|
||||
x="164.82353"
|
||||
y="538.24451">Tx</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3040"
|
||||
y="538.24451"
|
||||
x="164.82353"
|
||||
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
|
||||
xml:space="preserve"><tspan
|
||||
y="538.24451"
|
||||
x="164.82353"
|
||||
id="tspan3042"
|
||||
sodipodi:role="line">Tx</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
|
||||
x="163.79311"
|
||||
y="572.0863"
|
||||
id="text3044"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3046"
|
||||
x="163.79311"
|
||||
y="572.0863">Rx</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="tx"
|
||||
style="display:inline"
|
||||
transform="translate(-154.70873,-215.24268)">
|
||||
<rect
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
id="tx0"
|
||||
width="53.658535"
|
||||
height="26.385658"
|
||||
x="222.90944"
|
||||
y="225.09811"
|
||||
ry="13.192829"
|
||||
inkscape:label="#rect3755-1-2-9" />
|
||||
<rect
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
id="tx1"
|
||||
width="53.658535"
|
||||
height="26.385658"
|
||||
x="282.90942"
|
||||
y="225.09811"
|
||||
ry="13.192829"
|
||||
inkscape:label="#rect3755-1-4-5-3" />
|
||||
<rect
|
||||
style="color:#000000;fill:#00c200;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="tx2"
|
||||
width="53.658535"
|
||||
height="26.385658"
|
||||
x="342.71429"
|
||||
y="225.09811"
|
||||
ry="13.192829"
|
||||
inkscape:label="#rect3755-1-1-19" />
|
||||
<rect
|
||||
style="color:#000000;fill:#00c200;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="tx3"
|
||||
width="53.658535"
|
||||
height="26.385658"
|
||||
x="402.71429"
|
||||
y="225.09811"
|
||||
ry="13.192829"
|
||||
inkscape:label="#rect3755-1-4-1-8" />
|
||||
<rect
|
||||
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
|
||||
id="tx4"
|
||||
width="53.658535"
|
||||
height="26.385658"
|
||||
x="462.71429"
|
||||
y="225.09811"
|
||||
ry="13.192829"
|
||||
inkscape:label="#rect3755-1-2-5-6" />
|
||||
<rect
|
||||
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
|
||||
id="tx5"
|
||||
width="53.658535"
|
||||
height="26.385658"
|
||||
x="522.71436"
|
||||
y="225.09811"
|
||||
ry="13.192829"
|
||||
inkscape:label="#rect3755-1-4-5-7-5" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="tx6"
|
||||
width="53.658535"
|
||||
height="26.385658"
|
||||
x="581.73871"
|
||||
y="225.83234"
|
||||
ry="13.192829"
|
||||
inkscape:label="#rect3755-1-4-1-2-2" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
x="647.0033"
|
||||
y="245.35291"
|
||||
id="txSpeed"
|
||||
sodipodi:linespacing="125%"
|
||||
inkscape:label="#text3167"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3169"
|
||||
x="647.0033"
|
||||
y="245.35291">0 b/s</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="rx"
|
||||
style="display:inline"
|
||||
transform="translate(-154.70873,-215.24268)">
|
||||
<rect
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rx0"
|
||||
width="53.658535"
|
||||
height="24.722538"
|
||||
x="222.35068"
|
||||
y="261.28473"
|
||||
ry="12.361269"
|
||||
inkscape:label="#rect3755-8-12" />
|
||||
<rect
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rx1"
|
||||
width="53.658535"
|
||||
height="24.722538"
|
||||
x="282.35068"
|
||||
y="261.28473"
|
||||
ry="12.361269"
|
||||
inkscape:label="#rect3755-7-4-3" />
|
||||
<rect
|
||||
style="color:#000000;fill:#00c200;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rx2"
|
||||
width="53.658535"
|
||||
height="24.722538"
|
||||
x="342.15555"
|
||||
y="261.28473"
|
||||
ry="12.361269"
|
||||
inkscape:label="#rect3755-5-3" />
|
||||
<rect
|
||||
style="color:#000000;fill:#00c200;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rx3"
|
||||
width="53.658535"
|
||||
height="24.722538"
|
||||
x="402.15555"
|
||||
y="261.28473"
|
||||
ry="12.361269"
|
||||
inkscape:label="#rect3755-7-7-41" />
|
||||
<rect
|
||||
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rx4"
|
||||
width="53.658535"
|
||||
height="24.722538"
|
||||
x="462.15555"
|
||||
y="261.28473"
|
||||
ry="12.361269"
|
||||
inkscape:label="#rect3755-8-1-1" />
|
||||
<rect
|
||||
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rx5"
|
||||
width="53.658535"
|
||||
height="24.722538"
|
||||
x="522.15552"
|
||||
y="261.28473"
|
||||
ry="12.361269"
|
||||
inkscape:label="#rect3755-7-4-2-3" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rx6"
|
||||
width="53.658535"
|
||||
height="24.722538"
|
||||
x="581.17987"
|
||||
y="261.97269"
|
||||
ry="12.361269"
|
||||
inkscape:label="#rect3755-7-7-4-7" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
x="646.22638"
|
||||
y="281.98114"
|
||||
id="rxSpeed"
|
||||
sodipodi:linespacing="125%"
|
||||
inkscape:label="#text3959"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3961"
|
||||
x="646.22638"
|
||||
y="281.98114">0 b/s</tspan></text>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 14 KiB |
@ -1,176 +0,0 @@
|
||||
#include "telemetrymonitorwidget.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QtGui>
|
||||
#include <QFont>
|
||||
#include <QDebug>
|
||||
|
||||
TelemetryMonitorWidget::TelemetryMonitorWidget(QWidget *parent) : QGraphicsView(parent)
|
||||
{
|
||||
setMinimumSize(180, 25); // From 100->25 to shorten the qwidget.
|
||||
setMaximumSize(180, 25); // as above.
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setAlignment(Qt::AlignCenter);
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
setStyleSheet("background:transparent;");
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
|
||||
QGraphicsScene *scene = new QGraphicsScene(0, 0, 180, 25, this); // keeping the scene in line with the widget for testing.
|
||||
|
||||
QSvgRenderer *renderer = new QSvgRenderer();
|
||||
if (renderer->load(QString(":/core/images/tx-rx.svg"))) {
|
||||
graph = new QGraphicsSvgItem();
|
||||
graph->setSharedRenderer(renderer);
|
||||
graph->setElementId("txrxBackground");
|
||||
|
||||
QString name;
|
||||
QGraphicsSvgItem *pt;
|
||||
|
||||
for (int i = 0; i < NODE_NUMELEM; i++) {
|
||||
name = QString("tx%0").arg(i);
|
||||
if (renderer->elementExists(name)) {
|
||||
pt = new QGraphicsSvgItem();
|
||||
pt->setSharedRenderer(renderer);
|
||||
pt->setElementId(name);
|
||||
pt->setParentItem(graph);
|
||||
txNodes.append(pt);
|
||||
}
|
||||
|
||||
name = QString("rx%0").arg(i);
|
||||
if (renderer->elementExists(name)) {
|
||||
pt = new QGraphicsSvgItem();
|
||||
pt->setSharedRenderer(renderer);
|
||||
pt->setElementId(name);
|
||||
pt->setParentItem(graph);
|
||||
rxNodes.append(pt);
|
||||
}
|
||||
}
|
||||
|
||||
scene->addItem(graph);
|
||||
|
||||
txSpeed = new QGraphicsTextItem();
|
||||
txSpeed->setDefaultTextColor(Qt::white);
|
||||
txSpeed->setFont(QFont("Helvetica", 22, 2));
|
||||
txSpeed->setParentItem(graph);
|
||||
scene->addItem(txSpeed);
|
||||
|
||||
rxSpeed = new QGraphicsTextItem();
|
||||
rxSpeed->setDefaultTextColor(Qt::white);
|
||||
rxSpeed->setFont(QFont("Helvetica", 22, 2));
|
||||
rxSpeed->setParentItem(graph);
|
||||
scene->addItem(rxSpeed);
|
||||
|
||||
scene->setSceneRect(graph->boundingRect());
|
||||
setScene(scene);
|
||||
}
|
||||
|
||||
connected = false;
|
||||
txValue = 0.0;
|
||||
rxValue = 0.0;
|
||||
|
||||
setMin(0.0);
|
||||
setMax(1200.0);
|
||||
|
||||
showTelemetry();
|
||||
}
|
||||
|
||||
TelemetryMonitorWidget::~TelemetryMonitorWidget()
|
||||
{
|
||||
while (!txNodes.isEmpty()) {
|
||||
delete txNodes.takeFirst();
|
||||
}
|
||||
|
||||
while (!rxNodes.isEmpty()) {
|
||||
delete rxNodes.takeFirst();
|
||||
}
|
||||
}
|
||||
|
||||
void TelemetryMonitorWidget::connect()
|
||||
{
|
||||
connected = true;
|
||||
|
||||
// flash the lights
|
||||
updateTelemetry(maxValue, maxValue);
|
||||
}
|
||||
|
||||
void TelemetryMonitorWidget::disconnect()
|
||||
{
|
||||
// flash the lights
|
||||
updateTelemetry(maxValue, maxValue);
|
||||
|
||||
connected = false;
|
||||
updateTelemetry(0.0, 0.0);
|
||||
}
|
||||
/*!
|
||||
\brief Called by the UAVObject which got updated
|
||||
|
||||
Updates the numeric value and/or the icon if the dial wants this.
|
||||
*/
|
||||
void TelemetryMonitorWidget::updateTelemetry(double txRate, double rxRate)
|
||||
{
|
||||
txValue = txRate;
|
||||
rxValue = rxRate;
|
||||
|
||||
showTelemetry();
|
||||
}
|
||||
|
||||
// Converts the value into an percentage:
|
||||
// this enables smooth movement in moveIndex below
|
||||
void TelemetryMonitorWidget::showTelemetry()
|
||||
{
|
||||
txIndex = (txValue - minValue) / (maxValue - minValue) * NODE_NUMELEM;
|
||||
rxIndex = (rxValue - minValue) / (maxValue - minValue) * NODE_NUMELEM;
|
||||
|
||||
if (connected) {
|
||||
this->setToolTip(QString("Tx: %0 bytes/sec\nRx: %1 bytes/sec").arg(txValue).arg(rxValue));
|
||||
} else {
|
||||
this->setToolTip(QString("Disconnected"));
|
||||
}
|
||||
|
||||
int i;
|
||||
int nodeMargin = 8;
|
||||
int leftMargin = 60;
|
||||
QGraphicsItem *node;
|
||||
|
||||
for (i = 0; i < txNodes.count(); i++) {
|
||||
node = txNodes.at(i);
|
||||
node->setPos((i * (node->boundingRect().width() + nodeMargin)) + leftMargin, (node->boundingRect().height() / 2) - 2);
|
||||
node->setVisible(connected && i < txIndex);
|
||||
node->update();
|
||||
}
|
||||
|
||||
for (i = 0; i < rxNodes.count(); i++) {
|
||||
node = rxNodes.at(i);
|
||||
node->setPos((i * (node->boundingRect().width() + nodeMargin)) + leftMargin, (node->boundingRect().height() * 2) - 2);
|
||||
node->setVisible(connected && i < rxIndex);
|
||||
node->update();
|
||||
}
|
||||
|
||||
QRectF rect = graph->boundingRect();
|
||||
txSpeed->setPos(rect.right() - 110, rect.top());
|
||||
txSpeed->setPlainText(QString("%0").arg(txValue));
|
||||
txSpeed->setVisible(connected);
|
||||
|
||||
rxSpeed->setPos(rect.right() - 110, rect.top() + (rect.height() / 2));
|
||||
rxSpeed->setPlainText(QString("%0").arg(rxValue));
|
||||
rxSpeed->setVisible(connected);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void TelemetryMonitorWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
fitInView(graph, Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
void TelemetryMonitorWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
fitInView(graph, Qt::KeepAspectRatio);
|
||||
}
|
@ -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
|
||||
|
||||
TARGET = LoggingGadget
|
||||
DEFINES += LOGGING_LIBRARY
|
||||
QT += svg
|
||||
|
||||
include(../../openpilotgcsplugin.pri)
|
||||
include(logging_dependencies.pri)
|
||||
HEADERS += loggingplugin.h \
|
||||
logfile.h \
|
||||
logginggadgetwidget.h \
|
||||
logginggadget.h \
|
||||
logginggadgetfactory.h
|
||||
# logginggadgetconfiguration.h
|
||||
# logginggadgetoptionspage.h
|
||||
|
||||
SOURCES += loggingplugin.cpp \
|
||||
logfile.cpp \
|
||||
logginggadgetwidget.cpp \
|
||||
logginggadget.cpp \
|
||||
logginggadgetfactory.cpp
|
||||
# logginggadgetconfiguration.cpp \
|
||||
# logginggadgetoptionspage.cpp
|
||||
|
||||
OTHER_FILES += LoggingGadget.pluginspec
|
||||
|
||||
FORMS += logging.ui
|
||||
# logginggadgetwidget.ui \
|
||||
# loggingdialog.ui
|
||||
|
||||
|
@ -323,7 +323,7 @@ bool LoggingPlugin::initialize(const QStringList & args, QString *errMsg)
|
||||
QList<int>() <<
|
||||
Core::Constants::C_GLOBAL_ID);
|
||||
cmd->setDefaultKeySequence(QKeySequence("Ctrl+L"));
|
||||
cmd->action()->setText("Start logging...");
|
||||
cmd->action()->setText(tr("Start logging..."));
|
||||
|
||||
ac->menu()->addSeparator();
|
||||
ac->appendGroup("Logging");
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "uavobjectmanager.h"
|
||||
#include "gcstelemetrystats.h"
|
||||
#include <uavtalk/uavtalk.h>
|
||||
#include <logfile.h>
|
||||
#include <utils/logfile.h>
|
||||
|
||||
#include <QThread>
|
||||
#include <QQueue>
|
||||
|
@ -49,6 +49,12 @@ plugin_uavtalk.subdir = uavtalk
|
||||
plugin_uavtalk.depends = plugin_uavobjects
|
||||
plugin_uavtalk.depends += plugin_coreplugin
|
||||
|
||||
# Telemetry plugin
|
||||
SUBDIRS += plugin_telemetry
|
||||
plugin_telemetry.subdir = telemetry
|
||||
plugin_telemetry.depends += plugin_uavtalk
|
||||
plugin_telemetry.depends += plugin_coreplugin
|
||||
|
||||
# OPMap UAVGadget
|
||||
plugin_opmap.subdir = opmap
|
||||
plugin_opmap.depends = plugin_coreplugin
|
||||
@ -238,3 +244,10 @@ plugin_setupwizard.depends += plugin_config
|
||||
plugin_setupwizard.depends += plugin_uploader
|
||||
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
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
<plugin name="Telemetry" version="1.0.0" compatVersion="1.0.0">
|
||||
<vendor>The OpenPilot Project</vendor>
|
||||
<copyright>(C) 2010 OpenPilot Project</copyright>
|
||||
<license>The GNU Public License (GPL) Version 3</license>
|
||||
<description>UAVTalk telemetry protocol</description>
|
||||
<url>http://www.openpilot.org</url>
|
||||
<dependencyList>
|
||||
<dependency name="Core" version="1.0.0"/>
|
||||
<dependency name="UAVTalk" version="1.0.0"/>
|
||||
</dependencyList>
|
||||
</plugin>
|
397
ground/openpilotgcs/src/plugins/telemetry/images/tx-rx.svg
Normal file
397
ground/openpilotgcs/src/plugins/telemetry/images/tx-rx.svg
Normal file
@ -0,0 +1,397 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="620"
|
||||
height="81"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="tx-rx.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
id="linearGradient3790"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#00ffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3792" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="6.5619509"
|
||||
inkscape:cx="421.10913"
|
||||
inkscape:cy="26.137279"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer2"
|
||||
showgrid="false"
|
||||
showguides="false"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="988"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
borderlayer="false"
|
||||
inkscape:showpageshadow="false"
|
||||
showborder="true">
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="5.0373595,-46.290199"
|
||||
id="guide3775" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="184.30564,4.9293069"
|
||||
id="guide3912" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="background"
|
||||
inkscape:label="background"
|
||||
inkscape:groupmode="layer"
|
||||
style="display:inline">
|
||||
transform="translate(0,0)"
|
||||
<g
|
||||
id="g3045"
|
||||
inkscape:label="#g3045"
|
||||
transform="translate(0,0)">
|
||||
<rect
|
||||
id="bg1"
|
||||
ry="13"
|
||||
y="0"
|
||||
x="0"
|
||||
height="81"
|
||||
width="633"
|
||||
style="fill:#333333;stroke:none" />
|
||||
<text
|
||||
id="txTitle"
|
||||
x="13"
|
||||
y="35"
|
||||
style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
|
||||
xml:space="preserve"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1,1)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3042"
|
||||
x="13"
|
||||
y="35">Tx</tspan></text>
|
||||
<rect
|
||||
id="tx_bg0"
|
||||
ry="13"
|
||||
y="10"
|
||||
x="72"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="tx_bg1"
|
||||
ry="13"
|
||||
y="10"
|
||||
x="132"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="tx_bg2"
|
||||
ry="13"
|
||||
y="10"
|
||||
x="192"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="tx_bg3"
|
||||
ry="13"
|
||||
y="10"
|
||||
x="252"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="tx_bg4"
|
||||
ry="13"
|
||||
y="10"
|
||||
x="312"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="tx_bg5"
|
||||
ry="13"
|
||||
y="10"
|
||||
x="372"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="tx_bg6"
|
||||
ry="13"
|
||||
y="10"
|
||||
x="432"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<text
|
||||
id="rxTitle"
|
||||
x="13"
|
||||
y="71"
|
||||
style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
|
||||
xml:space="preserve"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1,1)"><tspan
|
||||
x="35"
|
||||
y="71"
|
||||
id="tspan3046"
|
||||
sodipodi:role="line">Rx</tspan></text>
|
||||
<rect
|
||||
id="rx_bg0"
|
||||
ry="13"
|
||||
y="46"
|
||||
x="72"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="rx_bg1"
|
||||
ry="13"
|
||||
y="46"
|
||||
x="132"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="rx_bg2"
|
||||
ry="13"
|
||||
y="46"
|
||||
x="192"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="rx_bg3"
|
||||
ry="13"
|
||||
y="46"
|
||||
x="252"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="rx_bg4"
|
||||
ry="13"
|
||||
y="46"
|
||||
x="312"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="rx_bg5"
|
||||
ry="13"
|
||||
y="46"
|
||||
x="372"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
<rect
|
||||
id="rx_bg6"
|
||||
ry="13"
|
||||
y="46"
|
||||
x="432"
|
||||
width="54"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="text"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="text"
|
||||
style="display:inline"
|
||||
transform="translate(0,0)">
|
||||
<rect
|
||||
id="txSpeed"
|
||||
x="499"
|
||||
y="10"
|
||||
width="115"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
inkscape:label="txSpeed" />
|
||||
<rect
|
||||
id="rxSpeed"
|
||||
x="499"
|
||||
y="46"
|
||||
width="115"
|
||||
height="25"
|
||||
style="fill:#4d4d4d;stroke:none" />
|
||||
inkscape:label="rxSpeed" />
|
||||
</g>
|
||||
<g
|
||||
id="tx"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="tx"
|
||||
style="display:inline"
|
||||
transform="translate(0,-100)">
|
||||
<rect
|
||||
id="tx0"
|
||||
width="54"
|
||||
height="25"
|
||||
x="72"
|
||||
y="10"
|
||||
ry="13"
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-1-2-9" />
|
||||
<rect
|
||||
id="tx1"
|
||||
width="54"
|
||||
height="25"
|
||||
x="132"
|
||||
y="10"
|
||||
ry="13"
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-1-4-5-3" />
|
||||
<rect
|
||||
id="tx2"
|
||||
width="54"
|
||||
height="25"
|
||||
x="192"
|
||||
y="10"
|
||||
ry="13"
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-1-1-19" />
|
||||
<rect
|
||||
id="tx3"
|
||||
width="54"
|
||||
height="25"
|
||||
x="252"
|
||||
y="10"
|
||||
ry="13"
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-1-4-1-8" />
|
||||
<rect
|
||||
id="tx4"
|
||||
width="54"
|
||||
height="25"
|
||||
x="312"
|
||||
y="10"
|
||||
ry="13"
|
||||
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-1-2-5-6" />
|
||||
<rect
|
||||
id="tx5"
|
||||
width="54"
|
||||
height="25"
|
||||
x="372"
|
||||
y="10"
|
||||
ry="13"
|
||||
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-1-4-5-7-5" />
|
||||
<rect
|
||||
id="tx6"
|
||||
width="54"
|
||||
height="25"
|
||||
x="432"
|
||||
y="10"
|
||||
ry="13"
|
||||
style="fill:#ff0000;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-1-4-1-2-2" />
|
||||
</g>
|
||||
<g
|
||||
id="rx"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="rx"
|
||||
style="display:inline"
|
||||
transform="translate(0,-100)">
|
||||
<rect
|
||||
id="rx0"
|
||||
width="54"
|
||||
height="25"
|
||||
x="72"
|
||||
y="46"
|
||||
ry="13"
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-8-12" />
|
||||
<rect
|
||||
id="rx1"
|
||||
width="54"
|
||||
height="25"
|
||||
x="132"
|
||||
y="46"
|
||||
ry="13"
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-7-4-3" />
|
||||
<rect
|
||||
id="rx2"
|
||||
width="54"
|
||||
height="25"
|
||||
x="192"
|
||||
y="46"
|
||||
ry="13"
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-5-3" />
|
||||
<rect
|
||||
id="rx3"
|
||||
width="54"
|
||||
height="25"
|
||||
x="252"
|
||||
y="46"
|
||||
ry="13"
|
||||
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-7-7-41" />
|
||||
<rect
|
||||
id="rx4"
|
||||
width="54"
|
||||
height="25"
|
||||
x="312"
|
||||
y="46"
|
||||
ry="13"
|
||||
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-8-1-1" />
|
||||
<rect
|
||||
id="rx5"
|
||||
width="54"
|
||||
height="25"
|
||||
x="372"
|
||||
y="46"
|
||||
ry="13"
|
||||
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-7-4-2-3" />
|
||||
<rect
|
||||
id="rx6"
|
||||
width="54"
|
||||
height="25"
|
||||
x="432"
|
||||
y="46"
|
||||
ry="13"
|
||||
style="fill:#ff0000;fill-opacity:1;stroke:none;display:inline"
|
||||
inkscape:label="#rect3755-7-7-4-7" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.9 KiB |
52
ground/openpilotgcs/src/plugins/telemetry/monitorgadget.cpp
Normal file
52
ground/openpilotgcs/src/plugins/telemetry/monitorgadget.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file monitorgadget.cpp
|
||||
* @author Philippe Renon
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup MonitorPlugin Telemetry Plugin
|
||||
* @{
|
||||
* @brief The Telemetry Monitor gadget
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 "monitorgadget.h"
|
||||
#include "monitorgadgetconfiguration.h"
|
||||
#include "monitorwidget.h"
|
||||
|
||||
MonitorGadget::MonitorGadget(QString classId, MonitorWidget *widget, QWidget *parent) :
|
||||
IUAVGadget(classId, parent), m_widget(widget)
|
||||
{}
|
||||
|
||||
MonitorGadget::~MonitorGadget()
|
||||
{
|
||||
delete m_widget;
|
||||
}
|
||||
|
||||
/*
|
||||
This is called when a configuration is loaded, and updates the plugin's settings.
|
||||
Careful: the plugin is already drawn before the loadConfiguration method is called the
|
||||
first time, so you have to be careful not to assume all the plugin values are initialized
|
||||
the first time you use them
|
||||
*/
|
||||
void MonitorGadget::loadConfiguration(IUAVGadgetConfiguration *config)
|
||||
{
|
||||
// MonitorGadgetConfiguration *m = qobject_cast<MonitorGadgetConfiguration *>(config);
|
||||
|
||||
// m_widget->setSystemFile(m->getSystemFile()); // Triggers widget repaint
|
||||
}
|
58
ground/openpilotgcs/src/plugins/telemetry/monitorgadget.h
Normal file
58
ground/openpilotgcs/src/plugins/telemetry/monitorgadget.h
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file monitorgadget.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup telemetry
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 MONITORGADGET_H
|
||||
#define MONITORGADGET_H
|
||||
|
||||
#include <coreplugin/iuavgadget.h>
|
||||
#include "monitorwidget.h"
|
||||
|
||||
// class IUAVGadget;
|
||||
// class QWidget;
|
||||
// class QString;
|
||||
// class NotifyPluginGadgetWidget;
|
||||
|
||||
using namespace Core;
|
||||
|
||||
class MonitorGadget : public IUAVGadget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MonitorGadget(QString classId, MonitorWidget *widget, QWidget *parent = 0);
|
||||
~MonitorGadget();
|
||||
|
||||
QWidget *widget()
|
||||
{
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
void loadConfiguration(IUAVGadgetConfiguration *config);
|
||||
|
||||
private:
|
||||
MonitorWidget *m_widget;
|
||||
};
|
||||
|
||||
#endif // MONITORGADGET_H
|
@ -0,0 +1,53 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file monitorgadgetconfiguration.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup TelemetryPlugin Telemetry Plugin
|
||||
* @{
|
||||
* @brief A gadget that displays a 3D representation of the UAV
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 "monitorgadgetconfiguration.h"
|
||||
|
||||
MonitorGadgetConfiguration::MonitorGadgetConfiguration(QString classId, QSettings *qSettings, QObject *parent) :
|
||||
IUAVGadgetConfiguration(classId, parent)
|
||||
{
|
||||
// if a saved configuration exists load it
|
||||
if (qSettings != 0) {}
|
||||
}
|
||||
|
||||
IUAVGadgetConfiguration *MonitorGadgetConfiguration::clone()
|
||||
{
|
||||
MonitorGadgetConfiguration *mv = new MonitorGadgetConfiguration(this->classId());
|
||||
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a configuration.
|
||||
*
|
||||
*/
|
||||
void MonitorGadgetConfiguration::saveConfig(QSettings *qSettings) const
|
||||
{
|
||||
// qSettings->setValue("acFilename", Utils::PathUtils().RemoveDataPath(m_acFilename));
|
||||
// qSettings->setValue("bgFilename", Utils::PathUtils().RemoveDataPath(m_bgFilename));
|
||||
// qSettings->setValue("enableVbo", m_enableVbo);
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file monitorgadgetconfiguration.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup TelemetryPlugin Telemetry Plugin
|
||||
* @{
|
||||
* @brief A gadget that displays telemetry connection speed monitoring
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 MONITORGADGETCONFIGURATION_H
|
||||
#define MONITORGADGETCONFIGURATION_H
|
||||
|
||||
#include <coreplugin/iuavgadgetconfiguration.h>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
class MonitorGadgetConfiguration : public IUAVGadgetConfiguration {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MonitorGadgetConfiguration(QString classId, QSettings *qSettings = 0, QObject *parent = 0);
|
||||
|
||||
void saveConfig(QSettings *settings) const;
|
||||
IUAVGadgetConfiguration *clone();
|
||||
};
|
||||
|
||||
#endif // MONITORGADGETCONFIGURATION_H
|
@ -0,0 +1,84 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file monitorgadgetfactory.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup telemetryplugin
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 "monitorgadgetfactory.h"
|
||||
#include "uavtalk/telemetrymanager.h"
|
||||
#include "extensionsystem/pluginmanager.h"
|
||||
#include "monitorgadgetconfiguration.h"
|
||||
#include "monitorgadget.h"
|
||||
#include "monitorgadgetoptionspage.h"
|
||||
|
||||
#include <coreplugin/connectionmanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
MonitorGadgetFactory::MonitorGadgetFactory(QObject *parent) :
|
||||
IUAVGadgetFactory(QString("TelemetryMonitorGadget"), tr("Telemetry Monitor"), parent)
|
||||
{}
|
||||
|
||||
MonitorGadgetFactory::~MonitorGadgetFactory()
|
||||
{}
|
||||
|
||||
Core::IUAVGadget *MonitorGadgetFactory::createGadget(QWidget *parent)
|
||||
{
|
||||
MonitorWidget *widget = createMonitorWidget(parent);
|
||||
|
||||
return new MonitorGadget(QString("TelemetryMonitorGadget"), widget, parent);
|
||||
}
|
||||
|
||||
MonitorWidget *MonitorGadgetFactory::createMonitorWidget(QWidget *parent)
|
||||
{
|
||||
MonitorWidget *widget = new MonitorWidget(parent);
|
||||
|
||||
// connect widget to telemetry manager
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
TelemetryManager *tm = pm->getObject<TelemetryManager>();
|
||||
|
||||
connect(tm, SIGNAL(connected()), widget, SLOT(telemetryConnected()));
|
||||
connect(tm, SIGNAL(disconnected()), widget, SLOT(telemetryDisconnected()));
|
||||
connect(tm, SIGNAL(telemetryUpdated(double, double)), widget, SLOT(telemetryUpdated(double, double)));
|
||||
|
||||
// and connect widget to connection manager (for retro compatibility)
|
||||
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
||||
|
||||
connect(cm, SIGNAL(deviceConnected(QIODevice *)), widget, SLOT(telemetryConnected()));
|
||||
connect(cm, SIGNAL(deviceDisconnected()), widget, SLOT(telemetryDisconnected()));
|
||||
|
||||
if (tm->isConnected()) {
|
||||
widget->telemetryConnected();
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
IUAVGadgetConfiguration *MonitorGadgetFactory::createConfiguration(QSettings *qSettings)
|
||||
{
|
||||
return new MonitorGadgetConfiguration(QString("TelemetryMonitorGadget"), qSettings);
|
||||
}
|
||||
|
||||
IOptionsPage *MonitorGadgetFactory::createOptionsPage(IUAVGadgetConfiguration *config)
|
||||
{
|
||||
return new MonitorGadgetOptionsPage(qobject_cast<MonitorGadgetConfiguration *>(config));
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file monitorgadgetfactory.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup monitorgadget
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 MONITORGADGETFACTORY_H
|
||||
#define MONITORGADGETFACTORY_H
|
||||
|
||||
#include "monitorwidget.h"
|
||||
#include <coreplugin/iuavgadgetfactory.h>
|
||||
|
||||
|
||||
namespace Core {
|
||||
class IUAVGadget;
|
||||
class IUAVGadgetFactory;
|
||||
}
|
||||
|
||||
using namespace Core;
|
||||
|
||||
class MonitorGadgetFactory : public IUAVGadgetFactory {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MonitorGadgetFactory(QObject *parent = 0);
|
||||
~MonitorGadgetFactory();
|
||||
|
||||
Core::IUAVGadget *createGadget(QWidget *parent);
|
||||
IUAVGadgetConfiguration *createConfiguration(QSettings *qSettings);
|
||||
IOptionsPage *createOptionsPage(IUAVGadgetConfiguration *config);
|
||||
|
||||
MonitorWidget *createMonitorWidget(QWidget *parent);
|
||||
};
|
||||
|
||||
#endif // MONITORGADGETFACTORY_H
|
@ -0,0 +1,104 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file monitorgadgetoptionspage.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief Telemetry Gadget options page
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup monitorgadget
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 "monitorgadgetoptionspage.h"
|
||||
#include <coreplugin/icore.h>
|
||||
// #include "ui_telemetrypluginoptionspage.h"
|
||||
#include "extensionsystem/pluginmanager.h"
|
||||
|
||||
MonitorGadgetOptionsPage::MonitorGadgetOptionsPage(MonitorGadgetConfiguration *config, QObject *parent)
|
||||
: IOptionsPage(parent)
|
||||
{}
|
||||
|
||||
MonitorGadgetOptionsPage::~MonitorGadgetOptionsPage()
|
||||
{}
|
||||
|
||||
QWidget *MonitorGadgetOptionsPage::createPage(QWidget * /* parent */)
|
||||
{
|
||||
// _optionsPage.reset(new Ui::TelemetryPluginOptionsPage());
|
||||
//// main widget
|
||||
// QWidget *optionsPageWidget = new QWidget;
|
||||
// _dynamicFieldWidget = NULL;
|
||||
// _dynamicFieldCondition = NULL;
|
||||
// resetFieldType();
|
||||
//// save ref to form, needed for binding dynamic fields in future
|
||||
// _form = optionsPageWidget;
|
||||
//// main layout
|
||||
// _optionsPage->setupUi(optionsPageWidget);
|
||||
//
|
||||
// _optionsPage->SoundDirectoryPathChooser->setExpectedKind(Utils::PathChooser::Directory);
|
||||
// _optionsPage->SoundDirectoryPathChooser->setPromptDialogTitle(tr("Choose sound collection directory"));
|
||||
//
|
||||
// connect(_optionsPage->SoundDirectoryPathChooser, SIGNAL(changed(const QString &)),
|
||||
// this, SLOT(on_clicked_buttonSoundFolder(const QString &)));
|
||||
// connect(_optionsPage->SoundCollectionList, SIGNAL(currentIndexChanged(int)),
|
||||
// this, SLOT(on_changedIndex_soundLanguage(int)));
|
||||
//
|
||||
// connect(this, SIGNAL(updateNotifications(QList<NotificationItem *>)),
|
||||
// _owner, SLOT(updateNotificationList(QList<NotificationItem *>)));
|
||||
//// connect(this, SIGNAL(resetNotification()),owner, SLOT(resetNotification()));
|
||||
//
|
||||
// _privListNotifications = _owner->getListNotifications();
|
||||
//
|
||||
//
|
||||
//// [1]
|
||||
// setSelectedNotification(_owner->getCurrentNotification());
|
||||
// addDynamicFieldLayout();
|
||||
//// [2]
|
||||
// updateConfigView(_selectedNotification);
|
||||
//
|
||||
// initRulesTable();
|
||||
// initButtons();
|
||||
// initPhononPlayer();
|
||||
//
|
||||
// int curr_row = _privListNotifications.indexOf(_selectedNotification);
|
||||
// _telemetryRulesSelection->setCurrentIndex(_telemetryRulesModel->index(curr_row, 0, QModelIndex()),
|
||||
// QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
//
|
||||
// return optionsPageWidget;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void MonitorGadgetOptionsPage::apply()
|
||||
{
|
||||
// getOptionsPageValues(_owner->getCurrentNotification());
|
||||
// _owner->setEnableSound(_optionsPage->chkEnableSound->isChecked());
|
||||
// emit updateNotifications(_privListNotifications);
|
||||
}
|
||||
|
||||
void MonitorGadgetOptionsPage::finish()
|
||||
{
|
||||
// disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)),
|
||||
// this, SLOT(on_changedIndex_UAVField(QString)));
|
||||
//
|
||||
// disconnect(_testSound.data(), SIGNAL(stateChanged(Phonon::State, Phonon::State)),
|
||||
// this, SLOT(on_changed_playButtonText(Phonon::State, Phonon::State)));
|
||||
// if (_testSound) {
|
||||
// _testSound->stop();
|
||||
// _testSound->clear();
|
||||
// }
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file monitorgadgetoptionspage.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief Telemetry Gadget options page header
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup telemetry
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 MONITORGADGETOPTIONSPAGE_H
|
||||
#define MONITORGADGETOPTIONSPAGE_H
|
||||
|
||||
#include "coreplugin/dialogs/ioptionspage.h"
|
||||
#include "uavobjectmanager.h"
|
||||
#include "uavobject.h"
|
||||
|
||||
#include "QString"
|
||||
#include <QDebug>
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
namespace Ui {
|
||||
class MonitorGadgetOptionsPage;
|
||||
};
|
||||
|
||||
class MonitorGadgetConfiguration;
|
||||
|
||||
using namespace Core;
|
||||
|
||||
class MonitorGadgetOptionsPage : public IOptionsPage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MonitorGadgetOptionsPage(MonitorGadgetConfiguration *config, QObject *parent = 0);
|
||||
~MonitorGadgetOptionsPage();
|
||||
|
||||
QWidget *createPage(QWidget *parent);
|
||||
void apply();
|
||||
void finish();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // MONITORGADGETOPTIONSPAGE_H
|
300
ground/openpilotgcs/src/plugins/telemetry/monitorwidget.cpp
Normal file
300
ground/openpilotgcs/src/plugins/telemetry/monitorwidget.cpp
Normal file
@ -0,0 +1,300 @@
|
||||
#include "monitorwidget.h"
|
||||
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
#include <QtGui/QFont>
|
||||
|
||||
namespace {
|
||||
/**
|
||||
* Create an SVG item and connect it to an element of the SVG file previously loaded into the parent item.
|
||||
* This then allows to show, hide, move, scale and rotate the element.
|
||||
* Opacity can also be changed.
|
||||
* Other characteristics (color, ...) of the element cannot be modified.
|
||||
*/
|
||||
// TODO move to some utility class that can be reused by other SVG manipulating code
|
||||
QGraphicsSvgItem *createSvgItem(QGraphicsSvgItem *parent, QString elementId)
|
||||
{
|
||||
QGraphicsSvgItem *item = new QGraphicsSvgItem(parent);
|
||||
|
||||
QSvgRenderer *renderer = parent->renderer();
|
||||
|
||||
// connect item to its corresponding element
|
||||
item->setSharedRenderer(renderer);
|
||||
item->setElementId(elementId);
|
||||
|
||||
// move item to its location
|
||||
QMatrix elementMatrix = renderer->matrixForElement(elementId);
|
||||
QRectF elementRect = elementMatrix.mapRect(renderer->boundsOnElement(elementId));
|
||||
item->setPos(elementRect.x(), elementRect.y());
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a text item based on a svg rectangle.
|
||||
* The rectangle must be in the correct location (hint: use a "text" layer on top of the "background layer")
|
||||
* The font size will be set to match as well as possible the rectangle height but it is not guaranteed.
|
||||
*
|
||||
* It is possible to show the text rectangle to help understand layout issues.
|
||||
*
|
||||
*/
|
||||
// TODO move to some utility class that can be reused by other SVG manipulating code
|
||||
QGraphicsTextItem *createTextItem(QGraphicsSvgItem *parent, QString elementId, QString fontName,
|
||||
bool showRect = false)
|
||||
{
|
||||
if (showRect) {
|
||||
// create and display the text rectangle
|
||||
// needs to be done first otherwise the rectangle will blank out the text.
|
||||
createSvgItem(parent, elementId);
|
||||
}
|
||||
|
||||
QGraphicsTextItem *item = new QGraphicsTextItem();
|
||||
|
||||
QSvgRenderer *renderer = parent->renderer();
|
||||
|
||||
// move new text item to location of rectangle element
|
||||
QMatrix elementMatrix = renderer->matrixForElement(elementId);
|
||||
QRectF elementRect = elementMatrix.mapRect(renderer->boundsOnElement(elementId));
|
||||
|
||||
qreal fontPointSizeF = elementRect.height();
|
||||
|
||||
QTransform matrix;
|
||||
matrix.translate(elementRect.x(), elementRect.y() - (fontPointSizeF / 2.0));
|
||||
|
||||
item->setParentItem(parent);
|
||||
item->setTransform(matrix, false);
|
||||
// to right align or center text we must provide a text width
|
||||
// item->setTextWidth(elementRect.width());
|
||||
|
||||
// create font to match the rectangle height
|
||||
// there is not guaranteed that all fonts will play well...
|
||||
QFont font(fontName);
|
||||
// not sure if PreferMatch helps to get the correct font size (i.e. that fits the text rectangle nicely)
|
||||
font.setStyleStrategy(QFont::PreferMatch);
|
||||
font.setPointSizeF(fontPointSizeF);
|
||||
|
||||
item->setFont(font);
|
||||
|
||||
#ifdef DEBUG_FONT
|
||||
// just in case
|
||||
qDebug() << "Font point size: " << fontPointSizeF;
|
||||
qDebug() << "Font pixel size: " << font.pixelSize();
|
||||
qDebug() << "Font point size: " << font.pointSize();
|
||||
qDebug() << "Font point size F: " << font.pointSizeF();
|
||||
qDebug() << "Font exact match: " << font.exactMatch();
|
||||
|
||||
QFontInfo fontInfo(font);
|
||||
qDebug() << "Font info pixel size: " << fontInfo.pixelSize();
|
||||
qDebug() << "Font info point size: " << fontInfo.pointSize();
|
||||
qDebug() << "Font info point size F: " << fontInfo.pointSizeF();
|
||||
qDebug() << "Font info exact match: " << fontInfo.exactMatch();
|
||||
#endif
|
||||
return item;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
MonitorWidget::MonitorWidget(QWidget *parent) :
|
||||
QGraphicsView(parent), aspectRatioMode(Qt::KeepAspectRatio)
|
||||
{
|
||||
// setMinimumWidth(180);
|
||||
|
||||
QGraphicsScene *scene = new QGraphicsScene();
|
||||
|
||||
setScene(scene);
|
||||
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
|
||||
|
||||
// no scroll bars
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
setBackgroundBrush(QBrush(Utils::StyleHelper::baseColor()));
|
||||
|
||||
setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
|
||||
|
||||
QSvgRenderer *renderer = new QSvgRenderer();
|
||||
|
||||
if (renderer->load(QString(":/telemetry/images/tx-rx.svg"))) {
|
||||
// create graph
|
||||
graph = new QGraphicsSvgItem();
|
||||
graph->setSharedRenderer(renderer);
|
||||
graph->setElementId("background");
|
||||
|
||||
graph->setFlags(QGraphicsItem::ItemClipsChildrenToShape | QGraphicsItem::ItemClipsToShape);
|
||||
|
||||
scene->addItem(graph);
|
||||
|
||||
int i;
|
||||
|
||||
// create tx nodes
|
||||
i = 0;
|
||||
while (true) {
|
||||
QString id = QString("tx%0").arg(i);
|
||||
QString bgId = QString("tx_bg%0").arg(i);
|
||||
if (!renderer->elementExists(id) || !renderer->elementExists(bgId)) {
|
||||
break;
|
||||
}
|
||||
QGraphicsSvgItem *item = createSvgItem(graph, bgId);
|
||||
item->setElementId(id);
|
||||
txNodes.append(item);
|
||||
i++;
|
||||
}
|
||||
|
||||
// create rx nodes
|
||||
i = 0;
|
||||
while (true) {
|
||||
QString id = QString("rx%0").arg(i);
|
||||
QString bgId = QString("rx_bg%0").arg(i);
|
||||
if (!renderer->elementExists(id) || !renderer->elementExists(bgId)) {
|
||||
break;
|
||||
}
|
||||
QGraphicsSvgItem *item = createSvgItem(graph, bgId);
|
||||
item->setElementId(id);
|
||||
rxNodes.append(item);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (renderer->elementExists("txSpeed")) {
|
||||
txSpeed = createTextItem(graph, "txSpeed", "Helvetica");
|
||||
txSpeed->setDefaultTextColor(Qt::white);
|
||||
} else {
|
||||
txSpeed = NULL;
|
||||
}
|
||||
|
||||
if (renderer->elementExists("rxSpeed")) {
|
||||
rxSpeed = createTextItem(graph, "rxSpeed", "Helvetica");
|
||||
rxSpeed->setDefaultTextColor(Qt::white);
|
||||
} else {
|
||||
rxSpeed = NULL;
|
||||
}
|
||||
// scene->setSceneRect(graph->boundingRect());
|
||||
}
|
||||
|
||||
connected = false;
|
||||
|
||||
setMin(0.0);
|
||||
setMax(1200.0);
|
||||
|
||||
telemetryUpdated(0.0, 0.0);
|
||||
}
|
||||
|
||||
MonitorWidget::~MonitorWidget()
|
||||
{
|
||||
while (!txNodes.isEmpty()) {
|
||||
delete txNodes.takeFirst();
|
||||
}
|
||||
while (!rxNodes.isEmpty()) {
|
||||
delete rxNodes.takeFirst();
|
||||
}
|
||||
if (txSpeed) {
|
||||
delete txSpeed;
|
||||
}
|
||||
if (rxSpeed) {
|
||||
delete rxSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Enables/Disables OpenGL
|
||||
*/
|
||||
// void LineardialGadgetWidget::enableOpenGL(bool flag)
|
||||
// {
|
||||
// if (flag) {
|
||||
// setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
|
||||
// } else {
|
||||
// setViewport(new QWidget);
|
||||
// }
|
||||
// }
|
||||
|
||||
void MonitorWidget::telemetryConnected()
|
||||
{
|
||||
qDebug() << "telemetry connected";
|
||||
if (!connected) {
|
||||
// flash the lights
|
||||
setToolTip(tr("Connected"));
|
||||
telemetryUpdated(maxValue, maxValue);
|
||||
connected = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MonitorWidget::telemetryDisconnected()
|
||||
{
|
||||
qDebug() << "telemetry disconnected";
|
||||
if (connected) {
|
||||
connected = false;
|
||||
|
||||
setToolTip(tr("Disconnected"));
|
||||
|
||||
// flash the lights???
|
||||
telemetryUpdated(maxValue, maxValue);
|
||||
|
||||
telemetryUpdated(0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Called by the UAVObject which got updated
|
||||
|
||||
Updates the numeric value and/or the icon if the dial wants this.
|
||||
*/
|
||||
void MonitorWidget::telemetryUpdated(double txRate, double rxRate)
|
||||
{
|
||||
double txIndex = (txRate - minValue) / (maxValue - minValue) * txNodes.count();
|
||||
double rxIndex = (rxRate - minValue) / (maxValue - minValue) * rxNodes.count();
|
||||
|
||||
if (connected) {
|
||||
this->setToolTip(QString("Tx: %0 bytes/s, Rx: %1 bytes/s").arg(txRate).arg(rxRate));
|
||||
}
|
||||
|
||||
for (int i = 0; i < txNodes.count(); i++) {
|
||||
QGraphicsItem *node = txNodes.at(i);
|
||||
bool visible = ( /*connected &&*/ (i < txIndex));
|
||||
if (visible != node->isVisible()) {
|
||||
node->setVisible(visible);
|
||||
node->update();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < rxNodes.count(); i++) {
|
||||
QGraphicsItem *node = rxNodes.at(i);
|
||||
bool visible = ( /*connected &&*/ (i < rxIndex));
|
||||
if (visible != node->isVisible()) {
|
||||
node->setVisible(visible);
|
||||
node->update();
|
||||
}
|
||||
}
|
||||
|
||||
if (txSpeed) {
|
||||
if (connected) {
|
||||
txSpeed->setPlainText(QString("%0").arg(txRate));
|
||||
}
|
||||
txSpeed->setVisible(connected);
|
||||
txSpeed->update();
|
||||
}
|
||||
|
||||
if (rxSpeed) {
|
||||
if (connected) {
|
||||
rxSpeed->setPlainText(QString("%0").arg(rxRate));
|
||||
}
|
||||
rxSpeed->setVisible(connected);
|
||||
rxSpeed->update();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void MonitorWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
fitInView(graph, aspectRatioMode);
|
||||
}
|
||||
|
||||
void MonitorWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
fitInView(graph, aspectRatioMode);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#ifndef TELEMETRYMONITORWIDGET_H
|
||||
#define TELEMETRYMONITORWIDGET_H
|
||||
#ifndef MONITORWIDGET_H
|
||||
#define MONITORWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QObject>
|
||||
@ -8,59 +8,56 @@
|
||||
#include <QtSvg/QGraphicsSvgItem>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
class TelemetryMonitorWidget : public QGraphicsView {
|
||||
class MonitorWidget : public QGraphicsView {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TelemetryMonitorWidget(QWidget *parent = 0);
|
||||
~TelemetryMonitorWidget();
|
||||
explicit MonitorWidget(QWidget *parent = 0);
|
||||
~MonitorWidget();
|
||||
|
||||
void setMin(double min)
|
||||
{
|
||||
minValue = min;
|
||||
}
|
||||
|
||||
double getMin()
|
||||
{
|
||||
return minValue;
|
||||
}
|
||||
|
||||
void setMax(double max)
|
||||
{
|
||||
maxValue = max;
|
||||
}
|
||||
|
||||
double getMax()
|
||||
{
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
// number of tx/rx nodes in the graph
|
||||
static const int NODE_NUMELEM = 7;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void connect();
|
||||
void disconnect();
|
||||
|
||||
void updateTelemetry(double txRate, double rxRate);
|
||||
void showTelemetry();
|
||||
void telemetryConnected();
|
||||
void telemetryDisconnected();
|
||||
void telemetryUpdated(double txRate, double rxRate);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
|
||||
private:
|
||||
bool connected;
|
||||
|
||||
double minValue;
|
||||
double maxValue;
|
||||
|
||||
QGraphicsSvgItem *graph;
|
||||
|
||||
QPointer<QGraphicsTextItem> txSpeed;
|
||||
QPointer<QGraphicsTextItem> rxSpeed;
|
||||
|
||||
QList<QGraphicsSvgItem *> txNodes;
|
||||
QList<QGraphicsSvgItem *> rxNodes;
|
||||
|
||||
bool connected;
|
||||
double txIndex;
|
||||
double txValue;
|
||||
double rxIndex;
|
||||
double rxValue;
|
||||
double minValue;
|
||||
double maxValue;
|
||||
Qt::AspectRatioMode aspectRatioMode;
|
||||
};
|
||||
|
||||
#endif // TELEMETRYMONITORWIDGET_H
|
||||
#endif // MONITORWIDGET_H
|
3
ground/openpilotgcs/src/plugins/telemetry/telemetry.pri
Normal file
3
ground/openpilotgcs/src/plugins/telemetry/telemetry.pri
Normal file
@ -0,0 +1,3 @@
|
||||
include(telemetry_dependencies.pri)
|
||||
|
||||
LIBS *= -l$$qtLibraryName(Telemetry)
|
29
ground/openpilotgcs/src/plugins/telemetry/telemetry.pro
Normal file
29
ground/openpilotgcs/src/plugins/telemetry/telemetry.pro
Normal file
@ -0,0 +1,29 @@
|
||||
TEMPLATE = lib
|
||||
TARGET = Telemetry
|
||||
|
||||
QT += svg
|
||||
|
||||
include(../../openpilotgcsplugin.pri)
|
||||
include(../../plugins/coreplugin/coreplugin.pri)
|
||||
include(telemetry_dependencies.pri)
|
||||
|
||||
HEADERS += telemetry_global.h \
|
||||
telemetryplugin.h \
|
||||
monitorwidget.h \
|
||||
monitorgadgetconfiguration.h \
|
||||
monitorgadget.h \
|
||||
monitorgadgetfactory.h \
|
||||
monitorgadgetoptionspage.h
|
||||
|
||||
SOURCES += telemetryplugin.cpp \
|
||||
monitorwidget.cpp \
|
||||
monitorgadgetconfiguration.cpp \
|
||||
monitorgadget.cpp \
|
||||
monitorgadgetfactory.cpp \
|
||||
monitorgadgetoptionspage.cpp
|
||||
|
||||
DEFINES += TELEMETRY_LIBRARY
|
||||
|
||||
RESOURCES += telemetry.qrc
|
||||
|
||||
OTHER_FILES += Telemetry.pluginspec
|
5
ground/openpilotgcs/src/plugins/telemetry/telemetry.qrc
Normal file
5
ground/openpilotgcs/src/plugins/telemetry/telemetry.qrc
Normal file
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/telemetry">
|
||||
<file>images/tx-rx.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -0,0 +1,3 @@
|
||||
include(../../plugins/uavtalk/uavtalk.pri)
|
||||
include(../../plugins/uavobjects/uavobjects.pri)
|
||||
|
39
ground/openpilotgcs/src/plugins/telemetry/telemetry_global.h
Normal file
39
ground/openpilotgcs/src/plugins/telemetry/telemetry_global.h
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file telemetry_global.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup TelemetryPlugin Telemetry Plugin
|
||||
* @{
|
||||
* @brief The Telemetry plugin
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 TELEMETRY_GLOBAL_H
|
||||
#define TELEMETRY_GLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if defined(TELEMETRY_LIBRARY)
|
||||
# define TELEMETRY_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define TELEMETRY_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#endif // TELEMETRY_GLOBAL_H
|
246
ground/openpilotgcs/src/plugins/telemetry/telemetryplugin.cpp
Normal file
246
ground/openpilotgcs/src/plugins/telemetry/telemetryplugin.cpp
Normal file
@ -0,0 +1,246 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file telemetryplugin.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup telemetryplugin
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 "telemetryplugin.h"
|
||||
#include "monitorgadgetfactory.h"
|
||||
|
||||
#include "extensionsystem/pluginmanager.h"
|
||||
#include "uavobjectmanager.h"
|
||||
#include "uavobject.h"
|
||||
#include "coreplugin/icore.h"
|
||||
#include "coreplugin/connectionmanager.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtPlugin>
|
||||
#include <QStringList>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/iuavgadget.h>
|
||||
|
||||
TelemetryPlugin::TelemetryPlugin()
|
||||
{}
|
||||
|
||||
TelemetryPlugin::~TelemetryPlugin()
|
||||
{
|
||||
// Core::ICore::instance()->saveSettings(this);
|
||||
}
|
||||
|
||||
bool TelemetryPlugin::initialize(const QStringList & args, QString *errMsg)
|
||||
{
|
||||
Q_UNUSED(args);
|
||||
Q_UNUSED(errMsg);
|
||||
|
||||
MonitorGadgetFactory *mf = new MonitorGadgetFactory(this);
|
||||
addAutoReleasedObject(mf);
|
||||
|
||||
// mop = new TelemetryPluginOptionsPage(this);
|
||||
// addAutoReleasedObject(mop);
|
||||
|
||||
// TODO not so good... g is probalby leaked...
|
||||
MonitorWidget *w = mf->createMonitorWidget(NULL);
|
||||
w->setMaximumWidth(180);
|
||||
|
||||
//
|
||||
// setAlignment(Qt::AlignCenter);
|
||||
|
||||
// no border
|
||||
w->setFrameStyle(QFrame::NoFrame);
|
||||
w->setWindowFlags(Qt::FramelessWindowHint);
|
||||
|
||||
// set svg background translucent
|
||||
w->setStyleSheet("background:transparent;");
|
||||
// set widget background translucent
|
||||
w->setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
w->setBackgroundBrush(Qt::NoBrush);
|
||||
|
||||
// add monitor widget to connection manager
|
||||
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
||||
// connect(cm, SIGNAL(deviceConnected(QIODevice *)), w, SLOT(telemetryConnected()));
|
||||
// connect(cm, SIGNAL(deviceDisconnected()), w, SLOT(telemetryDisconnected()));
|
||||
|
||||
cm->addWidget(w);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TelemetryPlugin::extensionsInitialized()
|
||||
{
|
||||
// Core::ICore::instance()->readSettings(this);
|
||||
|
||||
// ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
|
||||
// connect(pm, SIGNAL(objectAdded(QObject *)), this, SLOT(onTelemetryManagerAdded(QObject *)));
|
||||
// _toRemoveNotifications.clear();
|
||||
// connectNotifications();
|
||||
}
|
||||
|
||||
// void TelemetryPlugin::saveConfig(QSettings *settings, UAVConfigInfo *configInfo)
|
||||
// {
|
||||
// configInfo->setVersion(VERSION);
|
||||
//
|
||||
// settings->beginWriteArray("Current");
|
||||
// settings->setArrayIndex(0);
|
||||
// currentNotification.saveState(settings);
|
||||
// settings->endArray();
|
||||
//
|
||||
// settings->beginGroup("listNotifies");
|
||||
// settings->remove("");
|
||||
// settings->endGroup();
|
||||
//
|
||||
// settings->beginWriteArray("listNotifies");
|
||||
// for (int i = 0; i < _notificationList.size(); i++) {
|
||||
// settings->setArrayIndex(i);
|
||||
// _notificationList.at(i)->saveState(settings);
|
||||
// }
|
||||
// settings->endArray();
|
||||
// settings->setValue(QLatin1String("Enable"), enable);
|
||||
// }
|
||||
|
||||
// void TelemetryPlugin::readConfig(QSettings *settings, UAVConfigInfo * /* configInfo */)
|
||||
// {
|
||||
//// Just for migration to the new format.
|
||||
//// Q_ASSERT(configInfo->version() == UAVConfigVersion());
|
||||
//
|
||||
// settings->beginReadArray("Current");
|
||||
// settings->setArrayIndex(0);
|
||||
// currentNotification.restoreState(settings);
|
||||
// settings->endArray();
|
||||
//
|
||||
//// read list of notifications from settings
|
||||
// int size = settings->beginReadArray("listNotifies");
|
||||
// for (int i = 0; i < size; ++i) {
|
||||
// settings->setArrayIndex(i);
|
||||
// NotificationItem *notification = new NotificationItem;
|
||||
// notification->restoreState(settings);
|
||||
// _notificationList.append(notification);
|
||||
// }
|
||||
// settings->endArray();
|
||||
// setEnable(settings->value(QLatin1String("Enable"), 0).toBool());
|
||||
// }
|
||||
|
||||
// void TelemetryPlugin::onTelemetryManagerAdded(QObject *obj)
|
||||
// {
|
||||
// telMngr = qobject_cast<TelemetryManager *>(obj);
|
||||
// if (telMngr) {
|
||||
// connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
|
||||
// }
|
||||
// }
|
||||
|
||||
void TelemetryPlugin::shutdown()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
// void TelemetryPlugin::onAutopilotDisconnect()
|
||||
// {
|
||||
// connectNotifications();
|
||||
// }
|
||||
|
||||
///*!
|
||||
// clear any telemetry timers from previous flight;
|
||||
// reset will be perform on start of option page
|
||||
// */
|
||||
// void TelemetryPlugin::resetNotification(void)
|
||||
// {
|
||||
//// first, reject empty args and unknown fields.
|
||||
// foreach(NotificationItem * ntf, _notificationList) {
|
||||
// ntf->disposeTimer();
|
||||
// disconnect(ntf->getTimer(), SIGNAL(timeout()), this, SLOT(on_timerRepeated_Notification()));
|
||||
// ntf->disposeExpireTimer();
|
||||
// disconnect(ntf->getExpireTimer(), SIGNAL(timeout()), this, SLOT(on_timerRepeated_Notification()));
|
||||
// }
|
||||
// }
|
||||
|
||||
// void TelemetryPlugin::connectNotifications()
|
||||
// {
|
||||
// foreach(UAVDataObject * obj, lstNotifiedUAVObjects) {
|
||||
// if (obj != NULL) {
|
||||
// disconnect(obj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(on_arrived_Notification(UAVObject *)));
|
||||
// }
|
||||
// }
|
||||
// if (phonon.mo != NULL) {
|
||||
// delete phonon.mo;
|
||||
// phonon.mo = NULL;
|
||||
// }
|
||||
//
|
||||
// if (!enable) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
// UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
||||
//
|
||||
// lstNotifiedUAVObjects.clear();
|
||||
// _pendingNotifications.clear();
|
||||
// _notificationList.append(_toRemoveNotifications);
|
||||
// _toRemoveNotifications.clear();
|
||||
//
|
||||
//// first, reject empty args and unknown fields.
|
||||
// foreach(NotificationItem * telemetry, _notificationList) {
|
||||
// telemetry->_isPlayed = false;
|
||||
// telemetry->isNowPlaying = false;
|
||||
//
|
||||
// if (telemetry->mute()) {
|
||||
// continue;
|
||||
// }
|
||||
//// check is all sounds presented for notification,
|
||||
//// if not - we must not subscribe to it at all
|
||||
// if (telemetry->toList().isEmpty()) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// UAVDataObject *obj = dynamic_cast<UAVDataObject *>(objManager->getObject(telemetry->getDataObject()));
|
||||
// if (obj != NULL) {
|
||||
// if (!lstNotifiedUAVObjects.contains(obj)) {
|
||||
// lstNotifiedUAVObjects.append(obj);
|
||||
//
|
||||
// connect(obj, SIGNAL(objectUpdated(UAVObject *)),
|
||||
// this, SLOT(on_arrived_Notification(UAVObject *)),
|
||||
// Qt::QueuedConnection);
|
||||
// }
|
||||
// } else {
|
||||
// qTelemetryDebug() << "Error: Object is unknown (" << telemetry->getDataObject() << ").";
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (_notificationList.isEmpty()) {
|
||||
// return;
|
||||
// }
|
||||
//// set notification message to current event
|
||||
// phonon.mo = Phonon::createPlayer(Phonon::NotificationCategory);
|
||||
// phonon.mo->clearQueue();
|
||||
// phonon.firstPlay = true;
|
||||
// QList<Phonon::AudioOutputDevice> audioOutputDevices =
|
||||
// Phonon::BackendCapabilities::availableAudioOutputDevices();
|
||||
// foreach(Phonon::AudioOutputDevice dev, audioOutputDevices) {
|
||||
// qTelemetryDebug() << "Telemetry: Audio Output device: " << dev.name() << " - " << dev.description();
|
||||
// }
|
||||
// connect(phonon.mo, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
|
||||
// this, SLOT(stateChanged(Phonon::State, Phonon::State)));
|
||||
// }
|
51
ground/openpilotgcs/src/plugins/telemetry/telemetryplugin.h
Normal file
51
ground/openpilotgcs/src/plugins/telemetry/telemetryplugin.h
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file telemetryplugin.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup telemetryplugin
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 TELEMETRYPLUGIN_H
|
||||
#define TELEMETRYPLUGIN_H
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
class MonitorGadgetFactory;
|
||||
|
||||
class TelemetryPlugin : public ExtensionSystem::IPlugin {
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "OpenPilot.Telemetry")
|
||||
|
||||
|
||||
public:
|
||||
TelemetryPlugin();
|
||||
~TelemetryPlugin();
|
||||
|
||||
void extensionsInitialized();
|
||||
bool initialize(const QStringList &arguments, QString *errorString);
|
||||
void shutdown();
|
||||
|
||||
private:
|
||||
MonitorGadgetFactory *mf;
|
||||
};
|
||||
|
||||
#endif // TELEMETRYPLUGIN_H
|
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 \
|
||||
uavobjectfield.h \
|
||||
uavobjectsinit.h \
|
||||
uavobjectsplugin.h
|
||||
uavobjectsplugin.h \
|
||||
uavobjecthelper.h
|
||||
|
||||
SOURCES += uavobject.cpp \
|
||||
uavmetaobject.cpp \
|
||||
uavobjectmanager.cpp \
|
||||
uavdataobject.cpp \
|
||||
uavobjectfield.cpp \
|
||||
uavobjectsplugin.cpp
|
||||
uavobjectsplugin.cpp \
|
||||
uavobjecthelper.cpp
|
||||
|
||||
OTHER_FILES += UAVObjects.pluginspec
|
||||
|
||||
|
@ -64,9 +64,9 @@ void TelemetryManager::onStart()
|
||||
telemetryMon = new TelemetryMonitor(objMngr, telemetry);
|
||||
connect(telemetryMon, SIGNAL(connected()), this, SLOT(onConnect()));
|
||||
connect(telemetryMon, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
|
||||
connect(telemetryMon, SIGNAL(telemetryUpdated(double, double)), this, SLOT(onTelemetryUpdate(double, double)));
|
||||
}
|
||||
|
||||
|
||||
void TelemetryManager::stop()
|
||||
{
|
||||
emit myStop();
|
||||
@ -92,3 +92,8 @@ void TelemetryManager::onDisconnect()
|
||||
autopilotConnected = false;
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void TelemetryManager::onTelemetryUpdate(double txRate, double rxRate)
|
||||
{
|
||||
emit telemetryUpdated(txRate, rxRate);
|
||||
}
|
||||
|
@ -50,12 +50,14 @@ public:
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void telemetryUpdated(double txRate, double rxRate);
|
||||
void myStart();
|
||||
void myStop();
|
||||
|
||||
private slots:
|
||||
void onConnect();
|
||||
void onDisconnect();
|
||||
void onTelemetryUpdate(double txRate, double rxRate);
|
||||
void onStart();
|
||||
void onStop();
|
||||
|
||||
|
@ -49,11 +49,6 @@ TelemetryMonitor::TelemetryMonitor(UAVObjectManager *objMngr, Telemetry *tel) :
|
||||
// Start update timer
|
||||
connect(statsTimer, SIGNAL(timeout()), this, SLOT(processStatsUpdates()));
|
||||
statsTimer->start(STATS_CONNECT_PERIOD_MS);
|
||||
|
||||
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
||||
connect(this, SIGNAL(connected()), cm, SLOT(telemetryConnected()));
|
||||
connect(this, SIGNAL(disconnected()), cm, SLOT(telemetryDisconnected()));
|
||||
connect(this, SIGNAL(telemetryUpdated(double, double)), cm, SLOT(telemetryUpdated(double, double)));
|
||||
}
|
||||
|
||||
TelemetryMonitor::~TelemetryMonitor()
|
||||
|
@ -1,18 +1,24 @@
|
||||
QT += network
|
||||
TEMPLATE = lib
|
||||
TARGET = UAVTalk
|
||||
|
||||
QT += network
|
||||
|
||||
include(../../openpilotgcsplugin.pri)
|
||||
include(uavtalk_dependencies.pri)
|
||||
|
||||
HEADERS += uavtalk.h \
|
||||
uavtalkplugin.h \
|
||||
telemetrymonitor.h \
|
||||
telemetrymanager.h \
|
||||
uavtalk_global.h \
|
||||
telemetry.h
|
||||
|
||||
SOURCES += uavtalk.cpp \
|
||||
uavtalkplugin.cpp \
|
||||
telemetrymonitor.cpp \
|
||||
telemetrymanager.cpp \
|
||||
telemetry.cpp
|
||||
|
||||
DEFINES += UAVTALK_LIBRARY
|
||||
|
||||
OTHER_FILES += UAVTalk.pluginspec
|
||||
|
Loading…
x
Reference in New Issue
Block a user