mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-14 08:38:45 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user