Computrainer 3dp file support

This commit is contained in:
Greg Lonnon
2009-10-29 07:10:48 -06:00
committed by Sean Rhea
parent 39c7787c19
commit 5a25dcb56a
5 changed files with 174 additions and 6 deletions

138
src/Computrainer3dpFile.cpp Normal file
View File

@@ -0,0 +1,138 @@
/*
* Copyright (c) 2007 Sean C. Rhea (srhea@srhea.net),
* Justin F. Knotzke (jknotzke@shampoo.ca)
* Copyright (c) 2009 Greg Lonnon (greg.lonnon@gmail.com)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Computrainer3dpFile.h"
#include <QRegExp>
#include <QTextStream>
#include <QDateTime>
#include <QString>
#include <algorithm> // for std::sort
#include <assert.h>
#include "math.h"
#include <iostream>
#include <QDebug>
#include "Units.h"
#include <QVector>
typedef unsigned char ubyte;
static int Computrainer3dpFileReaderRegistered =
RideFileFactory::instance().registerReader("3dp",
new
Computrainer3dpFileReader
());
RideFile *Computrainer3dpFileReader::openRideFile(QFile & file,
QStringList & errors)
const
{
if (!file.open(QFile::ReadOnly)) {
errors << ("Could not open ride file: \"" + file.fileName() +
"\"");
return NULL;
}
RideFile *rideFile = new RideFile();
QDataStream is(&file);
is.setByteOrder(QDataStream::LittleEndian);
// looks like the first part is a header... ignore it.
is.skipRawData(4);
char perfStr[5];
is.readRawData(perfStr, 4);
perfStr[4] = NULL;
is.skipRawData(0x8);
char userName[65];
is.readRawData(userName, 65);
ubyte age;
is >> age;
is.skipRawData(6);
float weight;
is >> weight;
int upperHR;
is >> upperHR;
int lowerHR;
is >> lowerHR;
int year;
is >> year;
ubyte month;
is >> month;
ubyte day;
is >> day;
ubyte hour;
is >> hour;
ubyte minute;
is >> minute;
int numberSamples;
is >> numberSamples;
// go back to the start, and go to the start of the data samples
file.seek(0);
is.skipRawData(0xf8);
for (; numberSamples; numberSamples--) {
ubyte hr;
is >> hr;
ubyte cad;
is >> cad;
unsigned short watts;
is >> watts;
float speed;
is >> speed;
speed = speed * KM_PER_MILE * 100;
int ms;
is >> ms;
is.skipRawData(4);
float miles;
is >> miles;
float km = miles * KM_PER_MILE;
is.skipRawData(0x1c);
rideFile->appendPoint((double) ms / 1000, (double) cad,
(double) hr, km, speed, 0.0, watts, 0, 0, 0);
}
QDateTime dateTime;
QDate date;
QTime time;
date.setDate(year, month, day);
time.setHMS(hour, minute, 0, 0);
dateTime.setDate(date);
dateTime.setTime(time);
rideFile->setStartTime(dateTime);
int n = rideFile->dataPoints().size();
n = qMin(n, 1000);
if (n >= 2) {
QVector < double >secs(n - 1);
for (int i = 0; i < n - 1; ++i) {
double now = rideFile->dataPoints()[i]->secs;
double then = rideFile->dataPoints()[i + 1]->secs;
secs[i] = then - now;
}
std::sort(secs.begin(), secs.end());
int mid = n / 2 - 1;
double recint = round(secs[mid] * 1000.0) / 1000.0;
rideFile->setRecIntSecs(recint);
}
rideFile->setDeviceType("Computrainer 3DP");
file.close();
return rideFile;
}

28
src/Computrainer3dpFile.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2009 Greg Lonnon (greg.lonnon@gmail.com)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _GC_COMPUTRAINER3DP_H
#define _GC_COMPUTRAINER3DP_H
#include "RideFile.h"
struct Computrainer3dpFileReader : public RideFileReader {
virtual RideFile *openRideFile(QFile &file, QStringList &errors) const;
};
#endif // _GC_COMPUTRAINER3DP_H

View File

@@ -537,11 +537,11 @@ MainWindow::importFile()
if (quarqInterpreterInstalled()) {
fileNames = QFileDialog::getOpenFileNames(
this, tr("Import from File"), lastDir,
tr("All Support Formats (*.raw *.csv *.srm *.tcx *.hrm *.wko *.qla);;Raw Powertap Files (*.raw);;Comma Separated Variable (*.csv);;SRM training files (*.srm);;Garmin Training Centre (*.tcx);;Polar Precision (*.hrm);;WKO+ Files (*.wko);;Quarq ANT+ Files (*.qla);;All files (*.*)"));
tr("All Support Formats (*.raw *.csv *.srm *.tcx *.hrm *.wko *.3dp *.qla);;Raw Powertap Files (*.raw);;Comma Separated Variable (*.csv);;SRM training files (*.srm);;Garmin Training Centre (*.tcx);;Polar Precision (*.hrm);;WKO+ Files (*.wko);;Computrainer 3dp (*.3dp);;Quarq ANT+ Files (*.qla);;All files (*.*)"));
} else {
fileNames = QFileDialog::getOpenFileNames(
this, tr("Import from File"), lastDir,
tr("All Support Formats (*.raw *.csv *.srm *.tcx *.hrm *.wko);;Raw Powertap Files (*.raw);;Comma Separated Variable (*.csv);;SRM training files (*.srm);;Garmin Training Centre (*.tcx);;Polar Precision (*.hrm);;WKO+ Files (*.wko);;All files (*.*)"));
tr("All Support Formats (*.raw *.csv *.srm *.tcx *.hrm *.wko *.3dp);;Raw Powertap Files (*.raw);;Comma Separated Variable (*.csv);;SRM training files (*.srm);;Garmin Training Centre (*.tcx);;Polar Precision (*.hrm);;WKO+ Files (*.wko);;Computrainer 3dp (*.3dp);;All files (*.*)"));
}

View File

@@ -227,9 +227,9 @@ RideImportWizard::process()
// is it one we understand ?
QRegExp suffixes;
if (quarqInterpreterInstalled())
suffixes.setPattern("^(raw|srm|csv|tcx|qla|hrm|wko)$");
suffixes.setPattern("^(raw|srm|csv|tcx|qla|hrm|wko|3dp)$");
else
suffixes.setPattern("^(raw|srm|csv|tcx|hrm|wko)$");
suffixes.setPattern("^(raw|srm|csv|tcx|hrm|wko|3dp)$");
suffixes.setCaseSensitivity(Qt::CaseInsensitive);

View File

@@ -48,6 +48,7 @@ HEADERS += \
BestIntervalDialog.h \
ChooseCyclistDialog.h \
CommPort.h \
Computrainer3dpFile.h \
ConfigDialog.h \
CpintPlot.h \
CriticalPowerWindow.h \
@@ -97,7 +98,7 @@ HEADERS += \
WkoRideFile.h \
XmlRideFile.h \
Zones.h \
srm.h
srm.h \
SOURCES += \
AllPlot.cpp \
@@ -107,6 +108,7 @@ SOURCES += \
BikeScore.cpp \
ChooseCyclistDialog.cpp \
CommPort.cpp \
Computrainer3dpFile.cpp \
ConfigDialog.cpp \
CpintPlot.cpp \
CriticalPowerWindow.cpp \
@@ -154,7 +156,7 @@ SOURCES += \
XmlRideFile.cpp \
Zones.cpp \
main.cpp \
srm.cpp
srm.cpp \
RESOURCES = application.qrc