1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-30 08:24:11 +01:00

Ground/Logging: Support for pausing and resuming playback and time rescaling plus an (ugly) toolbar to control it.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1712 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
peabody124 2010-09-21 21:43:23 +00:00 committed by peabody124
parent d30c6830e7
commit 2a9fd99b06
12 changed files with 545 additions and 25 deletions

View File

@ -63,8 +63,8 @@ void LogFile::timerFired()
{ {
qint64 dataSize; qint64 dataSize;
// TODO: support time rescaling and seeking // TODO: going back in time will be a problem
while (myTime.elapsed() > lastTimeStamp) { while ((myTime.elapsed() - timeOffset) * playbackSpeed > lastTimeStamp) {
file.read((char *) &dataSize, sizeof(dataSize)); file.read((char *) &dataSize, sizeof(dataSize));
dataBuffer.append(file.read(dataSize)); dataBuffer.append(file.read(dataSize));
emit readyRead(); emit readyRead();
@ -76,9 +76,9 @@ void LogFile::timerFired()
bool LogFile::startReplay() { bool LogFile::startReplay() {
dataBuffer.clear(); dataBuffer.clear();
myTime.restart(); myTime.restart();
timeOffset = 0;
playbackSpeed = 1;
file.read((char *) &lastTimeStamp,sizeof(lastTimeStamp)); file.read((char *) &lastTimeStamp,sizeof(lastTimeStamp));
timer.setInterval(10); timer.setInterval(10);
timer.start(); timer.start();
return true; return true;
@ -88,3 +88,16 @@ bool LogFile::stopReplay() {
timer.stop(); timer.stop();
return true; return true;
} }
void LogFile::pauseReplay()
{
timer.stop();
pausedTime = myTime.elapsed();
}
void LogFile::resumeReplay()
{
timeOffset += myTime.elapsed() - pausedTime;
timer.start();
}

View File

@ -7,6 +7,7 @@
#include <QDebug> #include <QDebug>
#include <QBuffer> #include <QBuffer>
#include <uavobjects/uavobjectmanager.h> #include <uavobjects/uavobjectmanager.h>
#include <math.h>
class LogFile : public QIODevice class LogFile : public QIODevice
{ {
@ -25,6 +26,11 @@ public:
bool stopReplay(); bool stopReplay();
public slots: public slots:
void setReplaySpeed(int val) { playbackSpeed = pow(10,((double) val)/100); qDebug() << playbackSpeed; };
void pauseReplay();
void resumeReplay();
protected slots:
void timerFired(); void timerFired();
signals: signals:
@ -36,6 +42,10 @@ protected:
QTime myTime; QTime myTime;
QFile file; QFile file;
qint32 lastTimeStamp; qint32 lastTimeStamp;
int timeOffset;
int pausedTime;
double playbackSpeed;
}; };
#endif // LOGFILE_H #endif // LOGFILE_H

View File

@ -7,23 +7,21 @@ include(../../plugins/uavobjects/uavobjects.pri)
include(../../plugins/uavtalk/uavtalk.pri) include(../../plugins/uavtalk/uavtalk.pri)
include(logging_dependencies.pri) include(logging_dependencies.pri)
HEADERS += loggingplugin.h \ HEADERS += loggingplugin.h \
logfile.h logfile.h \
# logginggadgetwidget.h \ logginggadgetwidget.h \
# loggingdialog.h \ logginggadget.h \
# logginggadget.h \ logginggadgetfactory.h
# logginggadgetfactory.h \
# logginggadgetconfiguration.h # logginggadgetconfiguration.h
# logginggadgetoptionspage.h # logginggadgetoptionspage.h
SOURCES += loggingplugin.cpp \ SOURCES += loggingplugin.cpp \
logfile.cpp logfile.cpp \
# logginggadgetwidget.cpp \ logginggadgetwidget.cpp \
# loggingdialog.cpp \ logginggadget.cpp \
# logginggadget.cpp \ logginggadgetfactory.cpp
# logginggadgetfactory.cpp \
# logginggadgetconfiguration.cpp \ # logginggadgetconfiguration.cpp \
# logginggadgetoptionspage.cpp # logginggadgetoptionspage.cpp
OTHER_FILES += LoggingGadget.pluginspec OTHER_FILES += LoggingGadget.pluginspec
#FORMS += logginggadgetoptionspage.ui \ FORMS += logging.ui
# logginggadgetwidget.ui \ # logginggadgetwidget.ui \
# loggingdialog.ui # loggingdialog.ui

View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Logging</class>
<widget class="QWidget" name="Logging">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>536</width>
<height>122</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>100</horstretch>
<verstretch>80</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>80</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
</property>
<item>
<widget class="QCommandLinkButton" name="playButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>30</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Play</string>
</property>
<property name="icon">
<iconset resource="../notify/res.qrc">
<normaloff>:/notify/images/play.png</normaloff>:/notify/images/play.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="pauseButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>30</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Pause</string>
</property>
<property name="icon">
<iconset resource="../notify/res.qrc">
<normaloff>:/notify/images/stop.png</normaloff>:/notify/images/stop.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="playbackSpeed">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>-100</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>50</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Status: </string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="statusLabel">
<property name="text">
<string>Idle</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources>
<include location="../notify/res.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,47 @@
/**
******************************************************************************
*
* @file GCSControlgadget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup GCSControlGadgetPlugin GCSControl Gadget Plugin
* @{
* @brief A gadget to control the UAV, either from the keyboard or a joystick
*****************************************************************************/
/*
* 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 "logginggadget.h"
#include "logginggadgetwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjects/uavobjectmanager.h"
#include "uavobjects/uavobject.h"
LoggingGadget::LoggingGadget(QString classId, LoggingGadgetWidget *widget, QWidget *parent) :
IUAVGadget(classId, parent),
m_widget(widget)
{
}
LoggingGadget::~LoggingGadget()
{
}
void LoggingGadget::loadConfiguration(IUAVGadgetConfiguration* config)
{
}

View File

@ -0,0 +1,60 @@
/**
******************************************************************************
*
* @file GCSControlgadget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup GCSControlGadgetPlugin GCSControl Gadget Plugin
* @{
* @brief A gadget to control the UAV, either from the keyboard or a joystick
*****************************************************************************/
/*
* 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 LoggingGADGET_H_
#define LoggingGADGET_H_
#include <coreplugin/iuavgadget.h>
namespace Core {
class IUAVGadget;
}
//class QWidget;
//class QString;
class LoggingGadgetWidget;
using namespace Core;
class LoggingGadget : public Core::IUAVGadget
{
Q_OBJECT
public:
LoggingGadget(QString classId, LoggingGadgetWidget *widget, QWidget *parent = 0);
~LoggingGadget();
QList<int> context() const { return m_context; }
QWidget *widget() { return m_widget; }
QString contextHelpId() const { return QString(); }
void loadConfiguration(IUAVGadgetConfiguration* config);
private:
QWidget *m_widget;
QList<int> m_context;
};
#endif // LoggingGADGET_H_

View File

@ -0,0 +1,49 @@
/**
******************************************************************************
*
* @file GCSControlgadgetfactory.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup GCSControlGadgetPlugin GCSControl Gadget Plugin
* @{
* @brief A gadget to control the UAV, either from the keyboard or a joystick
*****************************************************************************/
/*
* 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 "logginggadgetfactory.h"
#include "logginggadgetwidget.h"
#include "logginggadget.h"
#include <coreplugin/iuavgadget.h>
LoggingGadgetFactory::LoggingGadgetFactory(QObject *parent) :
IUAVGadgetFactory(QString("LoggingGadget"),
tr("Logging"),
parent)
{
loggingPlugin = (LoggingPlugin *) parent;
}
LoggingGadgetFactory::~LoggingGadgetFactory()
{
}
IUAVGadget* LoggingGadgetFactory::createGadget(QWidget *parent) {
LoggingGadgetWidget* gadgetWidget = new LoggingGadgetWidget(parent);
gadgetWidget->setPlugin(loggingPlugin);
return new LoggingGadget(QString("LoggingGadget"), gadgetWidget, parent);
}

View File

@ -0,0 +1,55 @@
/**
******************************************************************************
*
* @file GCSControlgadgetfactory.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup GCSControlGadgetPlugin GCSControl Gadget Plugin
* @{
* @brief A gadget to control the UAV, either from the keyboard or a joystick
*****************************************************************************/
/*
* 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 LoggingGADGETFACTORY_H_
#define LoggingGADGETFACTORY_H_
#include <coreplugin/iuavgadgetfactory.h>
namespace Core {
class IUAVGadget;
class IUAVGadgetFactory;
}
using namespace Core;
class LoggingPlugin;
class LoggingGadgetFactory : public IUAVGadgetFactory
{
Q_OBJECT
public:
LoggingGadgetFactory(QObject *parent = 0);
~LoggingGadgetFactory();
void setPlugin(LoggingPlugin * p) { loggingPlugin = p; };
IUAVGadget *createGadget(QWidget *parent);
private:
LoggingPlugin * loggingPlugin;
};
#endif // LoggingGADGETFACTORY_H_

View File

@ -0,0 +1,68 @@
/**
******************************************************************************
*
* @file GCSControlgadgetwidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup GCSControlGadgetPlugin GCSControl Gadget Plugin
* @{
* @brief A gadget to control the UAV, either from the keyboard or a joystick
*****************************************************************************/
/*
* 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 "logginggadgetwidget.h"
#include "ui_logging.h"
#include <QDebug>
#include <QStringList>
#include <QtGui/QWidget>
#include <QtGui/QTextEdit>
#include <QtGui/QVBoxLayout>
#include <QtGui/QPushButton>
#include <loggingplugin.h>
LoggingGadgetWidget::LoggingGadgetWidget(QWidget *parent) : QLabel(parent)
{
m_logging = new Ui_Logging();
m_logging->setupUi(this);
}
LoggingGadgetWidget::~LoggingGadgetWidget()
{
// Do nothing
}
void LoggingGadgetWidget::setPlugin(LoggingPlugin * p)
{
loggingPlugin = p;
connect(p,SIGNAL(stateChanged(QString)),this,SLOT(stateChanged(QString)));
connect(m_logging->playButton,SIGNAL(clicked()),p->getLogfile(),SLOT(resumeReplay()));
connect(m_logging->pauseButton,SIGNAL(clicked()),p->getLogfile(),SLOT(pauseReplay()));
connect(m_logging->playbackSpeed,SIGNAL(valueChanged(int)),p->getLogfile(),SLOT(setReplaySpeed(int)));
void pauseReplay();
void resumeReplay();
}
void LoggingGadgetWidget::stateChanged(QString status)
{
m_logging->statusLabel->setText(status);
}
/**
* @}
* @}
*/

View File

@ -0,0 +1,59 @@
/**
******************************************************************************
*
* @file GCSControlgadgetwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup GCSControlGadgetPlugin GCSControl Gadget Plugin
* @{
* @brief A place holder gadget 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 LoggingGADGETWIDGET_H_
#define LoggingGADGETWIDGET_H_
#include <QtGui/QLabel>
class Ui_Logging;
class LoggingPlugin;
class LoggingGadgetWidget : public QLabel
{
Q_OBJECT
public:
LoggingGadgetWidget(QWidget *parent = 0);
~LoggingGadgetWidget();
void setPlugin(LoggingPlugin * p);
protected slots:
void stateChanged(QString status);
signals:
void pause();
void play();
private:
Ui_Logging *m_logging;
LoggingPlugin * loggingPlugin;
};
#endif /* LoggingGADGETWIDGET_H_ */

View File

@ -28,6 +28,7 @@
*/ */
#include "loggingplugin.h" #include "loggingplugin.h"
#include "logginggadgetfactory.h"
#include <QDebug> #include <QDebug>
#include <QtPlugin> #include <QtPlugin>
#include <QThread> #include <QThread>
@ -167,6 +168,9 @@ bool LoggingPlugin::initialize(const QStringList& args, QString *errMsg)
connect(cmd2->action(), SIGNAL(triggered(bool)), this, SLOT(toggleReplay())); connect(cmd2->action(), SIGNAL(triggered(bool)), this, SLOT(toggleReplay()));
mf = new LoggingGadgetFactory(this);
addAutoReleasedObject(mf);
return true; return true;
} }
@ -223,6 +227,7 @@ void LoggingPlugin::startLogging(QString file)
connect(loggingThread,SIGNAL(finished()),this,SLOT(loggingStopped())); connect(loggingThread,SIGNAL(finished()),this,SLOT(loggingStopped()));
state = LOGGING; state = LOGGING;
loggingThread->start(); loggingThread->start();
emit stateChanged("LOGGING");
} else { } else {
QErrorMessage err; QErrorMessage err;
err.showMessage("Unable to open file for logging"); err.showMessage("Unable to open file for logging");
@ -236,17 +241,18 @@ void LoggingPlugin::startLogging(QString file)
void LoggingPlugin::startReplay(QString file) void LoggingPlugin::startReplay(QString file)
{ {
logFile = new LogFile; logFile.setFileName(file);
logFile->setFileName(file); if(logFile.open(QIODevice::ReadOnly)) {
if(logFile->open(QIODevice::ReadOnly)) {
qDebug() << "Replaying " << file; qDebug() << "Replaying " << file;
state = REPLAY; state = REPLAY;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
uavTalk = new UAVTalk(logFile, objManager); uavTalk = new UAVTalk(&logFile, objManager);
logFile->startReplay(); logFile.startReplay();
emit stateChanged("REPLAY");
} else { } else {
QErrorMessage err; QErrorMessage err;
err.showMessage("Unable to open file for replay"); err.showMessage("Unable to open file for replay");
@ -268,13 +274,13 @@ void LoggingPlugin::stopLogging()
*/ */
void LoggingPlugin::stopReplay() void LoggingPlugin::stopReplay()
{ {
logFile->stopReplay(); logFile.stopReplay();
logFile->close(); logFile.close();
free(uavTalk); free(uavTalk);
free(logFile);
uavTalk = 0; uavTalk = 0;
logFile = 0;
state = IDLE; state = IDLE;
emit stateChanged("IDLE");
} }
/** /**
@ -285,6 +291,9 @@ void LoggingPlugin::loggingStopped()
{ {
if(state == LOGGING) if(state == LOGGING)
state = IDLE; state = IDLE;
emit stateChanged("IDLE");
free(loggingThread); free(loggingThread);
loggingThread = NULL; loggingThread = NULL;
} }

View File

@ -36,6 +36,7 @@
#include <QReadWriteLock> #include <QReadWriteLock>
class LoggingPlugin; class LoggingPlugin;
class LoggingGadgetFactory;
class LoggingThread : public QThread class LoggingThread : public QThread
{ {
@ -68,9 +69,13 @@ public:
bool initialize(const QStringList & arguments, QString * errorString); bool initialize(const QStringList & arguments, QString * errorString);
void shutdown(); void shutdown();
LogFile * getLogfile() { return &logFile; };
signals: signals:
void stopLoggingSignal(void); void stopLoggingSignal(void);
void stopReplaySignal(void); void stopReplaySignal(void);
void stateChanged(QString);
protected: protected:
enum {IDLE, LOGGING, REPLAY} state; enum {IDLE, LOGGING, REPLAY} state;
@ -78,7 +83,7 @@ protected:
// These are used for replay, logging in its own thread // These are used for replay, logging in its own thread
UAVTalk * uavTalk; UAVTalk * uavTalk;
LogFile * logFile; LogFile logFile;
private slots: private slots:
void toggleLogging(); void toggleLogging();
@ -88,6 +93,9 @@ private slots:
void stopLogging(); void stopLogging();
void stopReplay(); void stopReplay();
void loggingStopped(); void loggingStopped();
private:
LoggingGadgetFactory *mf;
}; };
#endif /* LoggingPLUGIN_H_ */ #endif /* LoggingPLUGIN_H_ */
/** /**