pcolby / bipolar

Free your data from Polar FlowSync
GNU General Public License v3.0
115 stars 16 forks source link

TCX speed unit ? #74

Closed pulmark closed 7 years ago

pulmark commented 7 years ago

I integrated bipolar master branch into V800_downloader and build it. Now it seems to support cycling power data in HRM files with PPT5.

I noticed that TCX conversion uses km/h for speed data as it should be m/s. I don't know if this is specific to my environment, I use M450 for cycling, I have Powertap G3 hub and download training data directly from head unit via USB connection by using V800_downloader in Linux OS. In addition to power, G3 hub measures also speed and cadence.

For building in Linux OS I cloned V800_downloader and then added bipolar into it by cloning it under V800_downloader (bipolar directory). I then had to edit some project files to build app with QT Creator. For some reason I couldn't get delivered Linux libusb files to work with QT Creator so just modified project files to use libusb development libraries and header files that I installed into my Linux OS.

I run then tests and noticed that HRM files now have power data and it is displayed in PPT5. Then did TCX testing and noticed speed unit error when uploading TCX file into MapMyRide web service. Fixed speed values to be m/s instead of km/h in

QDomDocument TrainingSession::toTCX(const QString &buildTime) const

method. All fine after modification.

Also to add power/speed data into TCX files I modified V800_downloader code to enable Garmin ActivityExtension (XML data - TPX element). This option cannot be set in V800_downloader UI.

pcolby commented 7 years ago

Hi @pulmark,

I noticed that TCX conversion uses km/h for speed data as it should be m/s.

Interesting. I didn't actually know what units TCX uses for speed. Its not made clear in the schema, and I never thought to check (a bit silly of me). It should be very easy to convert... I'll take a closer look in the next couple of days.

For building in Linux OS I cloned V800_downloader and then added bipolar into it by cloning it under V800_downloader (bipolar directory).

You could, if you prefer, just use my v800_downloader clone instead of the official. The original author appears to have abandoned the project, and my clone is simply the latest version with all Bipolar updates applied (just as you have done).

There's an open pull request if you want to see the differences.

Thanks! :smiley:

pulmark commented 7 years ago

Ok, thanks for the info !

Yep, fix speed units is easy, I just did "divide by 3.6" modifications into the TrainingSession::toTCX() method.

I have working build environment now. I will investigate your v800_downloader clone. I don't know how you have done it but maybe building a separate library of bipolar parts that are common to V800_downloader and bipolar would be the next step ?

pcolby commented 7 years ago

I don't know how you have done it but maybe building a separate library of bipolar parts that are common to V800_downloader and bipolar would be the next step ?

Yep, would be pretty easy to do - there's only a very small amount of UI logic that's leaked into the protobuf and Polar-specific classes that v800d uses. I've put together a basic project outline already, but its not a high priority right now.

Cheers.

MHatGH commented 7 years ago

first of all - this is a very nice Project !! I'm using it with a M400 and it works fine, so you can add the M400 to the list of supported models :-). While testing the new extended tcx Option, I saw that you missed to change the unit of speed values when writing tcx files in extended Format. You changed it in summaries but not in the trackpoints. I use RubiTracks 4 to view my data and I got wrong values displayed. (too smal by a factor of 3.6)

And I've seen you are planing to integrate FIT file Export ? Flexible & Interoperable Data Transfer (FIT) output Feature( #48 opened on Jan 12 2015) This feature is very interesting to me because of the ability to transfer stepp-length values comming from my foot-pod. Is this still ongoing ore did you cancel it ? Any timeplan for this ?

pcolby commented 7 years ago

first of all - this is a very nice Project !!

Thanks :)

saw that you missed to change the unit of speed values when writing tcx files in extended Format.

Oh. Can you provide more details of what you think is missed? I had a good look, and thought I covered everything, but the specs are pretty ambiguous in their language. Which "extended" format are you referring to? (Garmin Activity Extension or Garmin Course Extension?) and which child element or attribute of the trackpoint? Thanks! :smile:

And I've seen you are planing to integrate FIT file Export? ... Is this still ongoing ore did you cancel it ? Any timeplan for this?

There's no timeline currently. Its one of those things that I'd like to do one day, but there's hasn't been much demand nor interest for it.

Out of curiosity, what application would you use the FIT output with? If there's something I can get my hands on to test generated FIT files, I might be more motivated to implement it :smiley:

Thanks again.

MHatGH commented 7 years ago

hi, refering to your current release:

In "QDomDocument TrainingSession::toTCX(const QString &buildTime) const"

"http://www.garmin.com/xmlschemas/ActivityExtension/v2"

LINE

You changed it here

2188 -> if (stats.contains(QLatin1String("speed"))) { 2189 -> lx.appendChild(doc.createElement(QLatin1String("AvgSpeed"))) 2190 -> .appendChild(doc.createTextNode(QString::fromLatin1("%1") 2191 -> .arg(first(firstMap(stats.value(QLatin1String("speed"))) 2192 -> .value(QLatin1String("average"))).toDouble() / 3.6))); 2193 -> }

but not here

2294 -> if ((index < cadence.length()) && (cadence.at(index).toInt() >= 0) && 2295 -> (!sensorOffline(samples.value(QLatin1String("speed-offline")).toList(), index))) { 2296 -> tpx.appendChild(doc.createElement(QLatin1String("Speed"))) 2297 -> .appendChild(doc.createTextNode(VARIANT_TO_STRING(speed.at(index)))); 2298 -> }

my replacement looks like this

(please do not laugh about it ! :) , Theese are my very first steps in Qt and C++ programming, Im interesting to see how this is done mor professionally)

            if ((index < cadence.length()) && (cadence.at(index).toInt() >= 0) &&
                (!sensorOffline(samples.value(QLatin1String("speed-offline")).toList(), index))) {
                tpx.appendChild(doc.createElement(QLatin1String("Speed")))
                    .appendChild(doc.createTextNode(QString::number(speed.at(index).toDouble()/3.6, 'f', 11)));
            }

and You changed it here

2434 -> if (stats.contains(QLatin1String("speed"))) { 2435 -> lap.appendChild(doc.createElement(QLatin1String("MaximumSpeed"))) 2436 -> .appendChild(doc.createTextNode(QString::fromLatin1("%1") 2437 -> .arg(first(firstMap(stats.value(QLatin1String("speed"))) 2438 -> .value(QLatin1String("maximum"))).toDouble() / 3.6))); 2439 -> }

MHatGH commented 7 years ago

Out of curiosity, what application would you use the FIT output with? If there's something I can get my hands on to test generated FIT files, I might be more motivated to implement it

I want to use it with RubiTracks 4 Pro. There is a Trial Option if you want to test it (mac only) But FIT files are also supported at strava. And maybe others

For me this Format (as far as I read the docu) gives the most among of data to be tranfered, therfor im interested in. The tcx files without the activity Extension, forces RubiTracks to calculate pace from GPS data, wich leads to poor quality Graphs. The tcx file including Activity Extension solves this Problem (if I use the unit conversion mentioned above). But the stride length values are still not available.

Beside this Im not realy shure if this is caused by the lack of data in the file. The stride length could be easily calculated from distance and cardence. A Support request to rubitracks, if this stride-length value is supported at all, is not answered yet

pcolby commented 7 years ago

Thanks @MHatGH! Now I can exactly what was missing. I really appreciate the effort you've made reporting the details for me :+1: I'll go ahead an fix that up now :smile:

PS: Good use of QString::number... I'm going to have to start using that one in a number of places now :)