FitRideFile: Add Calibration Event parsing

This commit is contained in:
Damien
2013-07-18 18:21:31 +02:00
parent 5c5207c7bb
commit caeaef6ea9
8 changed files with 127 additions and 8 deletions

View File

@@ -805,6 +805,7 @@ AllPlot::recalc()
setYMax();
refreshIntervalMarkers();
refreshCalibrationMarkers();
refreshZoneLabels();
//replot();
@@ -843,6 +844,36 @@ AllPlot::refreshIntervalMarkers()
}
}
void
AllPlot::refreshCalibrationMarkers()
{
foreach(QwtPlotMarker *mrk, cal_mrk) {
mrk->detach();
delete mrk;
}
cal_mrk.clear();
if (rideItem->ride()) {
foreach(const RideFileCalibration &calibration, rideItem->ride()->calibrations()) {
QwtPlotMarker *mrk = new QwtPlotMarker;
cal_mrk.append(mrk);
mrk->attach(this);
mrk->setLineStyle(QwtPlotMarker::VLine);
mrk->setLabelAlignment(Qt::AlignRight | Qt::AlignTop);
mrk->setLinePen(QPen(GColor(CCALIBRATIONMARKER), 0, Qt::DashDotLine));
QwtText text("\n\n"+calibration.name);
text.setFont(QFont("Helvetica", 9, QFont::Bold));
text.setColor(GColor(CCALIBRATIONMARKER));
if (!bydist)
mrk->setValue(calibration.start / 60.0, 0.0);
else
mrk->setValue((context->athlete->useMetricUnits ? 1 : MILES_PER_KM) *
rideItem->ride()->timeToDistance(calibration.start), 0.0);
mrk->setLabel(text);
}
}
}
void
AllPlot::setYMax()
{
@@ -1180,6 +1211,7 @@ AllPlot::setDataFromPlot(AllPlot *plot, int startidx, int stopidx)
refreshIntervalMarkers();
refreshCalibrationMarkers();
refreshZoneLabels();
//if (this->legend()) this->legend()->show();

View File

@@ -61,6 +61,7 @@ class AllPlot : public QwtPlot
bool shadeZones() const;
void refreshZoneLabels();
void refreshIntervalMarkers();
void refreshCalibrationMarkers();
void setAxisTitle(int axis, QString label);
// refresh data / plot parameters
@@ -116,6 +117,7 @@ class AllPlot : public QwtPlot
// plot objects
QwtPlotGrid *grid;
QVector<QwtPlotMarker*> d_mrk;
QVector<QwtPlotMarker*> cal_mrk;
QwtPlotMarker *allMarker1;
QwtPlotMarker *allMarker2;
QwtPlotCurve *wattsCurve;

View File

@@ -110,6 +110,7 @@ void GCColor::setupColors()
{ tr("Alternate Power"), "CALTPOWER", Qt::magenta },
{ tr("Left Balance"), "CBALANCELEFT", QColor(178,0,0) },
{ tr("Right Balance"), "CBALANCERIGHT", QColor(128,0,50) },
{ tr("Plot Markers"), "COLORCALIBRATIONMARKER", QColor(40,40,40) },
{ "", "", QColor(0,0,0) },
};

View File

@@ -99,7 +99,7 @@ class ColorEngine : public QObject
#define GColor(x) GCColor::getColor(x)
// Define how many cconfigurable metric colors are available
#define CNUMOFCFGCOLORS 70
#define CNUMOFCFGCOLORS 71
#define CPLOTBACKGROUND 0
#define CRIDEPLOTBACKGROUND 1
@@ -171,5 +171,6 @@ class ColorEngine : public QObject
#define CALTPOWER 67
#define CBALANCELEFT 68
#define CBALANCERIGHT 69
#define CCALIBRATIONMARKER 70
#endif

View File

@@ -68,6 +68,7 @@ struct FitFileReaderState
QMap<int, FitDefinition> local_msg_types;
QSet<int> unknown_record_fields, unknown_global_msg_nums, unknown_base_type;
int interval;
int calibration;
int devices;
bool stopped;
int last_event_type;
@@ -76,7 +77,7 @@ struct FitFileReaderState
FitFileReaderState(QFile &file, QStringList &errors) :
file(file), errors(errors), rideFile(NULL), start_time(0),
last_time(0), last_distance(0.00f), interval(0), devices(0), stopped(true),
last_time(0), last_distance(0.00f), interval(0), calibration(0), devices(0), stopped(true),
last_event_type(-1), last_event(-1), last_msg_type(-1)
{
}
@@ -251,8 +252,10 @@ struct FitFileReaderState
}
void decodeEvent(const FitDefinition &def, int, const std::vector<fit_value_t> values) {
int time = -1;
int event = -1;
int event_type = -1;
qint16 data16 = -1;
int i = 0;
foreach(const FitField &field, def.fields) {
fit_value_t value = values[i++];
@@ -261,10 +264,15 @@ struct FitFileReaderState
continue;
switch (field.num) {
case 253: //time = value + qbase_time.toTime_t();
case 253: // timestamp field (s)
time = value + qbase_time.toTime_t();
break;
case 0: event = value; break;
case 1: event_type = value; break;
case 0: // event field
event = value; break;
case 1: // event_type field
event_type = value; break;
case 2: // data16 field
data16 = value; break;
default: ; // do nothing
}
}
@@ -292,7 +300,19 @@ struct FitFileReaderState
stopped = true;
break;
default:
errors << QString("Unknown event type %1").arg(event_type);
errors << QString("Unknown timer event type %1").arg(event_type);
}
}
else if (event == 36) { // Calibration event
int secs = (start_time==0?0:time-start_time);
switch (event_type) {
case 3: // marker
++calibration;
rideFile->addCalibration(secs, data16, QString("Calibration %1 (%2)").arg(calibration).arg(data16));
qDebug() << "marker" << secs << data16;
break;
default:
errors << QString("Unknown calibration event type %1").arg(event_type);
}
}
// printf("event type %d\n", event_type);
@@ -375,8 +395,10 @@ struct FitFileReaderState
case 13: temperature = value; break;
case 29: // ACCUMULATED_POWER
break;
case 30: lrbalance = (value & 0x80 ? 100 - (value & 0x7F) : value & 0x7F);break;
case 30: lrbalance = (value & 0x80 ? 100 - (value & 0x7F) : value & 0x7F);
break;
case 31: // GPS Accuracy
break;
default: unknown_record_fields.insert(field.num);
}
}

View File

@@ -51,6 +51,8 @@
\"NAME\" return NAME;
\"START\" return START;
\"STOP\" return STOP;
\"CALIBRATIONS\" return CALIBRATIONS;
\"VALUE\" return VALUE;
\"REFERENCES\" return REFERENCES;
\"SAMPLES\" return SAMPLES;
\"SECS\" return SECS;

View File

@@ -43,6 +43,7 @@ static RideFile *JsonRide;
// term state data is held in these variables
static RideFilePoint JsonPoint;
static RideFileInterval JsonInterval;
static RideFileCalibration JsonCalibration;
static QString JsonString,
JsonTagKey, JsonTagValue,
JsonOverName, JsonOverKey, JsonOverValue;
@@ -108,6 +109,7 @@ static QString unprotect(const QString string)
%token RIDE STARTTIME RECINTSECS DEVICETYPE IDENTIFIER
%token OVERRIDES
%token TAGS INTERVALS NAME START STOP
%token CALIBRATIONS VALUE
%token REFERENCES
%token SAMPLES SECS KM WATTS NM CAD KPH HR ALTITUDE LAT LON HEADWIND SLOPE TEMP LRBALANCE
@@ -136,6 +138,7 @@ rideelement: starttime
| overrides
| tags
| intervals
| calibrations
| references
| samples
;
@@ -194,6 +197,22 @@ interval: '{' NAME ':' string ',' { JsonInterval.name = JsonString; }
JsonInterval = RideFileInterval();
}
/*
* Calibrations
*/
calibrations: CALIBRATIONS ':' '[' calibration_list ']' ;
calibration_list: calibration | calibration_list ',' calibration ;
calibration: '{' NAME ':' string ',' { JsonCalibration.name = JsonString; }
START ':' number ',' { JsonCalibration.start = JsonNumber; }
VALUE ':' number { JsonCalibration.value = JsonNumber; }
'}'
{ JsonRide->addCalibration(JsonCalibration.start,
JsonCalibration.value,
JsonCalibration.name);
JsonCalibration = RideFileCalibration();
}
/*
* Ride references
*/
@@ -403,6 +422,26 @@ JsonFileReader::writeRideFile(Context *, const RideFile *ride, QFile &file) cons
out <<"\n\t\t]";
}
//
// CALIBRATION
//
if (!ride->calibrations().empty()) {
out << ",\n\t\t\"CALIBRATIONS\":[\n";
bool first = true;
foreach (RideFileCalibration i, ride->calibrations()) {
if (first) first=false;
else out << ",\n";
out << "\t\t\t{ ";
out << "\"NAME\":\"" << protect(i.name) << "\"";
out << ", \"START\": " << QString("%1").arg(i.start);
out << ", \"VALUE\": " << QString("%1").arg(i.value) << " }";
}
out <<"\n\t\t]";
}
//
// SAMPLES
//

View File

@@ -74,6 +74,19 @@ struct RideFileInterval
bool operator< (RideFileInterval right) const { return start < right.start; }
};
struct RideFileCalibration
{
double start;
int value;
QString name;
RideFileCalibration() : start(0.0), value(0) {}
RideFileCalibration(double start, int value, QString name) :
start(start), value(value), name(name) {}
// order bu start time
bool operator< (RideFileCalibration right) const { return start < right.start; }
};
class RideFile : public QObject // QObject to emit signals
{
Q_OBJECT
@@ -145,6 +158,12 @@ class RideFile : public QObject // QObject to emit signals
void fillInIntervals();
int intervalBegin(const RideFileInterval &interval) const;
// Working with CAIBRATIONS
const QList<RideFileCalibration> &calibrations() const { return calibrations_; }
void addCalibration(double start, int value, const QString &name) {
calibrations_.append(RideFileCalibration(start, value, name));
}
// Index offset calculations
double timeToDistance(double) const; // get distance in km at time in secs
int timeIndex(double) const; // get index offset for time in secs
@@ -206,6 +225,7 @@ class RideFile : public QObject // QObject to emit signals
QString deviceType_;
QString fileFormat_;
QList<RideFileInterval> intervals_;
QList<RideFileCalibration> calibrations_;
QMap<QString,QString> tags_;
EditorData *data;
double weight_; // cached to save calls to getWeight();