mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
Calculate tau for W'
The implementation set tau to a constant when it should be derived from the recovery power across the ride. I've also added tau to the chart so you can see what value has been derived.
This commit is contained in:
@@ -297,6 +297,9 @@ AllPlot::AllPlot(AllPlotWindow *parent, Context *context):
|
||||
wCurve = new QwtPlotCurve(tr("W' Balance (j)"));
|
||||
wCurve->setYAxis(yRight3);
|
||||
|
||||
curveTitle.attach(this);
|
||||
curveTitle.setLabelAlignment(Qt::AlignRight);
|
||||
|
||||
intervalHighlighterCurve = new QwtPlotCurve();
|
||||
intervalHighlighterCurve->setYAxis(yLeft);
|
||||
intervalHighlighterCurve->setData(new IntervalPlotData(this, context));
|
||||
@@ -1176,6 +1179,10 @@ AllPlot::setDataFromPlot(AllPlot *plot, int startidx, int stopidx)
|
||||
stopidx = plot->timeIndex(plot->timeArray[(stopidx>=plot->timeArray.size()?plot->timeArray.size()-1:stopidx)]/60)-1;
|
||||
}
|
||||
|
||||
// center the curve title
|
||||
curveTitle.setYValue(30);
|
||||
curveTitle.setXValue(2);
|
||||
|
||||
// make sure indexes are still valid
|
||||
if (startidx > stopidx || startidx < 0 || stopidx < 0) return;
|
||||
|
||||
@@ -1198,6 +1205,14 @@ AllPlot::setDataFromPlot(AllPlot *plot, int startidx, int stopidx)
|
||||
|
||||
// attach appropriate curves
|
||||
//if (this->legend()) this->legend()->hide();
|
||||
if (showW && parent->wpData->TAU > 0) {
|
||||
QwtText text(QString("tau=%1").arg(parent->wpData->TAU));
|
||||
text.setFont(QFont("Helvetica", 10, QFont::Bold));
|
||||
text.setColor(Qt::red);
|
||||
curveTitle.setLabel(text);
|
||||
} else {
|
||||
curveTitle.setLabel(QwtText(""));
|
||||
}
|
||||
|
||||
wCurve->detach();
|
||||
wattsCurve->detach();
|
||||
@@ -1330,6 +1345,7 @@ AllPlot::setDataFromRide(RideItem *_rideItem)
|
||||
if (_rideItem == NULL) return;
|
||||
|
||||
wattsArray.clear();
|
||||
curveTitle.setLabel(QwtText(QString(""), QwtText::PlainText)); // default to no title
|
||||
|
||||
RideFile *ride = rideItem->ride();
|
||||
if (ride && ride->dataPoints().size()) {
|
||||
@@ -1550,6 +1566,14 @@ AllPlot::setShowW(bool show)
|
||||
{
|
||||
showW = show;
|
||||
wCurve->setVisible(show);
|
||||
if (showW && parent->wpData->TAU > 0) {
|
||||
QwtText text(QString("tau=%1").arg(parent->wpData->TAU));
|
||||
text.setFont(QFont("Helvetica", 10, QFont::Bold));
|
||||
text.setColor(Qt::red);
|
||||
curveTitle.setLabel(text);
|
||||
} else {
|
||||
curveTitle.setLabel(QwtText(""));
|
||||
}
|
||||
setYMax();
|
||||
replot();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
|
||||
#include <qwt_plot.h>
|
||||
#include <qwt_series_data.h>
|
||||
#include <qwt_plot_zoomer.h>
|
||||
#include <qwt_plot_marker.h>
|
||||
#include <qwt_point_3d.h>
|
||||
#include <qwt_compat.h>
|
||||
#include <QtGui>
|
||||
|
||||
class QwtPlotCurve;
|
||||
@@ -121,6 +125,7 @@ class AllPlot : public QwtPlot
|
||||
QwtPlotGrid *grid;
|
||||
QVector<QwtPlotMarker*> d_mrk;
|
||||
QVector<QwtPlotMarker*> cal_mrk;
|
||||
QwtPlotMarker curveTitle;
|
||||
QwtPlotMarker *allMarker1;
|
||||
QwtPlotMarker *allMarker2;
|
||||
QwtPlotCurve *wattsCurve;
|
||||
|
||||
@@ -36,12 +36,9 @@
|
||||
#include "WPrime.h"
|
||||
|
||||
const double WprimeMultConst = -1.0;
|
||||
const double WprimeDecayConst = 336;
|
||||
const int WprimeDecayPeriod = 1200; // 1200 seconds or 20 minutes
|
||||
const double E = 2.71828183;
|
||||
|
||||
inline double decaySchedule(double sec) { return pow(E, -(sec/WprimeDecayConst)); }
|
||||
|
||||
WPrime::WPrime()
|
||||
{
|
||||
// XXX will need to reset metrics when they are added
|
||||
@@ -64,6 +61,7 @@ WPrime::setRide(RideFile *input)
|
||||
|
||||
//XXX will need to reset metrics when they are added
|
||||
minY = maxY = 0;
|
||||
TAU=0;
|
||||
//qDebug()<<"now work to do"<<time.elapsed();
|
||||
return;
|
||||
}
|
||||
@@ -93,13 +91,23 @@ WPrime::setRide(RideFile *input)
|
||||
// since we will be running up and down the data series multiple times
|
||||
// as we iterate and run a SUMPRODUCT it is best to extract the data
|
||||
// into a vector of ints for the watts above CP
|
||||
double totalBelowCP=0;
|
||||
double countBelowCP=0;
|
||||
QVector<int> inputArray(last+1);
|
||||
for (int i=0; i<last; i++) {
|
||||
|
||||
int value = smoothed.value(i);
|
||||
inputArray[i] = value > CP ? value-CP : 0;
|
||||
|
||||
if (value < CP) {
|
||||
totalBelowCP += value;
|
||||
countBelowCP++;
|
||||
}
|
||||
}
|
||||
|
||||
TAU = 546.00f * pow(E,-0.01*(CP - (totalBelowCP/countBelowCP))) + 316.00f;
|
||||
TAU = int(TAU); // round it down
|
||||
|
||||
//qDebug()<<"data preparation took"<<time.elapsed();
|
||||
|
||||
// STEP 2: ITERATE OVER DATA TO CREATE W' DATA SERIES
|
||||
@@ -121,7 +129,7 @@ WPrime::setRide(RideFile *input)
|
||||
|
||||
double sumproduct = 0;
|
||||
for (int j=0; j<1200 && (i-j) > 0; j++) {
|
||||
sumproduct += inputArray.at(i-j) * pow(E, -(j/WprimeDecayConst));
|
||||
sumproduct += inputArray.at(i-j) * pow(E, -(double(j)/TAU));
|
||||
}
|
||||
values[i] = sumproduct * WprimeMultConst;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ class WPrime {
|
||||
QVector<double> &xdata() { return xvalues; }
|
||||
|
||||
double minY, maxY;
|
||||
double TAU;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user