Base code for additional ride and video types (#3469)

Related to #3376
This commit is contained in:
ericchristoffersen
2020-06-22 10:35:43 -07:00
committed by GitHub
parent ad4d06faa8
commit 225cf0c9d5
4 changed files with 172 additions and 31 deletions

View File

@@ -42,6 +42,19 @@ static bool setSupported()
::supported << ".zwo";
::supported << ".gpx";
::supported << ".tts";
// Additional supportable ridefile types. Uncomment to enable.
//::supported << ".bin";
//::supported << ".bin2";
//::supported << ".fit";
//::supported << ".fitlog";
//::supported << ".hrm";
//::supported << ".pwx";
//::supported << ".srd";
//::supported << ".srm";
//::supported << ".tcx";
//::supported << ".wko";
return true;
}
static bool isinit = setSupported();
@@ -107,15 +120,19 @@ ErgFile::fromContent2(QString contents, Context *context)
void ErgFile::reload()
{
// All file endings that can be loaded as ergfile from rideFileFactory.
// Actual permitted file types are controlled by ::supported list at
// top of this file.
QRegExp fact(".+[.](gpx|bin|bin2|fit|fitlog|hrm|pwx|srd|srm|tcx|wko)$", Qt::CaseInsensitive);
// which parser to call? NOTE: we should look at moving to an ergfile factory
// like we do with ride files if we end up with lots of different formats
if (filename.endsWith(".pgmf", Qt::CaseInsensitive)) parseTacx();
else if (filename.endsWith(".zwo", Qt::CaseInsensitive)) parseZwift();
else if (filename.endsWith(".gpx", Qt::CaseInsensitive)) parseGpx();
else if (filename.endsWith(".erg2", Qt::CaseInsensitive)) parseErg2();
else if (filename.endsWith(".tts", Qt::CaseInsensitive)) parseTTS();
if (filename.endsWith(".pgmf", Qt::CaseInsensitive)) parseTacx();
else if (filename.endsWith(".zwo", Qt::CaseInsensitive)) parseZwift();
else if (fact.exactMatch(filename)) parseFromRideFileFactory();
else if (filename.endsWith(".erg2", Qt::CaseInsensitive)) parseErg2();
else if (filename.endsWith(".tts", Qt::CaseInsensitive)) parseTTS();
else parseComputrainer();
}
void ErgFile::parseZwift()
@@ -693,8 +710,22 @@ void ErgFile::parseComputrainer(QString p)
}
}
// parse gpx into ergfile
void ErgFile::parseGpx()
// Parse anything that the ridefile factory knows how to load
// and which contains gps data, altitude or slope.
//
// File types supported:
// .bin Joule GPS File
// .bin2 Joule GPS File
// .fit Garmin FIT
// .fitlog Sporttracks FITLOG
// .gpx GPS Track
// .hrm Polar Precision
// .pwx TrainingPeaks PWX
// .srd Polar SRD
// .srm SRM Powercontrol
// .tcx Garmin TCX
// .wko TrainingPeaks WKO
void ErgFile::parseFromRideFileFactory()
{
// Initialise
Version = "";

View File

@@ -106,18 +106,18 @@ class ErgFile
static ErgFile *fromContent(QString, Context *); // read from memory *.erg
static ErgFile *fromContent2(QString, Context *); // read from memory *.erg2
static bool isWorkout(QString); // is this a supported workout?
static bool isWorkout(QString); // is this a supported workout?
void reload(); // reload after messed about
void reload(); // reload after messed about
void parseComputrainer(QString p = ""); // its an erg,crs or mrc file
void parseTacx(); // its a pgmf file
void parseZwift(); // its a zwo file (zwift xml)
void parseGpx(); // its a gpx...
void parseErg2(QString p = ""); // ergdb
void parseTTS(); // its ahh tts
void parseTacx(); // its a pgmf file
void parseZwift(); // its a zwo file (zwift xml)
void parseFromRideFileFactory(); // its something we can parse using ridefilefactory...
void parseErg2(QString p = ""); // ergdb
void parseTTS(); // its ahh tts
bool isValid(); // is the file valid or not?
bool isValid(); // is the file valid or not?
double Cp;
int format; // ERG, CRS, MRC, ERG2 currently supported

View File

@@ -30,7 +30,21 @@ static bool setSupported()
{
::supported << ".rlv";
::supported << ".tts";
//TODO ::supported << ".gpx";
// Additional file types that are supportable as videosync file.
// Uncomment to enable.
//::supported << ".gpx";
//::supported << ".bin";
//::supported << ".bin2";
//::supported << ".fit";
//::supported << ".fitlog";
//::supported << ".hrm";
//::supported << ".pwx";
//::supported << ".srd";
//::supported << ".srm";
//::supported << ".tcx";
//::supported << ".wko";
return true;
}
static bool isinit = setSupported();
@@ -55,10 +69,13 @@ VideoSyncFile::VideoSyncFile(Context *context) : context(context)
void VideoSyncFile::reload()
{
// These types are enabled using ::supported list at top of this file.
QRegExp fact(".+[.](gpx|bin|bin2|fit|fit|fitlog|hrm|pwx|srd|srm|tcx|wko)$", Qt::CaseInsensitive);
// which parser to call?
if (filename.endsWith(".rlv", Qt::CaseInsensitive)) parseRLV();
if (filename.endsWith(".tts", Qt::CaseInsensitive)) parseTTS();
//TODO else if (filename.endsWith(".gpx", Qt::CaseInsensitive)) parseGPX();
if (filename.endsWith(".rlv", Qt::CaseInsensitive)) parseRLV();
else if (filename.endsWith(".tts", Qt::CaseInsensitive)) parseTTS();
else if (fact.exactMatch(filename)) parseFromRideFileFactory();
}
void VideoSyncFile::parseTTS()
@@ -92,15 +109,9 @@ void VideoSyncFile::parseTTS()
// -----------------------------------------------------------------
// VideoSyncFilePoint
const std::vector<NS_TTSReader::Point> &ttsPoints = ttsReader.getPoints();
if (ttsReader.hasFrameMapping()) {
NS_TTSReader::Point fakeFirstPoint;
fakeFirstPoint = ttsPoints[1];
fakeFirstPoint.setDistanceFromStart(0);
fakeFirstPoint.setTime(0);
const std::vector<NS_TTSReader::Point>& ttsPoints = ttsReader.getPoints();
size_t pointCount = ttsPoints.size();
for (size_t i = 0; i < pointCount; i++) {
@@ -348,6 +359,104 @@ void VideoSyncFile::parseRLV()
}
}
void VideoSyncFile::parseFromRideFileFactory()
{
// Initialise
manualOffset = 0;
Version = "";
Units = "";
Filename = "";
Name = "";
Duration = -1;
valid = false; // did it parse ok as sync file?
format = RLV;
Points.clear();
static double km = 0;
QFile rideFile(filename);
// Check file exists
if (!rideFile.exists())
return;
// Instantiate RideFile
QStringList errors_;
RideFile* ride = RideFileFactory::instance().openRideFile(context, rideFile, errors_);
if (ride == NULL)
return;
// Enumerate the data types that are available.
bool fHasKm = ride->areDataPresent()->km;
bool fHasTime = ride->areDataPresent()->secs;
bool fHasKph = ride->areDataPresent()->kph;
// These files have no frame rate. Let use determine
VideoFrameRate = 0;
// Video sync needs distance and time.
if (!(fHasKm && fHasTime))
return;
double d0 = ride->dataPoints()[1]->km - ride->dataPoints()[0]->km;
double t0 = ride->dataPoints()[1]->secs - ride->dataPoints()[0]->secs;
double v0 = (d0 / t0) * 60. * 60.; // initial kph, use second kph
// If out of range set kph to zero.
if (v0 > 1000. || v0 < 0.) v0 = 0.;
double initialSecs = ride->dataPoints()[0]->secs;
int pointCount = ride->dataPoints().count();
for (int i = 0; i < pointCount; i++) {
VideoSyncFilePoint add;
const RideFilePoint& point = *ride->dataPoints()[i];
// distance
add.km = point.km;
// time (first entry in file is 0.)
add.secs = point.secs - initialSecs;
// speed
double kph = 0.;
if (fHasKph) {
kph = point.kph;
} else if (i == 0) {
kph = v0;
} else {
const RideFilePoint& prevPoint = *ride->dataPoints()[i-1];
double distDelta = point.km - prevPoint.km;
double timeDelta = point.secs - prevPoint.secs;
double kph = 0.;
if (timeDelta) {
kph = (distDelta / timeDelta) * 60. * 60.; // initial kph, use second kph
} else {
// Propagate previous speed if time is unchanged.
kph = Points.last().kph;
}
// If out of range set kph to zero.
if (kph > 1000. || kph < 0.) v0 = 0.;
}
add.kph = kph;
Points.append(add);
}
// set RLVFile duration
Duration = Points.last().secs * 1000.0; // last is the end point in msecs
Distance = Points.last().km;
rideFile.close();
valid = true;
}
VideoSyncFile::~VideoSyncFile()
{

View File

@@ -74,10 +74,11 @@ class VideoSyncFile
static bool isVideoSync(QString); // is this a supported videosync?
void reload(); // reload after messed about
void parseRLV(); // its a rlv file
void parseTTS(); // its a tts file
bool isValid(); // is the file valid or not?
void reload(); // reload after messed about
void parseRLV(); // its a rlv file
void parseTTS(); // its a tts file
void parseFromRideFileFactory(); // try an skrimp video sync info from a ride file.
bool isValid(); // is the file valid or not?
double VideoFrameRate;