Added Equivalent Performance for Target Race to VDOT Calculator

Also fixed constant term error in VO2 formula
This commit is contained in:
Alejandro Martinez
2015-10-22 15:02:24 -03:00
parent e5085a26fc
commit 0e6d7c1f6b
2 changed files with 62 additions and 4 deletions

View File

@@ -31,7 +31,7 @@ double
VDOTCalculator::vdot(double mins, double vel)
{
// estimated VO2 cost of running at vel speed in m/min
double VO2 = -4.3 + 0.182258*vel + 0.000104*pow(vel, 2);
double VO2 = -4.6 + 0.182258*vel + 0.000104*pow(vel, 2);
// fractional utilization of VO2max for mins duration
double FVO2 = 0.8 + 0.1894393*exp(-0.012778*mins) + 0.2989558*exp(-0.1932605*mins);
@@ -47,6 +47,24 @@ VDOTCalculator::vVdot(double VDOT)
return 29.54 + 5.000663*VDOT - 0.007546*pow(VDOT, 2);
}
double
VDOTCalculator::eqvTime(double VDOT, double dist)
{
// equivalent time for VDOT at dist, estimated by Newton-Raphson method
double t = dist/vVdot(VDOT)/0.9; // initial guess at TPace
int iter = 100; // max iterations
double f_t, fprime_t;
do {
f_t = (0.000104*pow(dist, 2)*pow(t, -2) + 0.182258*dist*pow(t, -1) -4.6)/(0.2989558*exp(-0.1932605*t) + 0.1894393*exp(-0.012778*t) + 0.8) - VDOT;
fprime_t = ((0.2989558*exp(-0.1932605*t) + 0.1894393*exp(-0.012778*t) + 0.8)*(-0.000208*pow(dist, 2)*pow(t,-3) - 0.182258*dist*pow(t, -2)) - ((0.000104*pow(dist, 2)*pow(t, -2) + 0.182258*dist*pow(t, -1) -4.6) * (-0.1932605*0.2989558*exp( -0.1932605*t) + -0.012778*0.1894393*exp(-0.012778*t)))) / pow(0.2989558*exp(-0.1932605*t) + 0.1894393*exp(-0.012778*t) + 0.8, 2);
t -= f_t/fprime_t;
iter--;
} while (abs(f_t/fprime_t) > 1e-3 && iter > 0);
return t;
}
VDOTCalculator::VDOTCalculator(QWidget *parent) : QDialog(parent)
{
bool metricRnPace = appsettings->value(this, GC_PACE, true).toBool();
@@ -57,13 +75,13 @@ VDOTCalculator::VDOTCalculator(QWidget *parent) : QDialog(parent)
setAttribute(Qt::WA_DeleteOnClose);
setFixedSize(300, 450);
setFixedSize(300, 480);
QVBoxLayout *mainVBox = new QVBoxLayout(this);
mainVBox->addWidget(new QLabel(tr("Your race (1500 to Marathon):")));
QHBoxLayout *distHBox = new QHBoxLayout;
distHBox->addWidget(new QLabel(tr("Your Test Race:")));
distHBox->addStretch();
distSpinBox = new QDoubleSpinBox(this);
distSpinBox->setDecimals(3);
if (metricRnPace) {
@@ -149,11 +167,45 @@ VDOTCalculator::VDOTCalculator(QWidget *parent) : QDialog(parent)
}
}
tableWidgetTPACE->selectRow(2); // Highlight T-Pace
tableWidgetTPACE->resizeRowsToContents();
tableLayout->addWidget(tableWidgetTPACE);
mainVBox->addLayout(tableLayout);
mainVBox->addStretch();
QHBoxLayout *targetHBox = new QHBoxLayout;
targetHBox->addWidget(new QLabel(tr("Your Target Race:")));
targetHBox->addStretch();
targetSpinBox = new QDoubleSpinBox(this);
targetSpinBox->setDecimals(3);
if (metricRnPace) {
targetSpinBox->setRange(1.5, 42.195);
targetSpinBox->setSuffix(tr(" km"));
targetSpinBox->setValue(21.0975);
} else {
targetSpinBox->setRange(1.5/KM_PER_MILE, 42.195/KM_PER_MILE);
targetSpinBox->setSuffix(tr(" mi"));
targetSpinBox->setValue(21.0975/KM_PER_MILE);
}
targetSpinBox->setSingleStep(1.0);
targetSpinBox->setWrapping(false);
targetSpinBox->setAlignment(Qt::AlignRight);
targetHBox->addWidget(targetSpinBox);
targetHBox->addStretch();
mainVBox->addLayout(targetHBox);
QHBoxLayout *eqvHBox = new QHBoxLayout;
eqvHBox->addStretch();
labelEQV = new QLabel(tr("Equivalent Time:"));
eqvHBox->addWidget(labelEQV);
txtEQV = new QLineEdit(this);
txtEQV->setAlignment(Qt::AlignRight);
txtEQV->setReadOnly(true);
eqvHBox->addWidget(txtEQV, Qt::AlignLeft);
eqvHBox->addStretch();
mainVBox->addLayout(eqvHBox);
mainVBox->addStretch();
QHBoxLayout *buttonHBox = new QHBoxLayout;
btnCalculate = new QPushButton(this);
btnCalculate->setText(tr("Calculate"));
@@ -206,4 +258,6 @@ void VDOTCalculator::on_btnCalculate_clicked()
tableWidgetTPACE->item(i, 2)->setData(Qt::EditRole, QString("%1")
.arg(i < 4 ? QTime(0,0,0).addSecs(pace).toString("mm:ss") : "-----"));
}
double targetDist = paceFactor*1000*targetSpinBox->value();
txtEQV->setText(QTime(0,0,0).addSecs(60*eqvTime(VDOT, targetDist)).toString("hh:mm:ss"));
}

View File

@@ -34,6 +34,7 @@ class VDOTCalculator : public QDialog
VDOTCalculator(QWidget *parent = 0);
static double vdot(double mins, double vel);
static double vVdot(double VDOT);
static double eqvTime(double VDOT, double dist);
private:
QPushButton *btnCalculate;
@@ -46,6 +47,9 @@ class VDOTCalculator : public QDialog
QDoubleSpinBox *hoursSpinBox;
QDoubleSpinBox *minsSpinBox;
QDoubleSpinBox *secsSpinBox;
QDoubleSpinBox *targetSpinBox;
QLabel *labelEQV;
QLineEdit *txtEQV;
private slots:
void on_btnOK_clicked();