dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
scatterplotdata.cpp
Go to the documentation of this file.
1 
12 /*
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  * for more details.
22  *
23  * You should have received a copy of the GNU General Public License along
24  * with this program; if not, see <http://www.gnu.org/licenses/>
25  */
26 
27 #include <QDebug>
28 #include <math.h>
29 
34 #include "scopegadgetwidget.h"
35 
36 #include "qwt/src/qwt.h"
37 #include "qwt/src/qwt_plot.h"
38 #include "qwt/src/qwt_plot_curve.h"
39 
44 void TimeSeriesPlotData::plotNewData(PlotData *plot2dData, ScopeConfig *scopeConfig,
45  ScopeGadgetWidget *scopeGadgetWidget)
46 {
47  Q_UNUSED(plot2dData);
48  Q_UNUSED(scopeConfig);
49  Q_UNUSED(scopeGadgetWidget);
50 
51  // Plot new data
52  if (readAndResetUpdatedFlag() == true)
53  curve->setSamples(*xData, *yData);
54 
55  QDateTime NOW = QDateTime::currentDateTime();
56  double toTime = NOW.toTime_t();
57  toTime += NOW.time().msec() / 1000.0;
58 
59  scopeGadgetWidget->setAxisScale(QwtPlot::xBottom, toTime - m_xWindowSize, toTime);
60 }
61 
66 void SeriesPlotData::plotNewData(PlotData *plot2dData, ScopeConfig *scopeConfig,
67  ScopeGadgetWidget *scopeGadgetWidget)
68 {
69  Q_UNUSED(plot2dData);
70  Q_UNUSED(scopeConfig);
71  Q_UNUSED(scopeGadgetWidget);
72 
73  // Plot new data
74  if (readAndResetUpdatedFlag() == true)
75  curve->setSamples(*xData, *yData);
76 }
77 
84 {
85  if (uavObjectName == obj->getName()) {
86 
87  // Get the field of interest
88  UAVObjectField *field = obj->getField(uavFieldName);
89 
90  if (field) {
91 
92  double currentValue =
93  valueAsDouble(obj, field, haveSubField, uavSubFieldName) * pow(10, scalePower);
94 
95  // Perform scope math, if necessary
96  if (mathFunction == "Boxcar average" || mathFunction == "Standard deviation") {
97  // Put the new value at the front
98  yDataHistory->append(currentValue);
99 
100  // calculate average value
101  meanSum += currentValue;
102  if (yDataHistory->size() > (int)meanSamples) {
103  meanSum -= yDataHistory->first();
104  yDataHistory->pop_front();
105  }
106 
107  // make sure to correct the sum every meanSamples steps to prevent it
108  // from running away due to floating point rounding errors
109  correctionSum += currentValue;
110  if (++correctionCount >= (int)meanSamples) {
112  correctionSum = 0.0f;
113  correctionCount = 0;
114  }
115 
116  double boxcarAvg = meanSum / yDataHistory->size();
117 
118  if (mathFunction == "Standard deviation") {
119  // Calculate square of sample standard deviation, with Bessel's correction
120  double stdSum = 0;
121  for (int i = 0; i < yDataHistory->size(); i++) {
122  stdSum += pow(yDataHistory->at(i) - boxcarAvg, 2) / (meanSamples - 1);
123  }
124  yData->append(sqrt(stdSum));
125  } else {
126  yData->append(boxcarAvg);
127  }
128  } else {
129  yData->append(currentValue);
130  }
131 
132  if (yData->size()
133  > getXWindowSize()) { // If new data overflows the window, remove old data...
134  yData->pop_front();
135  } else //...otherwise, add a new y point at position xData
136  xData->insert(xData->size(), xData->size());
137 
138  return true;
139  }
140  }
141 
142  return false;
143 }
144 
151 {
152  if (uavObjectName == obj->getName()) {
153  // Get the field of interest
154  UAVObjectField *field = obj->getField(uavFieldName);
155 
156  if (field) {
157  QDateTime NOW = QDateTime::currentDateTime(); // THINK ABOUT REIMPLEMENTING THIS TO SHOW
158  // UAVO TIME, NOT SYSTEM TIME
159  double currentValue =
160  valueAsDouble(obj, field, haveSubField, uavSubFieldName) * pow(10, scalePower);
161 
162  // Perform scope math, if necessary
163  if (mathFunction == "Boxcar average" || mathFunction == "Standard deviation") {
164  // Put the new value at the back
165  yDataHistory->append(currentValue);
166 
167  // calculate average value
168  meanSum += currentValue;
169  if (yDataHistory->size() > (int)meanSamples) {
170  meanSum -= yDataHistory->first();
171  yDataHistory->pop_front();
172  }
173  // make sure to correct the sum every meanSamples steps to prevent it
174  // from running away due to floating point rounding errors
175  correctionSum += currentValue;
176  if (++correctionCount >= (int)meanSamples) {
178  correctionSum = 0.0f;
179  correctionCount = 0;
180  }
181 
182  double boxcarAvg = meanSum / yDataHistory->size();
183 
184  if (mathFunction == "Standard deviation") {
185  // Calculate square of sample standard deviation, with Bessel's correction
186  double stdSum = 0;
187  for (int i = 0; i < yDataHistory->size(); i++) {
188  stdSum += pow(yDataHistory->at(i) - boxcarAvg, 2) / (meanSamples - 1);
189  }
190  yData->append(sqrt(stdSum));
191  } else {
192  yData->append(boxcarAvg);
193  }
194  } else {
195  yData->append(currentValue);
196  }
197 
198  double valueX = NOW.toTime_t() + NOW.time().msec() / 1000.0;
199  xData->append(valueX);
200 
201  // Remove stale data
202  removeStaleData();
203 
204  return true;
205  }
206  }
207 
208  return false;
209 }
210 
215 {
216  double newestValue;
217  double oldestValue;
218 
219  while (1) {
220  if (xData->size() == 0)
221  break;
222 
223  newestValue = xData->last();
224  oldestValue = xData->first();
225 
226  if (newestValue - oldestValue > getXWindowSize()) {
227  yData->pop_front();
228  xData->pop_front();
229  } else
230  break;
231  }
232 }
233 
238 void TimeSeriesPlotData::removeStaleDataTimeout()
239 {
240  removeStaleData();
241 }
242 
247 {
248  curve->detach();
249 
250  delete curve;
251  delete scatterplotData;
252 }
253 
258 {
259  yData->clear();
260  xData->clear();
261 }
unsigned int meanSamples
Definition: plotdata.h:105
QVector< double > * xData
Definition: plotdata.h:90
virtual void deletePlots(PlotData *)
ScatterplotData::deletePlots Delete all plot data.
virtual bool readAndResetUpdatedFlag()
Definition: plotdata2d.h:50
bool append(UAVObject *obj)
TimeSeriesPlotData::append Appends data to time series data.
QVector< double > * yDataHistory
Definition: plotdata2d.h:47
virtual void plotNewData(PlotData *, ScopeConfig *, ScopeGadgetWidget *)
Scatterplot2dScopeConfig::plotNewData Update plot with new data.
double correctionSum
Definition: plotdata.h:109
QString uavFieldName
Definition: plotdata.h:100
virtual void removeStaleData()
TimeSeriesPlotData::removeStaleData Removes stale data from time series plot.
double meanSum
Definition: plotdata.h:107
for i
Definition: OPPlots.m:140
void clearPlots()
ScatterplotData::clearPlots Clear all plot data.
int correctionCount
Definition: plotdata.h:110
QVector< double > * yData
Definition: plotdata.h:91
virtual void plotNewData(PlotData *, ScopeConfig *, ScopeGadgetWidget *)
Scatterplot2dScopeConfig::plotNewData Update plot with new data.
bool append(UAVObject *obj)
Append new data to the plot.
UAVObjectField * getField(const QString &name)
Definition: uavobject.cpp:236
double getXWindowSize()
Definition: plotdata.h:65
The ScopeConfig class The parent class for scope configuration classes data sources.
Definition: scopesconfig.h:56
QString uavSubFieldName
Definition: plotdata.h:101
int scalePower
Definition: plotdata.h:104
QString getName()
Definition: uavobject.cpp:131
bool haveSubField
Definition: plotdata.h:102
Scope Plugin Gadget Widget.
QString mathFunction
Definition: plotdata.h:106
double valueAsDouble(UAVObject *obj, UAVObjectField *field, bool haveSubField, QString uavSubFieldName)
valueAsDouble Fetch the value from the UAVO and return it as a double
Definition: plotdata.cpp:148
QString uavObjectName
Definition: plotdata.h:99
QwtPlotCurve * curve
double m_xWindowSize
Definition: plotdata.h:93