diff --git a/src/ModelPlot.cpp b/src/ModelPlot.cpp index 566fa6af7..fddadd5ee 100644 --- a/src/ModelPlot.cpp +++ b/src/ModelPlot.cpp @@ -19,6 +19,7 @@ #include "ModelPlot.h" #include "ModelWindow.h" #include "MainWindow.h" +#include "Settings.h" #include "Zones.h" #include "RideFile.h" #include "Units.h" // for MILES_PER_KM @@ -194,6 +195,7 @@ class ModelDataProvider : public Function double pointType(const RideFilePoint *, int); QString describeType(int, bool); double maxz, minz; + double cranklength; // used for CPV/AEPF calculation }; double @@ -207,13 +209,17 @@ ModelDataProvider::pointType(const RideFilePoint *point, int type) case MODEL_HEARTRATE : return point->hr; case MODEL_SPEED : return point->kph; case MODEL_ALT : return point->alt; - case MODEL_PEDALFORCE : return point->nm; + case MODEL_TORQUE : return point->nm; case MODEL_TIME : return point->secs; case MODEL_DISTANCE : return point->km; case MODEL_INTERVAL : return point->interval; case MODEL_LAT : return point->lat; case MODEL_LONG : return point->lon; - + case MODEL_AEPF : + if (point->watts == 0 || point->cad == 0) return 0; + else return ((point->watts * 60.0) / (point->cad * cranklength * 2.0 * PI)); + case MODEL_CPV : + return 100 * ((point->cad * cranklength * 2.0 * PI) / 60.0); // these you need to do yourself cause there is some // logic needed and I'm just lookup table! case MODEL_XYTIME : return 1; @@ -234,12 +240,14 @@ ModelDataProvider::describeType(int type, bool longer) case MODEL_HEARTRATE : return ("Heartrate (bpm)"); case MODEL_SPEED : return ("Speed (kph)"); //XXX metric / imperial! case MODEL_ALT : return ("Altitude (meters)"); // XXX metric / imperial - case MODEL_PEDALFORCE : return ("Pedal Force (nm)"); + case MODEL_TORQUE : return ("Torque (N)"); case MODEL_TIME : return ("Elapsed Time (secs)"); case MODEL_DISTANCE : return ("Elapsed Distance (km)"); //XXX metric/imperial case MODEL_INTERVAL : return ("Interval Number"); // XXX implemented differently case MODEL_LAT : return ("Latitude (degree offset)"); case MODEL_LONG : return ("Longitude (degree offset)"); + case MODEL_CPV : return ("Circumferential Pedal Velocity (cm/s)"); + case MODEL_AEPF : return ("Average Effective Pedal Force (N)"); // these you need to do yourself cause there is some // logic needed and I'm just lookup table! @@ -255,7 +263,7 @@ ModelDataProvider::describeType(int type, bool longer) case MODEL_HEARTRATE : return ("Heartrate"); case MODEL_SPEED : return ("Speed"); //XXX metric / imperial! case MODEL_ALT : return ("Altitude"); // XXX metric / imperial - case MODEL_PEDALFORCE : return ("Pedal Force"); + case MODEL_TORQUE : return ("Pedal Force"); case MODEL_TIME : return ("Time"); case MODEL_DISTANCE : return ("Distance"); //XXX metric/imperial case MODEL_INTERVAL : return ("Interval"); // XXX implemented differently @@ -263,6 +271,8 @@ ModelDataProvider::describeType(int type, bool longer) case MODEL_LONG : return ("Longitude"); case MODEL_XYTIME : return ("Time at X/Y"); case MODEL_POWERZONE : return ("Zone"); + case MODEL_CPV : return ("CPV"); + case MODEL_AEPF : return ("AEPF"); } return ("None");; // ? unknown channel ? } @@ -290,6 +300,15 @@ ModelDataProvider::ModelDataProvider (BasicModelPlot &plot, ModelSettings *setti return; } + cranklength = 0.0; + boost::shared_ptr appsettings = GetApplicationSettings(); + if (appsettings) { + cranklength = appsettings->value(GC_CRANKLENGTH).toDouble() / 1000.0; + } + + // if its not setup or no settings exist default to 175mm cranks + if (cranklength == 0.0) cranklength = 0.175; + // Run through the ridefile points putting the selected // values into the approprate bins settings->colorProvider->color.clear(); @@ -646,15 +665,32 @@ ModelDataProvider::ModelDataProvider (BasicModelPlot &plot, ModelSettings *setti xscale *=factor; } + // general plot settings plot.setScale(xscale, yscale, zscale); plot.setTitle(""); + plot.setTitleFont(font.family(),font.pointSize(), QFont::Bold); plot.setCoordinateStyle(FRAME); plot.setMeshLineWidth(1); + plot.setIsolines(10); + plot.setSmoothMesh(true); + + // cordinates - labels, gridlines, tic markers etc + if (settings->gridlines == true) + plot.coordinates()->setGridLines(true, true, Qwt3D::BACK | Qwt3D::LEFT | Qwt3D::FLOOR); + else + plot.coordinates()->setGridLines(true, true, 0); plot.coordinates()->setLineWidth(1); plot.coordinates()->setNumberFont(font.family(),font.pointSize()); - plot.setTitleFont(font.family(),font.pointSize(), QFont::Bold); + plot.coordinates()->adjustLabels(25); + plot.coordinates()->adjustNumbers(10); + for (unsigned int i=0; i < plot.coordinates()->axes.size(); i++) { + plot.coordinates()->axes[i].setMajors(7); + plot.coordinates()->axes[i].setMinors(5); + plot.coordinates()->axes[i].recalculateTics(); + } plot.coordinates()->setLabelFont(font.family(), font.pointSize(), QFont::Bold); + plot.coordinates()->axes[Z1].setLabelString(describeType(settings->z, true)); plot.coordinates()->axes[Z2].setLabelString(describeType(settings->z, true)); plot.coordinates()->axes[Z3].setLabelString(describeType(settings->z, true)); @@ -667,6 +703,38 @@ ModelDataProvider::ModelDataProvider (BasicModelPlot &plot, ModelSettings *setti plot.coordinates()->axes[Y2].setLabelString(describeType(settings->y, true)); plot.coordinates()->axes[Y3].setLabelString(describeType(settings->y, true)); plot.coordinates()->axes[Y4].setLabelString(describeType(settings->y, true)); + + plot.coordinates()->axes[Z1].setTicLength(25.0/xscale, 10.0/xscale); + plot.coordinates()->axes[Z2].setTicLength(25.0/xscale, 10.0/xscale); + plot.coordinates()->axes[Z3].setTicLength(25.0/xscale, 10.0/xscale); + plot.coordinates()->axes[Z4].setTicLength(25.0/xscale, 10.0/xscale); + plot.coordinates()->axes[X1].setTicLength(25.0/yscale, 10.0/yscale); + plot.coordinates()->axes[X2].setTicLength(25.0/yscale, 10.0/yscale); + plot.coordinates()->axes[X3].setTicLength(25.0/yscale, 10.0/yscale); + plot.coordinates()->axes[X4].setTicLength(25.0/yscale, 10.0/yscale); + plot.coordinates()->axes[Y1].setTicLength(25.0/xscale, 10.0/xscale); + plot.coordinates()->axes[Y2].setTicLength(25.0/xscale, 10.0/xscale); + plot.coordinates()->axes[Y3].setTicLength(25.0/xscale, 10.0/xscale); + plot.coordinates()->axes[Y4].setTicLength(25.0/xscale, 10.0/xscale); + + // reset the flippin tic orientation, really this library + // is a bit of a pain now! + plot.coordinates()->axes[X1].setTicOrientation(0, -1, 0); + plot.coordinates()->axes[X2].setTicOrientation(0, -1, 0); + plot.coordinates()->axes[X3].setTicOrientation(0, 1, 0); + plot.coordinates()->axes[X4].setTicOrientation(0, 1, 0); + + plot.coordinates()->axes[Y1].setTicOrientation( 1, 0, 0); + plot.coordinates()->axes[Y2].setTicOrientation(-1, 0, 0); + plot.coordinates()->axes[Y3].setTicOrientation(-1, 0, 0); + plot.coordinates()->axes[Y4].setTicOrientation( 1, 0, 0); + + plot.coordinates()->axes[Z1].setTicOrientation( 1, 0, 0); + plot.coordinates()->axes[Z2].setTicOrientation( 1, 0, 0); + plot.coordinates()->axes[Z3].setTicOrientation(-1, 0, 0); + plot.coordinates()->axes[Z4].setTicOrientation(-1, 0, 0); + + // now, at last we can draw the axes markers. phew. plot.coordinates()->axes[Z1].draw(); plot.coordinates()->axes[Z2].draw(); plot.coordinates()->axes[Z3].draw(); @@ -677,18 +745,6 @@ ModelDataProvider::ModelDataProvider (BasicModelPlot &plot, ModelSettings *setti plot.coordinates()->axes[Y2].draw(); plot.coordinates()->axes[Y3].draw(); - for (unsigned int i=0; i < plot.coordinates()->axes.size(); i++) { - plot.coordinates()->axes[i].setMajors(7); - plot.coordinates()->axes[i].setMinors(5); - } - plot.setIsolines(10); - plot.setSmoothMesh(true); - plot.coordinates()->adjustLabels(diag_*2); - if (settings->gridlines == true) - plot.coordinates()->setGridLines(true, true, Qwt3D::BACK | Qwt3D::LEFT | Qwt3D::FLOOR); - else - plot.coordinates()->setGridLines(true, true, 0); - // turn off zpane -- causes nasty flashing when left on between plots zpane = 0; diff --git a/src/ModelPlot.h b/src/ModelPlot.h index ad836088f..311c5551f 100644 --- a/src/ModelPlot.h +++ b/src/ModelPlot.h @@ -35,7 +35,7 @@ #define MODEL_HEARTRATE 3 #define MODEL_SPEED 4 #define MODEL_ALT 5 -#define MODEL_PEDALFORCE 6 +#define MODEL_TORQUE 6 #define MODEL_TIME 7 #define MODEL_DISTANCE 8 #define MODEL_INTERVAL 9 @@ -43,6 +43,8 @@ #define MODEL_LONG 11 #define MODEL_XYTIME 12 #define MODEL_POWERZONE 13 +#define MODEL_CPV 14 +#define MODEL_AEPF 15 using namespace Qwt3D; diff --git a/src/ModelWindow.cpp b/src/ModelWindow.cpp index 7926515d1..e683b0162 100644 --- a/src/ModelWindow.cpp +++ b/src/ModelWindow.cpp @@ -36,7 +36,9 @@ ModelWindow::addStandardChannels(QComboBox *box) box->addItem(tr("Heartrate"), MODEL_HEARTRATE); box->addItem(tr("Speed"), MODEL_SPEED); box->addItem(tr("Altitude"), MODEL_ALT); - box->addItem(tr("Pedal Force"), MODEL_PEDALFORCE); + box->addItem(tr("Torque"), MODEL_TORQUE); + box->addItem(tr("AEPF"), MODEL_AEPF); + box->addItem(tr("CPV"), MODEL_CPV); box->addItem(tr("Time"), MODEL_TIME); box->addItem(tr("Distance"), MODEL_DISTANCE); //box->addItem(tr("Interval"), MODEL_INTERVAL); //XXX supported differently for now @@ -78,13 +80,13 @@ ModelWindow::ModelWindow(MainWindow *parent, const QDir &home) : QWidget(parent) zSelector = new QComboBox; addStandardChannels(zSelector); zSelector->addItem(tr("Time at X&Y"), MODEL_XYTIME); - zSelector->setCurrentIndex(9); // time at xy + zSelector->setCurrentIndex(11); // time at xy colorSelector = new QComboBox; addStandardChannels(colorSelector); colorSelector->addItem(tr("Power Zone"), MODEL_POWERZONE); colorSelector->addItem(tr("Time at X&Y"), MODEL_XYTIME); - colorSelector->setCurrentIndex(9); // time at xy + colorSelector->setCurrentIndex(11); // power zone styleSelector = new QComboBox; styleSelector->addItem(tr("Bar")); @@ -299,9 +301,9 @@ static struct preset { } presets[] = { { "User Defined", 0, 0, 0, 0, true, 20 }, - { "Natural Cadence Selection", 1, 2, 9, 9, false, 5 }, // don't ignore zero for cadences! - { "Power Fatigue", 8, 1, 9, 9, true, 5 }, - { "Impact of Altitude", 5, 3, 1, 9, true, 10 }, + { "Natural Cadence Selection", 1, 2, 11, 11, false, 5 }, // don't ignore zero for cadences! + { "Power Fatigue", 10, 1, 11, 11, true, 5 }, + { "Impact of Altitude", 5, 3, 1, 11, true, 10 }, { "", 0, 0, 0, 0, false, 0 } };