From 02b4eedf1e4e527fc2f49c3ee45655eaf043412d Mon Sep 17 00:00:00 2001 From: Dag Gruneau Date: Sat, 16 Jan 2010 20:18:41 +0100 Subject: [PATCH] quarqd - cadence, wheel rotation, error checking Fixed a number of issues with data from quarqd inf and nan values where inserted as valid data points and thus destoying all plotting in the realtime window and in later analysis. The unit was used to distinguish between the entities, thus rpm was erroneously used as a cadence, rpm is used as the unit for wheel rotation and for cadence. This made the cadence useless together with a PowerTap hub which reports both cadence and wheel rotation. No error checking was performed on the received data, bad data is ignored now. --- src/ComputrainerController.cpp | 2 +- src/QuarqdClient.cpp | 134 ++++++++++++++++++++++++--------- src/QuarqdClient.h | 4 +- src/RealtimeData.cpp | 11 ++- src/RealtimeData.h | 7 +- src/RealtimeWindow.cpp | 6 +- src/SimpleNetworkClient.cpp | 6 +- 7 files changed, 117 insertions(+), 53 deletions(-) diff --git a/src/ComputrainerController.cpp b/src/ComputrainerController.cpp index c11242fb5..c63d242c4 100644 --- a/src/ComputrainerController.cpp +++ b/src/ComputrainerController.cpp @@ -92,7 +92,7 @@ ComputrainerController::getRealtimeData(RealtimeData &rtData) // rtData.setWatts(Power); rtData.setHr(HeartRate); - rtData.setRPM(Cadence); + rtData.setCadence(Cadence); rtData.setSpeed(Speed); // diff --git a/src/QuarqdClient.cpp b/src/QuarqdClient.cpp index f4a5f8a08..41437a201 100644 --- a/src/QuarqdClient.cpp +++ b/src/QuarqdClient.cpp @@ -20,9 +20,24 @@ #include #include #include +#include #include "QuarqdClient.h" #include "RealtimeData.h" + +// Strings as received from quarqd +// tested with a Garmin ANT+ stick +// +static QString powerStr = "portSpec).section(':',1,1).toInt(); // after the colon antIDs = config->deviceProfile.split(","); lastReadWatts = 0; - lastReadRPM = 0; + lastReadCadence = 0; + lastReadSpeed = 0; } QuarqdClient::~QuarqdClient() @@ -90,47 +106,93 @@ QuarqdClient::parseElement(QString &strBuf) // updates QuarqdClient::telemetry { QStringList qList = strBuf.split("\n"); + // qDebug("%s",strBuf.toAscii().data()); + //Loop for all the elements. for(int i=0; i 0) { + // TODO: let wheel size be a configurable, default now to 2101 mm + telemetry.setSpeed((value*2101/1000*60)/1000); // meter/minute -> meter/hour -> km/hour + lastReadSpeed = elapsedTime.elapsed(); + } + telemetry.setTime(getTimeStamp(str)); + } + } else if(str.startsWith(heartRateStr)) + { + start = str.indexOf("BPM"); + start += 5; + end = str.indexOf("'", start); + + mid = str.mid(start, end - start); + value = mid.toDouble(&ok); + + if (ok && mid != "nan" && mid != "inf") { + telemetry.setHr(value); + telemetry.setTime(getTimeStamp(str)); + } + } else if(str.startsWith(sensorDropStr) || str.startsWith(sensorStaleStr) || str.startsWith(sensorLostStr))//Try and save + { + int start = str.indexOf("id"); + start += 4; + int end = str.indexOf("'", start); reinitChannel(str.mid(start, end - start)); } - if(elapsedTime.elapsed() - lastReadRPM > 5000) - telemetry.setRPM(0); + if(elapsedTime.elapsed() - lastReadCadence > 5000) + telemetry.setCadence(0); if(elapsedTime.elapsed() - lastReadWatts > 5000) - telemetry.setWatts(0); + telemetry.setWatts(0); + + if(elapsedTime.elapsed() - lastReadSpeed > 5000) + telemetry.setSpeed(0); } } @@ -141,7 +203,7 @@ long QuarqdClient::getTimeStamp(QString &str) int start = str.indexOf("timestamp='"); start += 11; int end = str.indexOf(".", start); - qDebug() << str.mid(start, end - start); + // qDebug() << str.mid(start, end - start); return str.mid(start, end - start).toLong(); } @@ -277,10 +339,10 @@ QuarqdClient::discover(DeviceConfiguration *config, QProgressDialog *progress) while(start.elapsed() <= 50000) //Scan for 50 seconds. { if (progress->wasCanceled()) - { - tcpSocket->close(); + { + tcpSocket->close(); return false; - } + } progress->setValue(start.elapsed()); @@ -309,7 +371,7 @@ QuarqdClient::discover(DeviceConfiguration *config, QProgressDialog *progress) if (tcpSocket->bytesAvailable() > 0) { QByteArray array = tcpSocket->readAll(); strBuf = array; - qDebug() << strBuf; + // qDebug() << strBuf; QStringList qList = strBuf.split("\n"); //Loop for all the elements. @@ -317,7 +379,7 @@ QuarqdClient::discover(DeviceConfiguration *config, QProgressDialog *progress) { progress->setValue(start.elapsed()); QString str = qList.at(i); - qDebug() << str; + // qDebug() << str; if(str.contains("id")) { int start = str.indexOf("id"); diff --git a/src/QuarqdClient.h b/src/QuarqdClient.h index 0295c013b..494d1f2da 100644 --- a/src/QuarqdClient.h +++ b/src/QuarqdClient.h @@ -71,7 +71,9 @@ private: int devicePort; QStringList antIDs; long lastReadWatts; - long lastReadRPM; + long lastReadCadence; + long lastReadWheelRpm; + long lastReadSpeed; QTime elapsedTime; bool sentDual, sentSpeed, sentHR, sentCad, sentPWR; void reinitChannel(QString _channel); diff --git a/src/RealtimeData.cpp b/src/RealtimeData.cpp index 97f340530..f4a344f0c 100644 --- a/src/RealtimeData.cpp +++ b/src/RealtimeData.cpp @@ -21,7 +21,7 @@ RealtimeData::RealtimeData() { - watts = hr = speed = rpm = load = 0; + watts = hr = speed = cadence = load = 0; time = 0; } @@ -41,15 +41,14 @@ void RealtimeData::setSpeed(double speed) { this->speed = speed; } -void RealtimeData::setRPM(double rpm) +void RealtimeData::setCadence(double aCadence) { - this->rpm = rpm; + cadence = aCadence; } void RealtimeData::setLoad(double load) { this->load = load; } - double RealtimeData::getWatts() { return watts; @@ -67,9 +66,9 @@ double RealtimeData::getSpeed() { return speed; } -double RealtimeData::getRPM() +double RealtimeData::getCadence() { - return rpm; + return cadence; } double RealtimeData::getLoad() { diff --git a/src/RealtimeData.h b/src/RealtimeData.h index d1b338acf..e90b97e6e 100644 --- a/src/RealtimeData.h +++ b/src/RealtimeData.h @@ -32,19 +32,20 @@ public: void setHr(double hr); void setTime(long time); void setSpeed(double speed); - void setRPM(double rpm); + void setCadence(double aCadence); void setLoad(double load); double getWatts(); double getHr(); long getTime(); double getSpeed(); - double getRPM(); + double getCadence(); double getLoad(); private: - double hr, watts, rpm, speed, load; + double hr, watts, speed, load; unsigned long time; + double cadence; // in rpm }; diff --git a/src/RealtimeWindow.cpp b/src/RealtimeWindow.cpp index 5f0b8dbe9..b873b5cc4 100644 --- a/src/RealtimeWindow.cpp +++ b/src/RealtimeWindow.cpp @@ -499,7 +499,7 @@ void RealtimeWindow::Stop() // when stop button is pressed void RealtimeWindow::updateData(RealtimeData &rtData) { displayPower = rtData.getWatts(); - displayCadence = rtData.getRPM(); + displayCadence = rtData.getCadence(); displayHeartRate = rtData.getHr(); displaySpeed = rtData.getSpeed(); displayLoad = rtData.getLoad(); @@ -519,7 +519,7 @@ void RealtimeWindow::guiUpdate() // refreshes the telemetry if (status&RT_RUNNING && deviceController->doesPull() == true) { deviceController->getRealtimeData(rtData); displayPower = rtData.getWatts(); - displayCadence = rtData.getRPM(); + displayCadence = rtData.getCadence(); displayHeartRate = rtData.getHr(); displaySpeed = rtData.getSpeed(); displayLoad = rtData.getLoad(); @@ -659,7 +659,7 @@ RealtimeWindow::streamUpdate() // get current telemetry... rtData.setWatts(displayPower); - rtData.setRPM(displayCadence); + rtData.setCadence(displayCadence); rtData.setHr(displayHeartRate); rtData.setSpeed(displaySpeed); rtData.setLoad(displayLoad); diff --git a/src/SimpleNetworkClient.cpp b/src/SimpleNetworkClient.cpp index 468a4e0d3..dd388d345 100644 --- a/src/SimpleNetworkClient.cpp +++ b/src/SimpleNetworkClient.cpp @@ -227,13 +227,13 @@ bool SimpleNetworkClient::read_next_line(QMutexLocker &locker, read_into_me.setHr(hr); read_into_me.setTime(time); read_into_me.setSpeed(speed); - read_into_me.setRPM(rpm); + read_into_me.setCadence(rpm); read_into_me.setLoad(load); printf("Read from network: %f %f %ld %f %f %f\n", read_into_me.getWatts(), read_into_me.getHr(), read_into_me.getTime(), read_into_me.getSpeed(), - read_into_me.getRPM(), read_into_me.getLoad()); + read_into_me.getCadence(), read_into_me.getLoad()); } return true; } @@ -246,7 +246,7 @@ bool SimpleNetworkClient::write_next_line(QMutexLocker &locker, snprintf(buffer, MAX_BYTES_PER_LINE-1, "%.2f %.2f %ld %.2f %.2f %.3f\n", record.getWatts(), record.getHr(), record.getTime(), - record.getSpeed(), record.getRPM(), record.getLoad()); + record.getSpeed(), record.getCadence(), record.getLoad()); locker.unlock(); num_written = server.write(buffer, strlen(buffer)); locker.relock();