diff --git a/src/Charts/CPPlot.cpp b/src/Charts/CPPlot.cpp index 1e7ec1e5d..6877f4bd7 100644 --- a/src/Charts/CPPlot.cpp +++ b/src/Charts/CPPlot.cpp @@ -25,6 +25,7 @@ #include "CPPlot.h" #include "PowerProfile.h" #include "RideCache.h" +#include "Banister.h" #include #include @@ -1384,7 +1385,7 @@ CPPlot::plotBests(RideItem *rideItem) // away from a linear regression // the best we found is stored in here - struct { int i; double p, t, d; } keep; + struct { int i; double p, t, d, pix; } keep; for(int i=0; i0) { // always keep pmax point @@ -1413,8 +1415,10 @@ CPPlot::plotBests(RideItem *rideItem) // if its beloe the line multiply distance by -1 double d = (p[x] * t[x] * 60.0f) - ((slope * t[x] * 60.00f) + intercept); + double pix = powerIndex(p[x],t[x]); - if (keep.d < d) { + // use the regression for shorter durations and 3p for longer + if ((keep.t < 120 && keep.d < d) || (keep.t >= 120 && keep.pix < pix)) { keep.d = d; keep.i = x; keep.p = p[x]; diff --git a/src/Metrics/Banister.cpp b/src/Metrics/Banister.cpp index 0ad4712d6..a116b36ea 100644 --- a/src/Metrics/Banister.cpp +++ b/src/Metrics/Banister.cpp @@ -48,6 +48,23 @@ const double typical_CP = 261, // and also useful to normalise TTEs for use in the Banister model as a // performance measurement. // + +double powerIndex(double averagepower, double duration) +{ + // so now lets work out what the 3p model says the + // typical athlete would do for the same duration + // + // P(t) = W' / (t - (W'/(CP-Pmax))) + CP + double typicalpower = (typical_WPrime / (duration - (typical_WPrime/(typical_CP-typical_Pmax)))) + typical_CP; + + // make sure we got a sensible value + if (typicalpower < 0 || typicalpower > 2500) return 0; + + // we could convert to linear work time model before + // indexing, but they cancel out so no value in doing so + return(100.0 * averagepower/typicalpower); +} + class PowerIndex : public RideMetric { Q_DECLARE_TR_FUNCTIONS(PowerIndex) public: @@ -100,24 +117,13 @@ class PowerIndex : public RideMetric { return; } - // so now lets work out what the 3p model says the - // typical athlete would do for the same duration - // - // P(t) = W' / (t - (W'/(CP-Pmax))) + CP - // - double typicalpower = (typical_WPrime / (duration - (typical_WPrime/(typical_CP-typical_Pmax)))) + typical_CP; - - // make sure we got a sensible value - if (typicalpower < 0 || typicalpower > 2500) { - setValue(RideFile::NIL); - setCount(0); - return; - } + // calculate power index, 0=out of bounds + double pix = powerIndex(averagepower, duration); // we could convert to linear work time model before // indexing, but they cancel out so no value in doing so - setValue(100.0 * averagepower/typicalpower); - setCount(1); + setValue(pix); + setCount(pix > 0 ? 1 : 0); } MetricClass classification() const { return Undefined; } diff --git a/src/Metrics/Banister.h b/src/Metrics/Banister.h index 8f434b04b..efb298b7c 100644 --- a/src/Metrics/Banister.h +++ b/src/Metrics/Banister.h @@ -23,4 +23,7 @@ // using floats because they are typically used in calculations // that require float precision (the actual values are integers) extern const double typical_CP, typical_WPrime, typical_Pmax; + +// calculate power index, used to model in cp plot too +extern double powerIndex(double averagepower, double duration); #endif