226
228
case 988: rideFile->setDeviceType("Garmin FR60"); break;
227
229
case 1018: rideFile->setDeviceType("Garmin FR310XT"); break;
228
230
case 1036: rideFile->setDeviceType("Garmin Edge 500"); break;
231
case 1124: rideFile->setDeviceType("Garmin FR110"); break;
229
232
case 1169: rideFile->setDeviceType("Garmin Edge 800"); break;
230
default: rideFile->setDeviceType(QString("Unknown Garmin Device %1").arg(prod));
233
case 1325: rideFile->setDeviceType("Garmin Edge 200"); break;
234
case 1561: rideFile->setDeviceType("Garmin Edge 510"); break;
235
case 1567: rideFile->setDeviceType("Garmin Edge 810"); break;
236
case 20119: rideFile->setDeviceType("Garmin Training Center"); break;
237
case 65534: rideFile->setDeviceType("Garmin Connect Website"); break;
238
default: rideFile->setDeviceType(QString("Garmin %1").arg(prod));
241
else if (manu == 38) {
243
case 1: rideFile->setDeviceType("o_synce navi2coach"); break;
244
default: rideFile->setDeviceType(QString("o_synce %1").arg(prod));
234
248
rideFile->setDeviceType(QString("Unknown FIT Device %1:%2").arg(manu).arg(prod));
250
rideFile->setFileFormat("FIT (*.fit)");
238
253
void decodeEvent(const FitDefinition &def, int, const std::vector<fit_value_t> values) {
241
255
int event_type = -1;
306
321
default: ; // ignore it
309
if (this_start_time == 0 || this_start_time-start_time < 0)
310
errors << QString("lap %1 has invalid start time").arg(interval);
312
if (rideFile->dataPoints().count()) // no samples means no laps..
313
rideFile->addInterval(this_start_time - start_time, time - start_time, QString("%1").arg(interval));
324
if (this_start_time == 0 || this_start_time-start_time < 0) {
325
//errors << QString("lap %1 has invalid start time").arg(interval);
326
this_start_time = start_time; // time was corrected after lap start
328
if (time == 0 || time-start_time < 0) {
329
errors << QString("lap %1 is ignored (invalid end time)").arg(interval);
334
if (rideFile->dataPoints().count()) // no samples means no laps..
335
rideFile->addInterval(this_start_time - start_time, time - start_time, QString("%1").arg(interval));
317
338
void decodeRecord(const FitDefinition &def, int time_offset, const std::vector<fit_value_t> values) {
319
340
if (time_offset > 0)
320
341
time = last_time + time_offset;
321
double alt = 0, cad = 0, km = 0, grade = 0, hr = 0, lat = 0, lng = 0, badgps = 0;
322
double resistance = 0, kph = 0, temperature = 0, time_from_course = 0, watts = 0;
342
double alt = 0, cad = 0, km = 0, hr = 0, lat = 0, lng = 0, badgps = 0, lrbalance = 0;
343
double kph = 0, temperature = RideFile::noTemp, watts = 0, slope = 0;
323
344
fit_value_t lati = NA_VALUE, lngi = NA_VALUE;
325
346
foreach(const FitField &field, def.fields) {
342
364
case 5: km = value / 100000.0; break;
343
365
case 6: kph = value * 3.6 / 1000.0; break;
344
366
case 7: watts = value; break;
345
case 8: break; // XXX packed speed/dist
346
case 9: grade = value / 100.0; break;
347
case 10: resistance = value; break;
348
case 11: time_from_course = value / 1000.0; break;
349
case 12: break; // XXX "cycle_length"
367
case 8: break; // packed speed/dist
368
case 9: slope = value / 100.0;
370
case 10: //resistance = value;
372
case 11: //time_from_course = value / 1000.0;
374
case 12: break; // "cycle_length"
350
375
case 13: temperature = value; break;
376
case 29: // ACCUMULATED_POWER
378
case 30: lrbalance = (value & 0x80 ? 100 - (value & 0x7F) : value & 0x7F);break;
351
380
default: unknown_record_fields.insert(field.num);
395
424
// Evil smart recording. Linearly interpolate missing points.
396
425
RideFilePoint *prevPoint = rideFile->dataPoints().back();
397
426
int deltaSecs = (int) (secs - prevPoint->secs);
398
if(deltaSecs != secs - prevPoint->secs)
399
throw BadDelta(); // no fractional part
427
assert(deltaSecs == secs - prevPoint->secs); // no fractional part
400
428
// This is only true if the previous record was of type record:
401
if(deltaSecs != time - last_time)
429
assert(deltaSecs == time - last_time);
403
430
// If the last lat/lng was missing (0/0) then all points up to lat/lng are marked as 0/0.
404
431
if (prevPoint->lat == 0 && prevPoint->lon == 0 ) {
415
442
double deltaLon = lng - prevPoint->lon;
416
443
double deltaLat = lat - prevPoint->lat;
417
444
double deltaHeadwind = headwind - prevPoint->headwind;
418
for (int i = 1; i < deltaSecs; i++) {
419
double weight = 1.0 * i / deltaSecs;
420
rideFile->appendPoint(
421
prevPoint->secs + (deltaSecs * weight),
422
prevPoint->cad + (deltaCad * weight),
423
prevPoint->hr + (deltaHr * weight),
424
prevPoint->km + (deltaDist * weight),
425
prevPoint->kph + (deltaSpeed * weight),
426
prevPoint->nm + (deltaTorque * weight),
427
prevPoint->watts + (deltaPower * weight),
428
prevPoint->alt + (deltaAlt * weight),
429
(badgps == 1) ? 0 : prevPoint->lon + (deltaLon * weight),
430
(badgps == 1) ? 0 : prevPoint->lat + (deltaLat * weight),
431
prevPoint->headwind + (deltaHeadwind * weight),
445
double deltaSlope = headwind - prevPoint->slope;
446
double deltaLeftRightBalance = lrbalance - prevPoint->lrbalance;
448
// only smooth for less than 30 minutes
449
// we don't want to crash / stall on bad
451
if (deltaSecs > 0 && deltaSecs < (60*30)) {
453
for (int i = 1; i < deltaSecs; i++) {
454
double weight = 1.0 * i / deltaSecs;
455
rideFile->appendPoint(
456
prevPoint->secs + (deltaSecs * weight),
457
prevPoint->cad + (deltaCad * weight),
458
prevPoint->hr + (deltaHr * weight),
459
prevPoint->km + (deltaDist * weight),
460
prevPoint->kph + (deltaSpeed * weight),
461
prevPoint->nm + (deltaTorque * weight),
462
prevPoint->watts + (deltaPower * weight),
463
prevPoint->alt + (deltaAlt * weight),
464
(badgps == 1) ? 0 : prevPoint->lon + (deltaLon * weight),
465
(badgps == 1) ? 0 : prevPoint->lat + (deltaLat * weight),
466
prevPoint->headwind + (deltaHeadwind * weight),
467
prevPoint->slope + (deltaSlope * weight),
469
prevPoint->lrbalance + (deltaLeftRightBalance * weight),
472
prevPoint = rideFile->dataPoints().back();
434
prevPoint = rideFile->dataPoints().back();
437
476
if (km < 0.00001f) km = last_distance;
438
rideFile->appendPoint(secs, cad, hr, km, kph, nm, watts, alt, lng, lat, headwind, interval);
477
rideFile->appendPoint(secs, cad, hr, km, kph, nm, watts, alt, lng, lat, headwind, slope, temperature, lrbalance, interval);
439
478
last_time = time;
440
479
last_distance = km;