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:
parent
ecfa9c41cd
commit
c0218be369
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user