1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-21 11:54:15 +01:00

OP-294 Add logging to scope plugin.

First attempt to add logging to the scope gadget.
Logs a snapshot of data from the scope configuration at the same rate as the update timer set in the options page.
This has configurability via the options page for logging path.
File name is based on the configuration name and the date/time the logging starts.
This uses synchronous file writes in the update timer.

Tested to work on Win XP and Linux (Fedora 14)

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2634 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
andrew 2011-01-31 02:09:44 +00:00 committed by andrew
parent 880a68a788
commit 9c313ebb7a
8 changed files with 867 additions and 556 deletions

View File

@ -74,6 +74,15 @@ void ScopeGadget::loadConfiguration(IUAVGadgetConfiguration* config)
Qt::BevelJoin) Qt::BevelJoin)
); );
} }
widget->setLoggingEnabled(sgConfig->getLoggingEnabled());
widget->setLoggingNewFileOnConnect(sgConfig->getLoggingNewFileOnConnect());
widget->setLoggingPath(sgConfig->getLoggingPath());
widget->csvLoggingStop();
widget->csvLoggingSetName(sgConfig->name());
widget->csvLoggingStart();
} }
ScopeGadget::~ScopeGadget() ScopeGadget::~ScopeGadget()

View File

@ -72,6 +72,11 @@ ScopeGadgetConfiguration::ScopeGadgetConfiguration(QString classId, QSettings* q
qSettings->endGroup(); qSettings->endGroup();
} }
m_LoggingEnabled = qSettings->value("LoggingEnabled").toBool();
m_LoggingNewFileOnConnect = qSettings->value("LoggingNewFileOnConnect").toBool();
m_LoggingPath = qSettings->value("LoggingPath").toString();
} }
} }
@ -119,6 +124,12 @@ IUAVGadgetConfiguration *ScopeGadgetConfiguration::clone()
m->addPlotCurveConfig(newPlotCurveConf); m->addPlotCurveConfig(newPlotCurveConf);
} }
m->setLoggingEnabled(m_LoggingEnabled);
m->setLoggingNewFileOnConnect(m_LoggingNewFileOnConnect);
m->setLoggingPath(m_LoggingPath);
return m; return m;
} }
@ -151,6 +162,12 @@ void ScopeGadgetConfiguration::saveConfig(QSettings* qSettings) const {
qSettings->endGroup(); qSettings->endGroup();
} }
qSettings->setValue("LoggingEnabled", m_LoggingEnabled);
qSettings->setValue("LoggingNewFileOnConnect", m_LoggingNewFileOnConnect);
qSettings->setValue("LoggingPath", m_LoggingPath);
} }
void ScopeGadgetConfiguration::replacePlotCurveConfig(QList<PlotCurveConfiguration*> newPlotCurveConfigs) void ScopeGadgetConfiguration::replacePlotCurveConfig(QList<PlotCurveConfiguration*> newPlotCurveConfigs)

View File

@ -70,6 +70,13 @@ public:
void saveConfig(QSettings* settings) const; void saveConfig(QSettings* settings) const;
IUAVGadgetConfiguration *clone(); IUAVGadgetConfiguration *clone();
bool getLoggingEnabled(){return m_LoggingEnabled;};
bool getLoggingNewFileOnConnect(){return m_LoggingNewFileOnConnect;};
QString getLoggingPath(){return m_LoggingPath;};
void setLoggingEnabled(bool value){m_LoggingEnabled=value;};
void setLoggingNewFileOnConnect(bool value){m_LoggingNewFileOnConnect=value;};
void setLoggingPath(QString value){m_LoggingPath=value;};
private: private:
static const uint m_configurationStreamVersion = 1000;//Increment this if the stream format is not compatible with previous versions. This would cause existing configs to be discarded. static const uint m_configurationStreamVersion = 1000;//Increment this if the stream format is not compatible with previous versions. This would cause existing configs to be discarded.
@ -79,7 +86,9 @@ private:
QList<PlotCurveConfiguration*> m_PlotCurveConfigs; QList<PlotCurveConfiguration*> m_PlotCurveConfigs;
void clearPlotData(); void clearPlotData();
bool m_LoggingEnabled;
bool m_LoggingNewFileOnConnect;
QString m_LoggingPath;
}; };

View File

@ -116,6 +116,17 @@ QWidget* ScopeGadgetOptionsPage::createPage(QWidget *parent)
setYAxisWidgetFromPlotCurve(); setYAxisWidgetFromPlotCurve();
//logging path setup
options_page->LoggingPath->setExpectedKind(Utils::PathChooser::Directory);
options_page->LoggingPath->setPromptDialogTitle(tr("Choose Logging Directory"));
options_page->LoggingPath->setPath(m_config->getLoggingPath());
options_page->LoggingConnect->setChecked(m_config->getLoggingNewFileOnConnect());
options_page->LoggingEnable->setChecked(m_config->getLoggingEnabled());
connect(options_page->LoggingEnable, SIGNAL(clicked()), this, SLOT(on_loggingEnable_clicked()));
on_loggingEnable_clicked();
return optionsPageWidget; return optionsPageWidget;
} }
@ -226,6 +237,12 @@ void ScopeGadgetOptionsPage::apply()
} }
m_config->replacePlotCurveConfig(plotCurveConfigs); m_config->replacePlotCurveConfig(plotCurveConfigs);
//save the logging config
m_config->setLoggingPath(options_page->LoggingPath->path());
m_config->setLoggingNewFileOnConnect(options_page->LoggingConnect->isChecked());
m_config->setLoggingEnabled(options_page->LoggingEnable->isChecked());
} }
/*! /*!
@ -309,3 +326,12 @@ void ScopeGadgetOptionsPage::on_lstCurves_currentRowChanged(int currentRow)
Q_UNUSED(currentRow); Q_UNUSED(currentRow);
setYAxisWidgetFromPlotCurve(); setYAxisWidgetFromPlotCurve();
} }
void ScopeGadgetOptionsPage::on_loggingEnable_clicked()
{
bool en = options_page->LoggingEnable->isChecked();
options_page->LoggingPath->setEnabled(en);
options_page->LoggingConnect->setEnabled(en);
options_page->LoggingLabel->setEnabled(en);
}

View File

@ -78,6 +78,8 @@ private slots:
void on_btnAddCurve_clicked(); void on_btnAddCurve_clicked();
void on_cmbUAVObjects_currentIndexChanged(QString val); void on_cmbUAVObjects_currentIndexChanged(QString val);
void on_btnColor_clicked(); void on_btnColor_clicked();
void on_loggingEnable_clicked();
}; };
#endif // SCOPEGADGETOPTIONSPAGE_H #endif // SCOPEGADGETOPTIONSPAGE_H

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>653</width> <width>550</width>
<height>580</height> <height>290</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -16,21 +16,26 @@
<widget class="QWidget" name="widget" native="true"> <widget class="QWidget" name="widget" native="true">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>10</x>
<y>0</y> <y>10</y>
<width>611</width> <width>541</width>
<height>241</height> <height>271</height>
</rect> </rect>
</property> </property>
<widget class="QWidget" name="horizontalLayoutWidget"> <widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>601</width> <width>531</width>
<height>231</height> <height>272</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>3</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint"> <property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum> <enum>QLayout::SetDefaultConstraint</enum>
@ -263,9 +268,62 @@ Update</string>
</layout> </layout>
</item> </item>
</layout> </layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QCheckBox" name="LoggingEnable">
<property name="text">
<string>Log data to csv file</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="LoggingConnect">
<property name="text">
<string>New file on connect</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="LoggingLabel">
<property name="text">
<string>Logging path</string>
</property>
</widget>
</item>
<item>
<widget class="Utils::PathChooser" name="LoggingPath" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget> </widget>
</widget> </widget>
</widget> </widget>
<customwidgets>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QWidget</extends>
<header>utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>

View File

@ -26,6 +26,7 @@
*/ */
#include <QDir>
#include "scopegadgetwidget.h" #include "scopegadgetwidget.h"
#include "utils/stylehelper.h" #include "utils/stylehelper.h"
@ -70,6 +71,21 @@ ScopeGadgetWidget::ScopeGadgetWidget(QWidget *parent) : QwtPlot(parent)
connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(stopPlotting())); connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(stopPlotting()));
connect(cm, SIGNAL(deviceConnected(QIODevice*)), this, SLOT(startPlotting())); connect(cm, SIGNAL(deviceConnected(QIODevice*)), this, SLOT(startPlotting()));
m_csvLoggingStarted=0;
m_csvLoggingEnabled=0;
m_csvLoggingHeaderSaved=0;
m_csvLoggingDataSaved=0;
m_csvLoggingNameSet=0;
m_csvLoggingConnected=0;
m_csvLoggingNewFileOnConnect=0;
m_csvLoggingPath = QString("./csvlogging/");
m_csvLoggingStartTime = QDateTime::currentDateTime();
//Listen to autopilot connection events
connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(csvLoggingDisconnect()));
connect(cm, SIGNAL(deviceConnected(QIODevice*)), this, SLOT(csvLoggingConnect()));
} }
/** /**
@ -267,7 +283,7 @@ void ScopeGadgetWidget::replotNewData()
setAxisScale(QwtPlot::xBottom, toTime - m_xWindowSize, toTime); setAxisScale(QwtPlot::xBottom, toTime - m_xWindowSize, toTime);
} }
//qDebug() << "replotNewData from " << NOW.addSecs(- m_xWindowSize) << " to " << NOW; //qDebug() << "replotNewData from " << NOW.addSecs(- m_xWindowSize) << " to " << NOW;
csvLoggingInsertData();
replot(); replot();
} }
@ -414,3 +430,151 @@ TestDataGen::~TestDataGen()
delete timer; delete timer;
} }
/*
int csvLoggingEnable;
int csvLoggingHeaderSaved;
int csvLoggingDataSaved;
QString csvLoggingPath;
QFile csvLoggingFile;
*/
int ScopeGadgetWidget::csvLoggingStart()
{
if (!m_csvLoggingStarted)
if (m_csvLoggingEnabled)
if ((!m_csvLoggingNewFileOnConnect)||(m_csvLoggingNewFileOnConnect && m_csvLoggingConnected))
{
QDateTime NOW = QDateTime::currentDateTime();
m_csvLoggingStartTime = NOW;
m_csvLoggingHeaderSaved=0;
m_csvLoggingDataSaved=0;
QDir PathCheck(m_csvLoggingPath);
if (!PathCheck.exists())
{
PathCheck.mkpath("./");
}
if (m_csvLoggingNameSet)
{
m_csvLoggingFile.setFileName(QString("%1/%2_%3_%4.csv").arg(m_csvLoggingPath).arg(m_csvLoggingName).arg(NOW.toString("yyyy-MM-dd")).arg(NOW.toString("hh-mm-ss")));
}
else
{
m_csvLoggingFile.setFileName(QString("%1/Log_%2_%3.csv").arg(m_csvLoggingPath).arg(NOW.toString("yyyy-MM-dd")).arg(NOW.toString("hh-mm-ss")));
}
QDir FileCheck(m_csvLoggingFile.fileName());
if (FileCheck.exists())
{
m_csvLoggingFile.setFileName("");
}
else
{
m_csvLoggingStarted=1;
csvLoggingInsertHeader();
}
}
return 0;
}
int ScopeGadgetWidget::csvLoggingStop()
{
m_csvLoggingStarted=0;
return 0;
}
int ScopeGadgetWidget::csvLoggingInsertHeader()
{
if (!m_csvLoggingStarted) return -1;
if (m_csvLoggingHeaderSaved) return -2;
if (m_csvLoggingDataSaved) return -3;
m_csvLoggingHeaderSaved=1;
if(m_csvLoggingFile.open(QIODevice::WriteOnly | QIODevice::Append)== FALSE)
{
qDebug() << "Unable to open " << m_csvLoggingFile.fileName() << " for csv logging Header";
}
else
{
QTextStream ts( &m_csvLoggingFile );
ts << "date" << ", " << "Time"<< ", " << "Sec since start"<< ", " << "Connected";
foreach(PlotData* plotData2, m_curvesData.values())
{
ts << ", ";
ts << plotData2->uavObject;
ts << "." << plotData2->uavField;
if (plotData2->haveSubField) ts << "." << plotData2->uavSubField;
}
ts << endl;
m_csvLoggingFile.close();
}
return 0;
}
int ScopeGadgetWidget::csvLoggingInsertData()
{
if (!m_csvLoggingStarted) return -1;
m_csvLoggingDataSaved=1;
m_csvLoggingDataValid=0;
QDateTime NOW = QDateTime::currentDateTime();
QString tempString;
if(m_csvLoggingFile.open(QIODevice::WriteOnly | QIODevice::Append)== FALSE)
{
qDebug() << "Unable to open " << m_csvLoggingFile.fileName() << " for csv logging Data";
}
else
{
QTextStream ss( &tempString );
ss << NOW.toString("yyyy-MM-dd") << ", " << NOW.toString("hh:mm:ss.z") << ", " << (NOW.toMSecsSinceEpoch() - m_csvLoggingStartTime.toMSecsSinceEpoch())/1000.00;
ss << ", " << m_csvLoggingConnected;
foreach(PlotData* plotData2, m_curvesData.values())
{
ss << ", ";
if (plotData2->xData->isEmpty ())
{
}
else
{
ss << QString().sprintf("%3.6g",plotData2->yData->last()/pow(10,plotData2->scalePower));
m_csvLoggingDataValid=1;
}
}
ss << endl;
if (m_csvLoggingDataValid)
{
QTextStream ts( &m_csvLoggingFile );
ts << tempString;
}
m_csvLoggingFile.close();
}
return 0;
}
void ScopeGadgetWidget::csvLoggingSetName(QString newName)
{
m_csvLoggingName = newName;
m_csvLoggingNameSet=1;
}
void ScopeGadgetWidget::csvLoggingConnect()
{
m_csvLoggingConnected=1;
if (m_csvLoggingNewFileOnConnect)csvLoggingStart();
return;
}
void ScopeGadgetWidget::csvLoggingDisconnect()
{
m_csvLoggingHeaderSaved=0;
m_csvLoggingConnected=0;
if (m_csvLoggingNewFileOnConnect)csvLoggingStop();
return;
}

View File

@ -114,7 +114,12 @@ public:
void addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor = 0, QPen pen = QPen(Qt::black)); void addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor = 0, QPen pen = QPen(Qt::black));
//void removeCurvePlot(QString uavObject, QString uavField); //void removeCurvePlot(QString uavObject, QString uavField);
void clearCurvePlots(); void clearCurvePlots();
int csvLoggingStart();
int csvLoggingStop();
void csvLoggingSetName(QString);
void setLoggingEnabled(bool value){m_csvLoggingEnabled=value;};
void setLoggingNewFileOnConnect(bool value){m_csvLoggingNewFileOnConnect=value;};
void setLoggingPath(QString value){m_csvLoggingPath=value;};
private slots: private slots:
void uavObjectReceived(UAVObject*); void uavObjectReceived(UAVObject*);
@ -122,6 +127,8 @@ private slots:
void showCurve(QwtPlotItem *item, bool on); void showCurve(QwtPlotItem *item, bool on);
void startPlotting(); void startPlotting();
void stopPlotting(); void stopPlotting();
void csvLoggingConnect();
void csvLoggingDisconnect();
private: private:
@ -138,6 +145,25 @@ private:
static TestDataGen* testDataGen; static TestDataGen* testDataGen;
QTimer *replotTimer; QTimer *replotTimer;
bool m_csvLoggingStarted;
bool m_csvLoggingEnabled;
bool m_csvLoggingHeaderSaved;
bool m_csvLoggingDataSaved;
bool m_csvLoggingNameSet;
bool m_csvLoggingDataValid;
bool m_csvLoggingConnected;
bool m_csvLoggingNewFileOnConnect;
QDateTime m_csvLoggingStartTime;
QString m_csvLoggingName;
QString m_csvLoggingPath;
QFile m_csvLoggingFile;
int csvLoggingInsertHeader();
int csvLoggingInsertData();
}; };