diff --git a/src/Computrainer.cpp b/src/Computrainer.cpp index e3e759a77..649881b0e 100644 --- a/src/Computrainer.cpp +++ b/src/Computrainer.cpp @@ -52,6 +52,19 @@ const static uint8_t ss_command[56] = { 0x29, 0x00, 0x00, 0x16, 0x40, 0x00, 0xE0 }; +const static uint8_t rrc_command[56] = { + + 0x31, 0x00, 0x00, 0x0e, 0x40, 0x00, 0xe0, + 0x69, 0x00, 0x00, 0x0e, 0x08, 0x00, 0xe0, + 0x61, 0x00, 0x00, 0x0e, 0x10, 0x00, 0xe0, + 0x78, 0x00, 0x00, 0x0e, 0x18, 0x61, 0xc1, + 0x4d, 0x00, 0x00, 0x0e, 0x24, 0x00, 0xe0, + 0x6e, 0x00, 0x00, 0x0e, 0x2c, 0x57, 0xc1, + 0x3d, 0x00, 0x00, 0x0e, 0x34, 0x00, 0xe0, + 0x23, 0x00, 0x00, 0x0e, 0x38, 0x16, 0xc2 + +}; + /* ---------------------------------------------------------------------- * CONSTRUCTOR/DESRTUCTOR * ---------------------------------------------------------------------- */ @@ -753,6 +766,11 @@ int Computrainer::sendCommand(int mode) // writes a command to the device return rawWrite(SS_Command, 56); break; + case CT_CALIBRATE : + return rawWrite(const_cast(rrc_command), 56); + break; + + default : return -1; break; diff --git a/src/Computrainer.h b/src/Computrainer.h index 2506ac6ef..eba3ee451 100644 --- a/src/Computrainer.h +++ b/src/Computrainer.h @@ -83,8 +83,9 @@ #define CT_NONE 0x80 /* Device operation mode */ -#define CT_ERGOMODE 0x01 -#define CT_SSMODE 0x02 +#define CT_ERGOMODE 0x01 +#define CT_SSMODE 0x02 +#define CT_CALIBRATE 0x04 /* UI operation mode */ #define UI_MANUAL 0x01 // using +/- keys to adjust diff --git a/src/ComputrainerController.cpp b/src/ComputrainerController.cpp index 3362387e7..d539c1f64 100644 --- a/src/ComputrainerController.cpp +++ b/src/ComputrainerController.cpp @@ -108,6 +108,14 @@ ComputrainerController::getRealtimeData(RealtimeData &rtData) // BUTTONS // + // toggle calibration + if (Buttons&CT_F3) { + parent->Calibrate(); + } + + // ignore other buttons if calibrating + if (parent->calibrating) return; + // ADJUST LOAD Load = myComputrainer->getLoad(); if ((Buttons&CT_PLUS) && !(Buttons&CT_F3)) { @@ -118,6 +126,7 @@ ComputrainerController::getRealtimeData(RealtimeData &rtData) } rtData.setLoad(Load); +#if 0 // F3 now toggles calibration // FFWD/REWIND if ((Buttons&CT_PLUS) && (Buttons&CT_F3)) { parent->FFwd(); @@ -125,7 +134,7 @@ ComputrainerController::getRealtimeData(RealtimeData &rtData) if ((Buttons&CT_MINUS) && (Buttons&CT_F3)) { parent->Rewind(); } - +#endif // LAP/INTERVAL if (Buttons&CT_F1 && !(Buttons&CT_F3)) { @@ -164,5 +173,6 @@ ComputrainerController::setMode(int mode) { if (mode == RT_MODE_ERGO) mode = CT_ERGOMODE; if (mode == RT_MODE_SPIN) mode = CT_SSMODE; + if (mode == RT_MODE_CALIBRATE) mode = CT_CALIBRATE; myComputrainer->setMode(mode); } diff --git a/src/TrainTool.cpp b/src/TrainTool.cpp index 86ccae850..a0e5cab3d 100644 --- a/src/TrainTool.cpp +++ b/src/TrainTool.cpp @@ -257,6 +257,7 @@ TrainTool::TrainTool(MainWindow *parent, const QDir &home) : GcWindow(parent), h deviceController = NULL; streamController = NULL; ergFile = NULL; + calibrating = false; // metric or imperial? QVariant unit = appsettings->value(this, GC_UNIT); @@ -677,6 +678,7 @@ void TrainTool::Start() // when start button is pressed session_elapsed_msec = 0; lap_time.start(); lap_elapsed_msec = 0; + calibrating = false; if (status & RT_WORKOUT) { load_timer->start(LOADRATE); // start recording @@ -770,6 +772,7 @@ void TrainTool::Stop(int deviceStatus) // when stop button is pressed deviceController = NULL; gui_timer->stop(); + calibrating = false; QDateTime now = QDateTime::currentDateTime(); @@ -880,8 +883,10 @@ void TrainTool::guiUpdate() // refreshes the telemetry rtData.setDistance(displayDistance); // time - total_msecs = session_elapsed_msec + session_time.elapsed(); - lap_msecs = lap_elapsed_msec + lap_time.elapsed(); + if (!calibrating) { // freeze time whilst calibrating + total_msecs = session_elapsed_msec + session_time.elapsed(); + lap_msecs = lap_elapsed_msec + lap_time.elapsed(); + } rtData.setMsecs(total_msecs); rtData.setLapMsecs(lap_msecs); @@ -990,6 +995,8 @@ void TrainTool::diskUpdate() long Torq = 0, Altitude = 0; QTextStream recordFileStream(recordFile); + if (calibrating) return; + // convert from milliseconds to minutes total_msecs = session_elapsed_msec + session_time.elapsed(); Minutes = total_msecs; @@ -1018,6 +1025,10 @@ void TrainTool::loadUpdate() int curLap; long load; double gradient; + + // we hold our horses whilst calibration is taking place... + if (calibrating) return; + // the period between loadUpdate calls is not constant, and not exactly LOADRATE, // therefore, use a QTime timer to measure the load period load_msecs += load_period.restart(); @@ -1053,6 +1064,50 @@ void TrainTool::loadUpdate() } } +void TrainTool::Calibrate() +{ + static QProgressDialog *bar=NULL; + + if (deviceController == NULL) return; + + // toggle calibration + if (calibrating) { + bar->reset(); // will hide... + + // restart gui etc + session_time.start(); + lap_time.start(); + load_period.restart(); + if (status & RT_WORKOUT) load_timer->start(LOADRATE); + main->notifyUnPause(); // get video started again, amongst other things + + // back to ergo/slope mode + if (status&RT_MODE_ERGO) deviceController->setMode(RT_MODE_ERGO); + else deviceController->setMode(RT_MODE_SPIN); + } else { + + if (bar == NULL) { + QString title = tr("Calibrating...\nPress F3 on Controller when done."); + bar = new QProgressDialog(title, tr("Done"), 0, 0, this); + bar->setWindowModality(Qt::WindowModal); + bar->setMinimumDuration(0); + bar->setAutoClose(true); // hide when reset + connect(bar, SIGNAL(canceled()), this, SLOT(Calibrate())); + } + bar->show(); + + // pause gui/load but keep recording! + session_elapsed_msec += session_time.elapsed(); + lap_elapsed_msec += lap_time.elapsed(); + if (status & RT_WORKOUT) load_timer->stop(); + load_msecs += load_period.restart(); + main->notifyPause(); // get video started again, amongst other things + + deviceController->setMode(RT_MODE_CALIBRATE); + } + calibrating = !calibrating; +} + void TrainTool::FFwd() { if ((status&RT_RUNNING) == 0) return; diff --git a/src/TrainTool.h b/src/TrainTool.h index cca9d8daf..fdd4e5934 100644 --- a/src/TrainTool.h +++ b/src/TrainTool.h @@ -37,8 +37,10 @@ #include // Status settings -#define RT_MODE_ERGO 0x0001 // load generation modes -#define RT_MODE_SPIN 0x0002 // spinscan like modes +#define RT_MODE_ERGO 0x0001 // load generation modes +#define RT_MODE_SPIN 0x0002 // spinscan like modes +#define RT_MODE_CALIBRATE 0x0004 // calibrate + #define RT_RUNNING 0x0100 // is running now #define RT_PAUSED 0x0200 // is paused #define RT_RECORDING 0x0400 // is recording to disk @@ -129,6 +131,7 @@ class TrainTool : public GcWindow void Pause(); // when Paude is pressed void Stop(int status=0); // when controller wants to stop + void Calibrate(); // toggle calibration mode void FFwd(); // jump forward when in a workout void Rewind(); // jump backwards when in a workout void FFwdLap(); // jump forward to next Lap marker @@ -214,6 +217,7 @@ class TrainTool : public GcWindow // everyone else wants this QCheckBox *recordSelector; boost::shared_ptr watcher; + bool calibrating; }; #endif // _GC_TrainTool_h