2010-08-10 07:42:39 +02:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
*
|
|
|
|
* @file scopegadgetwidget.cpp
|
|
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
|
|
* @addtogroup GCSPlugins GCS Plugins
|
|
|
|
* @{
|
|
|
|
* @addtogroup ScopePlugin Scope Gadget Plugin
|
|
|
|
* @{
|
|
|
|
* @brief The scope Gadget, graphically plots the states of UAVObjects
|
|
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* 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 "scopegadgetwidget.h"
|
2010-08-26 21:54:23 +02:00
|
|
|
#include "utils/stylehelper.h"
|
2010-08-10 07:42:39 +02:00
|
|
|
|
2011-01-20 23:30:49 +01:00
|
|
|
#include "uavtalk/telemetrymanager.h"
|
|
|
|
#include "extensionsystem/pluginmanager.h"
|
2011-01-22 18:38:22 +01:00
|
|
|
#include "uavobjectmanager.h"
|
|
|
|
#include "uavobject.h"
|
2011-01-20 23:30:49 +01:00
|
|
|
#include "coreplugin/icore.h"
|
|
|
|
#include "coreplugin/connectionmanager.h"
|
|
|
|
|
2010-08-10 07:42:39 +02:00
|
|
|
#include "qwt/src/qwt_plot_curve.h"
|
|
|
|
#include "qwt/src/qwt_legend.h"
|
|
|
|
#include "qwt/src/qwt_legend_item.h"
|
|
|
|
#include "qwt/src/qwt_plot_grid.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <math.h>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QColor>
|
|
|
|
#include <QStringList>
|
|
|
|
#include <QtGui/QWidget>
|
|
|
|
#include <QtGui/QVBoxLayout>
|
|
|
|
#include <QtGui/QPushButton>
|
|
|
|
|
2011-01-20 23:30:49 +01:00
|
|
|
using namespace Core;
|
2010-08-10 07:42:39 +02:00
|
|
|
|
|
|
|
TestDataGen* ScopeGadgetWidget::testDataGen;
|
|
|
|
|
|
|
|
ScopeGadgetWidget::ScopeGadgetWidget(QWidget *parent) : QwtPlot(parent)
|
|
|
|
{
|
2010-09-01 23:29:24 +02:00
|
|
|
//if(testDataGen == 0)
|
|
|
|
// testDataGen = new TestDataGen();
|
2010-08-10 07:42:39 +02:00
|
|
|
|
2010-08-14 22:25:55 +02:00
|
|
|
//Setup the timer that replots data
|
|
|
|
replotTimer = new QTimer(this);
|
|
|
|
connect(replotTimer, SIGNAL(timeout()), this, SLOT(replotNewData()));
|
2011-01-20 23:30:49 +01:00
|
|
|
|
|
|
|
// Listen to telemetry connection/disconnection events, no point
|
|
|
|
// running the scopes if we are not connected and not replaying logs
|
|
|
|
// Also listen to disconnect actions from the user
|
|
|
|
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
|
|
|
connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(onTelemetryDisconnected()));
|
|
|
|
connect(cm, SIGNAL(deviceConnected(QIODevice*)), this, SLOT(onTelemetryConnected()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Starts/stops telemetry
|
|
|
|
*/
|
|
|
|
void ScopeGadgetWidget::onTelemetryConnected()
|
|
|
|
{
|
|
|
|
if(!replotTimer->isActive())
|
|
|
|
replotTimer->start(m_refreshInterval);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScopeGadgetWidget::onTelemetryDisconnected()
|
|
|
|
{
|
|
|
|
replotTimer->stop();
|
2010-08-10 07:42:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ScopeGadgetWidget::preparePlot(PlotType plotType)
|
|
|
|
{
|
|
|
|
m_plotType = plotType;
|
|
|
|
|
|
|
|
clearCurvePlots();
|
|
|
|
|
|
|
|
setMinimumSize(64, 64);
|
|
|
|
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
|
|
|
// Show a title
|
2010-08-14 22:25:55 +02:00
|
|
|
setTitle("Scope");
|
|
|
|
|
2010-08-26 21:54:23 +02:00
|
|
|
setCanvasBackground(Utils::StyleHelper::baseColor());
|
2010-08-14 22:25:55 +02:00
|
|
|
|
|
|
|
//Add grid lines
|
|
|
|
QwtPlotGrid *grid = new QwtPlotGrid;
|
|
|
|
grid->setMajPen(QPen(Qt::gray, 0, Qt::DashLine));
|
|
|
|
grid->setMinPen(QPen(Qt::lightGray, 0 , Qt::DotLine));
|
|
|
|
grid->attach(this);
|
2010-08-10 07:42:39 +02:00
|
|
|
|
|
|
|
// Show a legend at the bottom
|
|
|
|
if (legend() == 0) {
|
|
|
|
QwtLegend *legend = new QwtLegend();
|
|
|
|
legend->setItemMode(QwtLegend::CheckableItem);
|
|
|
|
legend->setFrameStyle(QFrame::Box | QFrame::Sunken);
|
|
|
|
insertLegend(legend, QwtPlot::BottomLegend);
|
|
|
|
}
|
|
|
|
|
|
|
|
connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)),this, SLOT(showCurve(QwtPlotItem *, bool)));
|
2010-08-14 22:25:55 +02:00
|
|
|
|
2011-01-20 23:30:49 +01:00
|
|
|
// Only start the timer if we are already connected
|
|
|
|
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
|
|
|
if (cm->getCurrentConnection()) {
|
|
|
|
if(!replotTimer->isActive())
|
|
|
|
replotTimer->start(m_refreshInterval);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
replotTimer->setInterval(m_refreshInterval);
|
|
|
|
}
|
2010-08-14 22:25:55 +02:00
|
|
|
}
|
|
|
|
|
2010-08-10 07:42:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ScopeGadgetWidget::showCurve(QwtPlotItem *item, bool on)
|
|
|
|
{
|
|
|
|
item->setVisible(!on);
|
|
|
|
QWidget *w = legend()->find(item);
|
|
|
|
if ( w && w->inherits("QwtLegendItem") )
|
|
|
|
((QwtLegendItem *)w)->setChecked(on);
|
|
|
|
|
|
|
|
replot();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScopeGadgetWidget::setupSequencialPlot()
|
|
|
|
{
|
|
|
|
preparePlot(SequencialPlot);
|
|
|
|
|
|
|
|
setAxisTitle(QwtPlot::xBottom, "Index");
|
|
|
|
setAxisScaleDraw(QwtPlot::xBottom, new QwtScaleDraw());
|
|
|
|
setAxisScale(QwtPlot::xBottom, 0, m_xWindowSize);
|
|
|
|
setAxisLabelRotation(QwtPlot::xBottom, 0.0);
|
|
|
|
setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScopeGadgetWidget::setupChronoPlot()
|
|
|
|
{
|
|
|
|
preparePlot(ChronoPlot);
|
|
|
|
|
|
|
|
setAxisTitle(QwtPlot::xBottom, "Time [h:m:s]");
|
|
|
|
setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw());
|
|
|
|
uint NOW = QDateTime::currentDateTime().toTime_t();
|
2010-08-14 22:25:55 +02:00
|
|
|
setAxisScale(QwtPlot::xBottom, NOW - m_xWindowSize / 1000, NOW);
|
|
|
|
setAxisLabelRotation(QwtPlot::xBottom, -15.0);
|
2010-08-10 07:42:39 +02:00
|
|
|
setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom);
|
|
|
|
|
|
|
|
/*
|
|
|
|
In situations, when there is a label at the most right position of the
|
|
|
|
scale, additional space is needed to display the overlapping part
|
|
|
|
of the label would be taken by reducing the width of scale and canvas.
|
|
|
|
To avoid this "jumping canvas" effect, we add a permanent margin.
|
|
|
|
We don't need to do the same for the left border, because there
|
|
|
|
is enough space for the overlapping label below the left scale.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QwtScaleWidget *scaleWidget = axisWidget(QwtPlot::xBottom);
|
|
|
|
const int fmh = QFontMetrics(scaleWidget->font()).height();
|
|
|
|
scaleWidget->setMinBorderDist(0, fmh / 2);
|
|
|
|
}
|
|
|
|
|
2010-09-01 23:29:24 +02:00
|
|
|
void ScopeGadgetWidget::addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor, QPen pen)
|
2010-08-10 07:42:39 +02:00
|
|
|
{
|
|
|
|
PlotData* plotData;
|
|
|
|
|
|
|
|
if (m_plotType == SequencialPlot)
|
2010-09-01 23:29:24 +02:00
|
|
|
plotData = new SequencialPlotData(uavObject, uavFieldSubField);
|
2010-08-10 07:42:39 +02:00
|
|
|
else if (m_plotType == ChronoPlot)
|
2010-09-01 23:29:24 +02:00
|
|
|
plotData = new ChronoPlotData(uavObject, uavFieldSubField);
|
2010-08-10 07:42:39 +02:00
|
|
|
//else if (m_plotType == UAVObjectPlot)
|
|
|
|
// plotData = new UAVObjectPlotData(uavObject, uavField);
|
|
|
|
|
|
|
|
plotData->m_xWindowSize = m_xWindowSize;
|
|
|
|
plotData->scalePower = scaleOrderFactor;
|
|
|
|
|
|
|
|
//If the y-bounds are supplied, set them
|
|
|
|
if (plotData->yMinimum != plotData->yMaximum)
|
|
|
|
setAxisScale(QwtPlot::yLeft, plotData->yMinimum, plotData->yMaximum);
|
|
|
|
|
2010-08-30 16:17:15 +02:00
|
|
|
//Create the curve
|
|
|
|
QString curveName = (plotData->uavObject) + "." + (plotData->uavField);
|
|
|
|
if(plotData->haveSubField)
|
|
|
|
curveName = curveName.append("." + plotData->uavSubField);
|
|
|
|
|
2010-09-01 23:29:24 +02:00
|
|
|
//Get the uav object
|
|
|
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
|
|
|
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
|
|
|
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject((plotData->uavObject)));
|
|
|
|
|
|
|
|
UAVObjectField* field = obj->getField(plotData->uavField);
|
|
|
|
QString units = field->getUnits();
|
|
|
|
|
|
|
|
if(units == 0)
|
|
|
|
units = QString();
|
|
|
|
|
2010-08-30 16:17:15 +02:00
|
|
|
QString curveNameScaled;
|
2010-08-30 00:45:12 +02:00
|
|
|
if(scaleOrderFactor == 0)
|
2010-09-01 23:29:24 +02:00
|
|
|
curveNameScaled = curveName + "(" + units + ")";
|
2010-08-30 00:45:12 +02:00
|
|
|
else
|
2010-09-01 23:29:24 +02:00
|
|
|
curveNameScaled = curveName + "(x10^" + QString::number(scaleOrderFactor) + " " + units + ")";
|
2010-08-30 00:45:12 +02:00
|
|
|
|
2010-08-30 16:17:15 +02:00
|
|
|
QwtPlotCurve* plotCurve = new QwtPlotCurve(curveNameScaled);
|
2010-08-10 07:42:39 +02:00
|
|
|
plotCurve->setPen(pen);
|
|
|
|
plotCurve->setData(*plotData->xData, *plotData->yData);
|
|
|
|
plotCurve->attach(this);
|
|
|
|
plotData->curve = plotCurve;
|
|
|
|
|
|
|
|
//Keep the curve details for later
|
2010-08-30 16:17:15 +02:00
|
|
|
m_curvesData.insert(curveNameScaled, plotData);
|
2010-08-10 07:42:39 +02:00
|
|
|
|
|
|
|
//Link to the signal of new data only if this UAVObject has not been to connected yet
|
|
|
|
if (!m_connectedUAVObjects.contains(obj->getName())) {
|
|
|
|
m_connectedUAVObjects.append(obj->getName());
|
|
|
|
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(uavObjectReceived(UAVObject*)));
|
|
|
|
}
|
|
|
|
|
|
|
|
replot();
|
|
|
|
}
|
|
|
|
|
2010-08-30 16:17:15 +02:00
|
|
|
//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;
|
|
|
|
//
|
|
|
|
// replot();
|
|
|
|
//}
|
2010-08-10 07:42:39 +02:00
|
|
|
|
|
|
|
void ScopeGadgetWidget::uavObjectReceived(UAVObject* obj)
|
|
|
|
{
|
|
|
|
foreach(PlotData* plotData, m_curvesData.values()) {
|
|
|
|
plotData->append(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScopeGadgetWidget::replotNewData()
|
|
|
|
{
|
2010-08-14 22:25:55 +02:00
|
|
|
foreach(PlotData* plotData, m_curvesData.values()) {
|
|
|
|
plotData->removeStaleData();
|
|
|
|
plotData->curve->setData(*plotData->xData, *plotData->yData);
|
|
|
|
}
|
|
|
|
|
|
|
|
QDateTime NOW = QDateTime::currentDateTime();
|
|
|
|
double toTime = NOW.toTime_t();
|
|
|
|
toTime += NOW.time().msec() / 1000.0;
|
2010-08-10 07:42:39 +02:00
|
|
|
if (m_plotType == ChronoPlot) {
|
2010-08-14 22:25:55 +02:00
|
|
|
setAxisScale(QwtPlot::xBottom, toTime - m_xWindowSize, toTime);
|
2010-08-10 07:42:39 +02:00
|
|
|
}
|
2010-08-14 22:25:55 +02:00
|
|
|
//qDebug() << "replotNewData from " << NOW.addSecs(- m_xWindowSize) << " to " << NOW;
|
|
|
|
|
2010-08-10 07:42:39 +02:00
|
|
|
replot();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScopeGadgetWidget::setupExamplePlot()
|
|
|
|
{
|
|
|
|
preparePlot(SequencialPlot);
|
|
|
|
|
|
|
|
// Show the axes
|
|
|
|
|
|
|
|
setAxisTitle(xBottom, "x");
|
|
|
|
setAxisTitle(yLeft, "y");
|
|
|
|
|
|
|
|
// Calculate the data, 500 points each
|
|
|
|
const int points = 500;
|
|
|
|
double x[ points ];
|
|
|
|
double sn[ points ];
|
|
|
|
double cs[ points ];
|
|
|
|
double sg[ points ];
|
|
|
|
|
|
|
|
for (int i = 0; i < points; i++) {
|
|
|
|
x[i] = (3.0 * 3.14 / double(points)) * double(i);
|
|
|
|
sn[i] = 2.0 * sin(x[i]);
|
|
|
|
cs[i] = 3.0 * cos(x[i]);
|
|
|
|
sg[i] = (sn[i] > 0) ? 1 : ((sn[i] < 0) ? -1 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// add curves
|
|
|
|
QwtPlotCurve *curve1 = new QwtPlotCurve("Curve 1");
|
|
|
|
curve1->setPen(QPen(Qt::blue));
|
|
|
|
QwtPlotCurve *curve2 = new QwtPlotCurve("Curve 2");
|
|
|
|
curve2->setPen(QPen(Qt::red));
|
|
|
|
QwtPlotCurve *curve3 = new QwtPlotCurve("Curve 3");
|
|
|
|
curve3->setPen(QPen(Qt::green));
|
|
|
|
|
|
|
|
// copy the data into the curves
|
|
|
|
curve1->setData(x, sn, points);
|
|
|
|
curve2->setData(x, cs, points);
|
|
|
|
curve3->setData(x, sg, points);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
curve1->attach(this);
|
|
|
|
curve2->attach(this);
|
|
|
|
curve3->attach(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// finally, refresh the plot
|
|
|
|
replot();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ScopeGadgetWidget::~ScopeGadgetWidget()
|
|
|
|
{
|
2010-08-14 22:25:55 +02:00
|
|
|
if (replotTimer)
|
|
|
|
replotTimer->stop();
|
|
|
|
delete replotTimer;
|
|
|
|
replotTimer = 0;
|
|
|
|
|
2010-08-10 07:42:39 +02:00
|
|
|
//Get the object to de-monitor
|
|
|
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
|
|
|
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
|
|
|
|
|
|
|
foreach(QString uavObjName, m_connectedUAVObjects) {
|
|
|
|
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(uavObjName));
|
|
|
|
disconnect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(uavObjectReceived(UAVObject*)));
|
|
|
|
}
|
|
|
|
|
|
|
|
clearCurvePlots();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScopeGadgetWidget::clearCurvePlots()
|
|
|
|
{
|
|
|
|
foreach(PlotData* plotData, m_curvesData.values()) {
|
|
|
|
plotData->curve->detach();
|
|
|
|
|
|
|
|
delete plotData->curve;
|
|
|
|
delete plotData;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_curvesData.clear();
|
|
|
|
}
|
|
|
|
|
2010-08-14 22:25:55 +02:00
|
|
|
|
2010-08-10 07:42:39 +02:00
|
|
|
TestDataGen::TestDataGen()
|
|
|
|
{
|
|
|
|
// Get required UAVObjects
|
|
|
|
ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
|
|
|
|
UAVObjectManager* objManager = pm->getObject<UAVObjectManager>();
|
|
|
|
|
2010-08-21 18:19:10 +02:00
|
|
|
baroAltitude = BaroAltitude::GetInstance(objManager);
|
2010-08-10 07:42:39 +02:00
|
|
|
gps = PositionActual::GetInstance(objManager);
|
2010-08-30 16:17:15 +02:00
|
|
|
attRaw = AttitudeRaw::GetInstance(objManager);
|
|
|
|
manCtrlCmd = ManualControlCommand::GetInstance(objManager);
|
2010-08-10 07:42:39 +02:00
|
|
|
|
|
|
|
//Setup timer
|
2010-08-30 16:17:15 +02:00
|
|
|
periodMs = 20;
|
2010-08-10 07:42:39 +02:00
|
|
|
timer = new QTimer(this);
|
|
|
|
connect(timer, SIGNAL(timeout()), this, SLOT(genTestData()));
|
2010-08-14 22:25:55 +02:00
|
|
|
timer->start(periodMs);
|
|
|
|
|
|
|
|
debugCounter = 0;
|
2010-08-30 16:17:15 +02:00
|
|
|
testTime = 0;
|
2010-08-10 07:42:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void TestDataGen::genTestData()
|
|
|
|
{
|
2010-08-21 18:19:10 +02:00
|
|
|
// Update BaroAltitude object
|
|
|
|
BaroAltitude::DataFields baroAltitudeData;
|
|
|
|
baroAltitudeData.Altitude = 500 * sin(1 * testTime) + 200 * cos(4 * testTime) + 800;
|
|
|
|
baroAltitudeData.Temperature = 30 * sin(0.5 * testTime);
|
2010-08-30 00:45:12 +02:00
|
|
|
baroAltitudeData.Pressure = baroAltitudeData.Altitude * 0.01 + baroAltitudeData.Temperature;
|
2010-08-21 18:19:10 +02:00
|
|
|
baroAltitude->setData(baroAltitudeData);
|
2010-08-10 07:42:39 +02:00
|
|
|
|
2010-08-30 16:17:15 +02:00
|
|
|
// Update Attitude Raw data
|
|
|
|
AttitudeRaw::DataFields attData;
|
2010-08-30 21:39:56 +02:00
|
|
|
// attData.accels[0] = 4 * sin(2 * testTime) + 1 * cos(6 * testTime) + 4;
|
2010-08-30 16:17:15 +02:00
|
|
|
// attData.accels[1] = 3 * sin(2.3 * testTime) + 1.5 * cos(3.3 * testTime) + 2;
|
|
|
|
// attData.accels[2] = 4 * sin(5.3 * testTime) + 1.5 * cos(1.3 * testTime) + 1;
|
|
|
|
attData.accels[0] = 1;
|
|
|
|
attData.accels[1] = 4;
|
|
|
|
attData.accels[2] = 9;
|
|
|
|
attRaw->setData(attData);
|
|
|
|
|
|
|
|
|
|
|
|
ManualControlCommand::DataFields manCtlData;
|
|
|
|
manCtlData.Channel[0] = 400 * cos(2 * testTime) + 100 * sin(6 * testTime) + 400;
|
|
|
|
manCtlData.Channel[1] = 350 * cos(2.3 * testTime) + 150 * sin(3.3 * testTime) + 200;
|
|
|
|
manCtlData.Channel[2] = 450 * cos(5.3 * testTime) + 150 * sin(1.3 * testTime) + 150;
|
|
|
|
manCtrlCmd->setData(manCtlData);
|
|
|
|
|
2010-08-14 22:25:55 +02:00
|
|
|
testTime += (periodMs / 1000.0);
|
|
|
|
|
2010-08-26 21:54:23 +02:00
|
|
|
// debugCounter++;
|
|
|
|
// if (debugCounter % (100/periodMs) == 0 )
|
|
|
|
// qDebug() << "Test Time = " << testTime;
|
2010-08-10 07:42:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TestDataGen::~TestDataGen()
|
|
|
|
{
|
|
|
|
if (timer)
|
|
|
|
timer->stop();
|
|
|
|
|
|
|
|
delete timer;
|
|
|
|
}
|