From 71ec5a9a64a60ac4de624a55733297a407e34239 Mon Sep 17 00:00:00 2001 From: Fredrik Arvidsson Date: Sun, 24 Nov 2013 17:50:07 +0100 Subject: [PATCH] OP-1119 Added helper class for synchronous uavo stuff. Added code for retrieval of flight side logs. --- .../plugins/flightlog/flightlogmanager.cpp | 60 +++++++++- .../src/plugins/flightlog/flightlogmanager.h | 8 +- .../plugins/uavobjects/uavobjecthelper.cpp | 103 ++++++++++++++++++ .../src/plugins/uavobjects/uavobjecthelper.h | 81 ++++++++++++++ .../src/plugins/uavobjects/uavobjects.pro | 6 +- 5 files changed, 254 insertions(+), 4 deletions(-) create mode 100644 ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.cpp create mode 100644 ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.h diff --git a/ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.cpp b/ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.cpp index 82c25dc73..4c3505c11 100644 --- a/ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.cpp +++ b/ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.cpp @@ -29,6 +29,7 @@ #include "extensionsystem/pluginmanager.h" #include "debuglogcontrol.h" +#include "uavobjecthelper.h" FlightLogManager::FlightLogManager(QObject *parent) : QObject(parent) { @@ -37,9 +38,15 @@ FlightLogManager::FlightLogManager(QObject *parent) : m_objectManager = pm->getObject(); Q_ASSERT(m_objectManager); + m_flightLogControl = DebugLogControl::GetInstance(m_objectManager); + Q_ASSERT(m_flightLogControl); + m_flightLogStatus = DebugLogStatus::GetInstance(m_objectManager); Q_ASSERT(m_flightLogStatus); + m_flightLogEntry = DebugLogEntry::GetInstance(m_objectManager); + Q_ASSERT(m_flightLogEntry); + DebugLogEntry *entry = new DebugLogEntry(); entry->setFlight(1); m_logEntries.append(entry); @@ -99,8 +106,59 @@ void FlightLogManager::clearAllLogs() { m_logEntries.clear(); } -void FlightLogManager::retrieveLogs(int flight) { +void FlightLogManager::retrieveLogs(int flightToRetrieve) { + + UAVObjectUpdaterHelper updateHelper; + UAVObjectRequestHelper requestHelper; + //Get logs from flight side + m_logEntries.clear(); + + // Set up what to retrieve + bool timedOut = false; + 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); + + UAVObjectUpdaterHelper::Result result = updateHelper.doObjectAndWait(m_flightLogControl, UAVTALK_TIMEOUT); + if(result == UAVObjectUpdaterHelper::SUCCESS) { + result = requestHelper.doObjectAndWait(m_flightLogEntry, UAVTALK_TIMEOUT); + if(result == UAVObjectUpdaterHelper::TIMEOUT) { + timedOut = true; + break; + } else { + if(!m_flightLogEntry->getType() == DebugLogEntry::TYPE_EMPTY && + m_flightLogEntry->getFlight() == flight && m_flightLogEntry->getEntry() == entry) { + + //Ok, we retrieved the entry, and it was the correct one. clone it and add it to the list + m_logEntries.append((DebugLogEntry*) m_flightLogEntry->clone(0)); + + // Increment to get next entry from flight side + entry++; + } else { + // We are done, not more entries on this flight + break; + } + } + } else { + break; + } + } + if(timedOut) { + // We timed out, do something smart here to alert the user + break; + } + } } void FlightLogManager::exportLogs() diff --git a/ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.h b/ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.h index d6e7df31b..f5d1eb5bb 100644 --- a/ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.h +++ b/ground/openpilotgcs/src/plugins/flightlog/flightlogmanager.h @@ -31,10 +31,12 @@ #include #include #include +#include #include "uavobjectmanager.h" #include "debuglogentry.h" #include "debuglogstatus.h" +#include "debuglogcontrol.h" class FlightLogManager : public QObject { Q_OBJECT @@ -56,14 +58,18 @@ signals: public slots: void clearAllLogs(); - void retrieveLogs(int flight = -1); + void retrieveLogs(int flightToRetrieve = -1); void exportLogs(); private: UAVObjectManager *m_objectManager; + DebugLogControl *m_flightLogControl; DebugLogStatus *m_flightLogStatus; + DebugLogEntry *m_flightLogEntry; QList m_logEntries; + const int UAVTALK_TIMEOUT = 4000; + }; #endif // FLIGHTLOGMANAGER_H diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.cpp b/ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.cpp new file mode 100644 index 000000000..3007843ed --- /dev/null +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.cpp @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * + * @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 + +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 != true) ? 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(); +} diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.h b/ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.h new file mode 100644 index 000000000..97a790fca --- /dev/null +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjecthelper.h @@ -0,0 +1,81 @@ +/** + ****************************************************************************** + * + * @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 +#include +#include +#include + +#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 diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro b/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro index 00cd3c29d..d1b002994 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro @@ -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