1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-17 02:52:12 +01:00

OP-263 Update Logging plugin to prepare the scopes auto stop/start. Logging replay is now done through the connection manager, as a virtual device. Pressing "Connect" prompts for the file to be replayed.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2494 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
edouard 2011-01-20 22:28:38 +00:00 committed by edouard
parent ecfa9c41cd
commit c0218be369
4 changed files with 141 additions and 29 deletions

View File

@ -8,10 +8,22 @@ LogFile::LogFile(QObject *parent) :
connect(&timer, SIGNAL(timeout()), this, SLOT(timerFired()));
}
/**
* Opens the logfile QIODevice and the underlying logfile. In case
* we want to save the logfile, we open in WriteOnly. In case we
* want to read the logfile, we open in ReadOnly.
*/
bool LogFile::open(OpenMode mode) {
// start a timer for playback
myTime.restart();
if (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
// connection manager call...
return true;
}
if(file.open(mode) == FALSE)
{
@ -23,18 +35,25 @@ bool LogFile::open(OpenMode mode) {
// they can be read back if ID's change
// Must call parent function for QIODevice to pass calls to writeData
QIODevice::open(mode);
// We always open ReadWrite, because otherwise we will get tons of warnings
// during a logfile replay. Read nature is checked upon write ops below.
QIODevice::open(QIODevice::ReadWrite);
return true;
}
void LogFile::close()
{
if (timer.isActive())
timer.stop();
file.close();
QIODevice::close();
}
qint64 LogFile::writeData(const char * data, qint64 dataSize) {
if (!file.isWritable())
return dataSize;
quint32 timeStamp = myTime.elapsed();
file.write((char *) &timeStamp,sizeof(timeStamp));
@ -48,6 +67,7 @@ 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());
memcpy(data,dataBuffer.data(),toRead);
dataBuffer.remove(0,toRead);
@ -65,6 +85,7 @@ void LogFile::timerFired()
if(file.bytesAvailable() > 4)
{
// TODO: going back in time will be a problem
while ((myTime.elapsed() - timeOffset) * playbackSpeed > lastTimeStamp) {
@ -80,7 +101,9 @@ void LogFile::timerFired()
return;
}
mutex.lock();
dataBuffer.append(file.read(dataSize));
mutex.unlock();
emit readyRead();
if(file.bytesAvailable() < 4) {

View File

@ -4,6 +4,7 @@
#include <QIODevice>
#include <QTime>
#include <QTimer>
#include <QMutexLocker>
#include <QDebug>
#include <QBuffer>
#include <uavobjects/uavobjectmanager.h>
@ -43,6 +44,8 @@ protected:
QTime myTime;
QFile file;
qint32 lastTimeStamp;
QMutex mutex;
int timeOffset;
int pausedTime;

View File

@ -47,6 +47,78 @@
#include "uavobjects/uavobjectmanager.h"
#include <uavobjects/uavobjectmanager.h>
LoggingConnection::LoggingConnection()
{
}
LoggingConnection::~LoggingConnection()
{
}
void LoggingConnection::onEnumerationChanged()
{
emit availableDevChanged(this);
}
QStringList LoggingConnection::availableDevices()
{
QStringList list;
list << "Logfile replay...";
return list;
}
QIODevice* LoggingConnection::openDevice(const QString &deviceName)
{
if (logFile.isOpen()){
logFile.close();
}
QFileDialog * fd = new QFileDialog();
fd->setAcceptMode(QFileDialog::AcceptOpen);
fd->setNameFilter("OpenPilot Log (*.opl)");
connect(fd, SIGNAL(fileSelected(QString)), this, SLOT(startReplay(QString)));
fd->exec();
return &logFile;
}
void LoggingConnection::startReplay(QString file)
{
logFile.setFileName(file);
if(logFile.open(QIODevice::ReadOnly)) {
qDebug() << "Replaying " << file;
// state = REPLAY;
logFile.startReplay();
}
}
void LoggingConnection::closeDevice(const QString &deviceName)
{
Q_UNUSED(deviceName);
//we have to delete the serial connection we created
if (logFile.isOpen()){
logFile.close();
m_deviceOpened = false;
}
}
QString LoggingConnection::connectionName()
{
return QString("Logfile replay");
}
QString LoggingConnection::shortName()
{
return QString("Logfile");
}
/**
* Sets the file to use for logging and takes the parent plugin
* to connect to stop logging signal
@ -259,7 +331,7 @@ bool LoggingPlugin::initialize(const QStringList& args, QString *errMsg)
QList<int>() <<
Core::Constants::C_GLOBAL_ID);
cmd->setDefaultKeySequence(QKeySequence("Ctrl+L"));
cmd->action()->setText("Logging...");
cmd->action()->setText("Start logging...");
ac->menu()->addSeparator();
ac->appendGroup("Logging");
@ -268,6 +340,7 @@ bool LoggingPlugin::initialize(const QStringList& args, QString *errMsg)
connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(toggleLogging()));
// Command to replay logging
/*
Core::Command* cmd2 = am->registerAction(new QAction(this),
"LoggingPlugin.Playback",
QList<int>() <<
@ -279,6 +352,7 @@ bool LoggingPlugin::initialize(const QStringList& args, QString *errMsg)
ac->addAction(cmd2, "Replay");
connect(cmd2->action(), SIGNAL(triggered(bool)), this, SLOT(toggleReplay()));
*/
mf = new LoggingGadgetFactory(this);
addAutoReleasedObject(mf);
@ -353,31 +427,6 @@ void LoggingPlugin::startLogging(QString file)
}
}
/**
* Starts the logging thread replaying a certain file
*/
void LoggingPlugin::startReplay(QString file)
{
logFile.setFileName(file);
if(logFile.open(QIODevice::ReadOnly)) {
qDebug() << "Replaying " << file;
state = REPLAY;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
uavTalk = new UAVTalk(&logFile, objManager);
logFile.startReplay();
emit stateChanged("REPLAY");
} else {
QErrorMessage err;
err.showMessage("Unable to open file for replay");
err.exec();
}
}
/**
* Send the stop logging signal to the LoggingThread
*/
@ -428,7 +477,7 @@ void LoggingPlugin::replayStopped()
void LoggingPlugin::extensionsInitialized()
{
// Do nothing
addAutoReleasedObject(new LoggingConnection);
}
void LoggingPlugin::shutdown()

View File

@ -27,6 +27,7 @@
#ifndef LOGGINGPLUGIN_H_
#define LOGGINGPLUGIN_H_
#include <coreplugin/iconnection.h>
#include <extensionsystem/iplugin.h>
#include <uavobjects/uavobjectmanager.h>
#include "uavobjects/gcstelemetrystats.h"
@ -40,6 +41,43 @@
class LoggingPlugin;
class LoggingGadgetFactory;
/**
* Define a connection via the IConnection interface
* Plugin will add a instance of this class to the pool,
* so the connection manager can use it.
*/
class LoggingConnection
: public Core::IConnection
{
Q_OBJECT
public:
LoggingConnection();
virtual ~LoggingConnection();
virtual QStringList availableDevices();
virtual QIODevice *openDevice(const QString &deviceName);
virtual void closeDevice(const QString &deviceName);
virtual QString connectionName();
virtual QString shortName();
bool deviceOpened() {return m_deviceOpened;}
private:
LogFile logFile;
protected slots:
void onEnumerationChanged();
void startReplay(QString file);
protected:
bool m_deviceOpened;
};
class LoggingThread : public QThread
{
Q_OBJECT
@ -99,7 +137,6 @@ private slots:
void toggleLogging();
void toggleReplay();
void startLogging(QString file);
void startReplay(QString file);
void stopLogging();
void loggingStopped();
void replayStopped();