added power hist

This commit is contained in:
Sean C. Rhea
2006-12-25 17:48:13 +00:00
parent 0d37100719
commit ccdbac9399
7 changed files with 245 additions and 4 deletions

View File

@@ -19,6 +19,7 @@ HEADERS += \
LogTimeScaleDraw.h \
LogTimeScaleEngine.h \
MainWindow.h \
PowerHist.h \
RawFile.h \
RideItem.h
SOURCES += \
@@ -29,6 +30,7 @@ SOURCES += \
LogTimeScaleDraw.cpp \
LogTimeScaleEngine.cpp \
MainWindow.cpp \
PowerHist.cpp \
RawFile.cpp \
RideItem.cpp \
\

View File

@@ -23,6 +23,7 @@
#include "ChooseCyclistDialog.h"
#include "CpintPlot.h"
#include "DownloadRideDialog.h"
#include "PowerHist.h"
#include "RawFile.h"
#include "RideItem.h"
#include "Settings.h"
@@ -152,6 +153,34 @@ MainWindow::MainWindow(const QDir &home) :
cpintPlot = new CpintPlot(home.path());
tabWidget->addTab(cpintPlot, "Critical Power Plot");
window = new QWidget;
vlayout = new QVBoxLayout;
QHBoxLayout *binWidthLayout = new QHBoxLayout;
QLabel *binWidthLabel = new QLabel(tr("Bin width (watts)"), window);
binWidthLineEdit = new QLineEdit(window);
binWidthLineEdit->setFixedWidth(30);
binWidthLayout->addWidget(binWidthLabel);
binWidthLayout->addWidget(binWidthLineEdit);
binWidthSlider = new QSlider(Qt::Horizontal);
binWidthSlider->setTickPosition(QSlider::TicksBelow);
binWidthSlider->setTickInterval(1);
binWidthSlider->setMinimum(1);
binWidthSlider->setMaximum(100);
binWidthLineEdit->setValidator(new QIntValidator(binWidthSlider->minimum(),
binWidthSlider->maximum(),
binWidthLineEdit));
binWidthLayout->addWidget(binWidthSlider);
powerHist = new PowerHist();
binWidthSlider->setValue(powerHist->binWidth());
binWidthLineEdit->setText(QString("%1").arg(powerHist->binWidth()));
vlayout->addWidget(powerHist);
vlayout->addLayout(binWidthLayout);
window->setLayout(vlayout);
window->show();
tabWidget->addTab(window, "Power Histogram");
connect(treeWidget, SIGNAL(itemSelectionChanged()),
this, SLOT(rideSelected()));
connect(splitter, SIGNAL(splitterMoved(int,int)),
@@ -170,6 +199,10 @@ MainWindow::MainWindow(const QDir &home) :
this, SLOT(setSmoothingFromSlider()));
connect(smoothLineEdit, SIGNAL(returnPressed()),
this, SLOT(setSmoothingFromLineEdit()));
connect(binWidthSlider, SIGNAL(valueChanged(int)),
this, SLOT(setBinWidthFromSlider()));
connect(binWidthLineEdit, SIGNAL(returnPressed()),
this, SLOT(setBinWidthFromLineEdit()));
connect(tabWidget, SIGNAL(currentChanged(int)),
this, SLOT(tabChanged(int)));
@@ -256,6 +289,7 @@ MainWindow::rideSelected()
allPlot->setData(ride->raw);
if (tabWidget->currentIndex() == 2)
cpintPlot->calculate(ride->fileName, ride->dateTime);
powerHist->setData(ride->raw);
return;
}
}
@@ -299,6 +333,25 @@ MainWindow::setSmoothingFromLineEdit()
}
}
void
MainWindow::setBinWidthFromSlider()
{
if (powerHist->binWidth() != binWidthSlider->value()) {
powerHist->setBinWidth(binWidthSlider->value());
binWidthLineEdit->setText(QString("%1").arg(powerHist->binWidth()));
}
}
void
MainWindow::setBinWidthFromLineEdit()
{
int value = binWidthLineEdit->text().toInt();
if (value != powerHist->binWidth()) {
powerHist->setBinWidth(value);
binWidthSlider->setValue(value);
}
}
void
MainWindow::tabChanged(int index)
{

View File

@@ -26,6 +26,7 @@
class AllPlot;
class CpintPlot;
class PowerHist;
class MainWindow : public QMainWindow
{
@@ -47,6 +48,8 @@ class MainWindow : public QMainWindow
void downloadRide();
void setSmoothingFromSlider();
void setSmoothingFromLineEdit();
void setBinWidthFromSlider();
void setBinWidthFromLineEdit();
void tabChanged(int index);
private:
@@ -62,7 +65,10 @@ class MainWindow : public QMainWindow
CpintPlot *cpintPlot;
QSlider *smoothSlider;
QLineEdit *smoothLineEdit;
QSlider *binWidthSlider;
QLineEdit *binWidthLineEdit;
QTreeWidgetItem *allRides;
PowerHist *powerHist;
};
#endif // _GC_MainWindow_h

107
src/gui/PowerHist.cpp Normal file
View File

@@ -0,0 +1,107 @@
/*
* $Id: PowerHist.cpp,v 1.2 2006/07/12 02:13:57 srhea Exp $
*
* Copyright (c) 2006 Sean C. Rhea (srhea@srhea.net)
*
* 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 2 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., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "PowerHist.h"
#include "RawFile.h"
#include "Settings.h"
#include <qwt_plot_curve.h>
#include <qwt_plot_grid.h>
#include <qwt_legend.h>
#include <qwt_data.h>
PowerHist::PowerHist() :
array(NULL), binw(20)
{
setCanvasBackground(Qt::white);
setAxisTitle(xBottom, "Power (watts)");
setAxisTitle(yLeft, "Cumulative Time (minutes)");
curve = new QwtPlotCurve("Power");
curve->setStyle(QwtPlotCurve::Steps);
curve->setRenderHint(QwtPlotItem::RenderAntialiased);
curve->setPen(QPen(Qt::red));
curve->attach(this);
grid = new QwtPlotGrid();
grid->enableX(false);
QPen gridPen;
gridPen.setStyle(Qt::DotLine);
grid->setPen(gridPen);
grid->attach(this);
}
void
PowerHist::recalc()
{
int count = (int) ceil((arrayLength - 1) / binw);
double *smoothWatts = new double[count+1];
double *smoothTime = new double[count+1];
int i;
for (i = 0; i < count; ++i) {
int low = i * binw;
int high = low + binw;
smoothWatts[i] = low;
smoothTime[i] = 0.0;
while (low < high)
smoothTime[i] += array[low++];
}
smoothTime[i] = 0.0;
smoothWatts[i] = i * binw;
curve->setData(smoothWatts, smoothTime, count+1);
setAxisScale(xBottom, 0.0, smoothWatts[count]);
setYMax();
replot();
delete [] smoothWatts;
delete [] smoothTime;
}
void
PowerHist::setYMax()
{
setAxisScale(yLeft, 0.0, curve->maxYValue() + 10.0);
}
void
PowerHist::setData(RawFile *raw)
{
setTitle(raw->startTime.toString(GC_DATETIME_FORMAT));
int maxPower = (int) round(raw->powerHist.keys().last());
delete [] array;
arrayLength = maxPower + 1;
array = new double[arrayLength];
for (int i = 0; i < arrayLength; ++i)
array[i] = 0.0;
QMapIterator<double,double> i(raw->powerHist);
while (i.hasNext()) {
i.next();
array[(int) round(i.key())] += i.value();
}
recalc();
}
void
PowerHist::setBinWidth(int value)
{
binw = value;
recalc();
}

62
src/gui/PowerHist.h Normal file
View File

@@ -0,0 +1,62 @@
/*
* $Id: PowerHist.h,v 1.2 2006/07/12 02:13:57 srhea Exp $
*
* Copyright (c) 2006 Sean C. Rhea (srhea@srhea.net)
*
* 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 2 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., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _GC_PowerHist_h
#define _GC_PowerHist_h 1
#include <qwt_plot.h>
class QwtPlotCurve;
class QwtPlotGrid;
class RawFile;
class PowerHist : public QwtPlot
{
Q_OBJECT
public:
QwtPlotCurve *curve;
PowerHist();
int binWidth() const { return binw; }
void setData(RawFile *raw);
public slots:
void setBinWidth(int value);
protected:
QwtPlotGrid *grid;
double *array;
int arrayLength;
int binw;
void recalc();
void setYMax();
};
#endif // _GC_PowerHist_h

View File

@@ -27,14 +27,17 @@ extern "C" {
struct RawFileReadState
{
QList<RawFilePoint*> &points;
QMap<double,double> &powerHist;
QStringList &errors;
double last_secs, last_miles;
unsigned last_interval;
time_t start_since_epoch;
unsigned rec_int;
RawFileReadState(QList<RawFilePoint*> &points, QStringList &errors) :
points(points), errors(errors), last_secs(0.0), last_miles(0.0),
last_interval(0), start_since_epoch(0), rec_int(0) {}
RawFileReadState(QList<RawFilePoint*> &points,
QMap<double,double> &powerHist,
QStringList &errors) :
points(points), powerHist(powerHist), errors(errors), last_secs(0.0),
last_miles(0.0), last_interval(0), start_since_epoch(0), rec_int(0) {}
};
static void
@@ -72,6 +75,12 @@ data_cb(double secs, double nm, double mph, double watts, double miles,
state->last_secs = secs;
state->last_miles = miles;
state->last_interval = interval;
double sum = state->rec_int * 0.021;
if (state->powerHist.contains(watts)) {
sum += state->powerHist.value(watts);
state->powerHist.remove(watts);
}
state->powerHist.insert(watts, sum);
}
static void
@@ -90,7 +99,7 @@ RawFile *RawFile::readFile(const QFile &file, QStringList &errors)
}
FILE *f = fdopen(result->file.handle(), "r");
assert(f);
RawFileReadState state(result->points, errors);
RawFileReadState state(result->points, result->powerHist, errors);
pt_read_raw(f, 0 /* not compat */, &state, config_cb,
time_cb, data_cb, error_cb);
result->rec_int = state.rec_int;

View File

@@ -24,6 +24,7 @@
#include <QDateTime>
#include <QFile>
#include <QList>
#include <QMap>
#include <QStringList>
struct RawFilePoint
@@ -51,6 +52,7 @@ class RawFile
QDateTime startTime;
int rec_int;
QList<RawFilePoint*> points;
QMap<double,double> powerHist;
static RawFile *readFile(const QFile &file, QStringList &errors);
};