mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-20 10:54:14 +01:00
GCS/Logging: First pass at a logging plugin. Data format is 32 bit timestamp (in ms from start of logging) then the UAVObject.pack. Still want to add a header to indicate the objects available. Next part will be writing a reader and then making a gadget to control playback (and to indicate recording status).
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1478 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
f906346795
commit
4f246c64ca
10
ground/src/plugins/logging/LoggingGadget.pluginspec
Normal file
10
ground/src/plugins/logging/LoggingGadget.pluginspec
Normal file
@ -0,0 +1,10 @@
|
||||
<plugin name="LoggingGadget" version="1.0.0" compatVersion="1.0.0">
|
||||
<vendor>The OpenPilot Project</vendor>
|
||||
<copyright>(C) 2010 OpenPilot</copyright>
|
||||
<license>The GNU Public License (GPL) Version 3</license>
|
||||
<description>A plugin that logs all UAVObject updates to a binary file</description>
|
||||
<url>http://www.openpilot.org</url>
|
||||
<dependencyList>
|
||||
<dependency name="Core" version="1.0.0"/>
|
||||
</dependencyList>
|
||||
</plugin>
|
26
ground/src/plugins/logging/logging.pro
Normal file
26
ground/src/plugins/logging/logging.pro
Normal file
@ -0,0 +1,26 @@
|
||||
TEMPLATE = lib
|
||||
TARGET = LoggingGadget
|
||||
DEFINES += LOGGING_LIBRARY
|
||||
QT += svg
|
||||
include(../../openpilotgcsplugin.pri)
|
||||
include(../../plugins/uavobjects/uavobjects.pri)
|
||||
include(logging_dependencies.pri)
|
||||
HEADERS += loggingplugin.h
|
||||
# logginggadgetwidget.h \
|
||||
# loggingdialog.h \
|
||||
# logginggadget.h \
|
||||
# logginggadgetfactory.h \
|
||||
# logginggadgetconfiguration.h
|
||||
# logginggadgetoptionspage.h
|
||||
|
||||
SOURCES += loggingplugin.cpp
|
||||
# logginggadgetwidget.cpp \
|
||||
# loggingdialog.cpp \
|
||||
# logginggadget.cpp \
|
||||
# logginggadgetfactory.cpp \
|
||||
# logginggadgetconfiguration.cpp \
|
||||
# logginggadgetoptionspage.cpp
|
||||
OTHER_FILES += LoggingGadget.pluginspec
|
||||
#FORMS += logginggadgetoptionspage.ui \
|
||||
# logginggadgetwidget.ui \
|
||||
# loggingdialog.ui
|
1
ground/src/plugins/logging/logging_dependencies.pri
Normal file
1
ground/src/plugins/logging/logging_dependencies.pri
Normal file
@ -0,0 +1 @@
|
||||
include(../../plugins/coreplugin/coreplugin.pri)
|
234
ground/src/plugins/logging/loggingplugin.cpp
Normal file
234
ground/src/plugins/logging/loggingplugin.cpp
Normal file
@ -0,0 +1,234 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file logging.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @brief Import/Export Plugin
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup Logging
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 "loggingplugin.h"
|
||||
#include <QDebug>
|
||||
#include <QtPlugin>
|
||||
#include <QThread>
|
||||
#include <QStringList>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QList>
|
||||
#include <QErrorMessage>
|
||||
#include <QWriteLocker>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <QKeySequence>
|
||||
|
||||
/**
|
||||
* Sets the file to use for logging and takes the parent plugin
|
||||
* to connect to stop logging signal
|
||||
* @param[in] file File name to write to
|
||||
* @param[in] parent plugin
|
||||
*/
|
||||
bool LoggingThread::openFile(QString file, LoggingPlugin * parent)
|
||||
{
|
||||
// TODO: Write a header at the beginng describing objects so that in future
|
||||
// they can be read back if ID's change
|
||||
logFile.setFileName(file);
|
||||
if(logFile.open(QIODevice::WriteOnly) == FALSE)
|
||||
{
|
||||
qDebug() << "Unable to open " << file << " for logging";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(parent,SIGNAL(stopLoggingSignal()),this,SLOT(stopLogging()));
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Logs an object update to the file. Data format is the
|
||||
* timestamp as a 32 bit uint counting ms from start of
|
||||
* file writing (flight time will be embedded in stream)
|
||||
* the UAVtalk packed object.
|
||||
*/
|
||||
void LoggingThread::objectUpdated(UAVObject * obj)
|
||||
{
|
||||
quint32 timeStamp = myTime.elapsed();
|
||||
quint32 objSize = obj->getNumBytes();
|
||||
quint8 * buffer = new quint8[objSize+4];
|
||||
|
||||
if(buffer == NULL)
|
||||
return;
|
||||
|
||||
obj->pack(&buffer[4]);
|
||||
memcpy(buffer,&timeStamp,4);
|
||||
|
||||
QWriteLocker locker(&lock);
|
||||
qint64 written = logFile.write((char *) buffer,objSize+4);
|
||||
|
||||
delete(buffer);
|
||||
|
||||
//qDebug() << obj->getName() << " logged at " << timeStamp << " size: " << objSize << " written " << written;
|
||||
};
|
||||
|
||||
/**
|
||||
* Connect signals from all the objects updates to the write routine then
|
||||
* run event loop
|
||||
*/
|
||||
void LoggingThread::run()
|
||||
{
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
||||
|
||||
QList< QList<UAVObject*> > list;
|
||||
list = objManager->getObjects();
|
||||
QList< QList<UAVObject*> >::const_iterator i;
|
||||
QList<UAVObject*>::const_iterator j;
|
||||
int objects = 0;
|
||||
|
||||
for (i = list.constBegin(); i != list.constEnd(); ++i)
|
||||
{
|
||||
for (j = (*i).constBegin(); j != (*i).constEnd(); ++j)
|
||||
{
|
||||
connect(*j, SIGNAL(objectUpdated(UAVObject*)), (LoggingThread*) this, SLOT(objectUpdated(UAVObject*)));
|
||||
objects++;
|
||||
//qDebug() << "Detected " << j[0];
|
||||
}
|
||||
}
|
||||
|
||||
myTime.restart();
|
||||
exec();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pass this command to the correct thread then close the file
|
||||
*/
|
||||
void LoggingThread::stopLogging()
|
||||
{
|
||||
QWriteLocker locker(&lock);
|
||||
logFile.close();
|
||||
qDebug() << "File " << logFile.fileName() << " closed";
|
||||
quit();
|
||||
}
|
||||
|
||||
|
||||
LoggingPlugin::LoggingPlugin() : state(IDLE)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
LoggingPlugin::~LoggingPlugin()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
bool LoggingPlugin::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_FILE);
|
||||
|
||||
Core::Command* cmd = am->registerAction(new QAction(this),
|
||||
"LoggingPlugin.Logging",
|
||||
QList<int>() <<
|
||||
Core::Constants::C_GLOBAL_ID);
|
||||
cmd->setDefaultKeySequence(QKeySequence("Ctrl+L"));
|
||||
cmd->action()->setText("Logging...");
|
||||
|
||||
ac->menu()->addSeparator();
|
||||
ac->appendGroup("Logging");
|
||||
ac->addAction(cmd, "Logging");
|
||||
|
||||
connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(toggleLogging()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The action that is triggered by the menu item which opens the
|
||||
* file and begins logging if successful
|
||||
*/
|
||||
void LoggingPlugin::toggleLogging()
|
||||
{
|
||||
if(state == IDLE)
|
||||
{
|
||||
QFileDialog * fd = new QFileDialog();
|
||||
fd->setAcceptMode(QFileDialog::AcceptSave);
|
||||
fd->setNameFilter("OpenPilot Log (*.opl)");
|
||||
connect(fd, SIGNAL(fileSelected(QString)), this, SLOT(startLogging(QString)));
|
||||
fd->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
stopLogging();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the logging thread to a certain file
|
||||
*/
|
||||
void LoggingPlugin::startLogging(QString file)
|
||||
{
|
||||
qDebug() << "Logging to " << file;
|
||||
LoggingThread *loggingThread = new LoggingThread();
|
||||
if(loggingThread->openFile(file,this))
|
||||
{
|
||||
connect(loggingThread,SIGNAL(finished()),this,SLOT(loggingStopped()));
|
||||
state = LOGGING;
|
||||
loggingThread->start();
|
||||
} else {
|
||||
QErrorMessage err;
|
||||
err.showMessage("Unable to open file for logging");
|
||||
err.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void LoggingPlugin::stopLogging()
|
||||
{
|
||||
emit stopLoggingSignal();
|
||||
}
|
||||
|
||||
void LoggingPlugin::loggingStopped()
|
||||
{
|
||||
state = IDLE;
|
||||
}
|
||||
void LoggingPlugin::extensionsInitialized()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void LoggingPlugin::shutdown()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
Q_EXPORT_PLUGIN(LoggingPlugin)
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
86
ground/src/plugins/logging/loggingplugin.h
Normal file
86
ground/src/plugins/logging/loggingplugin.h
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file loggingplugin.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup loggingplugin
|
||||
* @{
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 LOGGINGPLUGIN_H_
|
||||
#define LOGGINGPLUGIN_H_
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
#include <uavobjects/uavobjectmanager.h>
|
||||
#include <QThread>
|
||||
#include <QTime>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
class LoggingPlugin;
|
||||
|
||||
class LoggingThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
bool openFile(QString file, LoggingPlugin * parent);
|
||||
|
||||
private slots:
|
||||
void objectUpdated(UAVObject * obj);
|
||||
|
||||
public slots:
|
||||
void stopLogging();
|
||||
|
||||
protected:
|
||||
void run();
|
||||
QFile logFile;
|
||||
QTime myTime;
|
||||
QReadWriteLock lock;
|
||||
};
|
||||
|
||||
class LoggingPlugin : public ExtensionSystem::IPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LoggingPlugin();
|
||||
~LoggingPlugin();
|
||||
|
||||
void extensionsInitialized();
|
||||
bool initialize(const QStringList & arguments, QString * errorString);
|
||||
void shutdown();
|
||||
|
||||
signals:
|
||||
void stopLoggingSignal(void);
|
||||
|
||||
protected:
|
||||
enum {IDLE, LOGGING} state;
|
||||
LoggingThread * loggingThread;
|
||||
|
||||
private slots:
|
||||
void toggleLogging();
|
||||
void startLogging(QString file);
|
||||
void stopLogging();
|
||||
void loggingStopped();
|
||||
};
|
||||
#endif /* LoggingPLUGIN_H_ */
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -111,12 +111,6 @@ plugin_config.depends = plugin_coreplugin
|
||||
plugin_config.depends = plugin_uavobjects
|
||||
SUBDIRS += plugin_config
|
||||
|
||||
# Export and Import GCS Configuration.
|
||||
#plugin_importexport.subdir = importexport
|
||||
#plugin_importexport.depends = plugin_coreplugin
|
||||
#SUBDIRS += plugin_importexport
|
||||
|
||||
|
||||
#GPS Display Gadget
|
||||
plugin_gpsdisplay.subdir = gpsdisplay
|
||||
plugin_gpsdisplay.depends = plugin_coreplugin
|
||||
@ -147,6 +141,11 @@ plugin_importexport.subdir = importexport
|
||||
plugin_importexport.depends = plugin_coreplugin
|
||||
SUBDIRS += plugin_importexport
|
||||
|
||||
# Export and Import GCS Configuration.
|
||||
plugin_logging.subdir = logging
|
||||
plugin_logging.depends = plugin_coreplugin
|
||||
SUBDIRS += plugin_logging
|
||||
|
||||
#GCS Control of UAV Gadget
|
||||
plugin_gcscontrol.subdir = gcscontrol
|
||||
plugin_gcscontrol.depends = plugin_coreplugin
|
||||
|
Loading…
x
Reference in New Issue
Block a user