the FIT saga continues

New idea: only linearly interpolate between two consecutive "record"
messages.  I don't know what else to do.  My FIT files have all sorts
of weirdness I can't explain.  One, for example, has two consecutive
start events with the same timestamp.  What does that mean?

This is all proof that just having the file "format" isn't really
enough.  What you need is the file *semantics*, and we don't have that
for FIT yet.
This commit is contained in:
Sean Rhea
2010-03-23 20:59:58 -07:00
parent cd4fe5fe2e
commit d1f003c190

View File

@@ -24,6 +24,8 @@
#include <stdio.h>
#include <stdint.h>
#define RECORD_TYPE 20
static int fitFileReaderRegistered =
RideFileFactory::instance().registerReader(
"fit", "Garmin FIT", new FitFileReader());
@@ -74,17 +76,18 @@ struct FitFileReaderState
int devices;
bool stopped;
int last_event_type;
int last_msg_type;
FitFileReaderState(QFile &file, QStringList &errors) :
file(file), errors(errors), rideFile(NULL), start_time(0),
last_time(0), interval(0), devices(0), stopped(true),
last_event_type(-1)
last_event_type(-1), last_msg_type(-1)
{
if (global_msg_names.isEmpty()) {
global_msg_names.insert(0, "file_id");
global_msg_names.insert(18, "session");
global_msg_names.insert(19, "lap");
global_msg_names.insert(20, "record");
global_msg_names.insert(RECORD_TYPE, "record");
global_msg_names.insert(21, "event");
global_msg_names.insert(22, "undocumented");
global_msg_names.insert(23, "device_info");
@@ -160,7 +163,6 @@ struct FitFileReaderState
default: ; // do nothing
}
}
bool wasStopped = stopped;
switch (type) {
case 0: // start
stopped = false;
@@ -174,14 +176,8 @@ struct FitFileReaderState
default:
errors << QString("unknown event type %1").arg(type);
}
// printf("event type %d\n", type);
last_event_type = type;
if (wasStopped && !stopped) {
assert(time > 0);
if (start_time > 0) {
// Skip over time when we were stopped.
last_time = time;
}
}
}
void decodeLap(const FitDefinition &def, int time_offset, const std::vector<int> values) {
@@ -205,7 +201,6 @@ struct FitFileReaderState
rideFile->addInterval(this_start_time - start_time, time - start_time,
QString("%1").arg(interval));
}
last_time = time;
}
void decodeRecord(const FitDefinition &def, int time_offset, const std::vector<int> values) {
@@ -257,11 +252,12 @@ struct FitFileReaderState
double nm = 0;
double headwind = 0.0;
int interval = 0;
if ((last_time != 0) && (time > last_time + 1)) {
if ((last_msg_type == RECORD_TYPE) && (last_time != 0) && (time > last_time + 1)) {
// Evil smart recording. Linearly interpolate missing points.
RideFilePoint *prevPoint = rideFile->dataPoints().back();
int deltaSecs = (int) (secs - prevPoint->secs);
assert(deltaSecs == secs - prevPoint->secs); // no fractional part
// This is only true if the previous record was of type record:
assert(deltaSecs == time - last_time);
double deltaCad = cad - prevPoint->cad;
double deltaHr = hr - prevPoint->hr;
@@ -384,7 +380,7 @@ struct FitFileReaderState
switch (def.global_msg_num) {
case 0: decodeFileId(def, time_offset, values); break;
case 19: decodeLap(def, time_offset, values); break;
case 20: decodeRecord(def, time_offset, values); break;
case RECORD_TYPE: decodeRecord(def, time_offset, values); break;
case 21: decodeEvent(def, time_offset, values); break;
case 23: /* device info */
case 18: /* session */
@@ -403,6 +399,7 @@ struct FitFileReaderState
*/
unknown_global_msg_nums.insert(def.global_msg_num);
}
last_msg_type = def.global_msg_num;
}
return count;
}