.. the authorise button on the add cloud wizard now
shows a 'Connect with Strava' icon
.. all other services continue to have a button that
is labelled 'Authorise'
.. this is needed to comply with the Strava API application
guidelines.
.. when data is downloaded from strava we now set the metadata
tag "StravaID" to the id of the activity on Strava.
.. On RideSummary a link is added at the bottom to view the activity
on Strava if the "StravaID" is set.
.. if the user clicks on the link the summary is replaced with the
strava page for the ride:
e.g. https://www.strava.com/activities/962515512
.. this is part of a couple of updates to comply with the Strava
guidelines for consumption of the Strava v3 API, see:
https://developers.strava.com/guidelines/
Some older (Tacx) RLVs do not have a sync point at the end of the course.
This work-around calculates the total distance of the course and sets a final sync point
if one does not already exist.
Revised code in VideoSyncFile::parseTacx to build syncpoint list with correct distances
when speed varies between two points
Revised code in VideoWindow::telemetryUpdate to interpolate position between 2 sync points.
Also do not update video if paused or not running.
Revised code in VideoWindow::startPlayback to set a minimal rate to start if video is
controlled by syncfile. This avoids the initial "rush" that otherwise happened and
makes for a smoother start.
Also reset distance to 0 on start.
As the rlv length now more accurately matches the workout length, we also need a check in
TrainSidebar::guiUpdate that will terminate the workout if the end of the video is reached.
This code has problems when distance is used on x-axis (#2842)
and it is redundant since there is a general mechanism to plot
any XData series as User Data in Activitiy chart.
This reverts commit f095416c5c.
* Initial implementation of Python data processors
* Add RideEditor to PyFIx script editor
* Enable write-access to activity data for python fixes
* Add GC.deleteActivitySample method
* Add GC.deleteSeries method
* Check for python fix for changes before close
* Build python fixes menu dynamically
* Make python fixes first class data processors
* Add GC.postProcess method
* Check GC_WANT_PYTHON and "Enable Python" setting for python fixes
* Add GC.createXDataSeries method
* Clean up ScriptContext ctor mess
* Support editing xdata series
* PDP: Implement xdata append/remove methods
the website appears to expect UTF8 by default, so let's send a UTF8
title (plus an explicit header)
tokens and boundaries are supposed to be ASCII, so they can keep their
latin1 encoding
GPSMap 66 can use ANT+ sensors, store in FIT format, synchronization with Garmin Connect and relevant to use with long-term activities (walk/hiking/ski).
Implement regex/hash based string substitution object to perform multiple
substitutions in 2 passes. Speeds up athlete data load by 2x.
Use QStringRef to avoid copy
Fixes#3234
Currently Device does not work on filters and set/unset/isset fail silently,
with this change Device can be used in filters as standard metadata and
the attempt to use in set/unset/isset reports an appropriate error.
We could enable these operations in the future but they require special casing.
To allow user testing, similar to linux builds.
Includes some minor fixes:
-Avoid compiler warnings for deprecated declarations to reduce the log size
-Patch GoldenCheetah.dmg to include missing libicudata.64.dylib
-fix command line error in mackdeployqt -fs option
If video config file is not present copy a default one to be used as a model
by the user. An empty video-layout.xml file disables video overlays
Fixes#2525
AddPairBTLE depends on the presence of an ANT+ dongle and sensors
to support ANT+ for detection, it looks like a copy paste of AddPair.
This works for Dual (ANT+/BTLE) sensors with an ANT+ dongle since
the sensors are detected, although is misleading since it seems to
imply you can pair them selectively, which is not true for current
BT40 GC implementation.
When an ANT+ dongle is not present (see #2771) or the sensors only
support BTLE (see #2983), the wizzard informs no sensor is dectected.
This is misleading since BT40device will dectect and use automatically
any Hr/Power/CSC sensor present at device startup.
This change replaces AddPairBTLE code with a simpler version matching
current BT40 support: it just informs the user the sensor types supported
indicating they will be autodetected on device startup.
Fixes#2771Fixes#2983
* Enable import of XDATA series from CSV files
Since XDATA series are preserved across merges this allows to add
arbitrary XDATA series to any activity.
Sample WEATHER file is included for testing.
Sample swim file is also included, once imported set Sport=Swim and use
Fix Lap Swim with pool length=25 to rebuild standard series and laps
Fixes#2010 item 4.
* FixLapSwim - Alternative way to store pauses in XData
Some devices s.t. Moov Now generates a CSV with REST field
after each length. FixLapSwim now can use this alternative
way to express pauses and to mark end of laps.
This is intended to be used together with XDATA csv import.
A Moov Now csv file modified to comply with our format is
added as an example to test folder.
* Allow Banister to use other performance metric besides Power Index
Performance metric can be selected from any Peak metric in LTM Charts
Datafilter now is banister(load_metric, perf_metric, ...)
* Travis-ci - R3.6 install update key
According to https://cloud.r-project.org/bin/linux/ubuntu/README
We need to save the calendar type for older CalDAV code to work,
additionally Google calendar needs the calendar ID (tipically the same
as the email address), used the optional Key setting field for this.
- When there is no power don't add (0w)
- Move the rounding to the format method to avoid Pace issues (Fixes#3106)
- Pending: make the rounding dependent on the series.
This solves the issue when activities not having all the data
channels available are aggregated.
Forces a metric recomputation to account for these changes.
Since counts are relevant for averaging them between different rides.
Required to fix the issues when aggregating Time in Zones Percentages.
The previous solution worked until you exit GC since when the RideDB
was reloaded the counts with zero values were lost.
So it aggregate properly in Metric Trends Charts, currently
when one of the rides to be aggregated has 0 percent in one of
the zones the aggregate is distorted and it can be higher than 100%
which is particularly notable when the bars are stacked.
This has been reported several times at the forum.
As for the L/R balance (see https://github.com/GoldenCheetah/GoldenCheetah/pull/3098) there are issues in the Torque Effectiveness and Pedal Smoothness computation when using Favero Assioma DUO pedals. In some cases, values for LTE, RTE, LPS, and/or RPS are stored in the file while the power and/or cadence data shows that the correspondent stroke was either void or no power generating (see the attached image in https://github.com/GoldenCheetah/GoldenCheetah/issues/3102). This was not taken into account in the code, as the only check was the existence of LTE, RTE, LPS, and RPS data greater than zero. I've made the necessary changes in order to check if the stroke was a power generator by verifying if the cadence, power and lrbalance values are valid (it is SUPPOSED that all files that contain LTE, RTE, LPS, and /or RPS contain also power, cadence, and lrbalance data, as they are necessary for the LTE, RTE, LPS, and RPS values computation)
Fixes#2745 which requests this metric plus it allows to fix the issue with
Time in Zone Percentages which don't add to 100% nor aggregate properly
when there are gaps in recording, tipically due to pauses.
When there are no gaps Time Recording equals Duration and Time in Zone
Percentages don't change.
The user is requesting explicitly the length expansion so, to avoid
confusion, we should ignore this setting, which was badly handled
to make things worse.
Fixes#2892
Change in order to manage correctly the Left/Right balance due to the issues detected with the Favero Assioma DUO pedals, as it was explained here: https://github.com/GoldenCheetah/GoldenCheetah/issues/2955
But after I detected the issue, this file was modified in order to accomplish the proportion of Ground Contact Time from each leg for runs, and a new check was added to the code (point->cad || point->rcad), while in the original code only the point->cad was tested. I'm not sure if the addition of my new checks, specially the (point->watts > 0.0f) one, are safe for the running part of the function
- Performances are computed independently for Rides and Runs in Estimator
- Running Performances are shown in LTM Charts When all selected activities
are runs for a Performance curve
- Banister models uses Performances from activities were score > 0
and for the same date with matching sport, so a Banister model based
on BikeScore/BikeStress will include only rides while one based on
GOVSS will include only runs
- Banister (Run) chart based on GOVSS metric added for testing
- PDEstimate now has a run flag, Estimator has 2 passes: rides and runs
MultiModel and WSModel are disabled for the same reason they were disabled
in CP chart, and to lower the performance impact.
- Show CP Models Estimates for Running in RideSummary when the involved
activities are all runs.
- DataFilter estimate function uses Bike or Run models based on activity type
- Metrics Trends charts Estimate allow Bike vs Run selection
Another attempt to minimize the use of issue tracker as a help desk.
Additionally we could use the new templates feature for bugs and features, but I don't have permissions to change repository settings.
-Extra data fields renamed and scaled according to spec: stance_time_percent,
activity_type, vertical_ratio and step_length
-Average metrics for the new fields: Average Stance Time Percent,
Average Vertical Ratio and Average Step Length
-Tested using Garmin 935 with Running Dynamics Pod
.. UserData series now have a zone string that
can be used to define upper values and associated
colors for shading a curve.
.. the format is: lim,colorname;lim,colorname;
where lim is an upper value and colorname is
either a #rgb string or any color name such
as red,green, blue etc from the list of SVG
color keyword names provided by the World Wide
Web Consortium.
e.g: 200,green;300,yellow;9999,red
which will shade points <200 green, <300 will be
yellow and then <9999 will be red.
The zones must be listed in ascending order.
.. there are too many incompatibilities between the
V3 license and other codebases we wish to work with
that are based upon the GPL-V2 license.
.. this downgrade is to ensure we are compatible and
can align with contributions from other parties in
the future.
.. a notification will be sent to the mailing list to
inform all users.
.. updated the QwtPlotCurve to fill using zones.
.. next commit to update user data curves in AllPlot
to let the user set zones and colors.
.. added as part of updates for Humon collaboration.
... with windows / VC2017 / 64Bit the code does not build / cannot resolve a overwritten function when using QT 5.12.1
... adding the newly introduced function similar to the other function resolves the compile problem
.. ErgFile now supports gpx format as well as .erg,.mrc et al
.. Location data is include in realtime data and passed through
.. the CSV file format has been fixed to record GPS with higher precision
Fixes#3021Fixes#3024
.. code originally developed by Eric Christoffersen
for merging data from virtual rides where distance is
recorded on a trainer, so the GPS and altitude data
can be merged in to the data.
Even when it is considered not relevant for runs and swims the metric
code computes the value if power data is present which may produce
unwanted results as reported at the users forum.
.. banister(metric, nte|pte|perf|cp)
so you can filter rides where predicted cp is over
300 with "banister(BikeScore, cp) > 300".
.. of course the real value is being able to access
banister data in metrics and formulas.
.. don't show helper in data table or compare mode.
.. always extend out banister date range to at least
a year from the current date. To make sure the
decay is calculated well into the future.
.. split if no gaps in seasons and combine if seasons
are too short.
.. this way we get fairly stable fits (2yr window size)
but also get to see parameters reflect aging, so
p0 declines and k1/k2 fit better.
.. still need to think how t1/t2 should adjust...
.. can refit to see affect of adjusting parameters.
.. doesn't "remember" them, need to think about what
that should mean (config in chart, season or athlete?)
.. also made t1/t2 fixed in the fit process so we have
fewer parameters and need less data to fit.
.. added a banister helper like on the CP plot
.. you can't adjust T1 and T2 yet, thats coming
in the next commit
.. also a few fixups related to submax filtering
of performances and some wip regarding how
the model fit works (windows, t1+t2 fixed etc).
.. Banister implementation is still under some
development, testing and validation but is in
good enough shape to try with your data.
.. we only have banister curves where there is data
so if there are gaps between seasons we should not
plot any data.
.. as a result also fixed bug that the qwt gapped
curve would always plot first zero in a curve.
.. Banister model fitting using LM
.. can plot Banister curves on trends plots;
- Performance curve (NTE+PTE)
- Predicted CP curve (Performance curve scaled)
- Negative Training Effect
- Positive Training Effect
.. the code is sub-optimal and needs to be refactored
to cache and refresh less frequently (using the same
pattern as PMC most likely).
.. the model fitting can fail and needs to be made a
lot more robust, along with ensuring the samples
we fit to are appropriate.
.. filter out submax performances
.. plot performances on LTMplot;
* tests - marked as TTEs by user
* weekly performances - found by algorithm
* submaximal performances - filtered out by algorithm
.. we now have the neccessary data to introduce the
Banister NTE/PTE and Performance curves in the next commit.
.. show weekly best performances (ready for banister curves)
.. show performance tests (also used by banister if present)
.. can toggle which ones to show.
.. use powerIndex to select points when t > 120s. This has resulted
in a much higher hit rate at finding performance tests in MMP
data (almost 99% of the time).
.. As part of a series of commits to add Banister IR modeling
this first one introduces a Power Index metric that can be
used to normalise TTEs of a different duration to a single
score.
.. This is so we can use performance tests of differing durations
when fitting Banister model curves to estimate k1 and k2.
.. The average power for an interval/ride is compared directly
with a power estimate for the same duration using the Morton
3-parameter model and mean values derived using opendata (where
CP=261, W'=15.5kJ and Pmax=1100w)
.. For the equivalence to be valid test must be in the 2-20 minute
range when used in banister modeling, but the index value is
valid as a comparison to the average athlete for all durations.
.. add option to apply a decay factor to CP and W' when plotting
the model curve in CP Plot.
.. since we always fit to observations <20mins the mostly submax
points at longer durations in the general population do not
impact the fit at all.
.. the decay factors for w' and cp have been fit to the results of:
Effects of Two Hours of Heavy-Intensity Exercise on the Power-
Duration Relationship
Clark IE, Vanhatalo A, Bailey SJ, Wylie LJ, Kirby BS, Wilkins BW,
Jones AM.
https://europepmc.org/abstract/med/29521722
Existing code for OSX was migrated to scripts on travis/osx without changes.
New scrtps for Linux were added to travis/linux based on previous work
by gcoco and LyzardKing
Install linux dependencies similar to OSX version, including samplerate,
vlc, ical, kml, d2xx, srmio, libusb-compat/libusb1.0 and R 3.5
Enable CloudDB and Cloud services using shared secrets with OSX version
Generate AppImage and set src/$FINAL_NAME to enable automatic deploy
Optionally upload the AppImage to transfer.sh for testing
* train: add support for serial daum devices
Add support for daum devices connected via serial port.
Such device could be:
- Daum Vital
- Daum ergo_bike series
* ergo_bike_2002
* ergo_bike 4004 TRS
* ergo_bike cardio
* ergo_bike vita
* ergo_bike fitness
The only device I own is a Daum Vital, therfore this is the only device
that is known to work correctly.
The default behaviour is to send the load to the device only once to
allow the user to interact with the device. The profile field is used
to pass a _force_ flag in form of a string containing the word _force_.
Doing so will cause the implementation to send the load to the device
every _poll interval_ (default 1s), except the training is paused.
Signed-off-by: Florian Nairz <nairz.florian@gmail.com>
* train: daum: fix unsigned/signed compare mismatch and add return value
.. using analysis from the opendata proejct we have now
got a normal distribution for CP, W' and Pmax parameters.
.. so we can now plot the percentiles on the CP plot that the
user's values sit in.
An explainer from Robert Chung for a regression method to estimate CdA and Crr from field data.
The key point being the generation of additional laps from a multi-lap run -- e.g. 3 x 18s laps of a velodrome
would normally be considered as 3 laps to fit against. Robert's approach is to create 36 laps from this data (!).
The first lap starts at 0s and lasts for 18s, the second lap at 1s ... up to the 36th lap starting at 37s.
We would then be able to get 36 estimates of Crr/CdA and calculate a mean and confidence interval (!).
The document committed explains how that regression would work mathematically, and how we
would adapt for working in the field (we need really good altitude data).
.. reads .rr file when processing csv and adds the XDATA
series "HRV".
NOTE: the HRV processing data added by Leif Warland will
process the data and calculate SDANN/SDNN and friends
since we use the same convention as for Polar HRV.
.. record hrv R-R data to .rr file in the "records" folder when
R-R data is available in train view.
.. next commit needs to read it in and save to XDATA
.. collect R-R data from ANT+ devices and deliver to
the train sidebar.
.. commit 2 needs to save to a file when recording a
workout in train view
.. commit 3 needs to import the R-R data into XDATA when
importing a train view CSV file
.. mousepad touch events require focus, so we disable
touch events to stop the overview window from
stealing focus from the ride list when scrolling
through rides.
.. so you can see how the parameter estimates look when plotted
in work time.
.. this means parameter estimation and model visualisation are
separated -- you can estimate CP/W' using the extended model
and an envelope fit but visualise with the linear work model.
.. add fitting option to fit CP2 model to points using
a linear regress.
.. kinda ironic that the most common and straight forward
method for estimating CP/W' is added so late.
.. when model changes set the fit type to the best practice
we would recommend with that model (and in the case of
multimodels disable unsupported fits)
* CP2/CP3 - LMA and Performance Tests
* Extednded CP - Envelope and all MMP
.. change the default intervals within the models - these
are used when estimating automatically via envelope and
were too long.
.. truncated the data used by the models to avoid using
MMP data beyond 20 minutes for 2/3p model.
.. results in much more robust estimates in CP History.
.. allows constrained fits
.. this is a GPL lib that is included into the
source tree to avoid adding another painful
deendency.
.. for details of the lib please see:
http://users.ics.forth.gr/~lourakis/levmar/
.. returns the number of performance test intervals for the ride.
.. can be used to filter for only rides with tests, or even multiple
tests in the same ride (e.g. 3,7,12 tests).
.. may add additional paramaters later to e.g. filter by duration or
average power etc.
.. honour interval color selected by user when plotting
performance tests on the CP plot
.. performance test symbol size is enlarged if the test is
within the currently selected ride (in activity view).
.. right click options to
* mark a user interval as a performance test
* create a performance test interval from a disovered interval
.. this way when interval discovery finds a hard effort that you
want to clone as a performance test, you can do it with one
click.
.. CP plot modelling will fallback when insufficient data
is available to model reliably, with a precedence:
1. Performance tests
2. Filtered MMP
3. All MMP
.. when modelling for a single ride collect bests/performance
data for the period up to that ride.
This is so as you select older rides the model reflects the
training status at that ride, not for the current period.
.. add adhoc season for 'Last 6 weeks' since it is a common
timeframe to use when tracking impact of training
.. tell user what fit or data was used as there is a cascade back
depending on the model selected and the availability of data.
.. the summary is also now in grey to indicate it is supplementary.
.. RMSE for now, just to get a basic sense
.. what type of fit was performed (since there is a fallback)
.. how many datapoints were used in the fit and RMSE calculation.
.. add option to CP chart to fit model to marked performances.
.. works, but very crude UI - no warnings if not enough data and
no constraints on combinations of model, fit and fit data that
can be selected.
.. will tidy up over the next few days.
.. as a first pass lets show the performance tests on the CP
plot to get a sense of how any bests / models align to the
results of our tests
.. we will look to fit to the tests using LMA in another commit.
.. editing a user interval color never worked properly.
the color wasn't changed or remembered at all.
.. lots of independent bugs conspired to cause this but
mostly it was because the interval color was not
recorded in the ride file.
NOTE: files created with this release will not be
backwards compatible with earlier releases.
.. allow the user to set a flag "Performance Test" against an interval
within an activity.
.. the distinction is needed to highlight the section of an activity
that was a test (as opposed to the entire activity containing
test efforts.
.. this is so we can fit them to PD and IR models in the future
avoiding the need to use algorithms to extract TTE type efforts.
.. the update was surprisingly complex since we need to update the
ridefile to record this with the interval and also update the
ride cache as well as adding the bool to all the interval helper
functions.
.. along the way it became clear why user specified colors for
intervals were getting lost (they are not in the ridefile) and
will fix this in another post.
.. NOTE: ridefiles created with this version will not be backward
compatible with earlier versions because they contain a
new field for intervals marked as performance tests.
Access SpecialFields::isMetric() via context->specialFields
Avoids duplication and fixes#2894 since the context->specialFields
is updated in RideCache when user metrics definitions are loaded.
.. its dead (not updated for 5 years)
.. it introduces dependency issues with openssl/crypto/icu
on Linux distros
.. we don't need it, since OAuthDialog does the heavy
lifting we need (ok, its not pretty but it works).
.. old code moved into the deprecated folder
Fixes#2881
.. the code to parse the redirect url and exract
the query item 'code' was fragile -- and got
broken when Strava added a new query item to
the returned URL.
.. we now use QUrlQuery to extract in a more
robust and future proof way
Fixes#2879
* fix unclosed file descriptors
* remove various compiler warnings
sometimes it was only ambiguous indentation, sometimes bugs were fixed:
- forgotten `break;` instructions or `fallthrough` annotations:
- src/ANT/ANTChannel.cpp
- src/Charts/CriticalPowerWindow.cpp
- src/Charts/MUPlot.cpp
- src/Core/DataFilter.cpp
- src/FileIO/RideFileCache.cpp
- src/FileIO/RideFileCommand.cpp
- src/Train/DialWindow.cpp
- forgotten braces:
- lmfit/lmmin.c
- src/FileIO/XDataDialog.cpp
- test on the wrong variables:
- src/Gui/Pages.cpp
- wrong parenthesis
- src/Charts/CPPlot.cpp
- missing macro argument
- src/Cloud/WithingsDownload.cpp
- missing `return;` statement
- src/Cloud/Xert.cpp
- unused variables
- src/Gui/DiarySidebar.cpp
- unclear indentation
- src/Core/RideItem.cpp
- src/FileIO/BinRideFile.cpp
- src/Metrics/PaceZones.cpp
- src/Metrics/RideMetadata.cpp
- src/Metrics/Zones.cpp
* remove unnecessary Leaf::Parameters enum value from data filters
lists of parameters don't exist as such outside of the parser, and have
no business using the same type `Leaf` as complete terms anyway
* remove unnecessary argument
`leaf1.print(leaf2,...)` would print `leaf2` and completely ignore
`leaf1`, so now `leaf2.print(...)` is used instead
.. when looking for efforts in a workout that are at or
above the limit of the athlete we stopped as soon as
we found a section that was too hard.
.. we now keep looking for impossible sections since there
are often multiple hard efforts hidden within a longer
section.
.. there does not seem to be any considerable performance
overhead with this approach.
.. when warning if sections of a workout TTE is longer
than athlete ability use the 3-param model not the 2
param model.
.. this will check intervals shorter than 2 mins.
.. was supposed to do this originally, but got lost in
other fixups and development.
.. makes compilation easier and removes a dependency
for what is effectively 2 C-source files.
.. additionally, getting the lmfit lib to compile
on windows with cmake was frought with issues.
.. also fix a debug message left behind by previous
commit.
.. adding an option to select least squares fit to the cp
chart, in addition to the existing envelope fit.
.. additionally, if filter bests option has been selected
the least squares fit will use these points rather than
all the points (since well over 95% will be submaximal).
.. It requires the lmfit library to be available - and this
has been an non-optional install for over a year - we
just haven't used it prior to this commit.
.. Each PD model needs to implement three functions to enable
the least squares fit to work:
* int nparms() - returns the number of parameters
* double f(double t, double *parms) - parametric function
* bool setParms(double *parms) - set the parameters post fit
.. This commit implements it for CP derivatives;
* Classic CP - 2 parameter model
* Morton 3 Parameter - 3 parameter model
* GC Extended CP model - the extended model
BUT: it is implemented and disabled for eCP for now until
we can set parameter constraints correctly.
.. A second commit is needed for the remaining models from
Ward Smith and Mike P. This should also show which of the
filtered points have been used for curve fitting on the
chart (maybe a different color)
xdataNames, xdataSeries and xdata refer to low level functions
activityXdata is a wrapper to obtain XData series by name without interpolation
activity includes all XData series interpolated
When name="" returns a list of XData series names present
When name is an XData series present return a dataframe with vectors for:
time, distance and each valuename
with a row for each XData sample.
Implements #2847
When name="" it returns XData names
When name is one of the names for the activity it returns valuenames
To dinamically obtain names/series for activityXdata and activityXdataSeries
.. if metadata is setup to use TSS, NP, IF then they
don't override the base metrics coggan_{tss,np,if}
this is because the symbol being used is for the
compatibility metrics which is one level of
abstraction away from the underlying metric.
.. instead we now handle the symbols within the
RideMetadata class, which maps TSS, NP, IF to
the coggan_tss, coggan_np and coggan_if symbols.
Fixes#2852
Even if Garmin Smart Recording is not enabled, make users life simpler
Since otherwise the datais useless and the original lenght-by-length
data is preserved as XData.
.. not checking timeIndex() for out of bounds
when secs goes negative during parsing.
.. also, enable interpolation for swim laps by
default to ensure no data loss (i.e. don't
insist on garmin smart recording setting).
Fixes#2953
New users comming from Strava, TP, etc. expect this behavior by default
This doesn't affect single sport metrics, only the global score.
TRIMP Zonal Points are a reazonable proxy and they are configurable
via trimp-k coefficients in HR Zones.
.. configuring calendar access was lost when
refactoring the cloud account config.
.. we use the cloud service framework for the
config steps (Oauth/user+pass etc).
.. existing code for interacting with the
service in CalendarDownload.cpp and
CalDAV.cpp is left untouched for now since
it isn't used in many places.
.. since the R interpreter doesn't support multithreading* and this
is needed for metric computation
* we could get around this with IPC/signals but decide it was not
worth the coding effort and maintenance overhead.
Carry RideItem, Specification and Metrics to consider the cases when
the script is part of a UserMetric or an LTMPlot formula
Python series, activityWbal and activityXdata honor RideItem and Specification
Python activityMetrics honors ScriptContext RideItem and Metrics
Python activityMeanMax honors ScriptContext RideItem
Force recomputation of metrics just in case Python Scripts were used before
.. were skipped when writing the ridecache file, so lost on restart!!
.. also now fix a refresh with new user metric version, almost certainly
not needed but better to be safe than sorry.
.. removal of summary pane in diary sidebar broke refreshing
when selecting a ride and no longer set the date range
appropriately.
.. the diary pane needs overhauling in v4 alongside planning
this is just a temporary hack.
.. Refresh model estimates when rides added, deleted, saved.
.. Lazy refresh will cancel any pending or running threads and
trigger a new one in 15 secs time.
.. This strategy allows us to call a lazy refresh even when importing
large number of rides, since the start will be delayed and cancelled
by the next ride added etc.
.. The thread stop() function is also called by the destructor to stop
when the user exits and avoiding delay/SEGV on exit.
.. new Estimator class to refresh model estimates in a thread.
.. localised all data access to the new class to resolve issues
with thread safety.
.. RideSummary and LTMPlot do not trigger refresh of the estimates
.. added a QMutex around access in Athlete::getPDEstimates and the
code in Estimator::run that updates them.
NOTE:
will still need a follow-up commit to resolve estimate refresh
e.g. after ride saved, or rides imported or rides downloaded from
a cloud service. This is a challenging problem since refreshes
need to be 'very lazy' to avoid wasted cycles.
Fixes#2820
.. after a long discussion about the relative merits of collecting
aggregate data with ML and Stats experts we concluded that it
was far better to collect sample data.
.. this means a typical opendata zip file is now roughly 30x the
size, so what was 1mb is now more likely to be 30mb.
.. as a result the files will be published via an AWS S3 bucket
since we would hit limits at github very quickly.
.. the opendata code has been updated to:
* ask permission now lists sample data that is collected
* we include csv files for all workouts in the zip that is sent
* we resend when the version of the file format changes
.. additionally the config dialog now allows users to change
their opt-in/out for sharing with opendata.
.. at startup we ask the user for permission to share
.. once permission is granted the upload is performed and
re-done every year, so long as > 100 workouts have been
collected since the last time.
Events ocurring on Season end date were not showing
Seasons ending, but not starting, on chart date range were not considered when looking for events
Fixes#2620
.. Will prepare and post data to an OpenData server running
in a background thread:
* will find servers from www.goldencheetah.org
* uses first server it finds that is running
* prepares and sends data
.. need to write the code to get explicit permission from
the user to do it, then send data when worthwhile.
.. thinking this is annually, but only if > 100 new workouts.
This ensures the filter used for all the other HRV metrics is also applied to rest HR . The previously used "average_hr" metric is calculated without the filter, which leads to skewed results due to the relatively short timespan and data point count of an HRV measurement.
... add Popup when download is complete, since QProgressBar does not show % values (following some Mac Style Guidelines)
... since Windows/Linux UI shows 100% in progress bar, the additional Popup is only displayed on Mac
.. the ride cache writer will write opendata format files
when passed the right parameters.
.. the file does not contain PII or user metadata or sample
level data.
.. instead it contains metrics as well as distribution and
mmp summary level info for Power, HR, Cadence and Speed.
... adjust so that Strava, Garmin Connect are able to import the file
... add special treatment for "Zwift" activities - so that Strava handles them correctly as "virtual rides"
New OSM maps had a blank default tile server URL and they are the new default.
Also include minor change to use an existing method and to avoid currentData.
.. phew! this was a subtle bug.
.. the SpecialFields class tells the data filter what
type of thing each symbol equates to.
.. it was saying TSS was metadata not a metric.
.. this is becuase SpecialFields is setup before the
user metrics are loaded, so it only saw it as a
metadata field.
.. we now refresh context.specialFields after the
user metrics are loaded. So this will not just
fix TSS but ALL user metrics that have an override
defined in metadata.
Previously, the call to usb_control_msg was suppressed for windows platforms in order to prevent
GoldenCheetah from failing when libusb was not available. This change allows usb_control_msg
to be explicitly linked at run time in the same way as other libusb functions within LibUsb.cpp
LibUsb.cpp will now resolve the usb_control_msg function in the same way it does other libusb references.
The 2 load functions ezusb_load_ram and ezusb_load_ram_imagic will now accept an extra argument.
For WIN32, the new argument will be a pointer to the usb_control_msg function in libusb0.
For other platforms, the new argument will be NULL.
For WIN32, EzUsb will now use the supplied pointer rather than defining its own reference
to usb_control_msg.
This should allow us to still start up OK when libusb is not available, but still be
able to load firmware when it is.
Support use of Imagic steering frame to scroll training display
Implemented as an optional extra as it is slightly less
self-contained than the basic device support.
.. users can no longer use metrics called TSS, IF and
NP to configure new charts.
.. existing charts will continue to work, but they are
using compatibility metrics only.
.. no user maintenance or selection
.. if they choose to create their own versions then the
compatibility metrics will be removed and they will
be able to select their own.
.. as usermetrics that alias the old metric name to
the renamed metric.
.. need to follow up with restrictions on the use of
the compatibility metrics.
.. renaming the 3 metrics they trademarked in 2013:
TSS => BikeStress
IF => BikeIntensity
NP => IsoPower
.. this will break data filters, user formula and
R and Python charts.
.. in the next commit will add user metrics to ensure
backward compatibility.
.. enable auto expansion of .zip files to enable
users to download a batch export of their data
from TrainingPeaks in a web chart and import in
a single hit.
.. what a clusterfuck the Python embedding API is. If you set PYTHONHOME
it loses PYTHONPATH. But only on a Mac. Go figure.
.. so we just set the environment to the user defined value in prefs.
.. until we fixup AVKit support in videowindow lets not try
and build with QuickTime since its fully deprecated now
and breaks the Mac based Travis build.
.. fixup trivial issues like PATHSEP and separators in general.
.. it seems that Py_SetProgramName will drive the initialisation of the
Python interpreter to set sys.path, sys.prefix and sys.exec_prefix.
.. rather than trying to fixup these directly instead we set the program
name to the python installed binary (full path).
.. you still need python in your path, will fixup in part 2.
.. lastly, also added a 'printd' macro to embed debug info, which can
be enabled in gcconfig.pri via DEFINES += PYTHON_DEBUG=true
.. look for python in path and check version and module path, then
use this when initialising to ensure the installed modules
are used, not the local copy.
.. needs testing on Windows and need to enable the user to specify
the location of Python so users don't need to modify PATH.
- Check for Zones/PaceZones availability
- make it relevant when there is power or for runs/swims
- Daniels Equivalent Power is relevan only when there is power data
- increment DBSchema to force metrics recomputation
Fixes#2681
.. we've pretty much deprecated it now, so don't default
to mac, default to flat.
.. this is only noticeable with new athletes setup after
GC_CHROME was deprecated.
.. similarly to embedding python when computing metrics
.. exactly the same semantics, although R isn't fussy
about whitespace.
.. and example metric might be:
{
value { %%R GC.result(19) %%; }
}
.. the interpreter is protected with a mutex which means
R programs will never run in multiple threads. This has
a performance penalty, but then using R for metrics is
likely to be rather specialised anyway.
.. allow the user to embed a python script into a datafilter.
.. this is primarily to enable the use of python when writing
user metrics.
.. the syntax is basically "%%python script %%" and it is
evaluated as an expresssion so the results can be assigned
to a variable or returned as a value.
.. additionally GC.result(double) has been added to the python
API to enable a return value to be set by the script.
.. since Python is really sensitive about white space its going
to be best practice to embed python scripts without honoring
any of the data filter spacing, for example:
{
value {
t <-
%%python
GC.result(100)
%%;
}
}
.. is likely to be a sensible way to use this.
.. also notice how the ; is needed after the expression. This
is because %%python ... %% is a numeric expression with the
same semantics as "1 + 2"
Similar to series but used to retrieve an XData series, like the R
activity.xdata counterpart, for example: GC.xdataseries("SWIM", "STROKES")
NB: I reserved xdata(name) to retrive a whole group of series by name
with its own sampling, not implemented in this commit.
.. since we will use it to share data via CloudDB and users must have
a mechanism for requesting their data is deleted.
.. since the GUID is used to anonymise the data the user must use it
to request the deletion, so we show on the about box.
When adding measures to an LTMPlot with other metrics, those measures
are not cleaned up properly on replot, because they don't have a symbol.
LTMPlot uses the symbol to store them in a 'curves' dictionary. All
metrics without a symbol are then identified by the default metric
symbol value, which is: "".
libvlccore is for plugins, but GoldenCheetah does not build a plugin. It
requires only functions available from libvlc.
Signed-off-by: Sebastian Ramacher <sramacher@debian.org>
.. mad conflict .. where scipy.stats.linregress conflicts
with a sndfile and crashes when calling sf_check_fpe
.. see fix stolen from here: https://github.com/scipy/scipy/issues/8130
... add options to either fix SmO2 or tHb or both data series
... add options to define max. value for tHb
... remove LTMOutliers (since the variance feature is not used)
A more efficient way to obtain a metric series for a large number
of activities, it can be converted to numpy array without copy:
import numpy as np
nparray = np.asarray(GC.metrics("Average_Power", True, "isRun=0 && isSwim=0")
.. update the registry to support both independently. This is
to get the ridesummary bool set to trigger refresh when the
user selects a season on trend view.
.. instead of an opengl canvas lets start with a Web canvas.
.. we might have options to use QtCharts or OpenGL later.
.. not working - committed to save WIP.
... all Tile Servers are configurable by the user - there is only a default for the "standard" OSM Tile Server, but even this default can be overwritten
... there are no dedicated Tile Servers Sources named / hard-coded, but in addition to the default OSM server 3 additional options are available for the user to configure
Why:
... tile servers either change their URL or their T&C - which happened for some of the "hard-coded" once recently - since this may happen
again in future the recent change de-couples the code from the Tile Server URL - and the availability of certain organisations providing
free tile servers
.. With german translation activated GC.activity() complains about
some utf-8 decoding stuff and returns error.
First I thought came from the real activity json file, but it's
from translation: Altitude -> Höhenmeter.
Is it necessary to use toLatin1() in goldencheetah.sip? With
toUtf8() it works and you get delta symbols instead of question marks.
.. With R the series names are always in english and use a naming
convention derived from the R trackR package -- we now follow the
same in Python bindings to ensure charts created in one locale
will continue to work in another.
Adding __getitem__ makes it to behave like a sequence enabling indexing
and iteration,for example:
s = GC.series(6)
print(s[0], s[-1])
for v in s: print(s)
l = list(s)
print(l.count(0))
.. very basic API as we develop out, it just returns a dict
for now. Need to expand to enable returning a list if
compare mode is active (like R).
.. implemented in a new source file Resources/python/library.py
which is loaded directly after the interpreter is loaded at
startup.
.. also updated src.pro to add library.py and goldencheetah.sip
to OTHER_FILES so they can be edited easily in QtCreator.
.. start of API to work with ride data, exposing the raw
sample data via the buffer protocol python api and SIP
.. adds utility functions that will ultimately be wrapped
inside a python class/function:
GC.series(n) - return series data as a python array
GC.seriesName(n) - return string describing series data
GC.seriesLast() - returns int for last series type
GC.seriesPresent(n) - returns True if series in ride
.. example of using these functions in python to create a
dict object collecting all available data:
activity = {}
for x in range(0, GC.seriesLast()):
if (GC.seriesPresent(x)):
activity[GC.seriesName(x)] = GC.series(x)
.. simple examples, lots of generated code changes which is
not very helpful.
.. but the only files that were edited by hand are goldencheetah.sip
Bindings.h and Bindings.cpp
... remove StreetView and Train/MapWindow from list of available Views
... both rely on WebKit - and have issues (they have already been reported to be de-precated)
Basic proof of concept for CPP binding using SIP but with
our own type conversion (to avoid overhead of SIP lib/deploy).
Its far from perfect but will serve as a starting point.
.. needed to fixup type conversion in goldencheetah.sip to
convert returning QString as PyUnicode
.. needed to fixup passing context when multi-threaded
.. needed to fixup Bindings.h/cpp to offer new API
.. Using SIP thats used in PyQt et al we have a module
called `goldencheetah' which includes bindings.
Currently there is only a single method `getValue()'
that returns 1. It's to get the basic plumbing in place.
src/Python/SIP contains all the files related to the
module. The cpp files are generated by the `sip' utility
which will need to be available if you want to work on the
bindings. Run make -f Makefile.hack to regenerate the cpp
files if you edit them.
I prefer to distribute the generated files at this point
whilst development occurs. We may change that at a later
date.
.. Please note that the gcconfig.pri.in file has changed as
we now include the python include path rather than set a
macro for the include directive (See PYTHONINCLUDES in
gcconfig.pri.in)
.. lastly, to test this is working in a python chart console:
> print(GC.getValue())
1
>
.. don't add concurrent to the qt modules list unless we
are building with Qt 5.
.. don't add ./R and ./Python to the INCLUDEPATH unless
we are building with them enabled
.. fixup comment regarding officially support versions of
QT - we now support 5.8 or higher and strongly recommend
5.9.2 or higher for crucial fixes to Qt Charts and QtOpenGL
.. runs in thread to avoid blocking GUI actions but GUI
will still wait for script to complete. ESC is trapped,
but mechanism to stop script not implemented yet.
.. added a python chart type, it doesn't execute code
yet. Just a reimplementation of the RChart UX
.. next we need to trap output and run code on selection
before proceeding to setting an API for Data and Charting
.. just bootstrapping, so Python is loaded and version
number made available in the about box.
.. see gcconfig.pri.in and src.pro for settings needed
.. not considering threading etc at this point
Part 5 of #2588
- BodyMeasures code in Athlete was moved to BodyMeasures class in Core
- HrvMeasures code in Athlete was moved to HrvMeasures class in Core
- Both implement the Abstract Base Class MeasuresGroup which provides uniform
access to measures
- Class Measures consolidate access to Body/Hrv Measures
- Body/Hrv measures file is accessed for only one place
- Names/Symbols for Body/Hrv measures are defined only once
measures(all=FALSE, group="Body"), returns a data frame with the fields
of the specified measures group (currently "Body" and "Hrv" are supported)
and a row for each day on the current selected date range if all=FALSE or
the whole range of available data if all=TRUE.
Part 3 of #2588
I updated INSTALL-LINUX with arch linux instructions, removed some old version numbers, like Ubuntu 11.04 on amd-64, and slightly cleaned this up. This will have to be checked for accuracy and installation success later on.
When the user check/uncheck a metric override checkbox
on RideMetadata an empty metric override is generated,
the line removed on JsonRideFile.y produces an extra ","
with errors reported at the forum
Strava API docs indicate this parameter is only relevant when also sending the resolution parameter
In any case, parameter need to be sent as POST data, not in the URL
This was mangling the temp series name. With this commit, Strava requests will also include the temp series
Android version generates date and time instead of a combined timestamp
of measurement, even worse date is not in ISO 8061 format in the contributed
files... Let's hope it does not change with locale.
.. Upload dialog asks for RPE, ROF, test, notes and reason
for missing any workouts.
.. Uploads a .txt file with metadata in it, as well as the
.csv of the time series data
.. ROF, RPE and Notes metadata is updated with the values
selected during the upload.
Lap swims synced from Strava don't have pool length nor precise
length by length information nor stroke rate (cadence), we use
distance and time information from the informed laps to fill the
gaps and fix distance for users unable or unwilling to import the
original file, which is the recommended approach.
For all activities expand Smart Recording if enabled.
Changed default FixGap stop parameter to work with open water swims
and runs with Smart Recording, in the future we could expand during
import like we do for other file formats.
Fixes#2605
.. the KentUniversity service has a consent page which is
now added to the add cloud wizard as an option.
.. in testing this also found that the refresh of the google
drive access token in MaybeRefreshCredentials() updated
the value in app settings but not in the cloud service
configuration settings. This is also fixed now for both
the google drive and kent uni cloud services.
.. bit of a catch 22 scenario with folder being selected
without opening the service by manually editing the
folder name.
.. this causes problems when open is then called and the
folder is invalid - especially when we're in the middle
of configuring the service anyway.
.. to avoid this, the folder widget is now read-only and
you must select the folder using the browse function.
.. update to the uploader to force the user to set key metadata
.. 3rd part will handle upload of metadata files to associate
with the CSV files and correct the CSV format from PT format.
.. it was lost during the refactor and means it is not possible
to set the folder to use (!)
.. fix applied to KentUniversity as well since they use
GoogleDrive to share files.
.. custom uploader, using CSV.
.. requires updating to support custom fields like RPE/ROF
but committing whilst trying to resolve a bug related
to the FOLDER_ID configuration setting.
.. just add as a Google Drive service
.. need to do upload dialog and file formats as subsequent
commits.
NOTE: this is a variant of Google Drive, not just subclassed
at this point. We may simplify this later to avoid two
classes that need bug fixes / changes as the Google API
changes over time.
Part 3 of #2406
Just preserve XData from first ride and add XData from the second,
if not already present, in the future we could let the user to
choose, like for standard series
-Allow lines ending in CR as generated by HRV4Training iPhone app.
-Allow ";" additionally to "," as separator.
-Skip unsupported columns.
-Skip empty lines and values.
-Recognize the alternative names generated by HRV4Training when
orthostatic test is selected.
The "activity" message contains data to determine the time zone the
ride was recorded in. Parse this and adjust the start time accordingly.
This also fixes e.g. Strava synchroniziation. Rides recorded in
time zones different to the box GC runs on now properly match.
Create named intervals using the provided "StartTime" attribute.
This creates the usual "Lap x" intervals when manually pressing the
associated button.
But for automatically created intervals we use the "TriggerMethod"
reason to name the interval in more detail, currently "Distance x",
"Location x", "Time x" or "HeartRate x".
.. uploader needs to open the store before calling writefile
.. in googledrive::open() needs to pre-fetch home() as writefile
assumes the cache is up-to-date.
.. there are so many QT bugs related to this with opengl and
other aspects of scaling we should just unset it. This is
because we now have native support for Hi-DPI so this setting
should not be needed anyway.
The objective is to enable fine tunning when a better estimate of CdA
and Drafting multiplier are available.
Using default CdA=0 and DraftM=1 the previous behavior is preserved
This patch closes#2216 which incorrectly prompts for 'Wind Heading
(origin)' when estimating power. The correct term for origin of wind is
'Wind Direction'.
.. preferences pane was getting lost behind the mainwindow.
.. a bit of a hack but better than adding a gazillion
parameter passes or updating context.
.. when comparing metrics/W'bal they were always being computed
using the context of the compare pane, not the file.
.. so when you drag from one athlete window to another it was
using the wrong athlete's settings etc.
.. curve data is embedded using quote delimeters but our
parser was lazy and just split on commas.
.. updated to handle quote delimeted data, but only for RP3
format files (don't want to break anything else!)
.. saves all other data and you can pass the Notes field
as part of the call.
.. also fixed a crash in writeFile in CloudService that passed
a NULL context to writeRideFile.
.. check looks at autoimport too (e.g. when checking a
directory that is mounted when connecting device).
.. changed the titles to make it clearer which are about
activities and which are about measurements.
.. no need to store data in a separate class variable
since its maintained in the settings widgets
.. the bug was caused by only setting the unneccessary
QString when settings were selected in the settings
pane
.. cleaned up some debug too.
Fixes#2403
.. another option for the CP plot to filter out MMP
data points that are not from distinct efforts.
.. at present we keep the first point on the MMP curve
not neccessarily the maximal point.
.. this is to indicate how sparse the data is that the
model is being fitted to.
.. we can revisit the filter to potentially keep the
maximal point from a power-duration perspective --
but not clear how to do this without using a PD
model (or if there is anything wrong with that).
.. the call methods structure changed at v3.4.0 of R
which means when you register routines you should
pass the correct structure.
.. this can only be determined at runtime when the R
dynamic library is loaded.
.. to support importing rides on download from a
web page, we now support files that are compressed
using gzip or zip.
.. the file name will still need to have the correct
file format encoded in the suffix but will be
deflated before being passed to the readers.
.. for example files downloaded from TrainingPeaks
via their webapp will likely end in .wko.gz.
As there is no notification of calibration completion in the SRM profile,
we progress the calibration state on to completion five seconds after we
start receiving calibration messages.
Temporarily removes support for auto-zero, as was not used, and current
code did not follow the standards set in the ANT+ documentation.
The main purpose is to fix editing when there are multiple records per day,
additionally it allows to enter more than one manual record per day which
may not be that useful but I think is more consistent.
.. remove twitter and google calendar
.. add comments to show where the basic OAUTH steps are
processed for implementors of future services
.. tidy up code formatting to be consistent with GC style
.. updated Cycling Analytics cloud service to support sync
with a readdir function.
.. need to sort out the download (which will need to combine
data streams like Strava/SportTracks).
.. upload seems to be failing (?)
... separate (single) default weight stored in GC_WEIGHT from time-dependent body measurements on UI
... To Do - analyse and if necessary adjust use of GC_WEIGHT vs. use of time-dependent body measurement
.. the C runtime declarations changed in R-base which broke
the RTool.cpp build.
.. fixed up to support 3.4.0 onwards with new structure whilst
still working for earlier versions.
.. includes new Metadata1 type field in the CloudService
settings types with support in AddCloudWizard.
.. also fixed a bug in CloudServiceFactory::saveSettings
which failed for Combo1 (and now Metadata1) config.
.. user gets a drop down of metadata fields to use as the
source for the name of the activity when posting to
strava.
.. if the field is blank then the activity name is posted.
.. writeFileCompleted debug statement was stealing the response
readAll data so when it was being requested to process there
was no data to receive.
.. changed the debug to be unobtrusive and output the data
using local variables instead.
.. this bug is only noticeable if you have enabled Strava
debug in gcconfig.pri
... "name" does not always contain the real file name and is editable - use our filename instead
... RPE may be double (e.g. when set in TP) - round to int for Overview Widget
Using Preferences->Athlete->Zones->Pace Zones for both Run/Swim to override Preferences->General->unit.
Simplify some code with if/else blocks.
Reorganize Tooltip variable argument order to match placement in text.
Still several problems around kph being used in chart y-value despite settings.
Use const when appropriate.
.. Gui notifications of background activity
.. a small notification area at the bottom of the analysis
sidebar shows checking and download status.
.. also fixed up the ride list to not select them, since that
is irritating if your in the middle of doing something.
.. initial plumbing to get the auto downloader integrated
into context, athlete and ridecache refresh.
.. part 2 will need to perform the download functions
.. part 3 to add the GUI / notification of progress
.. the code to combine ST streams added blanks when there
was a gap in recording, it is better to preserve such
gaps and let the user manage with the 'fix gaps' tool.
.. needs to combine streams of data into a newly created
ridefile, which is painful, but done.
.. we may need to review the resolution of the data and
derivation of missing series in a later refining update
.. Secrets.h for appveyor CI build
.. duration/distance in readdir
.. beginnings of readFile, need to write a parser for
the SportTracks format (streams not samples). sigh.
.. set raw headers when I shouldn't.
.. added when trying to resolve issues earlier and didnt
remove them when they had no effect.
.. SportTracks OAuth config now works.
.. because we convert the file to json in the response
when adding RPE data we need to update the name used
in the notifyReadComplete.
.. this fixes a bug where downloaded FIT files are
converted to JSON but the sync tool tries to parse
the returned data as FIT and fails.
.. resolve a memory leak re-allocating the storage
for the returned byte array.
.. couple of other minor tidyups that were vestiges
from my refactor of the code.
.. their is a bug downloading FIT files now -- the
response is always converted to JSON, so we should
not list as .FIT in readdir.
.. when working with the factory get a sorted list of
service names so they can be offered in order
.. the addcloudwizard now list in alphabetical order
.. fixed up CloudService::type() to const
.. configuration dialog complete
.. will always attempt to bind user to service, if
that has already occurred it fails, so we always
ignore the response.
.. the QWebView embedded in OAuthDialog needs to be zoomed
so you can see the fonts.
.. the QT recomendation is to set the application wide
scaling (!) to scale QWebEngine on hi-dpi screens obvs
thats a really shit solution we ignore.
.. add template code and definition. This is not a functional
update, it is to get the basics in place and run through
CI to check for cross-platform issues.
.. part 2 to implement oauth
.. part 3 to implement configuration
.. part 4 to implement readdir()
.. part 5 to implement readFile()
.. part 6 to update CloudSyncDialog for download only services
.. remove the old "passwords" tab in the config pane.
.. added a new "accounts" tab in the athlete page and
consolidated the zones tabs to a new "zones" tab
.. edit/add actions use the wizard, delete sets the
service to inactive (but doesn't scrub settings).
... when asynchronously reading Files, "data" object needs to survive as it it referenced in the "buffers_" QMap
(this is a quick fix - I suspect there are better ways to handle this)
.. enable auth settings to have a combo that is defined by the
service and user selectable.
.. Syntax:
settingname::name::val1::va12::val3
In the first example we used it to set the google drive scope
for authorisation, so in this case it is defined:
"<athlete-private>google_drive/
auth_scope::Scope::drive::drive.appdata::drive.file"
Which results in a user selectable combo box labelled "Scope"
from which they can select from the values drive, drive.appdata
and drive.file. The value is used to update the auth_scope
setting in config/athlete-private.ini
.. We can add more of these later if they are needed, perhaps on
the setting screen for settings not related to authorisation.
.. A "SettingCombo" widget has been created to simplify the way
a QComboBox is setup and queried.
The power service also provides speed and cadence readings, connecting to
both isn't needed and causes problems since we only keep one each of the
relevant variables (prevCrankStaleness, prevCrankTime, prevCrankRevs,
prevWheelTime and prevWheelRevs).
.. AddCloudWizard is now feature complete.
.. HOWEVER, OAuthDialog is written to support AddCloudWizard
*and* Pages.cpp:CredentialsPage -- this is a hack whilst we
convert all services to use CloudService (Withings/Calendar)
.. HOWEVER, Google Drive Scope and Today's Plan Athlete selection
need to be handled in a generic way too.
Tooltip in ‘Ride’ view will now show hundredths due to precision selection.
Fix comparison of headers which simply used ‘contains’ rather than equals and would cause a problem if translation is in effect.
Fix rounding of gear ratio in derived series.
.. maintain within the instantiated service and then write
it to appsettings.
.. this means folder selection now uses config as maintained
by the wizard.
.. configuration is injected into the CloudService by the
CloudServiceFactory.
.. next steps are to include this into the AddCloudWizard
and OAuthDialog and ConfigDialog's Pages code.
.. cloud services should still be working fully after this
commit -- so long as config is performed via Options and
not via the AddCloudWizard (although its close to complete).
.. share menu is now much simpler since:
* twitter and calendar removed
* individual upload/sync options removed
* only shows sync/upload for configured accounts
.. full wizard now done, will write appsettings.
.. need to now look at how OAuth can be call mid-config as
a refactor if OAuthDialog in part 2
.. need to also look at how folder selection can be called using
"in-progress" config in part 3
.. need to tidy up special topics in Part 4, such as google drive
id and todays plan handling coach/athlete selection.
We see a few bug reports where people have combined speed
and cadence sensors, but only running one magnet (i.e. on
a direct drive trainer so no wheel magnet, or with a crank
based PM with no crank arm magnet). This interferes with
any valid speed and cadence data from other sensors (i.e
from a trainer or power meter).
This patch ignores the data from either the speed or cadence
side of the sensor, until at least one changed timestamp is
received on the channel for that data type. (The timestamps
never change if not triggered by the magnet).
Return an error if either usb_set_configuration() or
usb_claim_interface() fail. This should help in the case
where the device has insufficient permissions (Linux) or
is already in use by ANT Agent (Windows/MAC).
Note that Linux support is complicated by the fact that we
have to forcibly disconnect the usb_serial driver. Because
of this, we attempt to grab the first device regardless of
whether it was already in use. For other OS, this patch
should enable the use of multiple ANT sticks (for instance,
one for Zwift and one for GC).
This typically happens after Ctrl-C out of running
train mode activity.
Current behaviour on failure to reset is that the next
session will simply not receive any data, now will at
least error and require user to connect again.
.. added settings to the cloud service to inform the config
pane the settings we need to be entered when adding an
account for this type of service
.. includes:
* OAuthToken - From OAuth 2.0 process
* Key - Optional user key used during OAuth process
* Username - Username
* Password - Password (when not using OAuth)
* Folder - Typically for storage like Google Drive, Dropbox
* URL - Base URL for service (when offer private tenants)
... add "source" and "originalSource"
... add "time" display for bodyMeasures read from cloud services
... store in /config not in /activities
... code clean-up (warnings, enum instead preprocessor constants)
.. creating the generic CloudService code for all the
services currently implemented as "uploaders" via the
share dialog.
.. the actual upload code and semantics need to be updated
for each service individually in the next commit.
Moved Height, W'bal Tau, and PMC settings to About tab
Measures tab is a Zones like UI to Body Measures model
Added fingerprint to BodyMeasure to detect changes
Fixes#1954
.. a CloudServiceFactory now has all full cloud services
registered for service we currently support for sync
including; Local File Store, Dropbox, Google Drive,
Todays Plan and SixCycle.
.. need to now refactors all the other cloud services
to use the CloudService base class: Strava, Cycling
Analytics, Ride With GPS, Withings, Web Calendar,
Training Stage Buch, Selfloops, Velo hero and Sports
Plus Health.
.. fix ridenavigator refresh on item data changed e.g. metadata
.. needed to hack in a call to update() for the ride navigator since it
appears to be ignoring data changes, but will repaint on mouse hover.
This needs to be investigated further as its a symptom of some a slot
and signal issue somewhere (or updates are disabled somewhere!).
... incomplete class initialization
... duplicate if statements
... typos in objects names (copy&paste) (AllPlot)
... missing else (CPPlot)
... missing DELETEs for objects (only if obvious that object is not used somewhere else)
... copy&paste errors (e.g. ModelPlot)
... small floats instead of integer evaluating to 0
... potential SEGV since pointer is not checked for NULL
... misleading code formatting (hard to read) in *zones.cpp
.. just reduce to default and chartlabels which are the only
font settings used across the codebase.
.. this is in preparation for overhauling the way fonts are
set across GC.
... body measures are weight/height data as provided by multiple fitness platform (one of the being the already support Withings platform)
... all access to Weight from external platforms is done through the body measures model - not direct use of Withings any more
... not all platform deliver all measures - but (hopefully) all are providing "weight in kg" as a minimum data
General Download Dialog for Body Measures
... allowing to select the source and the daterange for which data is downloaded (e.g. only the new data since last available measure)
... Support existing Withings Download
... Support new Today's Plan as data source (which is able to receive measures from other sits - e.g. Garmin Connect)
... Support CSV files as data source
Store Body Measures Data in one fix file under /activities (not in /cache like Withings) (so that e.g. backup works like before).
What's open:
... CSV File Import (Info Message on missing feature)
... Test of "old" Withings Download API (since I can't do this)
.. slight adjustment to the scheme (before working through
303 different metrics)
.. added sport() which can return an OR'ed value of sports
the metric is relevant for (e.g. Run|Bike) and added
some shorthand values Triathlon == Run|Bike|Swim whilst
any is 0xff (matches all).
.. add classification and validity attributes to every
ridemetric with a default of Unknown and None to get
things started.
.. next step is to work through each and update based upon
available evidence. This might be best performed in 2
passes: first pass where criteria is beyond reasonable
argument and is unlikely to be disputed, and a second
pass where evidence has been identified.
.. should use device independent pixels !
.. VirtualBox, Windows and Linux all use different ratios
of device pixels to device independent pixels so its
important we stay device independent.
.. some nasty bugs caused by QT losing contentsMargins when
hidpi and not scaled. Really weird.
.. but now titles and reveal controls and More.. menu works
as they would when not on hi-dpi screens
.. run through the entire code base looking for calls to
setColumnWidth, resizeColumns, setFixedSize and replace
with calls that apply dpiXFactor/dpiYFactor
.. the padding around pushbuttons and combo boxes is not scaled
for hidpi displays, so we fix up with a global style sheet
in main.cpp
.. it is only applied in hi-dpi for Windows and Linux.
.. not perfect, but to support this correctly the code will
need to change and affect normal usage.
.. lets get it to a reasonable place, since all the mainwindow
chrome will get replaced in v4.0 anyway
.. but might revisit the toolbar pushbutton icon size !
.. MainWindow::ConfigChanged() was setting the application wide
font back to the configured defaults.
.. this was fine, until we decided to override the config when
running on hi-dpi displays, in which case it breaks things
.. we need to fixup the configuration dialog to stop users from
setting font sizes and instead set them programmatically for
hi-dpi and non-dpi displays
.. for now we just disable the reset in MainWindow - which means
most widgetry now honours the default font (until it is changed
in config, then you need to restart).
.. Start of support for hi-dpi displays; only relevant if you
are running on a hi-dpi display and have not chosen to set
any 'auto' scaling.
.. it just sets a dialog box ratio (which is unused at this
point) and sets the default font to something reasonable for
the display size.
.. next steps are to check impact across Linux, Windows and
MacOS hi-dpi displays and then work through and correct code
that works with dialog boxes and sets widget sizes.
.. this will be a bit of a slog, but worth it for crisper
rendering on those expensive 4k panels
.. noone will likely notice but the matching algorithm
now matches for highest score across all matches instead
of sequentially matching each new point to the old.
.. by filtering out points we don't want (note how
the class member 'points' was masked by the parameter
'points' in BubbleViz::setPoints() (!)
.. will wrap by own knuckles for bad practice.
... Check both hrm and pdd files for ReplacementCharacters in which
case Codec ISO 8859-1 is used
... The number of rows in [ExerciseInfo] can be different, both for
numbers and for text. Use the provided information in the PDD file
to be sure.
.. matching algorithm is pretty blunt for speed since
its really eye candy rather than something where
absolute accuracy is required.
.. can always improve the scoring mechanism and
algorithm (it takes best match point by point in
linear fashion rather than considering the quality
of all matches across all points).
.. looks nice enough.
... does not like "near" or "far" as variable names (which seem to be a DOS legacy of near and far pointers)
... surprisingly the SDK version used in CI is fine with it
... renaming fixes the problem - so no further investigation if there are other ways to overcome this.
... for new Overview Windows
... for one special HRV Metric
Overview - PMC values
... Align Headers like in all other Cards (left justified, not centered)
Update Translation DE
.. to be complete and to test the fixes above
.. don't include zeroes, since most of the time they
are because data is not present (e.g. HR, RPE) and
the sparkline already ignores zeroes - so including
them in the average is very misleading.
.. the scatter plot in Qt Charts was a terrible
memory leak (and wasn't a bubble chart as desired).
.. replaced with a very basic bubble chart viz that
doesn't have any animation or interactivity - we
can add some of that later.
.. also added an elapsed_time metric for interval
based plots.
.. like the ride list, a color of 1,1,1,1 indicates
to use the ride color from notes keywords.
.. should also add options to set the pen, as depending
upon the user settings the colors could be quite
bright (!)
.. event propagation bug into RPErating when clicked
to start resizing a tile -- we needed to accept the
event and stop it being propagated further.
.. fixes a bug introduced in commit 234fcf5001
.. just to make it super obvious that the computeMetrics
method updates RideItem/IntervalItem directly (spooky
action at a distance) because user metrics need it.
.. so added an if clause to limit it, and provide more
clarity to future devs (including me!)
.. whenever ride data is changed, metadata, ride data etc then shortly
after making the change the ride list would lose focus and lose
the current selection
.. this was caused by reseetting the ride list model when data changed.
this was unneccessary and also time consuming.
.. it took 3 hours of debugging to comment out 1 offending line, I think
that might be a record !
... add copyright notice to file
... store .dbg and .log in Athlete Directory (if known) and in installation directory only as default
... unify handling of "win32-msvc*" specific qmake commands in src.pro
.. Leif Warland is developing the HRV metric support
and some of these are std deviations. When you
aggregate std deviations the mean and variances
are needed.
.. RideMetric::stdmean() and ::stdvariance() return
a value that is stored in the RideDB if it is
non-zero.
.. RideItem::getStdMeanForSymbol()
RideItem::getStdVarianceForSymbol
return the stored value for use when aggregating in
the same way that RideItem::getCountForSymbol() does.
Both SixCycle and TodaysPlan uses QByteArray::toStdString
(introduced in Qt 5.4), while in QJsonParseError (introduced in Qt
5.0) is used in TodaysPlanWorkoutDownload.
.. the RideMetric::count() value is written to the ride
cache (rideDB.json) if it is non-zero.
.. it is not used in the aggregation logic yet, but the
rideDB version number has been incremented to force
a rebuild on first run.
.. don't use a Map, instead paint the route
.. it just filters out the points to simplify, I tried to
implement FastSTray but gave up and just arbitrarily
filter out 95% of all points instead.
.. the paper here describes FastSTray if anyone fancies
implementing it in a way that is quick:
https://arxiv.org/pdf/1608.07338.pdf
... if lap data contains a developer field, lap starting time is corrupt, if field num of the developer field == 2
... since we don't store any lap specific developer fields, let's ignore them all
.. to tidy up embedding chart widgets in the dashboard
.. not so much about the web view for the map as fixing
bugs that will impact embedding more interesting kinds
of charts.
.. there is a really irritating bug related to setCursor()
not working once the mouse has hovered over the
QWebEngine window in the dashboard.
.. did I ever mention how much I hate QWebEngine ?
.. map is styled using "snazzymaps.com" css template
.. but it looks naff, loads slowly and adds a dependency
on embedding a QWebEngineView, which is one of the
reasons we're developing this in the first place (!)
.. it shows how to embed charts in the dashboard, so that
proxy code will be useful in the future.
.. likely to replace the google map visualisation with a
GPS route pixmap and route profile using altitude in
the next commit or two.
.. implement the sparkline using native painters since
the Qt Chart had many regression issues that caused
significant slow downs and memory leaks
.. delete the xyseries in the scatter chart for intervals
every now and again to avoid another memory leak there
.. reduce the amount of animation in the chart to avoid
another memory leak
.. in short, Qt Charts are very promising, but they are
new and lack the maturity of QWT.
.. if you scroll up and down the ride list whilst the
overview is open Qt Charts will crash trying to
complete an animation.
.. to fix this we disable animations before trying
to update the chart (including setting animation
options back on)
.. QWebEnginePage::setHtml() steals keyboard focus (!)
.. to stop this behaviour setEnabled(false) stops it
from trying to do that.
.. this obviously only happens when NOWEBKIT is defined.
.. an Interval plot plot on the dashboard is an xy
scatterplot, good for time/power, hr/power etc
.. have also removed (temporarily) the drag animation
that shrinks tiles since its a major performance
overhead against Qt Charts.
.. there is still work to do tidying up the interval
scatter plot and adding some kind of mouse hover
feedback.
.. we only plot a sparkline for activities in the last 14 days
and don't plot zero values.
.. alongside the sparkline the max and min are shown to provide
context as the Y-axis is scaled to the data
... in addition to DateTime in the .json File name (which is in local Time), also check for duplicates using UTC from RideCache to avoid duplicate imports if user changes his PC TimeZone (e.g. when travelling)
... the problem e.g. occurs in Autoimport where the same files would be imported again, if the PC TimeZone changes
.. not quite working right - need to look at how
the axis range can be set after the data has been
modified as it seems to break things.
.. looks back 21 rides, but perhaps would be better to
look back n days.
.. when looking for activities it doesn't filter so
you see zero values for other sports e.g. power
will be zero for a swim
.. needs refinement after real users get to try it
.. not really a memory leak, more a design flaw in
the way QParallelAnimation works (it assumes you
don't reuse it).
.. there may be other issues with the other animation
groups but can look at those separately.
... Default directory for the WebEngine Profile and Cache is /AppData/Local/<AppName which is the same GC uses as Default for Athletes
Changing the location for QtWebEngine needs to be done for EVERY QWebPage. Until the use of QtWebEngine is limited to a few locations
the easier way is to filter out the Directories created by QtWebEngine (assuming that no-one will call their athletes either "cache" or "QtWebEngine".
... This is only done if build with QtWebEngine and for Windows (on other OS Qt uses a better location for cache data, not a user location).
.. enforce use of QT 5.8 for building the Overview and
use of Qt Charts.
.. Qt 5.7.x doesn't neccessarily come with Qt Charts as it
was a technology preview (and breaks the current Appveyor
builds)
.. hacked in a proof of concept, using Qt Charts
.. only does the time in zone for HR at present, but can now
look to refactor to better code and then add in pace, power
and w'bal time in zone too.
.. note that now we are using Qt Charts the overview will
only be built with Qt >= 5.7
.. although hacked in, at least we get a dashboard that looks
like the real thing (till we have configuration code).
.. need to work on adding time in zones via Qt Charts next !
.. modes for config and view scrapped - too confusing when you
have config of layout vs config of individual cards
.. need to set a constraint on the size of each card to make
it easier to design content and manage typefaces in a
consistent manner across the cards
.. add / delete / modify will be made available at all times.
add will need a '+' card to float at the end of the
dashboard, whilst delete and modify can be on the card
decoration.
.. using a gear icon in the top right to switch between
viewing an overview and configuring it.
.. now need to think about how cards react and are
decorated and the main mechanisms for configuring
the content on the page (not the layout).
.. easing curve for autoscroll should be linear as it can
be continuous and is jarring if speeds up and slows down
.. some of the animation durations were too slow and made the
UI feel slow instead of snappy
.. getting ready to work on card aesthetics
.. reflects changes as they are made and can be
used to scroll the view.
.. we manage this ourselves instead of letting the
view manage it as we also want to diable it.
.. when a scrollbar is disabled it now makes the
slider invisible.
.. use boundaries of view so it doesn't 'suddenly' start
scrolling - you force it by going to the edge or beyond.
.. make sure the mouse is moving in the right direction of
the autoscroll so it stops when you move up/down against
the direction of the autoscroll.
.. you can scroll up and down with up/down arrow keys
and page up/down.
.. the scroll is animated if the distance is far enough
otherwise it just happens immediately.
.. need to add scrollbar scrolling, drag scrolling and
mouse wheel / gesture scrolling next.
.. scene / view rectangles changing caused mouse move
events to arrive with different co-ordinates which
broke y-resize.
.. so we no longer adjust the view whilst resizing on
the y-axis (already did that for the x-axis)
.. dragging one tile in the last column to make a
new column SEGV (incrementing itself)
.. bug bought to you via extensive testing from my
13yr old son who takes great pride in breaking
his Dad's code.
.. inadvertently committed alongside updates for sport tags.
.. these updates introduced a serious regression for the
ridefile JSON format and backwards compatibility
.. reverts the following commits:
b47cb733a2d432602b35
.. dragging the rhs of a card will make the column it is
part of resize.
.. scaling paused whilst dragging and resize leads to a
less jarring experience -- but scaling could also do
with being animated to avoid the jumpy experience.
.. we can now resize tiles by dragging them from the bottom.
.. need to sort out zooming, scrolling and 'fit in view' type
problems next, before save/restore layout to chart settings.
.. don't assume the sync with TP is only using JSON files as
the files are uploaded manually or synched from Garmin so
they could be just about any type.
.. not that TodaysPlan support .act and .bdx files which we
do not. So users with those (rare?) file formats will not
be able to sync.
.. as the layout changes we animate.
.. in the prototype you click on a rectangle to remove it,
which triggers the rest of the items to fall up into
the space vacated.
.. now the animation is in place we can start working on
the click to drag and relocate as we move the cursor
.. just saving away some hacky code as the overview is being
prototyped. The code will evolve over time, the current
focus is on drag and drop of cards with animation.
.. this code does very little, just populates a scene and
tracks mouse movement within the scene.
.. widget to replace summary chart - but at this stage is
just blank and need to work on drag and drop ui for
managing cards before adding any content
.. also commented out the planning widget for 3.4.1
.. very simple hack to import any file that is
downloaded from a webpage.
.. when working with e.g. TodaysPlan if you click
on Download Original it will download and
import it into GC.
.. nice way of getting data from web sites that
offer a manual download but no sync api
This extends the existing support for Computrainer calibration to
include ANT+ devices, and provides initial support for both zero
offset and spindown calibration.
A new button (with wrench graphic) is provided to invoke calibration.
Ongoing calibration status is fed back in the new notification area
of the bottom bar. Calibration will automatically exit on completion
or error, or can be cancelled though the calibration button.
Supports multiple devices, and will round-robin between them, this
applies to both multiple ANT+ sensors (i.e. power meter and trainer),
and also multiple GC device selections (i.e. CompuTrainer and ANT+
power meter).
If an ANT+ device has advertised that calibration is required (currently
just FE-C trainers), then it will be chosen for calibration in preference
to other ANT+ devices.
Patch has been tested against FE-C trainer (Tacx Vortex Smart) and
PowerTap hub. Support for SRM (crank torque frequency) devices will
require additional changes to process the different response messages.
Shuffle bottom bar around, with new icons and state tracking
for intensity adjustment.
Add a basic text notification area into bottom bar, using a
read-only QPlainTextEdit control (defeated by QLabel resizing
with the content). Include some basic notifications for button
events.
Support for setting and clearing notification text, with timer
support for auto-clearing.
Sizes the bottom bar for three lines of text, but don't clip the
buttons vertically if text is smaller.
TODO: reinstate auto-hide functionality (new settings checkbox
not in use), and extend to include new notifcations as trigger.
... improve Telemetry Dialog
... add more data to Telemetry Storage / including user counter
... do not show any network errors / lack of connection
... call all CloudDB functions asynchronously without blocking UI
... use an installer specific UUID as identifier - not IP address (as this is to volatile)
Added missing Mass factor in kinetic energy contribution, probably of little
effect in practice since it is a minor contribution in distance running.
Changed cAero to per kg to follow Skiba Paper, doesn't change the result.
Thanks Ramon Castañer for the heads up.
.. the type parameter was being ignored (it wasn't
implemented at all.
.. now you can do:
hills <- GC.season.intervals(type="CLIMBING")
peakpower <- GC.season.intervals(type="PEAK POWER")
all <- GC.season.intervals()
.. SixCycle should be spelt as Sixcycle, this has
been fixed across the user visible strings
.. Upload of PWX works, but not TCX, so switching
to using PWX for now.
.. Query filestore now added.
.. You can query and upload using the API, but at present no files are
being accepted (we send as TCX uncompressed).
.. Part 4 will include download then we can pass over to SixCycle for
them to test and fixup.
.. note that SixCycle uses enddate (!?!) for their activity and not
start time this requires a bit of gymnastics to match in syncdialog
there are some pending fixups required for syncdialog download
because of this.
.. updated the secure environment to include:
* GC_DROPBOX_CLIENT_ID
* GC_MAPQUESTAPI_KEY
* GC_CLOUD_DB_BASIC_AUTH
* GC_CLOUD_DB_APP_NAME
* GC_GOOGLE_DRIVE_CLIENT_ID
* GC_GOOGLE_DRIVE_CLIENT_SECRET
* GC_GOOGLE_DRIVE_API_KEY
* GC_TODAYSPLAN_CLIENT_SECRET
.. Since Arun has now fixed deployment its important that the
builds include the keys.
.. upload activities
.. need to work with tech support at SC to debug the call as we
are posting multipart form data but its not being processed
and we receive no error or confirmation response for call.
.. trademarks acknowledged in about, don't need to
duplicate that in the summary
.. Peaksware have rescinded permissions, so we will
need to remove use across the user visible and
default setup.
.. added SixCycle FileStore implementation
.. in this part the authentication mechanism is complete and extracts
both the session token and session userid for subsequent requests.
.. follow up commits will need to implement readdir, writeFile readFile.
Prevent stray lap alerts at start of workout with no laps
defined, or at start of manual mode workout.
Ensure buttons reflect current state when opening train view, regression
from move to bottom bar (likely that slot not yet connected when signal
is emitted in TrainSidebar constructor).
.. to work with data before or after an interval the
before and after functions have been added to the
user metric program.
.. as an example, to calculate kj of work done
before the interval:
init { work <- 0 }
before { work <- work + (POWER*RECINTSECS); }
value { work/1000 }
.. you can do the same for work done after using
the after function name instead of before.
Ensure QtMultiMedia support is built for Qt5 (wasn't on OSX)
Only enforce Qt 5.6 onwards on Linux, as official builds are
using 5.5, and this Qt volume bug only affects systems using
pulseaudio
This provides a fixed bell sound, played 3s before the
start of each new lap. This feature can be enabled under
the new training preferences dialog.
See the following bug report - quite exciting under Linux -
https://bugreports.qt.io/browse/QTBUG-40823
Due to this, is only currently enabled for QT versions 5.6.0
and above, could make this a platform specific check if felt this
is overly restrictive?
.. you can query the window size with GC.size(), it will return a vector
if 2 integers for width and height.
.. the default page size is no longer 500x500 instead it defaults to the
size of the chart
.. if you do choose a size it is scaled to the window size, but keeps
the original aspect ratio -- so setting the chart size can be
useful to ensure the chart has a particular aspect ratio.
.. if the "Download" text is translated then the code that checks
if we're uploading or downloading doesn't translate the text
leading to it continually trying to upload if the language
selected is not English.
Due to poor quality data from Tacx simulated S&C channels, we
ignore any Speed & Cadence data from the same device_id as a
Tacx FE-C device.
The speed and cadence data is also provided over the FE-C channel,
so not losing anything except bad data.
Note that it can take ~33s to receive a manufacturer id
message and take effect.
.. when authorising via SSL we may get handshake "errors" as
the protocol is established, this seems to occur with
openssl on Sierra and Mavericks.
.. since the request is completed then some form of protocol was
established so we ignore it in this instance.
.. even if there is a problem its likely the tokens will be blank
and that will trigger another error, so fairly safe to ignore
.. connect.garmin.com still hangs the browser window
.. filesystem api isn't supported by qwebengine so trainingpeaks
downloads don't trigger
.. still work to do!
.. struggling to get any of the fitness websites to behave.
.. no new functionality, just trying to fixup for garmin/trainingpeaks
.. both have issues.. garmin sets cpu to 100% and is unresponsive !
.. now has reveal controls to change url
.. can be added to trends, activities and train view
.. needs testing with webkit and updating to intercept
downloads to try and import as ride files.
... do not allow Upload of charts containing User Metrics (as they will not work for other users)
... do not allow Upload of trivial charts (without configuration) - as they do not provide any value for others
... when downloading "R" charts - check if R is active - if not, inform the user that he/she needs R for the chart to work
We now place a reasonable upper limit on the number of ticks shown
on an AllPlot chart to prevent unbounded memory allocation and
crash when one of the activities to be merged has a wide data range
due to large anomalous data points.
There are two paths to displaying the power/time overlay on a workout block:
* Hover over the block
* Select the qwkcode line corresponding to the block
Both of these paths had their own uniquely flawed method of calculating the block duration to display. The first path stored the previous time point as a truncated integer number of seconds, then subtracted it from the current, double precision time point. This resulted in occasional over-reported durations. The second path took the double precision difference between the current and previous time points, then truncated that difference for display. This resulted in occasional under-reported durations.
Both of these paths now consistently report the same value. The value shown will take the format ss.s for times less than 60s, or hh:mm:ss for times 60s or more.
Qwkcode is limited to integer values of seconds. When a workout is specified in qwkcode then saved to an ERG file, the interval durations are rounded from integer seconds to fractional minutes with 2 decimal places of precision. When the ERG file is read, it is translated to a WWPoint object that stores time as double seconds. To accurately calculate the duration of a time interval defined by two WWPoints we should round the individual points first then take the integer difference. The table below demonstrates the consistency of rounding on both ends of the qwkcode -> ERG -> qwkcode round trip.
| qwkcode (original) | ERG time (rounded from qwkcode) | WWPoint time (precisely calculated from ERG time) | qwkcode (rounded from WWPoint) |
|--------------------|---------------------------------|---------------------------------------------------|--------------------------------|
| 1 | 0.02 | 1.2 | 1 |
| 2 | 0.03 | 1.8 | 2 |
| 3 | 0.05 | 3 | 3 |
(3 seconds is the smallest unit that fits evenly into a base ten fractional minute, so this pattern will repeat without loss of precision.)
.. from December 7th 2016 read access (for downloading
from TrainingPeaks) has been revoked, even for paid
up members.
.. write access (upload) is not revoked.
.. This is essentially anti-competitive behaviour and
returns TrainingPeaks and their products, once again
to that of a 'closed' product.
.. We will no longer support their service since we
cannot and will not promote such behaviours now
or ever.
.. We are now considering the best way to purge all
other references to their trademarks and remove
any indication that their products are endorsed.
.. they were removed from code recently but still
lingered harmlessly in the codebase.
.. now moving into the deprecated folder to stop
them from being used again in the future.
.. we no longer build with QT4, so deprecate it in Travis
.. there are still some users that build with QT4 on Linux/OpenBSD
but we no longer seek to support this configuration officially
.. a data processor can now be configured to run on save
.. in addition, the data processor is now passed the operation
that is triggering it: "Manual", "ADD", "UPDATE", "DELETE",
"IMPORT".
.. a new data processor has been added to write a JSON file to
the snippet directory (added to the athlete structure).
.. this is so we can output a snippet every time an activity is
added, updated or deleted (i.e. runs "on save").
.. these JSON snippets can be used to update external datastores
where coaches use other analytic software but don't want to
manually sync GC changes with there external stores.
.. add a reference count for clones and originals, noting
that for user metrics the factory gets a clone and the
original is always deleted at startup.
.. additionally when the clone in the factory is deleted
on metric changes we finally delete the program that
was created initially.
.. note there is also a fix to let the configuration
settings spot when aggregate zero and istime change
in options as these were not spotted before.
fixes#2158
Issue:
The contents of the combo box, the array holding the raw mm values and
the index range checks were out of sync.
This led to wrong or no values at all during the wheel perimeter
calculation.
Changes:
* Add missing rim diameter 584mm
* Adjust rouding error in tire casing diameter
* Make index range checks more robust by using the actual array size
instead of just assuming a length
* Display ISO5775/ETRTO mm values in combo box
Combined with the Group By feature, it allows a simple way
to see weekly, monthly and yearly averages for cumulative
metrics s.t. Duration, Distance, TSS, etc.
.. lots of warnings about unused global variables that
are being used to call functions before main
.. a few other smaller nits that could be fixed easily
.. now get fewer warnings and more meaningful to then
review and resolve them
It is a more natural unit is most cases and allows enhanced
plotting in LTM charts since seconds are converted to hours.
Labels and ToolTip are shown in sexagesimal format.
.. the code was never written, so the season code just
crashes using an index of -1 into the season array
.. updated LTMSidebar.cpp to catch delete phase and handle
it appropriately, but the real fix should be to abstract
the code added into the Season/Phase classes.
Fixes#2139.
To enhance usability, specially when the locale uses 2 digits years.
Fixes#2123
In some places s.t. TPDowloadDialog and FileStore it was already set.
Not added to RideMetadata and RideImportWizard where 4 digits year is fixed.
#### **Do you have questions about how to use GoldenCheetah?**
* Ask any question about how to use GoldenCheetah on [golden-cheetah-users mailing list](https://groups.google.com/forum/#!forum/golden-cheetah-users), ideally after watching the corresponding [tutorials](https://www.goldencheetah.org/#section-tutorials) and/or reading the relevant parts of the [documentation](https://github.com/GoldenCheetah/GoldenCheetah/wiki).
#### **Do you have questions about the source code?**
* Ask any question about how to build GoldenCheetah or anything related to the source code in the [golden-cheetah-developers mailing list](https://groups.google.com/forum/#!forum/golden-cheetah-developers), please see the [GoldenCheetah Developers Guide](https://github.com/GoldenCheetah/GoldenCheetah/wiki/Developers-guide) for addtional information.
## How to contribute to GoldenCheetah
#### **Did you find a bug?**
* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/GoldenCheetah/GoldenCheetah/issues).
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/GoldenCheetah/GoldenCheetah/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and **steps to reproduce the problem** or a **test file** demonstrating the expected behavior that is not occurring.
#### **Did you write a patch that fixes a bug?**
* Open a new GitHub pull request with the patch.
* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
* See [GoldenCheetah Guidelines for submitting a patch](https://github.com/GoldenCheetah/GoldenCheetah/wiki/Guidelines-for-submitting-a-patch) for additional information.
#### **Did you fix whitespace, format code, or make a purely cosmetic patch?**
Changes that are cosmetic in nature and do not add anything substantial to the stability or functionality of GoldenCheetah will generally not be accepted.
#### **Do you intend to add a new feature or change an existing one?**
* Suggest your change in the [golden-cheetah-developers mailing list](https://groups.google.com/forum/#!forum/golden-cheetah-developers) and start writing code.
* Do not open an issue on GitHub until you have collected positive feedback about the change. GitHub issues are primarily intended for bug reports and fixes.
#### **Do you want to contribute to GoldenCheetah translations?**
* Translators are very welcome, please see [GoldenCheetah Guidelines for translators](https://github.com/GoldenCheetah/GoldenCheetah/wiki/Guidelines-for-translators)
#### **Do you want to contribute to GoldenCheetah documentation?**
* The [GoldenCheetah wiki](https://github.com/GoldenCheetah/GoldenCheetah/wiki) is open to user's contributions. feel free to add what you consider relevant to make other's users experience smoother.
GoldenCheetah is a volunteer effort. Contributions are welcome!
3. ADDING OPTIONAL DEPENDENCIES WHEN BUILDING VERSION 3
@@ -34,7 +33,7 @@ CONTENTS
1. BASIC INSTALLATION WITH MANDATORY DEPENDENCIES
=================================================
Installed Ubuntu 11.04 from CD image amd-64.iso. You will not need to do this if you
Installed Linux distribution of choice on platforms i386 or amd-64 (currently Debian-based distributions and Arch-based distributions are covered). You will not need to do this if you
already have a Linux distribution installed. Left this step in to highlight the
Linux distribution the commands below were executed on.
@@ -42,8 +41,12 @@ login and open a terminal to get a shell prompt
Download MANDATORY DEPENDENCIES (browser)
-----------------------------------------
Download and install the Qt 4.8 SDK from http://qt-project.org/
Once that is completed test qmake is ok with: qmake --version (should report 4.7.0 or higher)
Download and install the Qt SDK from http://qt-project.org/
Once that is completed test qmake is ok with: qmake --version (should report 4.9.8 or higher)
DEBIAN-BASED DISTRIBUTION INSTRUCTIONS
--------------------------------------
Install git with:
$ sudo apt-get install git
@@ -55,6 +58,20 @@ Install FLEX and BISON
You will need flex v2.5.9 or later
$ sudo apt-get install bison
$ sudo apt-get install flex
-----------------------------------
ARCH-BASED DISTRIBUTION INSTRUCTIONS
------------------------------------
Install git:
$ sudo pacman -S git
INSTALL FLEX and BISON
----------------------
$ sudo pacman -S flex bison
NEXT STEPS
----------
$ vi gcconfig.pri
Ensure you have the following lines (which are now also in gcconfig.pri.in which has
@@ -74,6 +91,20 @@ $ make clean
$ qmake
$ make
To compile translation you need QT tool - lrelease
If it is not found using he defaults in src/src.pro then set the full path and filename in gcconfig.pri
QMAKE_LRELEASE = /usr/bin/lrelease
When build first time you get number of error messages on .qm files missing:
"RCC: Error in 'Resources/application.qrc': Cannot find file 'translations/gc_fr.qm'"
You can ignore these messages for your build. The .qm files will be created during the
build at a later point in time via the "lrelease" command you configured in gcconfig.pri)
If your QT build includes its own local compress libs then you should comment the line below in gcconfig.pri,
otherwise you will need to have the compress libraries installed separately.
#LIBZ_INCLUDE =
#LIBZ_LIBS = -lz
You will now have a release3 binary but with none of the release3 dependencies compiled in.
Get latest GOLDEN CHEETAH source files
--------------------------------------
@@ -175,96 +206,6 @@ $ make
You now have SRM support built in.
OAUTH/CRYPT - For Tweet my ride (twitter) support
-------------------------------------------------
You should be able to install liboauth and dependencies
directly with:
$ sudo apt-get install liboauth-dev
If this does not work then:
Download the source from: http://sourceforge.net/projects/liboauth/files/liboauth-0.9.4.tar.gz/download and
unpack it into ~/Projects/liboauth-0.9.4 using archive manager
$ cd ~/Projects/liboauth-0.9.4
You may find that libcurl is not installed (which liboauth depends upon) so download it
from http://curl.haxx.se/download/curl-7.21.6.tar.gz and unpack it into ~/Projects/curl-7.21.6
using archive manager to drag and drop into your Projects folder
$ cd ~/Projects/curl-7.21.6
$ ./configure
$ make
$ sudo make install
You should now have libcurl and friends installed in /usr/local
You may find that liboauth also requires the openssl libs installed, these are available
pre-packaged thankfully so:
$ sudo apt-get install libssl-dev
This will also install zlibg which liboauth also desires.
$ cd ~/Projects/liboauth-0.9.4
$ ./configure
$ make
$ sudo make install
Now we have liboauth and libcurl in /usr/local and libssl in /usr/lib, so we can go back to
GoldenCheetah and update the gcconfig.pri to point at the right places:
$ cd ~/Projects/Live/GoldenCheetah/src
$ vi gcconfig.pri
Make sure the following are set:
LIBOAUTH_INSTALL = /usr/local
LIBCRYPTO_INSTALL = -lcrypto
LIBCURL_INSTALL=-lcurl
Make clean is needed if you have previously built, since source files examine #defines before
including this feature. You can skip it if you know why ;)
$ make clean
$ qmake
$ make
You can now tweet your rides and amaze your friends, or alternatively tweet your rides but
omit to mention average power to hide your weaknesses.
LIBQWTPLOT3D - For 3D plot
--------------------------
Download the tarball from http://qwtplot3d.svn.sourceforge.net/viewvc/qwtplot3d/branches/maintain_0_2_x/qwtplot3d/?view=tar
and unarchive it into your Projects directory using archive manager. There is no version number it just creates a
subdirectory called qwtplot3d
You will need to install libgl and extensions, this can be done with;
$ sudo apt-get install libgl1-mesa-dev
$ sudo apt-get install libglu-dev
On Ubuntu 12.10 I also ran
$ sudo apt-get install freeglut3 freeglut3-dev
$ cd ~/Projects/qwtplot3d
Edit the qwtplot3d.pri and add
CONFIG += staticlib
You will find that on modern Linuxes you also need to fix include/qwt3d_global.h by adding the line:
#include <GL/glu.h>
then build
$ qmake
$ make
Then to let gc know where the qwtplot3d libs are you need to edit gcconfig.pri;
$ cd ~/Projects/Live/GoldenCheetah/src
$ vi gcconfig.pri
And uncomment the following line and set the install directory to where you build
Issue tracker is **only** for Bugs and Features, before to open a new issue please read the Contributing document (link at the right) and use the forums if you need help.
/*if (site == DROPBOX || site == STRAVA || site == CYCLING_ANALYTICS || site == POLAR || site == SPORTTRACKS || site == GOOGLE_DRIVE || site == KENTUNI || site == TODAYSPLAN) {
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.