1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-03-16 08:29:15 +01:00

OP-1554 Scope re-factoring to prepare for enum plot.

This commit is contained in:
m_thread 2014-10-22 00:52:39 +02:00
parent 21820045a4
commit b156f86de0
5 changed files with 175 additions and 227 deletions

View File

@ -30,35 +30,20 @@
#include <math.h> #include <math.h>
#include <QDebug> #include <QDebug>
PlotData::PlotData(QString p_uavObject, QString p_uavField) PlotData::PlotData(QString objectName, QString fieldName, QString elementName,
{ QwtPlotCurve *plotCurve, int scaleOrderFactor, int meanSamples,
uavObject = p_uavObject; QString mathFunction, double plotDataSize) :
m_objectName(objectName), m_fieldName(fieldName), m_elementName(elementName),
m_plotCurve(plotCurve), m_scalePower(scaleOrderFactor), m_meanSamples(meanSamples),
m_mathFunction(mathFunction), m_plotDataSize(plotDataSize)
{
m_plotCurve->setSamples(xData, yData);
if (p_uavField.contains("-")) { m_meanSum = 0.0f;
QStringList fieldSubfield = p_uavField.split("-", QString::SkipEmptyParts); m_correctionSum = 0.0f;
uavField = fieldSubfield.at(0); m_correctionCount = 0;
uavSubField = fieldSubfield.at(1); m_yMin = 0;
haveSubField = true; m_yMax = 0;
} else {
uavField = p_uavField;
haveSubField = false;
}
xData = new QVector<double>();
yData = new QVector<double>();
yDataHistory = new QVector<double>();
curve = 0;
scalePower = 0;
meanSamples = 1;
meanSum = 0.0f;
// mathFunction=0;
correctionSum = 0.0f;
correctionCount = 0;
yMinimum = 0;
yMaximum = 0;
m_xWindowSize = 0;
} }
double PlotData::valueAsDouble(UAVObject *obj, UAVObjectField *field) double PlotData::valueAsDouble(UAVObject *obj, UAVObjectField *field)
@ -66,8 +51,8 @@ double PlotData::valueAsDouble(UAVObject *obj, UAVObjectField *field)
Q_UNUSED(obj); Q_UNUSED(obj);
QVariant value; QVariant value;
if (haveSubField) { if (!m_elementName.isEmpty()) {
int indexOfSubField = field->getElementNames().indexOf(QRegExp(uavSubField, Qt::CaseSensitive, QRegExp::FixedString)); int indexOfSubField = field->getElementNames().indexOf(QRegExp(elementName(), Qt::CaseSensitive, QRegExp::FixedString));
value = field->getValue(indexOfSubField); value = field->getValue(indexOfSubField);
} else { } else {
value = field->getValue(); value = field->getValue();
@ -80,66 +65,67 @@ double PlotData::valueAsDouble(UAVObject *obj, UAVObjectField *field)
PlotData::~PlotData() PlotData::~PlotData()
{ {
delete xData; m_plotCurve->detach();
delete yData; delete m_plotCurve;
delete yDataHistory;
} }
void PlotData::updatePlotCurveData()
{
m_plotCurve->setSamples(xData, yData);
}
bool SequentialPlotData::append(UAVObject *obj) bool SequentialPlotData::append(UAVObject *obj)
{ {
if (uavObject == obj->getName()) { if (objectName() == obj->getName()) {
// Get the field of interest // Get the field of interest
UAVObjectField *field = obj->getField(uavField); UAVObjectField *field = obj->getField(fieldName());
if (field) { if (field) {
double currentValue = valueAsDouble(obj, field) * pow(10, scalePower); double currentValue = valueAsDouble(obj, field) * pow(10, m_scalePower);
// Perform scope math, if necessary // Perform scope math, if necessary
if (mathFunction == "Boxcar average" || mathFunction == "Standard deviation") { if (m_mathFunction == "Boxcar average" || m_mathFunction == "Standard deviation") {
// Put the new value at the front // Put the new value at the front
yDataHistory->append(currentValue); yDataHistory.append(currentValue);
// calculate average value // calculate average value
meanSum += currentValue; m_meanSum += currentValue;
if (yDataHistory->size() > meanSamples) { if (yDataHistory.size() > m_meanSamples) {
meanSum -= yDataHistory->first(); m_meanSum -= yDataHistory.first();
yDataHistory->pop_front(); yDataHistory.pop_front();
} }
// make sure to correct the sum every meanSamples steps to prevent it // make sure to correct the sum every meanSamples steps to prevent it
// from running away due to floating point rounding errors // from running away due to floating point rounding errors
correctionSum += currentValue; m_correctionSum += currentValue;
if (++correctionCount >= meanSamples) { if (++m_correctionCount >= m_meanSamples) {
meanSum = correctionSum; m_meanSum = m_correctionSum;
correctionSum = 0.0f; m_correctionSum = 0.0f;
correctionCount = 0; m_correctionCount = 0;
} }
double boxcarAvg = meanSum / yDataHistory->size(); double boxcarAvg = m_meanSum / yDataHistory.size();
if (mathFunction == "Standard deviation") { if (m_mathFunction == "Standard deviation") {
// Calculate square of sample standard deviation, with Bessel's correction // Calculate square of sample standard deviation, with Bessel's correction
double stdSum = 0; double stdSum = 0;
for (int i = 0; i < yDataHistory->size(); i++) { for (int i = 0; i < yDataHistory.size(); i++) {
stdSum += pow(yDataHistory->at(i) - boxcarAvg, 2) / (meanSamples - 1); stdSum += pow(yDataHistory.at(i) - boxcarAvg, 2) / (m_meanSamples - 1);
} }
yData->append(sqrt(stdSum)); yData.append(sqrt(stdSum));
} else { } else {
yData->append(boxcarAvg); yData.append(boxcarAvg);
} }
} else { } else {
yData->append(currentValue); yData.append(currentValue);
} }
if (yData->size() > m_xWindowSize) { // If new data overflows the window, remove old data... if (yData.size() > m_plotDataSize) { // If new data overflows the window, remove old data...
yData->pop_front(); yData.pop_front();
} else { // ...otherwise, add a new y point at position xData } else { // ...otherwise, add a new y point at position xData
xData->insert(xData->size(), xData->size()); xData.insert(xData.size(), xData.size());
} }
// notify the gui of changes in the data
// dataChanged();
return true; return true;
} }
} }
@ -149,61 +135,58 @@ bool SequentialPlotData::append(UAVObject *obj)
bool ChronoPlotData::append(UAVObject *obj) bool ChronoPlotData::append(UAVObject *obj)
{ {
if (uavObject == obj->getName()) { if (objectName() == obj->getName()) {
// Get the field of interest // Get the field of interest
UAVObjectField *field = obj->getField(uavField); UAVObjectField *field = obj->getField(fieldName());
// qDebug() << "uavObject: " << uavObject << ", uavField: " << uavField; // qDebug() << "uavObject: " << uavObject << ", uavField: " << uavField;
if (field) { if (field) {
QDateTime NOW = QDateTime::currentDateTime(); // THINK ABOUT REIMPLEMENTING THIS TO SHOW UAVO TIME, NOT SYSTEM TIME QDateTime NOW = QDateTime::currentDateTime(); // THINK ABOUT REIMPLEMENTING THIS TO SHOW UAVO TIME, NOT SYSTEM TIME
double currentValue = valueAsDouble(obj, field) * pow(10, scalePower); double currentValue = valueAsDouble(obj, field) * pow(10, m_scalePower);
// Perform scope math, if necessary // Perform scope math, if necessary
if (mathFunction == "Boxcar average" || mathFunction == "Standard deviation") { if (m_mathFunction == "Boxcar average" || m_mathFunction == "Standard deviation") {
// Put the new value at the back // Put the new value at the back
yDataHistory->append(currentValue); yDataHistory.append(currentValue);
// calculate average value // calculate average value
meanSum += currentValue; m_meanSum += currentValue;
if (yDataHistory->size() > meanSamples) { if (yDataHistory.size() > m_meanSamples) {
meanSum -= yDataHistory->first(); m_meanSum -= yDataHistory.first();
yDataHistory->pop_front(); yDataHistory.pop_front();
} }
// make sure to correct the sum every meanSamples steps to prevent it // make sure to correct the sum every meanSamples steps to prevent it
// from running away due to floating point rounding errors // from running away due to floating point rounding errors
correctionSum += currentValue; m_correctionSum += currentValue;
if (++correctionCount >= meanSamples) { if (++m_correctionCount >= m_meanSamples) {
meanSum = correctionSum; m_meanSum = m_correctionSum;
correctionSum = 0.0f; m_correctionSum = 0.0f;
correctionCount = 0; m_correctionCount = 0;
} }
double boxcarAvg = meanSum / yDataHistory->size(); double boxcarAvg = m_meanSum / yDataHistory.size();
// qDebug()<<mathFunction; // qDebug()<<mathFunction;
if (mathFunction == "Standard deviation") { if (m_mathFunction == "Standard deviation") {
// Calculate square of sample standard deviation, with Bessel's correction // Calculate square of sample standard deviation, with Bessel's correction
double stdSum = 0; double stdSum = 0;
for (int i = 0; i < yDataHistory->size(); i++) { for (int i = 0; i < yDataHistory.size(); i++) {
stdSum += pow(yDataHistory->at(i) - boxcarAvg, 2) / (meanSamples - 1); stdSum += pow(yDataHistory.at(i) - boxcarAvg, 2) / (m_meanSamples - 1);
} }
yData->append(sqrt(stdSum)); yData.append(sqrt(stdSum));
} else { } else {
yData->append(boxcarAvg); yData.append(boxcarAvg);
} }
} else { } else {
yData->append(currentValue); yData.append(currentValue);
} }
double valueX = NOW.toTime_t() + NOW.time().msec() / 1000.0; double valueX = NOW.toTime_t() + NOW.time().msec() / 1000.0;
xData->append(valueX); xData.append(valueX);
// qDebug() << "Data " << uavObject << "." << field->getName() << " X,Y:" << valueX << "," << valueY; // qDebug() << "Data " << uavObject << "." << field->getName() << " X,Y:" << valueX << "," << valueY;
// Remove stale data // Remove stale data
removeStaleData(); removeStaleData();
// notify the gui of chages in the data
// dataChanged();
return true; return true;
} }
} }
@ -217,16 +200,16 @@ void ChronoPlotData::removeStaleData()
double oldestValue; double oldestValue;
while (1) { while (1) {
if (xData->size() == 0) { if (xData.size() == 0) {
break; break;
} }
newestValue = xData->last(); newestValue = xData.last();
oldestValue = xData->first(); oldestValue = xData.first();
if (newestValue - oldestValue > m_xWindowSize) { if (newestValue - oldestValue > m_plotDataSize) {
yData->pop_front(); yData.pop_front();
xData->pop_front(); xData.pop_front();
} else { } else {
break; break;
} }
@ -238,12 +221,5 @@ void ChronoPlotData::removeStaleData()
void ChronoPlotData::removeStaleDataTimeout() void ChronoPlotData::removeStaleDataTimeout()
{ {
removeStaleData(); removeStaleData();
// dataChanged();
// qDebug() << "removeStaleDataTimeout"; // qDebug() << "removeStaleDataTimeout";
} }
bool UAVObjectPlotData::append(UAVObject *obj)
{
Q_UNUSED(obj);
return false;
}

View File

@ -43,13 +43,7 @@
/*! /*!
\brief Defines the different type of plots. \brief Defines the different type of plots.
*/ */
enum PlotType { enum PlotType {SequentialPlot, ChronoPlot};
SequentialPlot,
ChronoPlot,
UAVObjectPlot,
NPlotTypes
};
/*! /*!
\brief Base class that keeps the data for each curve in the plot. \brief Base class that keeps the data for each curve in the plot.
@ -58,29 +52,26 @@ class PlotData : public QObject {
Q_OBJECT Q_OBJECT
public: public:
PlotData(QString uavObject, QString uavField); PlotData(QString objectName, QString fieldName, QString elementName,
QwtPlotCurve *plotCurve, int scaleOrderFactor, int meanSamples,
QString mathFunction, double plotDataSize);
~PlotData(); ~PlotData();
QString uavObject; QVector<double> xData;
QString uavField; QVector<double> yData;
QString uavSubField; QVector<double> yDataHistory;
bool haveSubField;
int scalePower; // This is the power to which each value must be raised QString objectName() const { return m_objectName; }
int meanSamples; QString fieldName() const { return m_fieldName; }
double meanSum; QString elementName() const { return m_elementName; }
QString mathFunction;
double correctionSum; bool isVisible() const { return m_plotCurve->isVisible(); }
int correctionCount;
double yMinimum; double yMin() const { return m_yMin;}
double yMaximum; double yMax() const { return m_yMax;}
double m_xWindowSize;
QwtPlotCurve *curve;
QVector<double> *xData;
QVector<double> *yData;
QVector<double> *yDataHistory;
virtual bool append(UAVObject *obj) = 0; virtual bool append(UAVObject *obj) = 0;
virtual PlotType plotType() = 0; virtual PlotType plotType() const = 0;
virtual void removeStaleData() = 0; virtual void removeStaleData() = 0;
void updatePlotCurveData(); void updatePlotCurveData();
@ -88,8 +79,22 @@ public:
protected: protected:
double valueAsDouble(UAVObject *obj, UAVObjectField *field); double valueAsDouble(UAVObject *obj, UAVObjectField *field);
signals: int m_scalePower; // This is the power to which each value must be raised
void dataChanged(); int m_meanSamples;
double m_meanSum;
QString m_mathFunction;
double m_correctionSum;
int m_correctionCount;
double m_plotDataSize;
private:
QString m_objectName;
QString m_fieldName;
QString m_elementName;
double m_yMin;
double m_yMax;
QwtPlotCurve *m_plotCurve;
}; };
/*! /*!
@ -99,8 +104,10 @@ signals:
class SequentialPlotData : public PlotData { class SequentialPlotData : public PlotData {
Q_OBJECT Q_OBJECT
public: public:
SequentialPlotData(QString uavObject, QString uavField) SequentialPlotData(QString objectName, QString fieldName, QString elementName,
: PlotData(uavObject, uavField) {} QwtPlotCurve *plotCurve, int scaleFactor, int meanSamples,
QString mathFunction, double plotDataSize)
: PlotData(objectName, fieldName, elementName, plotCurve, scaleFactor, meanSamples, mathFunction, plotDataSize) {}
~SequentialPlotData() {} ~SequentialPlotData() {}
/*! /*!
@ -111,7 +118,7 @@ public:
/*! /*!
\brief The type of plot \brief The type of plot
*/ */
virtual PlotType plotType() PlotType plotType() const
{ {
return SequentialPlot; return SequentialPlot;
} }
@ -119,7 +126,7 @@ public:
/*! /*!
\brief Removes the old data from the buffer \brief Removes the old data from the buffer
*/ */
virtual void removeStaleData() {} void removeStaleData() {}
}; };
/*! /*!
@ -128,47 +135,25 @@ public:
class ChronoPlotData : public PlotData { class ChronoPlotData : public PlotData {
Q_OBJECT Q_OBJECT
public: public:
ChronoPlotData(QString uavObject, QString uavField) ChronoPlotData(QString objectname, QString fieldname, QString elementName,
: PlotData(uavObject, uavField) QwtPlotCurve *plotCurve, int scaleFactor, int meanSamples,
QString mathFunction, double plotDataSize)
: PlotData(objectname, fieldname, elementName, plotCurve, scaleFactor, meanSamples, mathFunction, plotDataSize)
{ {
scalePower = 1;
} }
~ChronoPlotData() {} ~ChronoPlotData() {}
bool append(UAVObject *obj); bool append(UAVObject *obj);
virtual PlotType plotType() PlotType plotType() const
{ {
return ChronoPlot; return ChronoPlot;
} }
virtual void removeStaleData(); void removeStaleData();
private:
private slots: private slots:
void removeStaleDataTimeout(); void removeStaleDataTimeout();
}; };
/*!
\brief UAVObject plot use a fixed size buffer of data, where the horizontal axis values come from
a UAVObject field.
*/
class UAVObjectPlotData : public PlotData {
Q_OBJECT
public:
UAVObjectPlotData(QString uavObject, QString uavField)
: PlotData(uavObject, uavField) {}
~UAVObjectPlotData() {}
bool append(UAVObject *obj);
virtual PlotType plotType()
{
return UAVObjectPlot;
}
virtual void removeStaleData() {}
};
#endif // PLOTDATA_H #endif // PLOTDATA_H

View File

@ -40,7 +40,7 @@ void ScopeGadget::loadConfiguration(IUAVGadgetConfiguration *config)
ScopeGadgetConfiguration *sgConfig = qobject_cast<ScopeGadgetConfiguration *>(config); ScopeGadgetConfiguration *sgConfig = qobject_cast<ScopeGadgetConfiguration *>(config);
ScopeGadgetWidget *widget = qobject_cast<ScopeGadgetWidget *>(m_widget); ScopeGadgetWidget *widget = qobject_cast<ScopeGadgetWidget *>(m_widget);
widget->setXWindowSize(sgConfig->dataSize()); widget->setPlotDataSize(sgConfig->dataSize());
widget->setRefreshInterval(sgConfig->refreshInterval()); widget->setRefreshInterval(sgConfig->refreshInterval());
if (sgConfig->plotType() == SequentialPlot) { if (sgConfig->plotType() == SequentialPlot) {

View File

@ -299,7 +299,7 @@ void ScopeGadgetWidget::setupSequentialPlot()
//// setAxisTitle(QwtPlot::xBottom, "Index"); //// setAxisTitle(QwtPlot::xBottom, "Index");
setAxisScaleDraw(QwtPlot::xBottom, new QwtScaleDraw()); setAxisScaleDraw(QwtPlot::xBottom, new QwtScaleDraw());
setAxisScale(QwtPlot::xBottom, 0, m_xWindowSize); setAxisScale(QwtPlot::xBottom, 0, m_plotDataSize);
setAxisLabelRotation(QwtPlot::xBottom, 0.0); setAxisLabelRotation(QwtPlot::xBottom, 0.0);
setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom); setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom);
@ -327,7 +327,7 @@ void ScopeGadgetWidget::setupChronoPlot()
setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw()); setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw());
uint NOW = QDateTime::currentDateTime().toTime_t(); uint NOW = QDateTime::currentDateTime().toTime_t();
setAxisScale(QwtPlot::xBottom, NOW - m_xWindowSize / 1000, NOW); setAxisScale(QwtPlot::xBottom, NOW - m_plotDataSize / 1000, NOW);
// setAxisLabelRotation(QwtPlot::xBottom, -15.0); // setAxisLabelRotation(QwtPlot::xBottom, -15.0);
setAxisLabelRotation(QwtPlot::xBottom, 0.0); setAxisLabelRotation(QwtPlot::xBottom, 0.0);
setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom); setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom);
@ -371,45 +371,34 @@ void ScopeGadgetWidget::setupChronoPlot()
// scaleWidget->setMinBorderDist(0, fmw); // scaleWidget->setMinBorderDist(0, fmw);
} }
void ScopeGadgetWidget::addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor, int meanSamples, QString mathFunction, QPen pen, bool antialiased) void ScopeGadgetWidget::addCurvePlot(QString objectName, QString fieldPlusSubField, int scaleFactor, int meanSamples, QString mathFunction, QPen pen, bool antialiased)
{ {
PlotData *plotData; QString fieldName = fieldPlusSubField;
QString elementName;
if (m_plotType == SequentialPlot) { if (fieldPlusSubField.contains("-")) {
plotData = new SequentialPlotData(uavObject, uavFieldSubField); QStringList fieldSubfield = fieldName.split("-", QString::SkipEmptyParts);
} else if (m_plotType == ChronoPlot) { fieldName = fieldSubfield.at(0);
plotData = new ChronoPlotData(uavObject, uavFieldSubField); elementName = fieldSubfield.at(1);
}
// else if (m_plotType == UAVObjectPlot)
// plotData = new UAVObjectPlotData(uavObject, uavField);
plotData->m_xWindowSize = m_xWindowSize;
plotData->scalePower = scaleOrderFactor;
plotData->meanSamples = meanSamples;
plotData->mathFunction = mathFunction;
// If the y-bounds are supplied, set them
if (plotData->yMinimum != plotData->yMaximum) {
setAxisScale(QwtPlot::yLeft, plotData->yMinimum, plotData->yMaximum);
} }
// Create the curve // Create the curve
QString curveName = (plotData->uavObject) + "." + (plotData->uavField); QString curveName = objectName + "." + fieldName;
if (plotData->haveSubField) { if (!elementName.isEmpty()) {
curveName = curveName.append("." + plotData->uavSubField); curveName.append("." + elementName);
} }
// Get the uav object // Get the uav object
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject *obj = dynamic_cast<UAVDataObject *>(objManager->getObject((plotData->uavObject))); UAVDataObject *obj = dynamic_cast<UAVDataObject *>(objManager->getObject(objectName));
if (!obj) { if (!obj) {
qDebug() << "Object " << plotData->uavObject << " is missing"; qDebug() << "Object " << objectName << " is missing";
return; return;
} }
UAVObjectField *field = obj->getField(plotData->uavField); UAVObjectField *field = obj->getField(fieldName);
if (!field) { if (!field) {
qDebug() << "In scope gadget, in fields loaded from GCS config file, field" << plotData->uavField << " of object " << plotData->uavObject << " is missing"; qDebug() << "In scope gadget, in fields loaded from GCS config file, field" <<
fieldName << " of object " << objectName << " is missing";
return; return;
} }
QString units = field->getUnits(); QString units = field->getUnits();
@ -419,10 +408,10 @@ void ScopeGadgetWidget::addCurvePlot(QString uavObject, QString uavFieldSubField
} }
QString curveNameScaled; QString curveNameScaled;
if (scaleOrderFactor == 0) { if (scaleFactor == 0) {
curveNameScaled = curveName + " (" + units + ")"; curveNameScaled = curveName + " (" + units + ")";
} else { } else {
curveNameScaled = curveName + " (x10^" + QString::number(scaleOrderFactor) + " " + units + ")"; curveNameScaled = curveName + " (x10^" + QString::number(scaleFactor) + " " + units + ")";
} }
QwtPlotCurve *plotCurve = new QwtPlotCurve(curveNameScaled); QwtPlotCurve *plotCurve = new QwtPlotCurve(curveNameScaled);
@ -432,9 +421,22 @@ void ScopeGadgetWidget::addCurvePlot(QString uavObject, QString uavFieldSubField
} }
plotCurve->setPen(pen); plotCurve->setPen(pen);
plotCurve->setSamples(*plotData->xData, *plotData->yData);
plotCurve->attach(this); plotCurve->attach(this);
plotData->curve = plotCurve;
PlotData *plotData;
if (m_plotType == SequentialPlot) {
plotData = new SequentialPlotData(objectName, fieldName, elementName, plotCurve, scaleFactor,
meanSamples, mathFunction, m_plotDataSize);
} else if (m_plotType == ChronoPlot) {
plotData = new ChronoPlotData(objectName, fieldName, elementName, plotCurve, scaleFactor,
meanSamples, mathFunction, m_plotDataSize);
}
// If the y-bounds are supplied, set them
if (plotData->yMin() != plotData->yMax()) {
setAxisScale(QwtPlot::yLeft, plotData->yMin(), plotData->yMax());
}
// Keep the curve details for later // Keep the curve details for later
m_curvesData.insert(curveNameScaled, plotData); m_curvesData.insert(curveNameScaled, plotData);
@ -450,22 +452,6 @@ void ScopeGadgetWidget::addCurvePlot(QString uavObject, QString uavFieldSubField
mutex.unlock(); mutex.unlock();
} }
// void ScopeGadgetWidget::removeCurvePlot(QString uavObject, QString uavField)
// {
// QString curveName = uavObject + "." + uavField;
//
// PlotData* plotData = m_curvesData.take(curveName);
// m_curvesData.remove(curveName);
// plotData->curve->detach();
//
// delete plotData->curve;
// delete plotData;
//
// mutex.lock();
// replot();
// mutex.unlock();
// }
void ScopeGadgetWidget::uavObjectReceived(UAVObject *obj) void ScopeGadgetWidget::uavObjectReceived(UAVObject *obj)
{ {
foreach(PlotData * plotData, m_curvesData.values()) { foreach(PlotData * plotData, m_curvesData.values()) {
@ -485,14 +471,14 @@ void ScopeGadgetWidget::replotNewData()
QMutexLocker locker(&mutex); QMutexLocker locker(&mutex);
foreach(PlotData * plotData, m_curvesData.values()) { foreach(PlotData * plotData, m_curvesData.values()) {
plotData->removeStaleData(); plotData->removeStaleData();
plotData->curve->setSamples(*plotData->xData, *plotData->yData); plotData->updatePlotCurveData();
} }
QDateTime NOW = QDateTime::currentDateTime(); QDateTime NOW = QDateTime::currentDateTime();
double toTime = NOW.toTime_t(); double toTime = NOW.toTime_t();
toTime += NOW.time().msec() / 1000.0; toTime += NOW.time().msec() / 1000.0;
if (m_plotType == ChronoPlot) { if (m_plotType == ChronoPlot) {
setAxisScale(QwtPlot::xBottom, toTime - m_xWindowSize, toTime); setAxisScale(QwtPlot::xBottom, toTime - m_plotDataSize, toTime);
} }
// qDebug() << "replotNewData from " << NOW.addSecs(- m_xWindowSize) << " to " << NOW; // qDebug() << "replotNewData from " << NOW.addSecs(- m_xWindowSize) << " to " << NOW;
@ -505,9 +491,6 @@ void ScopeGadgetWidget::replotNewData()
void ScopeGadgetWidget::clearCurvePlots() void ScopeGadgetWidget::clearCurvePlots()
{ {
foreach(PlotData * plotData, m_curvesData.values()) { foreach(PlotData * plotData, m_curvesData.values()) {
plotData->curve->detach();
delete plotData->curve;
delete plotData; delete plotData;
} }
@ -516,11 +499,12 @@ void ScopeGadgetWidget::clearCurvePlots()
void ScopeGadgetWidget::saveState(QSettings *qSettings) void ScopeGadgetWidget::saveState(QSettings *qSettings)
{ {
/*
// plot state // plot state
int i = 1; int i = 1;
foreach(PlotData * plotData, m_curvesData.values()) { foreach(PlotData * plotData, m_curvesData.values()) {
bool plotVisible = plotData->curve->isVisible(); bool plotVisible = plotData->isVisible();
if (!plotVisible) { if (!plotVisible) {
qSettings->setValue(QString("plot%1").arg(i), plotVisible); qSettings->setValue(QString("plot%1").arg(i), plotVisible);
@ -529,17 +513,19 @@ void ScopeGadgetWidget::saveState(QSettings *qSettings)
} }
// legend state // legend state
qSettings->setValue("legendVisible", legend() != NULL); qSettings->setValue("legendVisible", legend() != NULL);
*/
} }
void ScopeGadgetWidget::restoreState(QSettings *qSettings) void ScopeGadgetWidget::restoreState(QSettings *qSettings)
{ {
/*
// plot state // plot state
int i = 1; int i = 1;
foreach(PlotData * plotData, m_curvesData.values()) { foreach(PlotData * plotData, m_curvesData.values()) {
bool visible = qSettings->value(QString("plot%1").arg(i), true).toBool(); bool visible = qSettings->value(QString("plot%1").arg(i), true).toBool();
showCurve(plotData->curve, !visible); showCurve(plotData->m_plotCurve, !visible);
i++; i++;
} }
// legend state // legend state
@ -549,6 +535,7 @@ void ScopeGadgetWidget::restoreState(QSettings *qSettings)
} else { } else {
deleteLegend(); deleteLegend();
} }
*/
} }
/* /*
@ -621,10 +608,10 @@ int ScopeGadgetWidget::csvLoggingInsertHeader()
foreach(PlotData * plotData2, m_curvesData.values()) { foreach(PlotData * plotData2, m_curvesData.values()) {
ts << ", "; ts << ", ";
ts << plotData2->uavObject; ts << plotData2->objectName();
ts << "." << plotData2->uavField; ts << "." << plotData2->fieldName();
if (plotData2->haveSubField) { if (!plotData2->elementName().isEmpty()) {
ts << "." << plotData2->uavSubField; ts << "." << plotData2->elementName();
} }
} }
ts << endl; ts << endl;
@ -655,14 +642,14 @@ int ScopeGadgetWidget::csvLoggingAddData()
foreach(PlotData * plotData2, m_curvesData.values()) { foreach(PlotData * plotData2, m_curvesData.values()) {
ss << ", "; ss << ", ";
if (plotData2->xData->isEmpty()) { if (plotData2->xData.isEmpty()) {
ss << ", "; ss << ", ";
if (plotData2->xData->isEmpty()) {} else { if (plotData2->xData.isEmpty()) {} else {
ss << QString().sprintf("%3.10g", plotData2->yData->last()); ss << QString().sprintf("%3.10g", plotData2->yData.last());
m_csvLoggingDataValid = 1; m_csvLoggingDataValid = 1;
} }
} else { } else {
ss << QString().sprintf("%3.10g", plotData2->yData->last()); ss << QString().sprintf("%3.10g", plotData2->yData.last());
m_csvLoggingDataValid = 1; m_csvLoggingDataValid = 1;
} }
} }

View File

@ -76,13 +76,13 @@ public:
return m_plotType; return m_plotType;
} }
void setXWindowSize(double xWindowSize) void setPlotDataSize(double plotDataSize)
{ {
m_xWindowSize = xWindowSize; m_plotDataSize = plotDataSize;
} }
double xWindowSize() double plotDataSize()
{ {
return m_xWindowSize; return m_plotDataSize;
} }
void setRefreshInterval(double refreshInterval) void setRefreshInterval(double refreshInterval)
{ {
@ -142,7 +142,7 @@ private:
PlotType m_plotType; PlotType m_plotType;
double m_xWindowSize; double m_plotDataSize;
int m_refreshInterval; int m_refreshInterval;
QList<QString> m_connectedUAVObjects; QList<QString> m_connectedUAVObjects;
QMap<QString, PlotData *> m_curvesData; QMap<QString, PlotData *> m_curvesData;