mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 08:08:42 +00:00
from Justin: zones editor, switch from FTP to CP
This commit is contained in:
@@ -95,7 +95,7 @@ class RelativeIntensity : public RideMetric {
|
||||
assert(deps.contains("skiba_xpower"));
|
||||
XPower *xp = dynamic_cast<XPower*>(deps.value("skiba_xpower"));
|
||||
assert(xp);
|
||||
reli = xp->xpower / zones->getFTP(zoneRange);
|
||||
reli = xp->xpower / zones->getCP(zoneRange);
|
||||
secs = xp->secs;
|
||||
}
|
||||
}
|
||||
@@ -122,8 +122,7 @@ class BikeScore : public RideMetric {
|
||||
assert(ri);
|
||||
double normWork = xp->xpower * xp->secs;
|
||||
double rawBikeScore = normWork * ri->value(true);
|
||||
// TODO: use CP, not FTP here
|
||||
double workInAnHourAtCP = zones->getFTP(zoneRange) * 3600;
|
||||
double workInAnHourAtCP = zones->getCP(zoneRange) * 3600;
|
||||
score = rawBikeScore / workInAnHourAtCP * 100.0;
|
||||
}
|
||||
RideMetric *clone() const { return new BikeScore(*this); }
|
||||
|
||||
@@ -23,10 +23,22 @@ ConfigDialog::ConfigDialog(QDir _home)
|
||||
|
||||
|
||||
configPage = new ConfigurationPage();
|
||||
//cyclistPage = new CyclistPage();
|
||||
|
||||
QFile zonesFile(_home.absolutePath() + "/power.zones");
|
||||
if (zonesFile.exists())
|
||||
{
|
||||
zones = new Zones();
|
||||
if (!zones->read(zonesFile))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Zones File Error"), zones->errorString());
|
||||
zones = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cyclistPage = new CyclistPage(this, zones);
|
||||
pagesWidget = new QStackedWidget;
|
||||
pagesWidget->addWidget(configPage);
|
||||
//pagesWidget->addWidget(cyclistPage);
|
||||
pagesWidget->addWidget(cyclistPage);
|
||||
//pagesWidget->addWidget(new QueryPage);
|
||||
|
||||
QPushButton *closeButton = new QPushButton(tr("Close"));
|
||||
@@ -37,6 +49,9 @@ ConfigDialog::ConfigDialog(QDir _home)
|
||||
|
||||
connect(closeButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(saveButton, SIGNAL(clicked()), this, SLOT(accept()));
|
||||
connect(cyclistPage->btnBack, SIGNAL(clicked()), this, SLOT(back_Clicked()));
|
||||
connect(cyclistPage->btnForward, SIGNAL(clicked()), this, SLOT(forward_Clicked()));
|
||||
connect(cyclistPage->btnNew, SIGNAL(clicked()), this, SLOT(new_Clicked()));
|
||||
|
||||
QHBoxLayout *horizontalLayout = new QHBoxLayout;
|
||||
horizontalLayout->addWidget(contentsWidget);
|
||||
@@ -65,28 +80,14 @@ void ConfigDialog::createIcons()
|
||||
configButton->setTextAlignment(Qt::AlignHCenter);
|
||||
configButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
/*
|
||||
|
||||
QListWidgetItem *cyclistButton = new QListWidgetItem(contentsWidget);
|
||||
cyclistButton->setIcon(QIcon(":images/cyclist.png"));
|
||||
cyclistButton->setText(tr("Cyclist Info"));
|
||||
cyclistButton->setTextAlignment(Qt::AlignHCenter);
|
||||
cyclistButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
*/
|
||||
|
||||
/*
|
||||
QListWidgetItem *powerButton = new QListWidgetItem(contentsWidget);
|
||||
powerButton->setIcon(QIcon("images/power.png"));
|
||||
powerButton->setText(tr("Power Levels"));
|
||||
powerButton->setTextAlignment(Qt::AlignHCenter);
|
||||
powerButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
|
||||
|
||||
QListWidgetItem *queryButton = new QListWidgetItem(contentsWidget);
|
||||
queryButton->setIcon(QIcon(":/images/query.png"));
|
||||
queryButton->setText(tr("Query"));
|
||||
queryButton->setTextAlignment(Qt::AlignHCenter);
|
||||
queryButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
*/
|
||||
|
||||
connect(contentsWidget,
|
||||
SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)),
|
||||
this, SLOT(changePage(QListWidgetItem *, QListWidgetItem*)));
|
||||
@@ -106,19 +107,138 @@ void ConfigDialog::save_Clicked()
|
||||
{
|
||||
QSettings settings(GC_SETTINGS_CO, GC_SETTINGS_APP);
|
||||
settings.setValue(GC_UNIT, configPage->unitCombo->currentText());
|
||||
|
||||
/*
|
||||
QString strLT = cyclistPage->txtThreshold->text();
|
||||
qDebug() << "LT is: " << strLT;
|
||||
double LT = strLT.toDouble();
|
||||
|
||||
|
||||
Zones *zones = new Zones();
|
||||
zones->write(LT, QDir(home));
|
||||
|
||||
delete zones;
|
||||
*/
|
||||
//If the user never switched pages, then make sure we have up to date data.
|
||||
if (cyclistPage->getCurrentRange() == zones->ranges.size() - 1)
|
||||
{
|
||||
// Record the End Date..
|
||||
zones->setStartDate(zones->ranges.size() - 1, cyclistPage->calendar->selectedDate());
|
||||
//Swap the end date for the previous zone..
|
||||
zones->setEndDate(zones->ranges.size() - 2, cyclistPage->calendar->selectedDate());
|
||||
|
||||
//Store the CP for the new Zone..
|
||||
zones->setCP(cyclistPage->getCurrentRange(), cyclistPage->txtThreshold->text().toInt());
|
||||
}
|
||||
|
||||
zones->write(home);
|
||||
|
||||
accept();
|
||||
|
||||
}
|
||||
|
||||
void ConfigDialog::back_Clicked()
|
||||
{
|
||||
|
||||
if ((cyclistPage->txtThreshold->isModified() == true) || cyclistPage->btnNew->isEnabled() == true)
|
||||
{
|
||||
if (cyclistPage->txtThreshold->text().length() == 0)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Missing Field"), "CP cannot be empty.");
|
||||
cyclistPage->txtThreshold->setFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
//Store the current CP before changing zones.
|
||||
zones->setCP(cyclistPage->getCurrentRange(), cyclistPage->txtThreshold->text().toInt());
|
||||
}
|
||||
cyclistPage->setCurrentRange(cyclistPage->getCurrentRange() - 1);
|
||||
cyclistPage->btnForward->setEnabled(true);
|
||||
int ftp = zones->getCP(cyclistPage->getCurrentRange());
|
||||
QString strCP;
|
||||
cyclistPage->txtThreshold->setText(strCP.setNum(ftp));
|
||||
|
||||
QDate _date = zones->getEndDate(cyclistPage->getCurrentRange());
|
||||
if (cyclistPage->btnNew->isEnabled() == true)
|
||||
cyclistPage->calendar->setEnabled(false);
|
||||
cyclistPage->calendar->setMinimumDate(zones->getStartDate(0));
|
||||
cyclistPage->calendar->setSelectedDate(_date);
|
||||
|
||||
if (cyclistPage->getCurrentRange() == 0)
|
||||
cyclistPage->btnBack->setEnabled(false);
|
||||
cyclistPage->lblCurRange->setText(QString("Current Zone Range: %1").arg(cyclistPage->getCurrentRange() + 1));
|
||||
|
||||
}
|
||||
|
||||
void ConfigDialog::forward_Clicked()
|
||||
{
|
||||
|
||||
if ((cyclistPage->txtThreshold->isModified() == true) || cyclistPage->btnNew->isEnabled() == true)
|
||||
{
|
||||
if (cyclistPage->txtThreshold->text().length() == 0)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Missing Field"), "CP cannot be empty");
|
||||
cyclistPage->txtThreshold->setFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
//Store the current CP before changing zones.
|
||||
zones->setCP(cyclistPage->getCurrentRange(), cyclistPage->txtThreshold->text().toInt());
|
||||
}
|
||||
if (cyclistPage->btnNew->isEnabled() == true)
|
||||
cyclistPage->calendar->setEnabled(false);
|
||||
//Now switch zones
|
||||
QDate date;
|
||||
cyclistPage->setCurrentRange(cyclistPage->getCurrentRange() + 1);
|
||||
|
||||
int ftp = zones->getCP(cyclistPage->getCurrentRange());
|
||||
QString strCP;
|
||||
cyclistPage->txtThreshold->setText(strCP.setNum(ftp));
|
||||
|
||||
if (cyclistPage->getCurrentRange() + 1 == zones->ranges.size())
|
||||
{
|
||||
cyclistPage->btnForward->setEnabled(false);
|
||||
date = zones->getStartDate(cyclistPage->getCurrentRange());
|
||||
}
|
||||
else
|
||||
date = zones->getEndDate(cyclistPage->getCurrentRange());
|
||||
|
||||
cyclistPage->calendar->setSelectedDate(date);
|
||||
cyclistPage->calendar->setMinimumDate(zones->getStartDate(cyclistPage->getCurrentRange()));
|
||||
cyclistPage->btnBack->setEnabled(true);
|
||||
cyclistPage->lblCurRange->setText(QString("Current Zone Range: %1").arg(cyclistPage->getCurrentRange() + 1));
|
||||
}
|
||||
|
||||
void ConfigDialog::new_Clicked()
|
||||
{
|
||||
|
||||
if ((cyclistPage->txtThreshold->isModified() == true) || cyclistPage->btnNew->isEnabled() == true)
|
||||
{
|
||||
if (cyclistPage->txtThreshold->text().length() == 0)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Missing Field"), "CP cannot be empty");
|
||||
cyclistPage->txtThreshold->setFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
//Store the current CP before changing zones.
|
||||
zones->setCP(cyclistPage->getCurrentRange(), cyclistPage->txtThreshold->text().toInt());
|
||||
}
|
||||
|
||||
|
||||
cyclistPage->setChoseNewZone(true);
|
||||
cyclistPage->txtThreshold->setText("");
|
||||
cyclistPage->btnNew->setEnabled(false);
|
||||
cyclistPage->calendar->setEnabled(true);
|
||||
|
||||
//Modify the current zone..
|
||||
zones->setEndDate(cyclistPage->getCurrentRange(), cyclistPage->calendar->selectedDate());
|
||||
|
||||
|
||||
//Create the Zone
|
||||
cyclistPage->calendar->setMinimumDate(zones->getStartDate(zones->ranges.size() - 1));
|
||||
zones->addZoneRange(zones->getStartDate(cyclistPage->getCurrentRange()), cyclistPage->calendar->selectedDate(), 0);
|
||||
cyclistPage->setCurrentRange(zones->ranges.size() - 1);
|
||||
cyclistPage->lblCurRange->setText(QString("Current Zone Range: %1").arg(cyclistPage->getCurrentRange() + 1));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
ConfigDialog::~ConfigDialog()
|
||||
{
|
||||
delete zones;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,14 @@ class ConfigDialog : public QDialog
|
||||
Q_OBJECT
|
||||
public:
|
||||
ConfigDialog(QDir home);
|
||||
~ConfigDialog();
|
||||
public slots:
|
||||
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
|
||||
void save_Clicked();
|
||||
|
||||
void back_Clicked();
|
||||
void forward_Clicked();
|
||||
void new_Clicked();
|
||||
|
||||
private:
|
||||
void createIcons();
|
||||
void calculateZones();
|
||||
@@ -31,6 +35,8 @@ class ConfigDialog : public QDialog
|
||||
CyclistPage *cyclistPage;
|
||||
QPushButton *saveButton;
|
||||
QDir home;
|
||||
Zones *zones;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
125
src/Pages.cpp
125
src/Pages.cpp
@@ -41,34 +41,72 @@ ConfigurationPage::ConfigurationPage(QWidget *parent)
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
/*
|
||||
CyclistPage::CyclistPage(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
|
||||
CyclistPage::CyclistPage(QWidget *parent, Zones *_zones)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QGroupBox *cyclistGroup = new QGroupBox(tr("Cyclist Options"));
|
||||
|
||||
QLabel *lblThreshold = new QLabel(tr("Threshold Power:"));
|
||||
zones = _zones;
|
||||
|
||||
setChoseNewZone(false);
|
||||
|
||||
QLabel *lblThreshold = new QLabel(tr("Critical Power:"));
|
||||
txtThreshold = new QLineEdit();
|
||||
txtThreshold->setInputMask("999");
|
||||
|
||||
//QLabel *lblWeight = new QLabel(tr("Weight:"));
|
||||
//QLineEdit *txtWeight = new QLineEdit(this);
|
||||
|
||||
calendar = new QCalendarWidget(this);
|
||||
setCurrentRange(zones->ranges.size() - 1);
|
||||
QDate date = zones->getStartDate(getCurrentRange());
|
||||
calendar->setSelectedDate(date);
|
||||
calendar->setMinimumDate(date);
|
||||
calendar->setEnabled(false);
|
||||
|
||||
QString strCP;
|
||||
|
||||
setCurrentRange((zones->ranges.size() - 1));
|
||||
int ftp = zones->getCP(zones->ranges.size() - 1);
|
||||
txtThreshold->setText(strCP.setNum(ftp));
|
||||
|
||||
lblCurRange = new QLabel(this);
|
||||
lblCurRange->setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
||||
lblCurRange->setText(QString("Current Zone Range: %1").arg(getCurrentRange() + 1));
|
||||
|
||||
btnBack = new QPushButton(this);
|
||||
btnBack->setText(tr("Back"));
|
||||
btnForward = new QPushButton(this);
|
||||
btnForward->setText(tr("Forward"));
|
||||
btnNew = new QPushButton(this);
|
||||
btnNew->setText(tr("New Zone Range"));
|
||||
|
||||
btnForward->setEnabled(false);
|
||||
|
||||
//Layout
|
||||
QHBoxLayout *powerLayout = new QHBoxLayout;
|
||||
QHBoxLayout *powerLayout = new QHBoxLayout();
|
||||
powerLayout->addWidget(lblThreshold);
|
||||
powerLayout->addWidget(txtThreshold);
|
||||
|
||||
|
||||
//QHBoxLayout *thresholdLayout = new QHBoxLayout;
|
||||
//thresholdLayout->addWidget(lblWeight);
|
||||
//thresholdLayout->addWidget(txtWeight);
|
||||
QHBoxLayout *rangeLayout = new QHBoxLayout();
|
||||
rangeLayout->addWidget(lblCurRange);
|
||||
|
||||
QHBoxLayout *zoneLayout = new QHBoxLayout();
|
||||
zoneLayout->addWidget(btnBack);
|
||||
zoneLayout->addWidget(btnForward);
|
||||
zoneLayout->addWidget(btnNew);
|
||||
|
||||
QHBoxLayout *calendarLayout = new QHBoxLayout();
|
||||
calendarLayout->addWidget(calendar);
|
||||
|
||||
QVBoxLayout *cyclistLayout = new QVBoxLayout;
|
||||
cyclistLayout->addLayout(powerLayout);
|
||||
//cyclistLayout->addLayout(thresholdLayout);
|
||||
cyclistLayout->addLayout(rangeLayout);
|
||||
cyclistLayout->addLayout(zoneLayout);
|
||||
cyclistLayout->addLayout(calendarLayout);
|
||||
|
||||
cyclistGroup->setLayout(cyclistLayout);
|
||||
|
||||
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(cyclistGroup);
|
||||
mainLayout->addStretch(1);
|
||||
@@ -77,50 +115,27 @@ CyclistPage::CyclistPage(QWidget *parent)
|
||||
|
||||
QString CyclistPage::getText()
|
||||
{
|
||||
qDebug() << txtThreshold->text();
|
||||
return txtThreshold->text();
|
||||
return txtThreshold->text();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
PowerPage::PowerPage(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
void CyclistPage::setCurrentRange(int _range)
|
||||
{
|
||||
QGroupBox *powerGroup = new QGroupBox(tr("Power Levels"));
|
||||
|
||||
QLabel *lblThreshold = new QLabel(tr("Threshold Power:"));
|
||||
QLineEdit *txtThreshold = new QLineEdit(this);
|
||||
|
||||
QLabel *lblWeight = new QLabel(tr("Weight:"));
|
||||
QLineEdit *txtWeight = new QLineEdit(this);
|
||||
|
||||
|
||||
//Layout
|
||||
QHBoxLayout *powerLayout = new QHBoxLayout;
|
||||
powerLayout->addWidget(lblThreshold);
|
||||
powerLayout->addWidget(txtThreshold);
|
||||
|
||||
|
||||
QHBoxLayout *thresholdLayout = new QHBoxLayout;
|
||||
thresholdLayout->addWidget(lblWeight);
|
||||
thresholdLayout->addWidget(txtWeight);
|
||||
|
||||
QVBoxLayout *cyclistLayout = new QVBoxLayout;
|
||||
cyclistLayout->addLayout(powerLayout);
|
||||
cyclistLayout->addLayout(thresholdLayout);
|
||||
powerGroup->setLayout(cyclistLayout);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(powerGroup);
|
||||
mainLayout->addStretch(1);
|
||||
setLayout(mainLayout);
|
||||
currentRange = _range;
|
||||
}
|
||||
*/
|
||||
|
||||
//Active recovery: <55%
|
||||
//Endurance: 56-75%
|
||||
//Tempo: 76-90%
|
||||
//Threshold: 91-105%
|
||||
//VO2 max: 106-120%
|
||||
//Anaerobic Capacity: 121-150%
|
||||
//Neuromuscular power: N/A but could be anything >151%
|
||||
int CyclistPage::getCurrentRange()
|
||||
{
|
||||
return currentRange;
|
||||
}
|
||||
|
||||
bool CyclistPage::isNewZone()
|
||||
{
|
||||
return newZone;
|
||||
}
|
||||
|
||||
void CyclistPage::setChoseNewZone(bool _newZone)
|
||||
{
|
||||
newZone = _newZone;
|
||||
}
|
||||
|
||||
|
||||
|
||||
30
src/Pages.h
30
src/Pages.h
@@ -3,6 +3,11 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include <QCalendarWidget>
|
||||
#include <QPushButton>
|
||||
#include <QList>
|
||||
#include "Zones.h"
|
||||
#include <QLabel>
|
||||
|
||||
class ConfigurationPage : public QWidget
|
||||
{
|
||||
@@ -14,11 +19,26 @@ class ConfigurationPage : public QWidget
|
||||
class CyclistPage : public QWidget
|
||||
{
|
||||
public:
|
||||
CyclistPage(QWidget *parent = 0);
|
||||
int thresholdPower;
|
||||
QLineEdit *txtThreshold;
|
||||
QString getText();
|
||||
//int weight;
|
||||
CyclistPage(QWidget *parent = 0, Zones *_zones = 0);
|
||||
int thresholdPower;
|
||||
QLineEdit *txtThreshold;
|
||||
QString getText();
|
||||
QCalendarWidget *calendar;
|
||||
void setCurrentRange(int range);
|
||||
QPushButton *btnBack;
|
||||
QPushButton *btnForward;
|
||||
QPushButton *btnNew;
|
||||
QLabel *lblCurRange;
|
||||
|
||||
int getCurrentRange();
|
||||
void setChoseNewZone(bool _newZone);
|
||||
bool isNewZone();
|
||||
|
||||
private:
|
||||
Zones *zones;
|
||||
int currentRange;
|
||||
bool newZone;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
166
src/Zones.cpp
166
src/Zones.cpp
@@ -176,12 +176,18 @@ void Zones::zoneInfo(int rnum, int znum,
|
||||
high = zone->hi;
|
||||
}
|
||||
|
||||
int Zones::getFTP(int rnum) const
|
||||
int Zones::getCP(int rnum) const
|
||||
{
|
||||
assert(rnum < ranges.size());
|
||||
return ranges[rnum]->ftp;
|
||||
}
|
||||
|
||||
void Zones::setCP(int rnum, int ftp)
|
||||
{
|
||||
ranges[rnum]->ftp = ftp;
|
||||
}
|
||||
|
||||
|
||||
QString Zones::summarize(int rnum, double *time_in_zone, int num_zones) const
|
||||
{
|
||||
assert(rnum < ranges.size());
|
||||
@@ -225,70 +231,100 @@ QString Zones::summarize(int rnum, double *time_in_zone, int num_zones) const
|
||||
return summary;
|
||||
}
|
||||
|
||||
/*
|
||||
// Eventually for automatically generating the power.zones file
|
||||
// Disabled for now until multiple date ranges are respected.
|
||||
*/
|
||||
/*
|
||||
void Zones::write(int LT, QDir home)
|
||||
void Zones::write(QDir home)
|
||||
{
|
||||
int active_recovery = 0;
|
||||
int endurance_start = 0;
|
||||
int endurance_end = 0;
|
||||
int tempo_start = 0;
|
||||
int tempo_end = 0;
|
||||
int threshold_start = 0;
|
||||
int threshold_end = 0;
|
||||
int vo2max_start = 0;
|
||||
int vo2max_end = 0;
|
||||
int anaerobicCapacity_start = 0;
|
||||
int anaerobicCapacity_end = 0;
|
||||
int neuromuscular = 0;
|
||||
|
||||
active_recovery = int(LT * .55);
|
||||
endurance_start = int(LT * .56);
|
||||
endurance_end = int(LT * .75);
|
||||
tempo_start = int(LT * .76);
|
||||
tempo_end = int(LT * .90);
|
||||
threshold_start = int(LT * .91);
|
||||
threshold_end = int(LT * 1.05);
|
||||
vo2max_start = int(LT * 1.06);
|
||||
vo2max_end = int(LT * 1.2);
|
||||
anaerobicCapacity_start = int(LT * 1.21);
|
||||
anaerobicCapacity_end = int(LT * 1.5);
|
||||
neuromuscular = int(LT * 1.51);
|
||||
|
||||
int active_recovery;
|
||||
int endurance_start;
|
||||
int endurance_end;
|
||||
int tempo_start;
|
||||
int tempo_end;
|
||||
int threshold_start;
|
||||
int threshold_end;
|
||||
int vo2max_start;
|
||||
int vo2max_end;
|
||||
int anaerobicCapacity_start;
|
||||
int anaerobicCapacity_end;
|
||||
int neuromuscular;
|
||||
QString strzones;
|
||||
strzones += QString("From BEGIN until END, FTP=%1:").arg(LT);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("1,Active Recovery, 1, %1").arg(active_recovery);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("2,Endurance, %1, %2").arg(endurance_start).arg(endurance_end);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("3,Tempo, %1, %2").arg(tempo_start).arg(tempo_end);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("4,Threshold, %1, %2").arg(threshold_start).arg(threshold_end);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("5,VO2Max, %1, %2").arg(vo2max_start).arg(vo2max_end);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("6,Anaerobic, %1, %2").arg(anaerobicCapacity_start).arg(anaerobicCapacity_end);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("7,Neuromuscular, %1,").arg(neuromuscular);
|
||||
strzones += QString("MAX");
|
||||
strzones += QString("\n");
|
||||
qDebug() << "Zones are:" << strzones;
|
||||
|
||||
QFile file( home.absolutePath() + "/power.zones" );
|
||||
if ( file.open( QFile::WriteOnly ) ) {
|
||||
QTextStream stream( &file );
|
||||
stream << strzones;
|
||||
file.close();
|
||||
}
|
||||
|
||||
*/
|
||||
for (int i = 0; i < ranges.size(); i++)
|
||||
{
|
||||
int LT = getCP(i);
|
||||
|
||||
active_recovery = 0;
|
||||
endurance_start = 0;
|
||||
endurance_end = 0;
|
||||
tempo_start = 0;
|
||||
tempo_end = 0;
|
||||
threshold_start = 0;
|
||||
threshold_end = 0;
|
||||
vo2max_start = 0;
|
||||
vo2max_end = 0;
|
||||
anaerobicCapacity_start = 0;
|
||||
anaerobicCapacity_end = 0;
|
||||
neuromuscular = 0;
|
||||
|
||||
|
||||
active_recovery = int (LT * .55);
|
||||
endurance_start = int (LT * .56);
|
||||
endurance_end = int (LT * .75);
|
||||
tempo_start = int (LT * .76);
|
||||
tempo_end = int (LT * .90);
|
||||
threshold_start = int (LT * .91);
|
||||
threshold_end = int (LT * 1.05);
|
||||
vo2max_start = int (LT * 1.06);
|
||||
vo2max_end = int (LT * 1.2);
|
||||
anaerobicCapacity_start = int (LT * 1.21);
|
||||
anaerobicCapacity_end = int (LT * 1.5);
|
||||
neuromuscular = int (LT * 1.51);
|
||||
|
||||
if (i == 0)
|
||||
strzones += QString("FROM BEGIN UNTIL %1, CP=%2:").arg(getEndDate(i).toString("yyyy/MM/dd")).arg(LT);
|
||||
else if (i == ranges.size() - 1)
|
||||
strzones += QString("FROM %1 UNTIL END, CP=%2:").arg(getStartDate(i).toString("yyyy/MM/dd")).arg(LT);
|
||||
else
|
||||
strzones += QString("FROM %1 UNTIL %2, CP=%3:").arg(getStartDate(i).toString("yyyy/MM/yy")).arg(getEndDate(i).toString("yyyy/MM/dd")).arg(LT);
|
||||
|
||||
|
||||
strzones += QString("\n");
|
||||
strzones += QString("1,Active Recovery, 1, %1").arg(active_recovery);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("2,Endurance, %1, %2").arg(endurance_start).arg(endurance_end);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("3,Tempo, %1, %2").arg(tempo_start).arg(tempo_end);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("4,Threshold, %1, %2").arg(threshold_start).arg(threshold_end);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("5,VO2Max, %1, %2").arg(vo2max_start).arg(vo2max_end);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("6,Anaerobic, %1, %2").arg(anaerobicCapacity_start).arg(anaerobicCapacity_end);
|
||||
strzones += QString("\n");
|
||||
strzones += QString("7,Neuromuscular, %1,").arg(neuromuscular);
|
||||
strzones += QString("MAX");
|
||||
strzones += QString("\n");
|
||||
strzones += QString("\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
QFile file(home.absolutePath() + "/power.zones");
|
||||
if (file.open(QFile::WriteOnly))
|
||||
{
|
||||
QTextStream stream(&file);
|
||||
stream << strzones << endl;
|
||||
file.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Zones::addZoneRange(QDate _start, QDate _end, int _ftp)
|
||||
{
|
||||
ZoneRange *range = new ZoneRange(_start, _end);
|
||||
range->ftp = _ftp;
|
||||
ranges.append(range);
|
||||
}
|
||||
/*
|
||||
From 2008/01/01 until END,FTP=270:
|
||||
From 2008/01/01 until END,CP=270:
|
||||
1,Active Recovery, 1, 150
|
||||
2,Endurance, 151, 204
|
||||
3,Tempo, 205, 245
|
||||
@@ -296,4 +332,12 @@ From 2008/01/01 until END,FTP=270:
|
||||
5,VO2Max, 286, 326
|
||||
6,Anaerobic, 327, MAX
|
||||
*/
|
||||
//}
|
||||
|
||||
void Zones::setEndDate(int rnum, QDate endDate)
|
||||
{
|
||||
ranges[rnum]->end = endDate;
|
||||
}
|
||||
void Zones::setStartDate(int rnum, QDate startDate)
|
||||
{
|
||||
ranges[rnum]->begin = startDate;
|
||||
}
|
||||
|
||||
13
src/Zones.h
13
src/Zones.h
@@ -60,18 +60,25 @@ class Zones : public QObject
|
||||
delete i.next();
|
||||
}
|
||||
|
||||
void addZoneRange(QDate _start, QDate _end, int _ftp);
|
||||
|
||||
bool read(QFile &file);
|
||||
void write(int LT, QDir home);
|
||||
void write(QDir home);
|
||||
const QString &errorString() const { return err; }
|
||||
|
||||
int whichRange(const QDate &date) const;
|
||||
int numZones(int range) const;
|
||||
int whichZone(int range, double value) const;
|
||||
void zoneInfo(int range, int zone,
|
||||
void zoneInfo(int range, int zone,
|
||||
QString &name, QString &description,
|
||||
int &low, int &high) const;
|
||||
QString summarize(int rnum, double *time_in_zone, int num_zones) const;
|
||||
int getFTP(int rnum) const;
|
||||
int getCP(int rnum) const;
|
||||
void setCP(int rnum, int ftp);
|
||||
QDate getStartDate(int rnum);
|
||||
QDate getEndDate(int rnum);
|
||||
void setEndDate(int rnum, QDate date);
|
||||
void setStartDate(int rnum, QDate date);
|
||||
};
|
||||
|
||||
#endif // _Zones_h
|
||||
|
||||
Reference in New Issue
Block a user