Will now read, interpret, and include any appropriately named .srm files in

the user's directory.  Ride summary, ride plot, and power histogram all work
fine, but opening the CP intervals graph causes a crash if any such files
exist.  Also need to add a menu item to import .srm files that renames them to
the proper form (date-time.srm).
This commit is contained in:
Sean C. Rhea
2007-04-09 20:43:52 +00:00
parent 513c87419d
commit 3ae2b985ce
8 changed files with 188 additions and 48 deletions

View File

@@ -5,9 +5,10 @@
TEMPLATE = app
TARGET +=
DEPENDPATH += .
INCLUDEPATH += /usr/local/include/qwt ../lib
INCLUDEPATH += /home/srhea/src/qwt-20060130/include ../lib ../srm
CONFIG += static
LIBS += /usr/local/lib/libqwt.a ../lib/libgc.a
LIBS += /home/srhea/src/qwt-20060130/lib/libqwt.a ../lib/libgc.a
LIBS += ../srm/libsrm.a
LIBS += -lm -lz
macx {
LIBS += -framework Carbon

View File

@@ -39,7 +39,7 @@
#define RIDE_TYPE 1
static char *rideFileRegExp = ("^(\\d\\d\\d\\d)_(\\d\\d)_(\\d\\d)"
"_(\\d\\d)_(\\d\\d)_(\\d\\d)\\.raw$");
"_(\\d\\d)_(\\d\\d)_(\\d\\d)\\.(raw|srm)$");
MainWindow::MainWindow(const QDir &home) :
home(home), settings(GC_SETTINGS_CO, GC_SETTINGS_APP)
@@ -70,13 +70,13 @@ MainWindow::MainWindow(const QDir &home) :
QRegExp rx(rideFileRegExp);
QStringList filters;
filters << "*.raw";
filters << "*.raw" << "*.srm";
QTreeWidgetItem *last = NULL;
QStringListIterator i(home.entryList(filters, QDir::Files));
while (i.hasNext()) {
QString name = i.next();
if (rx.exactMatch(name)) {
assert(rx.numCaptures() == 6);
assert(rx.numCaptures() == 7);
QDate date(rx.cap(1).toInt(), rx.cap(2).toInt(),rx.cap(3).toInt());
QTime time(rx.cap(4).toInt(), rx.cap(5).toInt(),rx.cap(6).toInt());
QDateTime dt(date, time);

View File

@@ -19,8 +19,11 @@
*/
#include "RawFile.h"
#include <math.h>
#include <assert.h>
#include <QMessageBox>
#include "srm.h"
extern "C" {
#include "pt.h"
}
@@ -93,19 +96,43 @@ error_cb(const char *msg, void *context)
state->errors.append(QString(msg));
}
RawFile *RawFile::readFile(const QFile &file, QStringList &errors)
RawFile *RawFile::readFile(QFile &file, QStringList &errors)
{
RawFile *result = new RawFile(file.fileName());
if (!result->file.open(QIODevice::ReadOnly)) {
delete result;
return NULL;
if (file.fileName().indexOf(".srm") == file.fileName().size() - 4) {
SrmData data;
if (!readSrmFile(file, data, errors)) {
delete result;
return NULL;
}
result->startTime = data.startTime;
result->rec_int = (unsigned) round(data.recint); // TODO
QListIterator<SrmDataPoint*> i(data.dataPoints);
while (i.hasNext()) {
SrmDataPoint *p1 = i.next();
RawFilePoint *p2 = new RawFilePoint(
p1->secs, 0, p1->kph * 0.62137119, p1->watts,
p1->km * 0.62137119, p1->cad, p1->hr, p1->interval);
if (result->powerHist.contains(p2->watts))
result->powerHist[p2->watts] += data.recint;
else
result->powerHist[p2->watts] = data.recint;
result->points.append(p2);
}
}
else {
if (!result->file.open(QIODevice::ReadOnly)) {
delete result;
return NULL;
}
FILE *f = fdopen(result->file.handle(), "r");
assert(f);
RawFileReadState state(result->points, result->powerHist, errors);
pt_read_raw(f, 0 /* not compat */, &state, config_cb,
time_cb, data_cb, error_cb);
result->rec_int = state.rec_int;
}
FILE *f = fdopen(result->file.handle(), "r");
assert(f);
RawFileReadState state(result->points, result->powerHist, errors);
pt_read_raw(f, 0 /* not compat */, &state, config_cb,
time_cb, data_cb, error_cb);
result->rec_int = state.rec_int;
return result;
}

View File

@@ -53,7 +53,7 @@ class RawFile
int rec_int;
QList<RawFilePoint*> points;
QMap<double,double> powerHist;
static RawFile *readFile(const QFile &file, QStringList &errors);
static RawFile *readFile(QFile &file, QStringList &errors);
};
#endif // _GC_RawFile_h

View File

@@ -1,8 +1,8 @@
#############################################################################
# Makefile for building: srm
# Generated by qmake (2.01a) (Qt 4.2.0) on: Sun Apr 8 18:34:58 2007
# Makefile for building: libsrm.a
# Generated by qmake (2.01a) (Qt 4.2.0) on: Mon Apr 9 13:27:14 2007
# Project: srm.pro
# Template: app
# Template: lib
# Command: /usr/bin/qmake -unix -o Makefile srm.pro
#############################################################################
@@ -13,14 +13,11 @@ CXX = g++
LEX = flex
YACC = yacc
DEFINES = -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
CFLAGS = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)
CXXFLAGS = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)
CFLAGS = -pipe -O2 -fPIC -Wall -W -D_REENTRANT $(DEFINES)
CXXFLAGS = -pipe -O2 -fPIC -Wall -W -D_REENTRANT $(DEFINES)
LEXFLAGS =
YACCFLAGS = -d
INCPATH = -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -I.
LINK = g++
LFLAGS =
LIBS = $(SUBLIBS) -L/usr/lib -lQtGui -L/build/buildd/qt4-x11-4.2.0/lib -L/usr/X11R6/lib -laudio -lXt -lpng -lSM -lICE -lXrender -lXrandr -lXfixes -lXcursor -lXinerama -lfreetype -lXext -lX11 -lQtCore -lfontconfig -lz -lm -lglib-2.0 -ldl -lpthread
AR = ar cqs
RANLIB =
QMAKE = /usr/bin/qmake
@@ -57,6 +54,8 @@ DIST = /usr/share/qt4/mkspecs/common/unix.conf \
/usr/share/qt4/mkspecs/features/default_pre.prf \
/usr/share/qt4/mkspecs/features/release.prf \
/usr/share/qt4/mkspecs/features/default_post.prf \
/usr/share/qt4/mkspecs/features/static.prf \
/usr/share/qt4/mkspecs/features/staticlib.prf \
/usr/share/qt4/mkspecs/features/warn_on.prf \
/usr/share/qt4/mkspecs/features/qt.prf \
/usr/share/qt4/mkspecs/features/unix/thread.prf \
@@ -66,7 +65,7 @@ DIST = /usr/share/qt4/mkspecs/common/unix.conf \
srm.pro
QMAKE_TARGET = srm
DESTDIR =
TARGET = srm
TARGET = libsrm.a
first: all
####### Implicit rules
@@ -90,10 +89,14 @@ first: all
####### Build rules
all: Makefile $(TARGET)
all: Makefile $(TARGET)
staticlib: $(TARGET)
$(TARGET): $(OBJECTS) $(OBJCOMP)
-$(DEL_FILE) $(TARGET)
$(AR) $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS)
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
Makefile: srm.pro /usr/share/qt4/mkspecs/linux-g++/qmake.conf /usr/share/qt4/mkspecs/common/unix.conf \
/usr/share/qt4/mkspecs/common/g++.conf \
@@ -105,6 +108,8 @@ Makefile: srm.pro /usr/share/qt4/mkspecs/linux-g++/qmake.conf /usr/share/qt4/mk
/usr/share/qt4/mkspecs/features/default_pre.prf \
/usr/share/qt4/mkspecs/features/release.prf \
/usr/share/qt4/mkspecs/features/default_post.prf \
/usr/share/qt4/mkspecs/features/static.prf \
/usr/share/qt4/mkspecs/features/staticlib.prf \
/usr/share/qt4/mkspecs/features/warn_on.prf \
/usr/share/qt4/mkspecs/features/qt.prf \
/usr/share/qt4/mkspecs/features/unix/thread.prf \
@@ -124,6 +129,8 @@ Makefile: srm.pro /usr/share/qt4/mkspecs/linux-g++/qmake.conf /usr/share/qt4/mk
/usr/share/qt4/mkspecs/features/default_pre.prf:
/usr/share/qt4/mkspecs/features/release.prf:
/usr/share/qt4/mkspecs/features/default_post.prf:
/usr/share/qt4/mkspecs/features/static.prf:
/usr/share/qt4/mkspecs/features/staticlib.prf:
/usr/share/qt4/mkspecs/features/warn_on.prf:
/usr/share/qt4/mkspecs/features/qt.prf:
/usr/share/qt4/mkspecs/features/unix/thread.prf:
@@ -137,7 +144,7 @@ qmake: FORCE
dist:
@$(CHK_DIR_EXISTS) .tmp/srm1.0.0 || $(MKDIR) .tmp/srm1.0.0
$(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/srm1.0.0/ && $(COPY_FILE) --parents srm.cpp .tmp/srm1.0.0/ && (cd `dirname .tmp/srm1.0.0` && $(TAR) srm1.0.0.tar srm1.0.0 && $(COMPRESS) srm1.0.0.tar) && $(MOVE) `dirname .tmp/srm1.0.0`/srm1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/srm1.0.0
$(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/srm1.0.0/ && $(COPY_FILE) --parents srm.h .tmp/srm1.0.0/ && $(COPY_FILE) --parents srm.cpp .tmp/srm1.0.0/ && (cd `dirname .tmp/srm1.0.0` && $(TAR) srm1.0.0.tar srm1.0.0 && $(COMPRESS) srm1.0.0.tar) && $(MOVE) `dirname .tmp/srm1.0.0`/srm1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/srm1.0.0
yaccclean:

View File

@@ -3,9 +3,7 @@
// (http://www.stephanmantler.com/?page_id=86).
//
#include <QDataStream>
#include <QDate>
#include <QFile>
#include "srm.h"
#include <assert.h>
#include <math.h>
#include <stdio.h>
@@ -32,18 +30,23 @@ static quint32 readLong(QDataStream &in)
return htonl(value); // SRM uses big endian
}
struct marker
{
int start, end;
};
struct blockhdr
{
QDateTime dt;
quint16 chunkcnt;
};
int main(int argc, char *argv[])
bool readSrmFile(QFile &file, SrmData &data, QStringList &errorStrings)
{
assert(argc > 1);
QFile file(argv[1]);
if (!file.open(QFile::ReadOnly))
assert(false);
if (!file.open(QFile::ReadOnly)) {
errorStrings << QString("can't open file %1").arg(file.fileName());
return false;
}
QDataStream in(&file);
char magic[5];
@@ -65,13 +68,13 @@ int main(int argc, char *argv[])
in.readRawData(comment, sizeof(comment) - 1);
comment[commentlen - 1] = '\0';
double recint = ((double) recint1) / recint2;
unsigned recintms = (unsigned) round(recint * 1000.0);
data.recint = ((double) recint1) / recint2;
unsigned recintms = (unsigned) round(data.recint * 1000.0);
printf("magic=%s\n", magic);
printf("wheelcirc=%d\n", wheelcirc);
printf("dayssince1880=%d\n", dayssince1880);
printf("recint=%f sec\n", recint);
printf("recint=%f sec\n", data.recint);
printf("blockcnt=%d\n", blockcnt);
printf("markercnt=%d\n", markercnt);
printf("commentlen=%d\n", commentlen);
@@ -82,6 +85,7 @@ int main(int argc, char *argv[])
printf("date=%s\n", date.toString().toAscii().constData());
marker *markers = new marker[markercnt + 1];
for (int i = 0; i <= markercnt; ++i) {
char mcomment[256];
in.readRawData(mcomment, sizeof(mcomment) - 1);
@@ -95,6 +99,8 @@ int main(int argc, char *argv[])
quint16 avgcad = readShort(in);
quint16 avgspeed = readShort(in);
quint16 pwc150 = readShort(in);
markers[i].start = start;
markers[i].end = end;
printf("marker %d:\n", i);
printf(" mcomment=%s\n", mcomment);
@@ -129,7 +135,15 @@ int main(int argc, char *argv[])
printf("slope=%d\n", slope);
printf("datacnt=%d\n", datacnt);
for (int i = 0, blknum = 0, blkidx = 0; i < datacnt; ++i) {
assert(blockcnt > 0);
int blknum = 0, blkidx = 0, mrknum = 0, interval = 0;
double km = 0.0, secs = 0.0;
if (markercnt > 0)
mrknum = 1;
for (int i = 0; i < datacnt; ++i) {
quint8 ps[3];
in.readRawData((char*) ps, sizeof(ps));
quint8 cad = readByte(in);
@@ -137,17 +151,76 @@ int main(int argc, char *argv[])
double kph = (((((unsigned) ps[1]) & 0xf0) << 3)
| (ps[0] & 0x7f)) * 3.0 / 26.0;
unsigned watts = (ps[1] & 0x0f) | (ps[2] << 0x4);
QDateTime dt = blockhdrs[blknum].dt.addMSecs(recintms * blkidx);
printf(" %s %5.1f %4d %3d %3d\n",
dt.toString().toAscii().constData(), kph, watts, hr, cad);
if (i == 0) {
data.startTime = blockhdrs[blknum].dt;
printf("startTime=%s\n",
data.startTime.toString().toAscii().constData());
}
if (i == markers[mrknum].end) {
++interval;
++mrknum;
}
if ((i > 0) && (i == markers[mrknum].start))
++interval;
km += data.recint * kph / 3600.0;
SrmDataPoint *point = new SrmDataPoint;
point->cad = cad;
point->hr = hr;
point->watts = watts;
point->interval = interval;
point->kph = kph;
point->km = km;
point->secs = secs;
data.dataPoints.append(point);
printf("%5.1f %5.1f %5.1f %4d %3d %3d %2d\n",
secs, km, kph, watts, hr, cad, interval);
++blkidx;
if (blkidx == blockhdrs[blknum].chunkcnt) {
if ((blkidx == blockhdrs[blknum].chunkcnt) && (blknum + 1 < blockcnt)) {
QDateTime end = blockhdrs[blknum].dt.addMSecs(
recintms * blockhdrs[blknum].chunkcnt);
++blknum;
blkidx = 0;
QDateTime start = blockhdrs[blknum].dt;
qint64 endms =
((qint64) end.toTime_t()) * 1000 + end.time().msec();
qint64 startms =
((qint64) start.toTime_t()) * 1000 + start.time().msec();
qint64 diff = startms - endms;
if (diff < 0) {
errorStrings << QString("ERROR: time goes backwards by %1 ms"
" on trans " "to block %2"
).arg(diff).arg(blknum);
secs += data.recint; // for lack of a better option
}
else {
// printf("jumping forward %lld ms\n", diff);
secs += diff / 1000.0;
}
}
else {
secs += data.recint;
}
}
file.close();
return 0;
return true;
}
/*
int main(int argc, char *argv[]) {
assert(argc > 1);
QFile file(argv[1]);
QStringList errorStrings;
SrmData data;
if (readSrmFile(file, data, errorStrings))
return 0;
else
return -1;
}
*/

31
src/srm/srm.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef _srm_h
#define _srm_h
#include <QDataStream>
#include <QDate>
#include <QFile>
#include <QStringList>
struct SrmDataPoint
{
int cad, hr, watts, interval;
double kph, km, secs;
};
struct SrmData
{
QDateTime startTime;
double recint;
QList<SrmDataPoint*> dataPoints;
~SrmData() {
QListIterator<SrmDataPoint*> i(dataPoints);
while (i.hasNext())
delete i.next();
}
};
bool readSrmFile(QFile &file, SrmData &data, QStringList &errorStrings);
#endif // _srm_h

View File

@@ -2,14 +2,15 @@
# Automatically generated by qmake (2.01a) Sun Apr 8 17:19:06 2007
######################################################################
TEMPLATE = app
TEMPLATE = lib
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
CXXFLAGS += -std=c99
CONFIG += static
LIBS += -lm
# Input
HEADERS += srm.h
SOURCES += srm.cpp