Helps startup time a bit more, mainly by removing
all of the QTextEdit controls used for html esacping
and moving them into a utils class.
also stopped excessive looping in setymax where axis height
was small.
simpler implementation of ceil used rather than calling qCeil.
G3 hubs intermittently broadcast battery status messages, which
were being treated as telemetry and saved into lastMessage. This
was then corrupting the ANT_WHEELTORQUE_POWER calculations for
speed & power after each battery message.
Note: don't have a G3 to verify this agaist, but this fix makes
sense given the supplied log files!
.. when zoomed if you highlight the qwkcode the view makes sure
the gui is visible and centered if poss.
.. also ensures 'now' is centred and visible when recording - makes
the view useful as a close-up view of 'whats coming up' during
recording.
.. zooming in / out now animates to make it less jarring.
.. we now need to add 'ensureVisible' for the cursor when
cursoring down the qwkcode to make sure block is visible
on the gui side when zoomed.
.. now user metrics will reference pre-computed metrics
during the computeMetrics() call, we need to NOT do
this when they're empty.
.. there is really only one time this happens - when we
are testing a metric in the preferences pane.
Changed EditUserMetricDialog parent so that Options/Preferences dialog doesn't get hidden by main window
Added double-click as an alternative to edit button
.. use the symbols computed for an interval when calculating
for an interval and not those calculated against the entire
ride.
.. we now use datafilters in a lot of contexts and should
consider moving to handling scope more formally within
the language grammar.
.. allow the user to create a new workout and also
to save as a new file, which are complementary functions.
.. we also now prompt the user if they have made changes that
have not been saved to make sure they don't lose them by
accident.
.. a few bits of code were not removed from the different
approaches taken whilst developing the splash progress
window before the last commit, so cleaning them away.
.. The eCP model keeps a note of the peak efforts used to derive the
model parameters. This is so we can work with them later, possibly
to store in the ride item and plot alongside the model etc
.. we may choose to use confidence intervals across them since they
will always represent the peak "anaerobic and/or aerobic" efforts
in each ride.
... GC needed a "libusb0.dll" being available on Windows system to be able to start (even if not used)
... Library/dll is now dynamically searched and loaded if available - allowing GC to start even if the system
has no "libusb0.dll" installed/available
Auto connects to the selected train device(s), re-connects if device
selection or configuration changes. Adds a temporary button to
manually toggle connected state.
Emits signal on change of view to support connect/disconnect on view change.
Only gathers telemetry when on train view tab, unless during workout.
Decouples the gui timer from session start/stop. Only updates time and
distance if session is running. Passes the running/paused state into
context, and only updates performance plot while running.
Builds list of active devices when connecting - used to disconnect the
previous selections when they have already changed in the device tree widget.
Disables whichever train view controls are not applicable to the current state.
Dependent on timing, the closing ANT channel can transition into a closed state
before it's checked, resulting in it being re-opened.
When the ANT channel is closed and then immediately re-opened (for instance when
changing the device selection in train view), it may generate a libusb error
message. Adds a small delay to the closing, enabling the device to settle.
... add menu for Curation only if started with "--clouddbcurator" option
... restructure menus (User vs. Curator)
... add Curator validation (check athlete UUID vs. entry in Curator DB)
.. if your power output is not within 5% of the
target power and you're in ERG mode the the
background color of the dial is changed to
let you know.
RED background power is > 105% of target
BLUE background power is < 95% of target
Basically mimics the scheme used in TrainerRoad.
.. the timer event for click and hold was not cleared
when the user pressed the mouse again (typically when
drawing points very quickly).
.. this mean't that the timeout from an earlier click event
arrived just after a new click event causing a block to
be added rather than a point.
.. we now clear the timer event when a new mouse click arrives
and set a new timer from this event.
.. not sure what it was trying to fix, but it didn't actually
do anything except declare a couple of variables and set them
to a value that was never used.
.. compiler no longer warnds 'unused variables'.
.. we can also write Zwift workout files using the
workout editor.
.. it doesn't retain texts, and category/categoryIndex
we can fix that when we look at metadata.
.. its just a temporary measure but moving them to the bottom
of the screen as they're really annoying popping up over the
main view -- have to move them out of the way EVERY time I
go into train view is a ballache !!
.. when cursoring up and down the Qwkcode text
the hover block now highlights the block in
the workout plot so you can see what points
the line is relevant to.
.. ensure duplicate points survive the round-trip
from points -> qwkcode -> points to enable editing
of qwkcode and mixing with undo/redo.
.. point data now stored as ints not doubles and use
integer arithmetic etc. Makes things more consistent
and a hell of a lot faster.
.. QT code supplied was QT5 only, fixed up to compile
on QT4 by including relevant headers
.. moved the responsibility for code highlighting back
to the editor as it is the sensible place to do it.
.. add a text edit to edit the workout quickly
without having to use a gui or work with the
ERG file format.
.. need to make it round-trip, hover highlight
and generally make it easier on the eye.
.. when updating an ergfile after edit if the duration of
the workout has changed the "Duration" member needs to be
updated to reflect the change since it is used by
wattsAt() to decide if at the last section of the erg file.
- Fortius read was timing out on some hardware
- If read fails then write fails
- Moved write before read to rectify
- Added windows 10 x64 compatible driver inf built with Zadig
.. so other plots see changes we made (without saving).
.. the reason we don't insist on saving the erg file is
because we often increase intensity or repeat sections
just for a one off run.
.. the changes made within the editor are applied to the in-memory
representation when the workout is started -- that way the edits
are executed.
.. the workout changes are not saved (yet).
.. will now plot telemetry as you are recording so can be
used as a drop in replacement for ErgFilePlot.
.. bear in mind it does not support slope mode yet, so
cannot be used for CRS, MRC and PGMF workouts.
.. will adjust what is shown when resized to a small size
.. will hide toolbar whilst recording
.. getting ready to plot telemetry when recording so we
can replace the workout plot.
... double-click on "small chart" opens Window with full version (re-sizable)
... pictures stored as PNG (not JPG) any more (due to much better quality when showing full chart screenshot)
... add "common" feature for this and future CloudDB artifacts
... add Cache for Chart Headers
... add Language parameter for Chart publishing
... add Text and Language as Filter for Chart Selection
... provide Terms&Conditions acceptance Popup (first proposal of T&C)
... will need Native Speaker adjustments
... track T&C acceptance / rejection in properties
.. on import and export, using the "pwrright" element.
.. this is not part of the public PWX schema but has
been used by ipbike when writing PWX, and may or may
not be supported by TrainingPeaks.com
.. using the sustained interval algorithm we can now
find sections of a ride that are impossible to
complete according to the 2 parameter model.
.. only looks at durations > 2 mins.
.. this pastes a 'block' that has been copy/cut
but needs to be updated to work in an expected
way -- it pastes points, not blocks which leads
to situations that will confuse users.
.. one fix would be to be paste intelligently to
avoid duplicate points and "join" the pasted
blocks to the existing blocks.
... move Chart Import to Library/Sidebar (and remove from LTMTool)
... enhance Import Dialog / First Filter function - Curated
... introduce local Cache to not re-read all time
... read/display in chunks of 10 charts from GAE
... simplify find structure (in sync with CloudDB)
... no statusId, no explicite versioning
... Refactoring of File and Class Names to provide a common
structure for future CloudDB artifacts
.. to cut and copy the block selection to the clipboard.
this is very different to delete points since it will
shift the remaining points to fill the gap.
.. from a UX perspective the cut/copy/paste functions will
work with BLOCKS not POINTS. This may cause a bit of
confusion.... not sure how to deal with that.
This prevents channel searches from taking precedence over
established connections.
When the timeslots for searching and established channels
overlap, the search will blocked for that period instead
of the established channel.
This prevents data loss on the established channels at the
expense of potentially longer search time (only in the case
of channel collisions).
Moved the signal to stop the timer from AttemptTransition() to
Close(), as was not reliably reached.
Also disconnect the timer event slot on close, to avoid multiple
calls on subsequent sessions.
Fixes related to debugging..
Recognise TX events from the master channel (avoid dropping
through to default handler).
Parse the event messages correctly, was checking wrong byte.
.. just a simple indicator in the x-axis for now
when points are selected. may extend to the y-axis
as well.
.. lots more to come on smart guides but needs a lot
of thought and play time.
.. estimates should be sport specific (modality)
.. this is a hack to fixup cycling, but the whole estimate
code needs to be reworked as it isn't well thought through
and isn't well integrated into the rest of the code.
.. thanks to Jon Beverley for heads up and code fixes.
.. when you create a block (by pressing and holding the mouse
button) it now enters dragging mode (dragblock state) to allow
the user to move it around before releasing the mouse button
to create.
.. we DESPERATELY need guides to appear whilst dragging (!)
For Date Ranges and Intervals, only when activities are homogeneous
to select the correct Pace Zones
Also enabled Time in Power Zones only when activities are homogeneouse
to select the correct Power Zones
.. press and hold a mouse button to create a block
whilst in draw mode (or shifted in select mode).
.. will add a block in the middle or at the end of
the workout depending on where you click.
.. refactor as paint based approach was awful
from a utility and performance perspective.
Even though it was just a UX experiment it
bombed to CPU on Linux and Windows.
.. needs to have pointer in it !
.. we may need to do this in the eventFilter rather than
the paint event to stop repainting every time the cursor
moves and also to manage block selection etc.
.. the toolbar draw/select buttons now set the mode.
.. in select mode you can select points (same as holding
shift whilst in draw mode).
.. this is just to make the UX less complex for casual users.
.. when using a rectangle selection we clear all
the currently selected points. More often than
not this behaviour is preferred, we could add a
keyboard modifier in the future.
.. added a static fastSearch() function to the
RideFileCache class to perform a search on a
single series of data without any data prep.
.. its super quick and will work with the workout
editor recompute() function, but need to think
about how we can display the MMP curve as we
edit.
.. for now pressing SHIFT and CLICK will enable
selecting points.
shift-click when hovering on a point will toggle
selection of that point
shift-click in space will start a rectangle select
tool; as it drags it will select points within it.
hitting the ESC key will clear all selections.
.. the toolbar button "Select" needs to be integrated
into this scheme so users don't need to know about
the ability to select with the shift key (as we had
this before with intervals and it wasn't intuitive
to casual users).
.. resampling is the WRONG approach for the erg points
they need to be INTERPOLATED!
.. e.g. a ramp from 0w to 100w over 10 minutes was previously
resampled as 10 minutes of 0w followed by a jump to 100w
and thus W'bal was way off !!
.. we calculate for ourselves since its probably
quite expensive to calculate every metric.
.. could look to use the metric factory in the future
if we want to make these metrics more configurable
... Windows/MSVC QWT config creates 2 libs (release and debug)
... previous patch to support MSVC for this did not consider the different behaviour on other OS
so this is reverted and changed to be platform specific
... error/exception only visible when running in Debug Mode
... the destructor fo tooltip fires (via multiple step) and mouse even to AllPlot standard,
which at that point is already deleted - changing the sequence let's GC
end gracefully also in Debug Mode
... Assert error in MSVC-core library when running code compied with /MDd (debug mode)
... Solution - removed BUGFix code related to QTBUG-14831 (which worked fine until now)
... Tested under MSVC (Release && Debug) QT 5.6.0 and MinGW (Release) QT 5.4.2
.. we only have two commands; create and move point
but baking this in early so we can adopt it for
all other commands as they arrive.
.. due to the interactive nature of a graphical editor
the command class behaves differently to the one
used on the ride data editor; commands are added to
the stack when they complete (so move point isn't a
history of the mouse cursor moving its just the begin
and end point).
.. of point based editing, which is a bit difficult
without constraints like snap-to, guides, undo
or delete. But the basic concept is there to play
with.
.. of course it will still be possible to edit in a more
traditional 'blocks' and 'rectangles' way too but that
code hasn't been written yet.
.. compress and maths libs with win32 and gnu toolchain
.. WINKIT_INSTALL to specify where winkit is installed for MSVC toolchain
.. update gcconfig.pri to reflect this
.. initial code to display an ERG file for editing
.. this just introduces the basic model for rendering
the erg file and loading the model.
.. the interaction model using a 'points' editor will
follow next and then one to use 'blocks'.
.. There is a LONG way to go, this commit is just to
put a checkpoint down and test across platforms
.. most importantly start to remove any reference
to .lib or .a library files since these differ
depending upon toolchain.
.. instead we should use a combination of
LIBS += -Lfolder
LIBS += -llib
.. so for example
LIBS += ../qwt/lib/libqwt.a
becomes
LIBS += -L../qwt/lib -lqwt
and is now platform neutral.
.. this needs to be applied throughout to ensure
src.pro works for MSVC and GNU toolchains
.. it had become a bit of a mess with various changes
over the last 5 years so restructured into 3 sections
* core and platform config
* optional dependencies
* source and headers
This is to help make it easier to maintain, especially
since support for the MSVC toolchain is likely to mean
it is modified quite a bit (in section 2 anyway)
.. gets rid of an iritating compiler warning when
compiling with VS2015 and MSVC
.. is good because user metrics aren't fixed so the
assert assumption is wrong now
.. means we have to add assert.h to all the source
files that had it from including RideMetric.h
and want to use it.
... first set of syntax error fixes to compile GC using Visual Studio 2015
... changes are encapsulated and tested to not conflict with GCC compilation
Note: there is no full compatibility - so GC is not building with MSVC2015 yet
.. if you delete a user metric after adding it to the
interval metrics list the interval summary window
will crash.
.. the fix goes to source where the RideMetric::compute()
method now ignores metrics that are not known instead
of adding a NULL pointer to the results.
.. the DataFilterFunctions[] were not processed correctly
after validation of calls to named functions was added
and the correction applied previously only worked for
functions defined by the lexer/parser, not those defined
in DataFilterFunctions[]
.. this fixes that, but it would be nice if this was cleaned
up in to one unified place in the datafilter.
.. recent commit for Pmax on the PfPv plot introduced
a stray line of code settng cranklength incorrectly.
This results in the QA plot being blank and a warning
message from qDebug() about trying to read a cyclist
setting incorrectly.
.. logic error if/else for plotting rides vs dateranges
along with assumption that zones will not be NULL (esp
for running) lead to a repeated crash when running power zones
are not defined.
.. additionally, when summarising for a date range the table was
displayed for running vs cylcing based upon the current ride item.
This has been changed to use cycling power zones always.
.. the proper fix would be to summarize power time in zone for running
and cycling separately.
.. the compare logic appears to be unaware of power time in zone for
running and so does not have the same SEGV but will also need to
be updated to list time in zone for running and power separately.
.. it broke all the builtin functions !
.. we need to check for user functions after all the
builtins e.g. config(cp) was marked as inerror
when it should not have been.
.. User Metrics now integrated into the factory, ride cache
and of course rides and intervals. Which means you can define
a user metric and it will be computed and displayed like any
of the builtin metrics.
.. lots of technical changes to support this:
* DataFilter gets a runtime object to support multi-threading
and uses a context for construction only - item contexts are
used when evaluating an expression
* RideMetric factory can now remove user metrics
* The context in which the user modifies the user metrics will
notify all other contexts of the change ***
*** NOTE: STRONGLY RECOMMEND THAT YOU DO NOT HAVE MULTIPLE ATHLETES
OPEN WHEN DEVELOPING NEW METRICS SINCE IT WILL TRIGGER A
METRIC REFRESH FOR ALL OPEN ATHLETES.
ZonePage, CPPage and SchemePage changes to support separate editing
Zones and Settings to allow for separate GC_USE_CP_FOR_FTP
RideItem and Coggan metrics are running aware por power zones
Update of all metrics to work with a RideItem
not directly with a RideFile.
When iterating over the activity samples we now
use a Specification and RideFileIterator to bound
the set of samples used. This means that we can
compute metrics for intervals without having to
create a temporary ridefile.
RideItem now has first class members for zoneRange,
hrZoneRange and paceZoneRange to avoid calculating
for every metric which are stored in RideDB.json.
Compare pane continues to construct a ride file
when working with intervals since it is used lots
of charts, this is unlikely to ever change.
A SEGV in compare intervals has been fixed where
interval items were repointed to temporary compare
pane objects that are deleted - see RideItem::setFrom.
THIS COMMIT CONTAINS 3 REGRESSIONS:
1. TcxRideFile no longer computes metrics
2. FitlogRideFile no longer computes metrics
3. WorkoutWizard no longer computes metrics
-- The workout wizard will be replaced with a new
Workout editor, whilst the RideFile metrics
may be deprecated (but considering options)
.. useful for simplifying iteration over the ride
samples in the metric compute() method and possibly
elsewhere in the code
.. will iterate for rides and intervals.
.. the specification class is used for filtering
rides but now also supports filtering ride points
.. this is so we can refactor the metric code to
use a specification when computing metrics
.. the next update will include a refactor of
all the metric compute() functions to use this
new approach
.. datafilter uses a context that was used to create it
which is fine until it is used in user metrics which
are global and shared across multiple contexts.
.. so now when evaluating a ride item we use the context
for the rideitem being evaluated not the context of
the data filter performing the evaluation
.. next couple of commits will need to look at the way
we use RideItem and RideFile when computing both
Ride and Interval metrics.
.. User metrics can be created, deleted and edited
in the preferences pane.
.. A new dialog has been created to create user metrics
and will need to be updated after step 3 of this multi
part update completes the UserMetric code and integrates
it into the RideMetric factory.
.. User defined metrics where a user can define code
to compute a metric from ride data that can be used
in the same way as builtin metrics.
* Part 1 : Introduce User Metrics, Settings and XML config
* Part 2 : Introduce Dialog for User Metric CRUD in Preferences
* Part 3 : Integrate with Cache refresh and fingerprints
* Part 4 : Resolve dependency tree and related aspects
.. The user code will be via a DataFilter; this code has
already been updated to include variables, functions and
if/else/while constructs.
We now have named functions that can be called in the datafilter.
This is primarily to support user defined metrics where we will expect
the user to optionally define a bunch of functions we will call as
part of the ridemetric methods (see design mock up).
.. Datafilters can be defimed in three forms;
* a single line, typically as a filter
e.g. TSS > 100
* a block of code, typically as a formula
e.g. { val <- TSS; val > 100; }
* a program made up of functions, typically as a user metric
e.g. { pass { TSS>100; } main { pass(); } }
.. This example is functionally equivalent to "TSS>250":
{
pass {
# only filter rides with a high TSS
TSS > 250;
}
main {
# call our function to filter rides
pass();
}
}
.. Functions can only be defined within a block
.. Functions must be defined before use
.. A "main" function must be defined as an entry point
into the program if any functions are defined.
When the Diary checkbox is set for a metric
"Name: value" is added to Calendar Text.
The "Weight" field is special cased to "Athlete Weight" metric.
Calendar Text is no longer stored in json files, just cached
from Metadata Configuration, Tags and Metrics values.
Fixes#1563
.. Balsamiq mock.
.. note the use of "special" symbols in the code
to introduce blocks of code that will be called
at certain points, these will need to be aligned
to the RideMetric class but limited to those
attributes that are activity specific
isRelevantForRide()
initialize()
compute()
setValue()
setCount()
we may want to add other attributes like aggregate
zero and lowerisbetter to the dialog too.
.. NA equates to RideFile::NA when working with
samples or averages etc and wanting to check
.. RECINTSECS is only really available when working
with ride samples (e.g. in user metrics coming soon)
.. Added if else logic but could not avoid
needing the statement to be terminated with a
semi-colon (;)
.. so examples are:
if (TSS>100) TSS; else 0;
if (TSS>100) {
temp <- TSS;
temp;
} else {
temp <- BikeScore;
temp;
}
.. Doesn't add much beyond the existing conditional statement
using '?' and ':' but is a lot more readable (!)
.. start of transition to a full grammar, so now
we have statements and compound statements.
This update just differentiates between an expression
which is a conditional, logical or binary expression
versus a statement introducing a user symbol
.. You can now use compound statements in data filters
.. A compound statement is:
{ s1; } evaluates to s1
{ s1; s2; s3; .. sn; } evaluates to sn
.. It is possible to use the recently added user defined
symbols to build up processing logic:
{ temp <- TSS; temp > 100 }
is functionally equivalent to
TSS > 100
.. At present there are no control statements outside of
the ? and ?: operators but these will no doubt be added
in due course.
.. allow users to introduce their own symbols
into a datafilter with:
symbol <- expression
Which will initialise symbol and evaluate it
with the expression. The symbol can override
a metric name, but that would be rather dumb!
Number of data fields depends on sensor model
MoxySensor transmit SMO2 as cadance, tHB as speed,
BSX Insight 2 transmit only SMO2 as cadance, tHB is not supported.
So in case of BSXInsight we should not convert speed data. Let's allow
user to chose which datafields to transfer.
This patch add two new check buttons FixMoxy dialog
- Cadence to SMO2
- Speed to tHb
.. x ?: y
Evaluates to x if it is non-zero, otherwise it
evaluates to y. y is only evaluated once and only
if x is zero. Similarly, x is only evaluated once
and returned if it is non-zero.
.. it doesn't work and might be better to use a
secure ftp approach or similar.
.. need to fix this for the nightly development
builds planned for v4.0
[skip ci]
Major new features
Sync across PCs via Dropbox cloud storage
Sync via local folder, thumb drive, Google mounted drive etc
Added Daniels VDOT and T-Pace tools for Running
User Formulas
Restful API Web-Services for integration with R,Matlab,Orange,Tableau etc
Support FE-C trainer
Monark ERG Support
Support Stryd Power Meter for Running
BSX Insight 2 support
Ambit SML import support
RLV Support, playback to riding speed.
Video Overlays in Train View
SportsPlusHealth upload support
Backup and Autobackup
Better swim workout support incl. lap workouts
SrmRideFile: v9 support (SRM PC8)
Add new language support: Chinese(Traditional)
GPL v3 License
Severe Bugs Fixed
Fix 3DP file import 'hang'
Joule GPS+ import issues
Checkbox metadata fields not saved, ^S save errors
Fix GPU battery drain on Mac OSX
Fix HR > 8 Zone Crash
Fix 'Fix Elevation' SEGV
Fix Interval Search SEGV on High Power
DataProcessor 'Auto' runs on import only
Fix Memory Exhaustion on Mass Import/Sync
Fix SEGV when sharing activity on Strava with no internet
Fix IntervalNavigator SEGV
Fix SEGV LTM Edit
Minor new features
TrainSidebar: Delete multiple workouts
Configure CP and FTP separately
FixSmO2: Add a tool to remove anomalies in SmO2 data
Recognise more Garmin devices based on FIT SDK
Fix Freewheeling Tool
Added W'bal Work In Zone Metrics
Add W'bal Zones - Time above CP
Added Autoimport Stealth/Background Mode
TrainMode - Use Multimedia Keys
Fix Speed from Distance tool
Delete Athlete now supported
Settings stored in athlete folder config directory
Bugfix merge of hrm and gpx
Mass update metadata with set, isset and unset commands
Add a Derive Distance tool (from GPS position)
Read R-R data from polar hrm files
Add User parameters for Bike Weight and CRR to Power Estimation Tool
Multiple fixups for DataFilter expressions and precedence logic
LTM Filter for a curve
Rename Route
.. updated COPYING file
.. We are GPL v3 to enable mixing with other licenses that
become important due to the libraries we optionally link
with that are already v3 or BSD/Apache/MIT; e.g. libsamplerate,
libkml or use LGPL; e.g. libvlc
.. The intention of upgrading this license is to enable GC
code to be shared more widely and used in other contexts
without the restrictions that were present in v2 of the GPL.
.. the resampling code caused issues (not 100% sure why) so
reimplemented using the resampling method from Txt file
processing (also for Computrainers).
.. we know that approach is accurate since it accumulates
work and resamples to 1s intervals precisely.
.. two regression impacts; we no longer import the virtual
altitude and sample rate is 1s not 250ms.
Samples of swimming type are used to update distance and speed
of periodic samples, cadence is computed counting Stroke events.
Includes test file contributed by Serban Mestecaneanu
... caused error in list-model since entries are added and "end-of" dbtable
... now only update of texts in upgrade to handle pre 3.3 translation problems
.. for future use, we create a QUUID when the athlete is
created and it is used for ever after that point.
.. it will be used to share data with the open data initiative
to ensure activities can be collected for a single athlete
without revealing any personal identifiable information.
Sport is now recognized as swimming and Pool length extracted from session message
There still remain lap alignment issues in some files from Garmin Swim and 920xt
..Support a user defined MapQuest API key in gcconfig.pri
.. Use exceptions to trap Bad Request and API errors and
stop processing early.
.. Delete the networkMgr object to prevent a file descriptor leak
which can cause GC to crash when fix-elevation is configured
for auto-processing on import of files and there are many files
being imported.
The ANT_TE_AND_PS_POWER events are directly related to
either the ANT_STANDARD_POWER or ANT_CRANKTORQUE_POWER events
(whichever is sooner). The eventCount of TE_AND_PS will match
the eventCount of either of those events to be considered valid.
This change is required for Garmin Vector pedals which deliver
a sequence of ANT_STANDARD_POWER events, interleaved with
ANT_CRANKTORQUE_POWER events and occasional ANT_TE_AND_PS_POWER
events. Without the change, the user will experience very frequent
power drop-outs (0W readings). With the change, the power readings
are smooth and consistent.
It generates both record and length messages for
each length, we use length messages to recognize
lap swimming and filter out record messages.
Includes test file contributed by Jonathan Beverley
.. when building on Debian there is no package for
KQOauth, so as a temporary measure we're pulling it
into the repo to support packaging.
.. as soon as a KQOauth package is made available we
will remove it from our repo
.. It seems like a good idea to provide a default value,
or you could just add a different #else case, e.g.,
.arg("no GC_VIDEO_ value provided"), or fail compilation.
.. usage: python gh-downloads.py GoldenCheetah GoldenCheetah <tag>
will fetch the binary downloads stats for the release with
the specified tag (e.g. v3.2)
.. it is a clone from: https://github.com/kefir500/ghstats
This reverts commit 2f9d74d759.
Will come back and look again at QT5.5 with QT7 but for
now lets just stick with the method that works (albeit the
binary created doesn't work!)
If a trainer does not advertise simulation support, it could be
put into power mode, with GC calcuating the required load from
current speed/gradient etc.
setChannelID() could be called with a null device_id. This may
result in pairing with an unexpected channel type if more than
one channel is available from that device_number.
.. don't want qt4 any more
.. qwtplot3d fails to build on QT 5.5, we may need to think about
either pulling it into the repo and patching, or just deprecating
it altogether.
.. for ANT+ CTF devices that are incorrectly recorded such
that Cadence/Power are repeated 3 times when the rider
starts to freewheel.
This was a common issue with Garmin firmware and is now
happening with SRM PC8 bike computers -- so added a tool
to fix it.
.. fixes a SEGV in ride summary window where only 8
HR Zones are supported, but historically the number that
can be configured in preferences was changed to 10.
.. the 10 limit was probably a cut and paste error but it
is out there now, so we need to support 10 zones.
.. all the other zone configurations are set to a max
of 10 zones anyway.
.. when freewheeling some headunits record the repeated
power/cadence values rather than resetting them.
.. the ANT spec for CTF power devices says that these
should be reset after 3 seconds on the display -- but
crucially they should also not be recorded in the file.
.. we should also add a 'fix tool' to find and fix these issues.
.. added an environment variable TESTVAR to see if
it can be made available during the build. Will
remove this once it is working in order to add
the API keys for twitter, dropbox etc
.. doesn't honour font sizes (long story but too complicated
to unpick all the fugly code in QtMacButton.mm)
.. but at least the chartbar is tall enough for the "standard"
size on OS X
.. and resizes as the font gets bigger so you can
at least adjust when running on a high resolution
display.
.. still need to do ScopeBar and SidebarItem too
.. videosync table version stored in TrainDB (was missing before)
.. upgrade to 3.3 fixes default entries for Workouts (e.g. due to wrong translation with missing " " in text - German)
... new Feature to Autoimport without Dialog (with same timeframe option like the Dialog version)
... in case "Dates/Time" is missing - the Dialog Window appears and waits for input -
if entered and "Save" presses no further input action is required
... malformed activity files are silently ignored
... to avoid inconsistencies closing of the Athlete for which Background Import is running
is blocked until the Import is finalized (Info on import complete is sent to UI)
.. UI is not blocked by Autoimport - but a bit less reactive as long as the import is executed
.. check for NULL.
.. this is odd, some behaviour upstream has changed
and needs to be investigated as this bug is too
significant to have only just been found.
... fix problems when dates are converted back/forth with fromString/toString to avoid Locale related mismatches
... use ISO 8601 format (YYYY-MM-DD) in such cases (Qt::ISODate)
... applied to "RideImport" and "ComparePane"
... does not recognize that Interval was added and may loose the intervals on saving
... causing inconsistency in Cache - blocking the deletion of the interval after re-starting
... add Multimedia Keys to control the train mode
... Start/Stop/Forward/Rewind/Pause working on MCE (Windows Media Center compatible remote controls) without any problems
... tested with 2 MCE remotes
... For "new Lap" none of the special media keys worked - so choose "0" since this is available even on pure remotes
Since in earlier versions of QT not all Keys are defined, just start with 5.4 as pre-requisite.
... store Videosync files in Workout Folder as well / adjust configuration description
... report non-existing Workouts/Videosyncs when scrolling through the treelist (and offer to remove them from the library)
... properly handle "imports" of files from the Workout Directory in case of "overwrite"
... add tr() in multiple places
... unify some of the texts - terminology
... add Directory to Configuration Page
... set Default similar to Workout Directory in Main
General
... start Directory Browsing on Config Page with the configured directory (if is existing/valid)
... collects all relevant Files from the Athletes directory subfolders (keeps the folder structure)
and add them to a .zip file which can be stored in a different folder
... runs automatically when closing an Athlete (window or tab)
... configurable per Athlete
-- Folder into which the .zip shall be stored
-- #of times GC shall close without backup before the backup is activated
(0 == no Auto Backup, every other number "x" means that GC closes
x-1 times without running the backup and after running, resets
the counter)
.. caused v3.2 to crash on interval discovery and
contains out of bound values for power, speed and
cadence.
.. good for testing code doesn't make assumptions about
data values.
.. thanks to Neil Jones for the test file and permission
to distribute for testing
... UTF-8 ByteOrderMarks was missing in the exported XML,... files causing problems on Windows e.g. in cyrillic
... BOM header added for PWX, Fitlog, GC and TCX format
... Fixes https://github.com/GoldenCheetah/GoldenCheetah/issues/1547
.. RideCache::addRide() deletes the prior ride, which is rather meaningless
if you are just importing a ride, but when syncing large numbers
of rides will stop memory being exhausted.
.. similarly in the FileStoreSyncDialog we now free up the memory
used to read the downloaded files before moving on to the next.
.. so we can read/write zip files that can be opened
outside of GC. For example, when working with a file
store we want to write .json.zip that could be read
using winzip et al
.. layout on athlete About row missed leaving a
gap between widgets vertically.
.. moved use CP for FTP checkbox to zone config page
and not on athlete About page.
... use an shared network drive (e.g. mounted via WebDAV) to synchronize activity data
(similar to Dropbox,...)
Open/TBD:
... where to best put the Preferences for the different FileStores
(currently add the Network folder configuration on Preferences->Passwords,
even though no PW is needed - with growing number of FileStores a
dedicated Preferences Page may be the solution)
... where to put the MainWindow Menu entries if the number of FileStores increases
.. Mac Finder creates .DS_Store in subdirectories when you
browse in them to store customisation etc. So we need to
wipe them away when deleting the athlete folders.
.. sync with a dropbox folder
This is based upon the TPDownloadDialog but refactored for
use with a FileStore (in this case Dropbox). It should be
extensible to use with any kind of FileStore object.
... first Athlete opened with new logic determines the general settings
... if configuration is already migrated (based on one of the previous commits) -
migration can be forced to happen again by removing the INI files or
just the preferences pages has to be opened and Saved with the
unit settings you want
.. basic functions working to upload a single ride
to a dropbox file store.
.. this is a safety commit before looking to resolve
issues with async updates.
NOTE: the upload completes but the dialog needs to
be cancelled manually -- this is a bug and
will be resolved in the next update.
.. so you can now choose the directory to sync
data with. Its a very basic file dialog but
will allow you to create and choose a folder.
.. Config is now completed with token a folders
now configurable by the user.
.. I cannot believe we needed to write a pesky file
chooser dialog in 2015 (!)
.. first parts of the implementation of a base class
for working with file stores and the Dropbox
API.
.. all we actually get in this commit is the abstract
classes and an implementation of readdir for Dropbox
along with a config setting which needs to browse
directories
.. in the next commit we'll add the directory chooser
dialog which will need to implement a ftw() across the
associated filestore and present a gui to choose a
directory to store athlete data in
... select only files for import which are created or changed of the last 90/180/360 days
... thus limiting the number of files which are considered for import in the source directory
(without changing/deleting the source files - and without the need to track indexes,...
of what has already been imported).
Based on TCX/GPX support
Includes laps and no-gps support for indoor activities, but not lap swimming.
Test files were contributed by forum members Frederic and Servan
Fixes#1559
... change storage format to .INI files (which is QTs cross-system format)
... differentiate between System, Global and Athlete specific settings
... store the Global Settings in the AthleteDirectory (root)
... store the Athlete specific Settings in the Athletes Names subdir /config
... migrate existing Settings from current location into new formats "on-the-fly"
.. by default no metadata is provided when you
get a ride list. So we now let you specify
via a parameter what metadata fields you
want.
e.g.
http://localhost:12021/athlete?metadata=allhttp://localhost:12021/athlete?metadata=Workout_Code,Recording_Interval
Metric overrides are ignored and all data is
fixed to never send a double quote ("), it is
converted to a single quote (') to avoid tripping
up CSV parsers.
To show it is a string field both the heading and
content are always surrounded by double quotes.
.. now we are able to manage settings with the response
to control how the response is built we don't need to
store it in the JSONContext structure - so just cleaning
it up.
.. to list rides without metrics and therefore just
traverse the activity directory and parse date from
the filename.
.. for a quick way to get a list of activities without
anything to plot etc.
.. adds overlay widgets to show telemetry on top
of video as you ride with a customisable view.
.. not tested but pulled into the repo to enable
testing to start with a view to inclusion in
the 3.3 release.
.. just the key parameters, not the zones themselves.
although we could add that possibly.
URL to get zone config:
http://localhost:12021/athlete/zones
By default will return power zones but can be
called with a 'for' parameter, which is one of;
power, hr, pace, swimpace.
The result is returned as csv data.
.. if the caller sets a content type we can provide in the
header of the http request then we honour it; e.g.
Accept: "text/csv" we will convert to CSV.
.. also updated to set the content type to match the file
format we are providing; just in case the client needs to
know what it got !
.. when retreiving an activity using the API
you can now specify the format you want the
data to be returned in.
it can be one of;
tcx - garmin training centre xml
pwx - training peaks xml
json - goldencheetah json
csv - all available data (not powertap csv)
.. along the way the file writers for the respective
formats now accept a NULL context to work standalone.
this may be useful as a file conversion tool.
.. just straight up for now, so;
http://localhost:12021/athlete/activity/2015_08_09_10_59_09.json
will just return the ride unchanged in the format
it is stored in. Some parameters will now be added
to enable the format to be selected, from those that
we can support.
.. To restrict to more recent rides the
API for list rides will now take a
parameter 'since'
localhost:12021/athlete/?since=2015/02/01
Will only list rides since 1st February 2015
and can of course be used alongside 'metrics'
to control what metrics are returned.
localhost:12021/athlete/?since=2015/02/01&metrics=NP
.. when getting the ride list its useful to be
able to get specific metrics (rather than all
260 odd).
URL can have parameter metrics that is a comma
separated list of metrics to provide e.g;
localhost:12021/athlete/?metrics=NP,Average_Power
.. will provide the metric db for an athlete as the
activity list including all metrics in CSV format
at the URL:
http://localhost:12021/Athlete Name/
The data is sent in chunks as it is parsed from the
ride cache. We do not cache or maintain state so this
call is expensive !
.. just 4 endpoints available;
- list athletes
- list rides
- get ride sample data
- get ride mmp data
.. next few commits will need to implement each of the 4
API endpoints, returning CSV data in the response.
.. GoldenCheetah --server [dir]
Will run without a GUI as a console application sending
log messages to stdout. A web server is never started
when in normal GUI mode.
The optional 'dir' parameter can be used to specify the
location of the athlete data -- you could run several
servers on different directories since the config for the
server is located in the root of the directory.
.. added the http listener, with a default handler
that just returns a 501 Not Implemented result.
.. now the basic server is available we can start to
add a request handler and build up an API that can
be called externally when GC is running.
.. the default config file is written to the gc home
directory above the athlete directories and sets the
server port to 12021.
.. 12021 was chosen as a memorable port number that does
not seem to be used by any other application that is
popular or well known.
.. see http://stefanfrings.de/qtwebapp/index-en.html
.. this is a lightweight web server to allow GC to
provide webservices.
.. we will be providing web services on localhost to
enable R integration.
.. we will use web services to standardise the
interface to provide something we can use in R
but also anything else at a later date.
.. gcconfig.pri contains $$HTPATH that points to
the location of the code, if it is not set then
the web server is not compiled in.
.. allow users to use a set command to add
an override or set metadata under certain
conditions.
e.g. set(Workout_Code, "HT", IF>0.9)
set(TSS, 65, TSS <= 0 && Route = "Fave Loop")
.. we should probably add an unset() command
to do the reverse and clear values under
conditions too.
USE WITH CAUTION -- TAKE A BACKUP BEFORE
MAKING ANY RADICAL CHANGES TO YOUR DATA
.. compare mode now works with user data
series on AllPlot.
.. probably a few minor nits to clean up
and maybe some refinements will come.
One thing is for sure, AllPlot and AllPlotWindow
have reached the limit of maintainability and we
should think carefully about how they move forward.
.. user curves now appear on the series and all plot
with axis hiding etc
Next commit will add to compare mode and then we
can start cleaning up the nits and refining how it
chooses axes and have a checkbox to hide and show
.. Edit dialogs and integration into AllPlotWindow
NOTE: AllPlot does not use the config, or even save
it to the property at this point. We just have
mostly reusable code for user maintenance of
formulas for ride series data.
.. passed to eval and symbols now recongised.
.. sample data is referenced using symbol names
in all caps to make it clear you are referencing
ride dample data.
.. the next commits will add defining formulas and plotting
the derived data series in allplot.
Tie HR warnings to Max-HR, if available, instead of hard-coded 200bpm
Speed warning changes to 9kph for swims, 36 for runs and 100 for rides
Cadence warning changes to 80 for swims, 120 for runs and 200 for rides
"Non-zero torque but zero cadence" is disabled for runs and swims
Fixes#1483
.. To select in a vector. The notation
is a selection criteria followed by
a list of values / vectors
e.g. which(x>0, TSS[date:date])
will create a vector where TSS is non
zero for the day.
"x" is replaced with the vector values
and as such is a special symbol.
.. also fixed a bug with the snip cache.
.. when running a formula it may use a vector
operation to calculate e.g. an average for the
date range.
.. these get called for every ride, but actually they
perform the same calculation over and over
.. we cache the vector operation and result to avoid
repeated calculations; these are only cached whilst
a datafilter is being evaluated, so we do not need
to worry about stale/refreshing.
.. estimate(model, duration) or to get the model
parameters estimate(model, parameter) always
for the date of the ride.
e.g. estimate(2p, cp) gets the estimated CP
for the date of the ride using the classic
2 parameter model
Models are one of;
2p - classic monod scherrer
3p - morton 3p
ext - gc extended
ws - ward-smith
velo - veloclinic
Parameters are one of;
w' - W'
cp - critical power
ftp - functional threshold power
pmax - max power
For watts per kilo just add / config(weight)
or Athlete_Weight to take into account ride
specific weight settings / overrides.
.. can now use a formula in the lts, sts
sb, rr functions.
.. e.g lts(TSS/2) evaluates to the "CTL"
value for the ride if using TSS/2 as
the input.
NOTE: you only get a value where a ride
exists. We may want to think about the
way we scope formulas; are they iterating
over rides or dates ?
.. slight fixup to use Leaf expression not the
entire data filter in PMCData and now the
series is stored in the Athlete PMC store
alongside the other series.
.. just need to adjust the parser to accept
expr rather than symbols as inputs to the
lts functions.
.. to use when e.g. using a data filter as an input
into the PMC functions. The data series is stored
against a signature for the function as opposed to
the metric symbol.
.. we need to do it for an expr not the data filter
.. add the computation of PMC stress using a
data filter as an input as opposed to a
metric.
.. part 2 will update the parser to support
sts/lts/rr/sb to use an expression.
.. part 3 will update Athlete to enable
storing PMCdata against the datafilter signature
instead of a metric name.
.. to use when e.g. using a data filter as an input
into the PMC functions. The data series is stored
against a signature for the function as opposed to
the metric symbol.
.. but do continue to highlight bad symbols etc
with a red wavy line.
.. still need to;
a) syntax highlight in the formula edit (just symbols
and literals, not parsing content)
b) add an error navigator to click on errors and have the
text highlighted that incurred that error.
Adding a comparison expression cexpr and separate productions
for each operator allows to define precedence rules to remove
all shift-reduce conflicts, except one due to the -probably
harmless- (expr) and (lexpr) ambiguity.
.. the daterange() commit broke almost every builtin
function ! (it converted them to integers due to
and if/else logic error.
.. also tidied parser to separate literals and symbols
whilst making builtin functions expr elements to
look more closely at precedence
.. oopsie on binary expression.
NOTE: it may be better to highlight tokens rather than
via the parser as errors make it impossible to
highlight the "intention" of the user
Particularly useful when working with a vector
but can be used with other things.
e.g. max(xPower, BikeScore)
Or, for getting a ride's TSS expressed as a percentage
of the average TSS for the currently selected daterange.
e.g. TSS / mean(TSS[daterange(start):daterange(stop)])
You can create a vector using the notation:
expr [ from : to ]
Where 'expr' will be evaluated for every activity
between the dates from and to.
e.g. TSS[today - 90 : today]
will evaluate to TSS for the last 90 days
e.g. Activities [ date:date ] > 1
Will find all days with more than one workout.
.. when using a vector in any arithmetic expression it
will be evaluated to a sum; this will be fixed shortly
to enable the use of sum/mean/max/min functions.
.. If needed we can add vector operations but this will
likely confuse many users (hell, they confuse developers)
so we will need a good reason to add them !
Lastly, I have also added daterange(from) and daterange(to)
literals to get access to the currently selected daterange
when working in the trends view.
.. update the editor to do some basic syntax
highlighting; literals in red, comments in
blue and so on.
.. next commit will focus on highlighting errors
with a wavy line and some form of error list.
.. updated the datafilter to handle general functions
and parse them without needing them declared in the lexer
.. makes it much easier to add new functions in the future
.. did this to add core math functions;
* sin, cos, tan, asin, acos, atan,
* sinh, cosh, tanh, asinh, acosh, atanh
* exp, log, log10, ceil, floor, round
* fabs, isinf, isnan
.. we can add more later; erf/gamma spring to mind !
.. uses the C/C++ notation:
expr ? expr2 : expr3
Where expr is the condition e.g. X>2
and expr2 is what to evaluate to if expr is true
and expr3 is what to evaluate to if expr is false
e.g.
(Workout_Code = "1L3") ? 1 : 0
Will evaluate as 1 for all workouts where the
workout code is 1L3 and 0 for all other workouts.
.. now will repeat completion beyond the very
first word on the line
.. needs to be enhanced to work when not at the
end of the text (i.e. cursor move)
.. resize event was checking menu icon, which was never
going to change due to a resize event.
.. it crashed during window exit since it dereferenced objects
that had been deleted.
.. for now, it crashes occasionally due to cross-thread
issues, and doesn't work across the text anyway.
will make it permanently associated by not active
when in search mode.
.. get rid of terrible cut and paste code, duplicating
eval for particular leafs
.. eval returns a Result() object which can be numeric
or textual (date strings are parsed to numeric)
.. can now add formulas to LTM as well as adding more
functions that may be useful (conditionals, maths
spring to mind first).
... removing tests,... from LIBKML build
... allowing building of base functionality of LIBKML on Windows with MinGW
... covering the LIBKML functional scope used by GoldenCheetah
.. NP > 200 && IF > 0.85 didn't work because the datafilter
grammar needed fixing up for precedence of the && and || operators.
.. this has been fixed by embedding into the grammar; binary expressions
and logical expressions are now declared individually.
.. the generated tree uses the same encoding so no changes required
to the code, just the grammar
Imported data:
- speed, cadence, hearthrate, power, latitude, longitude, altitude, temperature.
Laps are not yet supported. (laps in Rox 10.0 slf are encoded at the end of the file as <Markers>).
In case user borked them in setup, applies to:
- Ride Date (startTime.date)
- Ride Time (startTime.time)
- Device (deviceType)
- Recording Interval (recIntSecs)
- Identifier (Id)
Since latest update for metadata now honours user configuration.
.. change LTM trend background to same as ride plot on upgrade
as by default it will be black and look different
.. remove metal look on anything other than Mac prior to the
10.10 Yosemite look. Metal looks naff these days.
.. we have been granted permission to use the TCore algorithm
and so the attributions have been added to the code and about
box.
.. Mark Buller should be added to the contributors too.
Added RPE to metadata.xml to allow data entry in the Workout tab and
PMC (Session RPE) to charts.xml
Added Equipment to Workout tab
Added GOVSS and SwimScore to Metric tab, to allow metric override
.. move use sidebar settings to basic page and
disable the other pages if its using sidebar
settings
.. when working in the sidebar, hide the basic
page since it is not shared
.. make the add chart dialog bigger if the screen
is large enough, since it needs to show a chart
and the config pane which has grown a little
over time.
.. remove all the editing/import/export functions
from the chart settings now they have their own
sidebar.
.. this also removes some of the problems with conflicts
and bugs in the code e.g. setting the first chart name
to "" by accident in the editingFinished() method (since
that is no longer supported !)
.. if you drag a chart in the LTM chart sidebar to beyond the
end of the list the move results in a QList assert abort.
.. this small fix checks for -1 and adjusts accordingly.
.. import/export charts
.. drag/drop them in the list to reorder
.. drop a 'charts.xml' (any .xml) file onto the mainwindow
to import charts exported by someone else.
.. when resetting the layouts we first go try the default
layouts from the goldencheetah website
http://www.goldencheetah.org/defaults/<release>/xxx-layout.xml
.. this means we can update the default setup independently of
the release binary; make tweaks etc
.. the same concept will shortly be introduced for resetting the
standard charts.xml presets for the trend view
.. if you select e.g. the TriScore PMC in the Library chart
in Trends, the high/low curves get left behind because they
use the same name (Best_xxx).
.. ironically this was already worked around by creating a name
that included the symbol, but this was not used when adding to
the curve mapping.
... ensures that Month is changed to month of current ride (which fixes the missing color)
... tested also for new Athlete creation (without any Ride data)
Note: Root cause may be a sequence issue of setting the calendar month, setting the ride, setting to current ride.
So there might be a better way to fix the problem.
... fill "units" field with original "units" from Metrics if new Chart is created
... store original "unit" into LTMSettings for later reference in automatic translation
... use a new version of LTMSettings to be compatible with any written version
- Code cleanup, removing deprecated code and refactoring
- Metrics translation is now done in a method for LTMSettings
- User defined metric name (uname) is translated if it matches english name
- User defined units (uunit) is only translated if it matches saved units
.. saves time, since translation not required
.. also avoids messing up the uunits when charts are customised
to have common y-axis e.g. Stress Ae and An Stress and PMC
using Stress instead of ATL, CTL, TSB etc
.. using the Holt-Winters double exponential smoothing to avoid
low on rising and high on falling data series.
.. works best with relatively noisy and contiguous data
.. added as they are handy for quick compare of changes
in the near term, without having to add temporary
date ranges
.. we should think about an "easy" way to do this for all
years and months for quick comparisons, in v4.0
.. fixes 80% of the issues with sorting 'strings'
.. we cannot just return metric values since they
need to be formatted to have the righ precision
or conversion to pace/duration etc.
.. was skipping 2p and 3p saves because it was agressively
checking W', FTP and Pmax when they didn't apply or
for values that were possibly correct (e.g. W'/kg > 100)
.. no need to pass across weight since we maintain two
models; absolute and per kg already.
NOTE: this has highlighted a bug in the code related to
estimated w/kg bests for 2 and 3 parameter models
that will be fixed shortly.
.. to augment the existing vo2max estimate using peak 5m
data in a ridefile, this now adds it as an estimate from
the PD model estimate for 5m peak power.
Implements #1432 as an option for Edit Interval, the user must
enable it via checkbox and confirm before it modifies speed and
distance for the underlying samples.
.. to speed up extracting the mean maximals.
.. we still work at 1s intervals for very short durations
but gradually increase to longer as the duration gets
over an hour.
.. for almost all usage this will not make a difference to the
values extracted since the actual values are largely rounded
to integer values (and therefore the granularity was already
being disposed after the search).
.. the exact durations are;
Duration Increment
<120 1
<600 2
<1200 5
<3600 20
<7200 120
>= 7200 300
This reverts commit 7fdedf0bfe.
.. we will come back to look at multisport FIT files in v4.0
The main problem is related to the position of the SESSION
header within the file.
.. fit file manu:76 identified as Moxy
.. support 7 field CSV, ignore session number
NOTE: support for UTC dates is not present since we
have no way of checking what TZ the ride was
recorded in !
.. show the An / Ae stress to provide context to the
changes in peak power durations.
.. or "why my anaerobic power isn't getting any better
despite spending all my time doing sweetspot"
.. since interval discovery impacts load time (reading from backing
store) and refresh time (computing metrics for intervals) we do
not search for PEAK power/pace by default.
.. if the user wants that info (which is of limited value) then they
can switch it on in preferences/options.
.. should help to reduce performance overhead for startup and refresh
especially as an experience immediately after upgrading to v3.2
.. lots of scenarios to cause the SEGV but all related
to the CurveColors::save/restore state functions that
cast QwtPlotIntervalCurves to the wrong type and BOOM!
.. thanks to Simon Brewer for the ride file that had this data.
.. select which kind of intervals we want
.. makes it faster and also reduces the size of
the rideDB.json file quite dramatically which
may be useful for some users.
.. if you filter the ride list the reset will search for
a heading "Calendar_Text" that will not exist since it
is prettified to "Calendar Text" in the constructor.
.. seems redundant, but at least reflect the type() of
metric when deciding; if the metric is defined as
being of type RideMetric::Low then return true
otherwise false.
.. the metric can override this method if needed if
is is still only an average (e.g. weight ?)
.. New derived data series representing an estimate of core temperature
on the basis of HR changes.
* shown on AllPlot and RideSummary
* 2 new metrics; max and avg core temperature
.. This has been based upon "Estimation of human core temperature from
sequential heart rate observations" Mark J Buller, William J Tharion,
Samuel N Cheuvront, Scott J Montain, Robert W Kenefick, John
Castellani, William A Latzka, Warren S Roberts, Mark Richter,
Odest Chadwicke Jenkins and Reed W Hoyt. (2013). Physiological
Measurement. IOP Publishing 34 (2013) 781–798.
.. all features now complete, bar a couple of minor
pending changes.
.. upgrade process feature complete, bar some minor
cosmetic nits for colors/metadata
.. time to validate the code changes since February
with the user community and freeze new features
.. add W'bal Zoned to Histogram
- for a ride
- for a date range
- *NOT* for a compared ride
- for a compared date range
This makes the last of the updates for W'bal
in zone, but highlights the issues related to
W'bal being held in a different structure to
the rest of the ride data.
Need to think on how that might work better
for intervals.
.. add W'bal Zoned to Histogram
- for a ride
- for a date range
- for a compared ride
- for a compared date range
.. still need to update ridesummary to show
summary of w'bal zone distribution (3c)
.. add W'bal distribution to Histogram
- for a ride
- for a date range
- for a compared ride
- for a compared date range
.. still need to revisit to do in zones (3b)
.. still need to update ridesummary to show
summary of w'bal zone distribution (3c)
In activities it depends on selected activity, bests are automatically filtered.
In range mode it can be set by sidebar or home filters for single sport
.. based upon Fiet-type formula elevation^2 / distance.
From an idea on Dan Conelly's blog.
Some examples:
Mt Ventoux - 121
Alpe d'Huez climb - 83
Galibier - 81
Glandon - 66
.. so it's not perfect, but gives a good sense of hard
versus easy !
For multi-sport files, the bike section might record vertical oscillation or
ground contact time from the HRM-RUN sensor when moving in and out of
transition.
For single ride use sport specific base metric
For date range use sport specific base metric if filtered activity
list is homogeneous or combined otherwise.
.. pops up a dialog to ask if you want to just add this
segment (the default) or add all intervals on this
segment for a season (you can select a season).
... exception "Truncated" for the "final" read call of the FIT file
reader was not catched, causing termination of the program (problem
reported with an example file being truncated at the end)
Multisport FIT files are imported as separate activities, one for each session
in the file.
The internal storage format for multisport files was also changed form TCX to
JSON, as the TCX file would not store advanced metrics, like the left-right
balance from the Garmin Vector power meter.
.. the lazy delete was a horrible hack and memory leak.
So, now the paint delegate no longer dereferences the
IntervalItem * from the QTreeWidgetItem.
Instead we use setData for UserRole+1 to store the interval
color when constructing the trees. The paint function can
get this directly and we avoid any contention when the
intervals are deleted and created.
The lazy delete can be removed and deleted once the changes
have been notified via intervalsUpdate().
.. since they are deleted in threads and affect the gui
.. to avoid the overhead of cross-thread mutex we just
delete intervals lazily; each time we refresh them
the last lot are wiped away.
.. SEGV on setting CP when no zones configured. Since
RideItem::updateIntervals() dereferenced a range
when CP is set, but none existed.
.. fixup use of Metadata field "W'" to override settings
in Metrics tab.
.. with a sidebar indicator
.. we may need to change when we have planned workouts
as the intervals will need to match the plan.
.. but we can use the same concept of 'quality' when
comparing a full activity with what was planned.
.. to indicate how far into the zone we got, so
3.1 is 10% into zone 3, whilst 7.9 is seriously
high Neuromuscular power, but below Pmax
.. we use Pmax to bound the upper value when calculating
how deep we got into the very upper zone; so it is
possible for the metric to be 8.x when only 7 zones
are defined (when the power value is > Pmax)
.. in stack mode always start from min W'bal or 0, whichever
is smaller. This makes it easier to identify when W'bal
is (or is not) being consumed across rides.
.. when looking at a ride and working with intervals it
is sometimes useful to look at the rest of the ride
exluding the intervals selected.
.. we now show the metrics for the intervals selected,
followed by for each interval then lastly for the
rest of the activity i.e. excluding the intervals
selected.
.. we now filter sustained efforts by zone rather than picking
the very best non-overlapping effort.
.. this means that a L7 sprint mid way through a L4 climb within
a L3 ride will find find 3 sustained intervals rather than just
the sprint.
.. just place TTE, EFFORTS and SPRINTS under
the EFFORTS interval type.
.. this is getting ready for handling overlapping
efforts rather than just the very best.
.. when the URL for the webservice is created it places
a slash between the host info from preferences and the
service path:
http://wbsapi.withings.net/measure?action=getmeas ..
By default, the withings server configuration has a
trailing slash, which results in a URL of the form:
http://wbsapi.withings.net//measure?action=getmeas ..
The double slash here ----^^ used to be accepted by
the Withings servers but more recently it is rejected
so this patch removes any trailing slash before
constructing the full path.
.. Route segments are found during interval refresh
.. Config/routes.xml only holds config now
.. The fingerprint for a rideitem includes the route
fingerprint now so it will refresh automatically
when the routes config changes
.. if no routes are defined then no work is done, so the
amount of work is really defined by the user
NOTE: RouteWindow, and now, RouteItem will need to
be reworked and fixed up for v4.0
.. it optimises out setRide when it is the same ride as currently
being plotted, but the intervals will have changed since they
were reloaded
.. so we always notify of intervals changed after intervalsUpdate()
just in case other charts skip refresh when the selected ride is
the same as the one they are already showing
.. by introducing a specific signal to trigger it.
.. its very specific, but its more flexible (and a lot less
work) than adopting a model for the QTreeView that would
be a better 'architecture'.
Rebuilds the interval tree when a ride is saved and
refreshes intervals as a result.
There are a number of other scenarios that will also
need to call a sidebar refresh as a result of the
intervals being updated.
* edit ride data
* change metadata
There may be others lurking. This needs a review of
the code pathways leading to RideItem::updateIntervals()
and how we keep the sidebar in sync.
.. the integrated joules and resampling to 1sec code
was not taking into account the first sample is 0 seconds
and was incrementing 1 sample early too.
As a result the integrated series was 2seconds ahead of the
recorded data, meaning the discovered efforts and sprints
would have a start time 2 seconds ahead of where they
should have been.
.. so we can keep a reference to the user interval
in a ridefile from the rideitem and not worry about
trying to match or handle index offsets into the array
.. this is required to fixup the relationship between
an IntervalItem and a RideFileInterval in RideItem
and RideFile respectively.
.. anything over 85% of the power for duration versus the configured
CP and W' between 2mins and 1hr will be flagged as a sustained
effort via the intervals for a ride.
.. they're pretty rare, but this code will find
any TTE efforts between 1hr and 2 minutes.
.. it will be extended to find sustained efforts
but this is just to get the code started
.. wrote empty METRICS array when all metrics zero in an
interval. Its pretty rare but breaks the parser
.. this means that metric were being refreshed on every run
.. was getting lost due to cut and paste error
NOTE: you will also need to delete RideDB.json to get
the problem fixed. I didn't think it was worthwhile
updating the version number since no dev releases
are out, noone except developers will be affected.
In this part we have now reinstated the sidebar interval tree
but it is refactored out of athlete and into AnalysisSidebar
where it belongs.
* you can hover and select/deselect intervals in the sidebar
Left to do;
* All the interval operations like sort, drag and drop, find
delete etc do not work at present and will require some work
* Add a color button to the tree to let the user change the color
for USER defined intervals
* Add more types of intervals to the discovery; esp routes and
sustained intervals
In this part we have updated all the charts to reference
the RideItem::intervals() members instead of the TreeWidget
and RideFile::intervals().
The code to create/change/delete intervals is not included
so selecting and editing on charts/sidebar is disabled til
part 3 of the update, but hover should work properly.
Still left todo in future updates;
* Updates to the interval sidebar to list intervals
in a tree (by interval type) with a color selector
* Code to create, edit, delete etc the intervals via
the rideitem/intervalitem and see them reflected in
the ridefile
* Update to search for all the different types of
IntervalItems including routes and sustained intervals
Computes the metrics for an interval and creates a temporary
ridefile locally so you don't have to.
.. previous design should have pushed this into the
class instead of performing it in RideItem
.. now there should be no reason to create a ridefile
during interval discovery.
In this part we have added Intervals to RideDB.json and
are refreshed within RideItem, including interval metrics.
At present the IntervalItems are loaded from the ride file
and we ignore peaks and entire laps in favour of creating
them in the discovery code.
Still left todo in future updates;
* Updates to the interval sidebar to list intervals
in a tree (by interval type) with a color selector
* Update all the interval charts and dialogs to use IntervalItem
and the updated sidebar
* Update to search for all the different types of
IntervalItems including climbs and routes
NOTE: We will not be adding an Interval view until v4.0
.. to avoid glitch related to native widgets in toolbar and
inability to switch back from fullscreen mode on a Mac.
.. see QTBUG https://bugreports.qt.io/browse/QTBUG-43299
which doesn't look like it will be fixed any time soon.
.. we are taking a different approach for v3.2
.. the auto discovery will augment rides and maintain a cache
of all intervals across all rides
.. the discovered intervals will be selectable alongside ride
intervals in the sidebar
.. new interval views will be developed in v4.0
.. heartbeats x joules, when unfit you may generate low watts
but with a high hr, as opposed to the other way around.
.. an attempt to combine central and peripheral stress, can be
used to compare with power only stress metrics
.. when selecting intervals the points on a scatter plot
are joined when they are not being framed against the
rest of the ride
.. this is to provide some context about the order the
data was generated in.
.. would be nice if we could have arrows (vectors)
.. racermate format for VELOtron and Computrainer use
a variable rate recording, mostly due to PC interrupts
and workload (e.g. 620ms, 619ms, 624ms sample rates)
.. so we resample on import to 1s samples, the 1000ms sample
rate can be changed in the code to 500ms or whatever
.. this is needed to enable resampling and merging with other
data files, most notably from Moxy.
Fixes#1359
.. this has been added to support some data handling activity
to support a blood glucose study and is not really for general
usage.
.. the libsamplerate library is being used in ridefile::resample()
which is only used by merge and export.
.. we may choose to formalise this library later but for now it
is not required for any functionality and is not used in
release builds.
.. set when on a Windows platform, but not used.
.. when testing on a QT 5.4 release the font metrics appear
to take the scaling factor into account, but adding the code
for compatibility in the future (if we need it)
I intentionally didn't add the IndendPlotMarkers to all markings,
but only to the interval markers at the top of the plot.
NOTE: the height of the spacing is actually what Qwt tells us
is the textheight.
I think this spacing is rather big.
We might want to reduce it somehow in the future.
Signed-off-by: Simon Egli (Silzo) <smn.egli@gmail.com>
This commit is adding a new class QwtIndPlotMarker that will enable us
to indend Labels. The usage is pretty much the same,
please look at the changes in LTMPlot.cpp to see what will
change for using the new class.
So far the functionality is implemented for horizontally written labels only.
This solves the issue of all Labels (e.g. Seasons and events in LTMPlot case)
being on one line and thus being unreadable.
Signed-off-by: Simon Egli (Silzo) <smn.egli@gmail.com>
There is no official proclamation that ID 260:0 is officially assigned
to Zwift; it is simply the value observed in data files downloaded from
Zwift for the author. A support request opened with Zwift requesting
confirmation has gone unanswered.
Smart recording interpolation fills the gaps in pwx files present
when the original .fit or .tcx files had them.
Test files for running: 1 activity in .fit, .tcx and .pwx formats
Lap swimming expands the sample-per-length and pause to 1-sec sampling.
Test files for lap swimming: 2 activities in .pwx format,
one from Garmin 910xt other from Finis SwimSense.
... draw Level 1 text at the end to have full contrast (not overlapped
by level 2 brush)
... dynamically choose font size for Level 2 texts from 4 options (based
on available space in rectangle) - easier readable on big screen - still
usable on small screen
... check if the "folder-upgrade" has really taken place - if not
reset, Upgrade Flag to force the new folder structure upgrade
... (allows to revert to the pre-upgrade backup of a folder structure -
which during test already had be successfully upgraded and therefore
marked as being ok).
When Sport="Other", there is no GPS data but there is distance information
it is assumed the file cames from lap swimming.
They have one Trackpoint per length, which are expanded to one point per second
in similar way to Smart Recording and laps without Trackpoints to signal pauses
which are expanded to one point per second up to 10x Smart Recording HWM.
Added contributed Garmin FR910xt pool swim file to test/rides folder
... allow resizing of Dialog Window (if using bigger fonts/translation)
to see all texts
... allow entry of Average Speed with precision (1) - like the metric is
defined
... shift plot if start date is earlier than any Power Estimates exist
... enhance grouping (calculation of averages for month/years/all
grouping)
... adjust estimates calculation
... to calculate non-overlapping weeks data
... to not create any "infinite" data for weeks before the first Power
based actitivity exists
Display and edition in Pace units, according to sport preferrences
Pace 00:00 is used to represent 0 kph
Fixed PaceZones::read to allow non-integer limits
... problems on deleting the source files (even they have have been
successfully copied to /target) are now reported as error (which require
to be cleaned up before Upgrade is marked as "successful")
... reason is that such "orphan" files may cause problems - e.g. if the
"upgrade-successful" indicator get's lost and we want to start 3.2 with
a fully cleaned file structure.
... check for valid Activity Filename format "YY_MM_DD_HH_MM_SS" (for
non-JSON files before conversion)
... check if the Activity filename contains a valid date/time
... report if File is not readable - not just "skip" it
Distance/Duration is a better approximation for Avg Speed than 0.0
and Duration is better than Time Moving in GOVSS/SwimScore estimation
for these cases.
.. metadata only flushed when ride marked dirty, but
ride won't be marked dirty until metadata focus/edit
ends.
.. because opening a menu doesn't change focus we need to
use the flush event to trigger the focus/edit end function
.. was not refreshed previously (!)
.. need to optimise this to only recompute w/kg stuff
rather than the entire cache for the ride when its
just because the athlete weight changed.
Allows to generate data points for manual activities from series of
work/rest intervas with distance/duration information and reps count.
It is enabled once sport is entered as Swim or Run and distance units
follows pace preferences for the selected sport.
Duration and Distance for the activity are calculated from laps information,
but it can be overridden by the user.
If LapsEditor is reactivated the lap information is preserved to allow corrections,
provided the sport is not changed.
Input method for duration is selected for simplicity and easy of input using
numeric pad, tab and enter.
... fix .FIT format Smart Recording (similar logic like for .TCX)
... use the GC-Preferences Settings to determine if Gaps shall be filled
(and which Gap size)
... make Upgrade Marker release independent
... adjust the texts from 3.11 to 3.2 verson id
... this will just make the Upgrade procedure run ONCE again for
Athletes which have been converted by a DEV build - but just to
check/report sucess
.. tile mode highlights on mouse over for a more
fluid feel, and better feedback
.. can customise the trend view charts background
.. fixed a SEGV on apply preset in chart setup
.. this is part of a set of updates to update the
standard setup to be more complete so the user
can pretty much run off a standard config.
... if configuration for requested feature is missing (but not in
MainWindow - initial download)
... any network errors coming back
... to simplify error analysis - since the API call may have multiple
reasons to fail (configuration, network, proxy,ssl,...)
... adds authorization required for new Google CalDAV interface
... adds CalDAV configuration variant (Generic vs. Google)
... corrects Refresh from Google to GC (as they a using a non-complient
XML-tag prefix)
... comment unused CalDAV features - which are not enhanced for Google
CalDAV as they are not used yet
.. LTM stress curves had the same symbol name and
so some were not deleted when the date range changed
leaving curves on the plot
.. we now set the best symbol for stress curves so we
have a unique name for each curve
... remove $$replace and use the latest src.pro code from QWT lib (which
allows in-source and out-of-source/shadow build)
($$replace - for unknown reasons - creates an empty string/fails if the
input string contains mixed Upper and Lower case characters - which it
happening in many file systems)
.. will break out of source builds in QT Creator
.. means everyone else's builds will still work
.. happy to apply change if it doesn't break builds for others
Fixes#1247
.. splits into words but will allow user to escape using the quote
character (") or the backslash (\).
.. so <"hello world" \"this\" t\est> will result in three strings
<hello world> <"this"> and <test>
.. use a simple free text search against the ridecache now we
have all the texts available and in memory
.. no need to maintain an index, no dependency on a horrid lib
with nasty dependencies and its faster too
.. the free text search is very simple, will need to bolster it
over time e.g. it matches text not words
... add "Up" - "Down" function for Curves Table Items in LTM Settings
(particular useful when add a curve in Stacked View and wanting to have
that curve shown at first position)
.. on windows especially, there were issues with the call to
IndexWriter::addDocument() resulting in an exception.
.. the introduction of a QMutexLocker to manage the mutex locking
seems to have fixed things, but they only seemed to manifest
on Windows.
... change calcuation of Averages for TE/PS by using the delivered
samples with valid values (> 0) and the number of delivered data samples
> 0 as the basis
... correct the path in RideItem after updating RideCache to the final
path (since RideItem has a local buffer for the path - which is e.g.
used at "Save Ride") any manual changes after the import will create a
new .JSON in /tmpActivities and not update the original .JSON in
/activities
(Problem only occurs when using the in-memory data after an Import or
Downlaod)
... for RideImport and RideDownload the created .JSON files are firstly
stored in /tempActivities and only moved to /activities after
successfull updating RideCache (with this files with "bad data" cause
RideCache calculations to crash can be identified when starting GC again
... in GC CrashDialog the /tempActivities are documented in the Crash
Log and moved to /quarantine for further analysis
... small addition - the existence of the new directory structure is
verified when opening an Athlete - missing directories are added to
ensure a consistent structure being in place at all times
.. but to avoid being too 'opinionated' about the users
training we limit to the really obvious things and
don't offer any opinion on middling values.
.. LTS > 80 is green > 100 is blue
.. SB < 40 is red -- overtraining
.. RR < -4 or > 8 is red -- detraining or overextending
.. it borders on bollocks given each athlete is different
and training is about managing the overreaching and recovery
to push at those boundaries
.. might end up removing this altogether .. but might flag
stuff up for newbies
.. value that result in nan/inf values need to be cleansed
to ensure the metric array in the rideitem is clean
.. because we load values from json we clean anyway in
PMC data since it seriously breaks the skiba PMC and
development users will have bad data.
.. was updating as you typed which created a nasty lag
but updated the metadata and metrics constantly
.. on one hand it was reassuring to see things change as
you typed, but on the other hand it was pretty tedious
.. we now catch focus change on text edits, see if they've
been changed and then trigger an update if that is the case
.. does all labels etc and integrates in with the rest
of the LTM chart and CurveColors classes.
.. underMouse() seems weird when legend is updated, might need
to find a better way to work out if/which legend was clicked.
.. if we get measures whilst the ridecache is being refreshed
it can cause a problem - and the refresh needs to be restarted
anyway.
.. download now stops and restarts any refresh.
.. headings are already adjusted in the ridecachemodel so
need to look for new name for CalendarText
.. this is a bit of a hack, but then so is the CalendarText
metadata field - it should be a first class RideItem class
member and be maintained alongside date etc
.. and also tidy up use of isPeak() etc
.. starting to wonder if we need to a) auto find intervals on import
and then b) list them in a tree c) allow user to select a 'class'
of intervals to show (i.e. select all climbs)
Especially for Vectors new metrics
- Left and Righ Platform Center Offset - eg: -8mm and -11mm
- Left and Right Top dead Center - eg: 10° and 11°
- Left and Right Bottom dead Center - eg: 203° and 210°
- Left and Right Peak Power Phase Start - eg: 83° and 76°
- Left and Right Peak Power Phase End - eg: 115° and 125°
.. will rerun as ride selection changes.
.. but will never stop until cleared so use at your
own risk, as will run EVERY time you select a
different ride.
.. remove a missed XXXREFRESH marker to get the CP bests
curve refreshed when a ride is saved in the period of
the bests curve.
.. would be nice if we showed the current in-memory version
rather than insisting on the on-disk .. need to adjust
ridefilecache to traverse the ridecache for that !
.. the "bak" directory was added during the development cycle
and will not be present for users that worked with an early
development build
.. when deleting rides the "bak" rename will fail due to the missing
directory
.. the error message has been changed to provide the details of the
directory where the failure is occurring to help signpost users
to the problem
.. we don't save the currently cached metrics etc
for rides that we discard on exit (i.e. don't save)
.. the metrics etc will then get recomputed when you
restart GoldenCheetah.
... Help Overview Window added to MainWindow - containing
.. Info on new "Shift"+"F1" Context specific Help
.. Links to Golden Cheetah Tutorials, Science, User's Guide, FAQ
.. notify if the metadata configuration has been changed
.. also snuck in a change to take hysteresis out of the
power zones fingerprint - it should not have been there
.. Needed to move about some of the color config
methods and remove the unneeded object from
mainwindow and initialise global color settings
in main() instead.
.. notify if Athlete weight or height were changed by
the user during the config dialog
.. no longer included in zones fingerprint
.. ridecache now picks up on specific config changes
... fix problem of not visible track (Windows,...)
... use "run" data series if track isRun()
... add "start" and "end" placemark
... enable translation of texts
.. ridefilecaches return incomplete flag if data not available
when aggregating (plotting during a refresh).
.. CP plot will refresh as the background update takes place.
.. this occurs even during a comparison.
.. no need to uplift this from the old metricDB as the model
now spots changes at an individual ride item basis AND
will refresh during a background refresh too.
.. no need to uplift the code that used to call for a metric
refresh after rides were imported since the addRide function
will now refresh for individual rides.
.. when downloading withings data the cache is refreshed
.. when the cache refreshes it notifies the *current* ride
changes if it is refreshed
.. ridesummary has been updated to process rideChanged() signals.
.. it is too slow. Need to think about how to implement
this with good performance.
.. if you really want it then add
DEFINES += GC_HAVE_RANKING
to gcconfig.pri
... correct Alt/Slope behavriour in FullPlot (default = inactive)
... handle Alt/Slope status properly when switching back/forth between
Compare Mode and normal Plot view
.. to let charts etc know that the *current* ride has
changed and will need to be replotted
.. the editor / dataprocessor functions have also been
integrated into the RideItem to notify the change
.. there is a qDebug() in RideCache in lieu of updating
all the charts to refresh on this signal.
.. introduce concept of configChanged(what) to
pass details of what config has been changed
.. fixed zones changes to re-read after write
to correct the save twice to get changes to
zones bug.
.. next parts need to spot changes (part 2) and
then action appropriately (part 3)
.. rather than check if lucene index contains every ride
upon startup just force a rebuild of the index is missing.
.. if the index gets out of sync its because people are copying
data and so they should delete the index when they do so
to make sure it stays in sync
.. in sidebar, we summarise for all the selected intervals.
.. we take into account if they overlap, so two intervals
of 10 and 5 mins where the 5 min interval is wholly
contained within the 10 minute interval will be summarised
as 10 minutes not 15 minutes duration.
.. the lucene index writing during RideCache updates needed
to avoid conflicts between multiple threads writing at
the same time.
.. just added a QMutex around write operations - reading is
still thread safe and can occur in parallel.
.. when using '*' for values we autocomplete based upon
previously entered values for the field, but we didn't
take into account ranking.
.. now the autocomplete list is ranked to most popular values
complete first.
.. from RideSummaryWindow as it is no longer needed since
we moved to using a specification object to manage the
filter sets and date ranges to filter on.
.. using the GPX format they add extensions to record
power, heartrate and cadence using element names
power, heartrate and cadence ! (way to simple!)
.. thanks to Wenqi Zhang for the sample.
.. to enable queries such as;
Date > "2014/02/28"
for rides since 28th February 2014
.. might be useful to allow localised dates
but using this makes it easier to document !
.. a query like today > "1900/01/01" will pass
on all rides, but user being an idiot.
.. use "Date" and "Today" which evaluate to the number
of days since 1st Jan 1900.
.. so a filter for the last 90 days would be:
(Today - Date) < 30
.. will add date strings next.
.. removes across the code base
.. need to fixup RideFileCache and Lucene refresh
within the RideItem/RideCache framework, they will
NOT be refreshed at present
.. need to look at how charts get refreshed on data
changes now RideItem provides a more granular
mechanism (look for XXXREFRESH in code)
.. New Intervals code will definitely NOT compile
and needs to be redesigned/reimplemented to fit
in with the ride cache
.. add/remove ride now works
.. fixed metric value in data()
.. need to test (especially with the diary
window and new athlete with zero rides and
then import, add, delete, change, sort
merge, split etc and push update to
fix such bugs in Part 3
.. getting the model in and integrated with the
ride list and diary
.. next steps to connect up to ridecache methods
::addRide and ::removeCurrentRide.
.. then fix up nits/bugs with diary view etc
.. this removes the dependencies on liboauth and friends
and replaces it with a single lib.
.. the library is available from http://github.com/kypeli/kQOAuth
.. the only current feature that requires OAuth is tweet
your ride, but this lib will provide the services for
future oauth services.
.. if a filter was being applied we created a local PMC
but also filtered on dates, this caused the PMC data
that was generated to only represent the activities in
the period selected !
.. thanks to Ale Martinez for pointing this out.
lts(metric), sts(metric), sb(metric) all return the PMC
value for the metric in question for the date of the ride
and therefore allow you to select rides based upon PMC data.
e.g. sb(TSS) > -5
could be considered a way of looking for rides when you were
in a well tapered state, or at least, when you should be able
to perform well.
or, e.g. lts(TSS) > 100
could be a way of looking for rides at peak form (if 100 is
a peak CTL for you).
... separated the "out-of-source" patch from yves from original pull
request
... the patch allows to use e.g. QTCreators "Shadow-Build" feature so
that GC is build not in source, but in a different directory
.. this is useful when using QTCreator and switch between different QT
versions / 32/64 bit builds - since every build resides in a separate
directory from GC source
-- since the original commit (at least from GitHub view) is shown in a
mixed pull request with other commits - this is a seperated version of
the single commit
.. so it is shared across charts when no filtering
is applied.
.. when filtering is applied then LTMPlot manages
the PMC data itself.
.. now we use the ridecache the PMC update is really
fast anyway.
.. also uses a copy to avoid delete/insert issues when adding
and deleting rides during a refresh
.. but still need to consider the delete operation and marking
items as in process or something
.. just playing with the concept, not neccessarily how
things will pan out.
.. If you delete rideDB.json and start GC then switch
to a PMC whilst the cache is being computed and look
at all dates you will see the chart refresh as data
arrives.
.. used to create a 'specification' against which we match
a rideitem when plotting etc.
.. so rather than passing an array/vector/list of data when
calling a plot, we pass the 'specification' to use instead.
.. the plots themselves should now iterate across the shared
ride cache only plotting the items that pass the specification.
.. this should reduce memory usage and increase performance.
.. moving away from passing data when working with groups of
rides to passing constraints instead.
.. so FilterSet allows us to pass a collection of filters
that can then be applied to data.
.. in this way the plots can iterate over cached data selecting
rideitems based upon constraints applied by the user.
.. these need to be embedded into LTM, TreeMap, Histogram etc
.. still a bit funky with the filtering, there is probably
some scope to simplify that, but at least now its only
a list of pointers not objects on the stack.
.. no longer uses metricDB but traverses in memory cache
and should be a lot faster.
NOTE: the line endings for DataFilter.{cpp,h} have been
changed from dos to unix format which has resulted in
the entire file being changed, apologies but needed to
clean that up anyway.
.. the clunky old way of using a 2 month rolling window has
been reworked to use a 12 week rolling window making the
code less susceptible to jumping around esp. on 1st of the month!
... adds "What's this" to (hopefully) most of the widgets (please report
on missing ones)
... defines draft "Whats' this" texts including a
context specific WikiLink
.. Help Key for all platforms is <Shift>+<F1> + in some widgets
"RightMouse - Click"
... Tested on Win and Mac (On Mac QtMacButton seems not supporting
"What's this") - so here <Shift>+<F1> has no result.
... ToDo: Create final texts and links based on the to be updated 3.11
Wiki
.. so available for current ride
.. and refreshed() when notifyDataChanged() is called
.. but not many classes call it!
.. we are moving to having the filecache read from the
RideCache rather than straight from disk so we have an
in-memory and persisted version.
.. so ONLY change version number of a refresh is going
to be needed !!!
.. I updated rideDB version to 1.1 to ensure present gets
refreshed as it is used by the PD model estimate code
.. from DBAccess to RideCache
.. and also SummaryMetrics::getForSymbol() now available in
RideItem to access the precomputed metrics for a single
ride.
.. removing any remaining references to measures in the
code. We now use withings only and that is handled
in a non-generic manner.
.. measures and equipment are likely to get put into
v3.3 once we've done planning.
.. loads the cache/rideDB.json back on startup to avoid
any refresh of metrics etc
.. uses a lex/bison JSON parser, not because of performance
since its only run one at startup, but because;
* QtJSON support is only available in QT5
* mvjson uses a DOM model that creates a memory overhead
* the existing bison/lex parser works well and is easy to
use as a template for this
We now have a good mechanism for metrics and metadata refresh,
cache and recovery so can look at using it in the charts and
the ride navigator next !
.. moved the overwrite of the withings cached response
to when we know we got something successfully.
.. previously we overwrote regardless of what we received
which means that when we have firewall/network type issues
the cache was overwritten with blank data !
.. but only refreshes the ride added rather than looking everywhere.
So, when we are importing large numbers of activities it won't
repeatedly run a full refresh (which was bonkers).
.. if we close GC during a background refresh operation
then the refresh is cancelled and cache saved in whatever
state it is in now .. the user clearly didn't want to wait !
.. when refresh() is called for a rideitem it will
now compute the metrics for the entire ride
.. when a ride is opened the cache is also updated
at the same time.
.. added to slow things down on my developer PC as its
to fast to notice when I'm testing.
.. also left in an erroneous line clearing RideItem::isstale
which is also wrong as breaks separation of concerns
This is quite a big patch with lots of nasty interdependencies
all collected together but essentially it deprecates;
* Measures are no longer stored in SQL tables
* Zeo support has been dropped (they went bust)
To achieve this there are a large number of updates;
* Withings json is now cached in /cache and in the Athlete
class. So can be traversed in memory rather than SQL
* All "measures" on LTM have been removed and the only metric
left is "Athlete Weight" that cascades from withings to ride
"Weight" metadata value to athlete settings to a 80kg default
* RideCache is now refreshed, but only for metadata. This is needed
to cache the "Weight" metadata from rides when calculating weight.
* JsonRideFile parser is now re-entrant since it will run in parallel
during RideCache refreshes (using the QtConcurrent::map()
framework).
BUT NOTE
* This is about deprecating the Measures table more than anything
else. Functionally we are in pretty much the same place; just that
data is stored in a different place.
e.g. metric/imperial handling of weight is not fixed yet, no
metrics are in the cache yet, load/save of the cache is not done
so startup is slow etc.
.. fingerprint for range should not take into account the
start/end date as its irrelevant and will change
.. RideItem now responsible for refresh and status updating
on the rideitem
.. framework seems good now; only rides that need to be refreshed
will get asked for a refresh -- but need to look more closely
at how we derive 'Weight' for each rideitem now...
.. instead of making the caller keep rideitem up to date etc
we are going to move to it looking after itself.
.. the first part of this is to make it responsible for checking
if it is stale and computing fingerprints etc
.. the next part will be making it responsible for refreshing
the cached values.
One big thing too:
.. the fingerprint is now based upon the zone config that applies
for the date of the ride -- not all zone config. So if the config
changes but not for the date of this ride (e.g. set a new CP starting
from today) then the old data does not get marked as stale.
.. needed to clean RideItem a touch
.. needed to isolate intervals code as it has some
problems and breaks metricaggregator for normal
use.
.. found a bit of Context code in MainWindow.cpp (!!)
.. subtle, thin progress bar on tabview to notify
when background updates are in progress
.. background updating code created but does not
perform a refresh yet, just sleeps for 0.2s
.. to enable 'visibility' of the code use WANT_RIDECACHE
to the defines in gcconfig.pri
.. added /BAK subdir where all actvities .BAK files are stored
.. do not delete any original files in /imports /downloads when deleting
activity
.. copy deleted activity .JSON as .BAK into /BAK subfolder
.. adjust upgrade procedure to copy .BAK files to /BAK
# By Mark Liversedge
# Via Mark Liversedge
* 'master' of https://github.com/mtbkeith/GoldenCheetah:
Added RideCache
Introduce the RideCache
Turn off interval hover on leave
.. each metric now has an index (identifier) that can is numeric
starting at 0 and going up.
.. it can be used to offset into an array when we add a cache for
storing precomputed metrics.
.. they are in Athlete::zones() et al now
.. this refactor was missed in the 3.0 mainwindow
refactoring and is part of the prep to use RideItem
as an in memory cache instead of the old metricDB
.. so we can now call that instead of doing the conversion
and formatting all over the code !
NOTE: it still needs to be /called/ in the code, that change
will need to be applied everywhere a metric is displayed
to the user.
.. to fix long standing bug with saving whilst editing
a field. But still leaves a problem if exiting whilst
editing a field (which is a bit weird tbh).
.. its been there since the beginning at the heart of the code
as a registry of the rides (RideItem) and controlling the
selection of rides.
.. in v3.0 we stopped showing it, but it was still created and
then hidden immediately. But removing the 'spine' of the code
was seen as a step too far.
.. this is the first part of moving from SQL to a NoSQL cache
for ride metrics, metadata and measures -- RideItem is now
no longer inheriting from QTreeWidgetItem with all the issues
that brings.
.. since its right at the heart there are likely to be unforeseen
bugs as we go, especially since it affects the ride navigator.
.. add/delete has been tested a fair amount and should be reliable.
... do not process the popup if no files with the correct extensions
were found / the directories were empty
... (this does not address to skip files which were already imported !)
... make Upgrade Check Window smaller (with scrollable Text)
... only allow to proceed if Text is scrolled down to end (full read)
... in Upgrade Log, only allow to proceed to athlete if Log has been
scrolled down to the end
The ride files will now be .json.gzip
Users will also now be able to add an emergency contact phone number.
Ride logger will use that number to update the contact on the riders current
location. It will also notify them if the acceleration is above 15 or m/s^2.
If so the emergency contact will get an sms with the current location.
TODO: 15m/s^2 is easy to trip. I need to research a way to minimize false positives.
Change month format in ride headder
Make sure numbers are formatted correctly ie not scientific notation
Log all current values:
Perviously it only logged values that were measured.
However, if GC doesn't see the other values it assumes they are zero.
.. Wahoo don't do that anymore.
.. now use the same channel as the device and just send plain old
ANT+ messages to set slope etc (why they didn't do that in the
first place is absolutely beyond me)
.. getting ready to implement Kickr for the THIRD time !!!
.. when not hovering over a curve, this worked ok for power
but not for anything else. Because the signal was ignored
when not showing power in pointHover.
Fixed units selection in histogram tooltip, it is independent of pace units
NB: CV chart currently doesn't obey units setting for speed, it is fixed to kph
In LTM Plot and on Summary Windows conversion
... data already converted for the curves was converted again
... for "Best" Summary the conversion was missing
Referring to issues #1067#1071 (see also comments on issue #1069
... fixed by
...... not considering Y-Axis values in the 0 to 4.993 minutes range
which are not shown for VAM anyway
... both in standard view and in compare view / intervals and date
ranges
... handle intervals below 4.993 minutes properly (since they are not
shown in CP VAM)
... but limit what individual services are build/offered based on oauth
availability (Strava, CyclingAnalytics). Load's of ifdef... making me
think about alternative solutions - especially now that the common
uploader base class allows to stuff them in a List/map/vector/whatever.
.. added Edit for all ride data processors now we
have quite a few to select from
.. shifted a few things around to make important
options more prominent (e.g. Share) and less important
ones less prominent (e.g. Heat Map)
introduced a base clase for the individual uploaders to reduce code
duplication.
This made it possible to
- default to download a ride to a service if it wasn't uploaded, yet.
- grey out checkboxes for services without credentials
tab order defaults to the order widgets are created - and not the order
they're added to the grid widget.
Reordered code to bring creation + adding of Widgets in sync.
.. and they will hang themselves !
.. seriously, the limits to the merge offsets
added no real value but would annoy a user
where the rides needed to be aligned to a
greater proportion.
.. adjust can shift the offset for the entire
length of the ride
.. line 1289 of AllPlotWindow was updated to rebuild the
plots when the ride was dirty, but it looks like there is
a strange interaction when rideItem doesn't change and
rideItem->ride() does.
NOTE: rides will not be refreshed after merge wizard completes
until this is fixed up in AllPlotWindow.
... handle Gear Ratio as part of the existing logic - just without
smoothing
... solves SEGV problem in Compare Mode (and probably other areas of
AllPlot)
.. need to save away with analyse() and combine()
now complete, and working pretty well on my data
.. now to work on the last piece, the 'adjust' page
to shift data-series left and right manually (for
cases where the calculated offsets are wrong or
need to be tweaked by the user)
.. page flow and join sorted
.. committing before resolving the merging code
- analyse() to identify offsets
- combine() to merge into a working copy
- ux for sliding offsets on a fullplot
.. next commit will complete this update to the
merge tool
NOTE: MERGE IS NOT CURRENTLY WORKING SO PLEASE
DO NOT USE IT !!!!
.. data can be sourced from file, download or list
.. next to update the mode (join or merge) and the
merge strategy and parameters.
.. will also need to update the download dialog to
allow you to specify which downloaded rides to
process -- at present the merge tool assumes that
the download dialog will only return 1 result
.. pleased with the way the download dialog is embedded
within the wizard, will use that for other things!
.. fix json writing so that user metadata no longer conflicts
with the tokens used by GoldenCheetah, e.g. a user entered
"NM" in the workout code and that conflicted with the
token used to delimit a torque value.
.. all user strings are now saved with a space " " appended to
the value and when read, if there is a trailing space it is
removed.
... in the escape &, ' and " as special XML chars where missing
....... causing that a rule for cLucene with "&&" could be stored, but
got lost on reading
... multiple pathes per Athlete (on Athlete-Preferences - AutoImport
TAB) - option per Path if Import shall be done or not (e.g. for
temporary de-activation without removig a path)
... configuration stored in XML file in /config subdir
... no "stealth" mode any more - but full log of Rides to be imported
with option to "Abort" the import process at any time
.. the download has data in a circular buffer - when you overrun
the buffer it starts back at the beginning and then downloads
that data as-is.
.. we now sort the downloaded data before extracting it into rides
and ignoring rides < 1 minute long.
.. split into separate rides when gap is greater
than 30 minutes between samples
.. discard subsequent rides that are less than a
minute long
BUT: Does not help resolve merge challenge and really
should let the user select which rides to import
regardless of how much data they contain.
.. works for download and clear
.. is pretty basic as the downloaded data
is treated as a single ride
.. need to think about how we can split into rides
and refactor the tool to create multiple rides
with the user selecting which to download.
... create folder structure for existing and new athletes
... upgrade existing athlete to new structure when opening / incl.
logging and error handling
... convert any "Downloaded" file to .JSON directly - store source file
in /downloads
... convert any "Imported" file to .JSON directly - store source file in
/imports
"Time Riding" was only calculated when the ride had kph values - although
it's then also including time without kph but cadence. This caused it to
skip all time spent on the trainer (... if there's no sensor on the rear
wheel).
This patch makes it consistently calculate "Time Riding" if there's kph or
cad... might be worth to count time with pwr or similar running metrics,
too.
.. the left/right scrolling is useful and takes very little
screen estate so always enable it
.. the full plot can still be show/hidden with the chart
controls
.. added config and page decoding for Moxy
Next steps are (2) add telemetry to realtime data structure
and display on the realtime chart and telemetry
(3) add SmO2 and tHb to file format which means moving
away from powertap csv format (!)
.. get timestamp from file not line number (to make sure
drops in recordings are not lost as they are numerous)
.. duplicate each line to get 1s recording that makes it
easier to merge manually (until the merge function is
fixed to handle these kinds of issues)
... introduce new "home" Folder structure object representing the
previous flat-folder
... adjust relevant QDir home - access to use the sub-folder method of
the new object
Note: the new structure is not yet active ! - everything is written to
the main folder still
To Do:
... add upgrade procedure for existing folder content to merge to the
new folders
... option to show the datapoints depending on a gear ratio intervall
... gear-ratio 0 to 1 -> Red
... gear ratio 1.01 to 2.49 -> Yellow
... gear ratio 2.5 to 3.99 -> Green
... gear ratio 4 to max (7.00) -> Blue
.. the Moxy can be configured as a SandC sensor, so in
readiness for ANT+ support in GC just adding code to
spot it.
.. will also need to update this for when it is paired
as a muscle oxygen monitor
.. will need to add SmO2 and tHb realtime data telemetry
.. will also need to add code to device config to notify
when SandC is spotted as a moxy
.. RideFile - add rounding approach for gear values (different roundings
depending on value) - leading to discrete GearRatio values
.. AllPlot - exclude Gear Ratio from Smoothing (to keep the discrete
value) - and change curve type to "Steps"
.. ScatterPlot - specific handling for GearRatio since values between
0.01 and 1 are relevant for GearRatio and must not be filtered out
.. RideFileChache - add Distribution Data for Gear Ratio and fix
Distribution Cache for DataSeries with > 0 decimalsFor
.. Histogram - add GearRatio to Histograms (both Rides and Trends)
.. as the scales were too high when shared with things like
power and torque and made them difficult to see
.. also now color shared axis according to what are selected;
so if only one series selected it will get that color rather
than e.g. yLeft,0 always being red
.. plotting the new running dynamics data series;
ground contact time, vertical oscillation and cadence
.. plotting the moxy data;
muscle oxygen (absolute) and haemoglobin mass (relative)
.. just added to the controls (AllPlotWindow)
.. part 2 is the slog to add to the plots (ugh)
.. metrics for time in zone
.. summary on ride summary
Still need to add to cache, histograms and allow editing
of custom zones in a sensible manner (currently edited in kph/mph)
.. in truth the code is largely a copy of Zones.{cpp,h}
written by Sean, but it seemed a bit odd to not show
that I introduced the file and the changes.
.. recognising that it doesn't /really/ matter much at all !
.. in this first part we just add the pace.zones file
and basic configuration of critical velocity history
in the configuration pane.
.. in part 2 we need to fixup custom zones and consider
how they might be adjusted for VDOT/Daniels etc etc
.. in part 3 we need to add pace zones to the ridefile
cache and then histogram and summary charts.
... import Ride Files automatically from a defined Directory per
Athlete
... runs silently/without "Import Rides" Widget if the files can be
imported/copied/... without error or warning
... Preferences->Athlete- defines
... the directory - per Athlete and- if the function is active at all
(default is OFF)
... the error handling
... report back ALL errors and warnings by opening the RideImportWizard
popup
... report back Errors and Warnings - but ignore the "File exists"
warning (so that the import directory can be continously supplied with
new files, without the need to remove the already imported ones)
Dave Waterworth has fixed my implementation of W'bal to
remove my "optimisations" and fix the math.
The W'bal is now computed in a single pass and is just
as fast as the differential form from Andy Froncioni but
has the benefit that is still uses Tau.
Many thanks to Dave, and I'll write this up shortly.
.. and interval hover on marker
.. need to also show interval on hover as gray path
but find a way of doing it without duping the code
in the webpage js.
... improved resizing by not changing other column sizes in "resizing"
... considering keeping a minimum column size of 20
... consideringkeeping all columns within the visible widget space
... the Alt/Plot settings were not in sync between standard anc compare
view (changes in compare view had not impact on standard view - when
de-activating compare)
... Alt/Plot is now also visible in "fullPlot" as this helps to find
sections to zoom in (by checking the color coding)
... add "Slope" curve based on Slope Data in Ride Files (with separate
new color)
... add "Alt/Slope" curve based on "Altitude" data series
... sections on "Alt/Slope" have 3 options - 1min/100 m OR 5min/500 m
OR 10min/1000 m
... color / slope assignments are defined in AllPlotSlopeCurve (to look
it up)
... if a plotted section is wide enough the slope % (distance) / VAM
(time) value is shown above
.. isRun is a bool, so isRun = 0 or isRun = 1
will filter for runs.
.. note isRun does more than just look at sport
it also checks if there are running data series
in the file and may extend to more over time
Problem:
... data points of "Smoothing" settings are set to Zero in result
... this cause e.g. Zero Altitude Values when Plot Smoothing is active
Solution:
... also most left values are "smoothed" now (using only the datapoint
left of them to create the average)
... 2 new metrics (estimates) mainly relevant for MTB or Race bike steep
passes
... a) Time Carrying = moving < 8kph, gaining height, no power, no
cadence
... b) Elevation Gain carring = same criteria, but adding up the
elevation gain
Since there is a certain level of error, the metrics is named as "Est".
.. if power is already present, or alt or speed are missing
then the fix derive power postProcess won't try and derive
power for the ride
.. this is so you can add it as an 'auto' tool and derive power
values for rides that don't have power but do have speed and
altitude.
.. it seems to be working ok
.. it provides too much output, even for debugging purposes
.. it isn't relavent for 99% of users now its in the master
repository and being compiled up and used
.. remove references to aerobic and anaerobic threshold as they
are not really used in the literature anymore
.. remove talk of training interventions and just point out that
power at LT2 (CP/FTP) is a good indicator of endurance performance
.. we should add a section on MU recruitment and fatigue and
training interventions with the new features in v3.2
.. the code has been updated to support the Wahoo Kickr
via an ANT+ USB stick.
.. this requires the Kickr to be running a beta firmware
of version v1.3.15. This can only be loaded via the
Wahoo utility.
.. for those that have access to the beta firmware this
patch will work, for all others they will need to wait
for the formal release by Wahoo.
.. the code contains *lots* of debug and does not yet support
calibration and slope mode is largely untested.
.. for posts to the usual websites
* bikeradar
* weight weenies
* wattage google group
* timetriallingforum.co.uk
* golden cheetah announce, users, developers
Will require formatting into the markup each site requires
but will take the effort out of formulating text
... values in the ride plot deviate from the ride data since smoothing
takes place even if the sample time is equal to the smoothing interval
(for which the expectation is that the original samples are plotted)
... on QT5 the conversion of chars > 127 did not work (ending with ???)
when loading a .JSON ride file
... by this change the implicite type cast (char to QString) when
calling "unprotect" does not take place any more, so the lexer string
must be 'Local8Bit' to what is has been converted when reading the file
... again QT has changed behavior of locale related processing in QT5
(all this worked fine in QT4)
... wrong Axis IDs causing the following problems
... X-Axis - not considered time, but high (wrong label/wrong scale)
... Y-Axis - altitude curve not properly scaled
... use similar minimum scale for altitude like AllPlot
... attach Alt-curve first (to be in background)
(used/tested at HrPw window, Split Activity Wizard, Merge Activity
Wizard)
.. Strava now works on Windows, avoiding the QScriptEngine crash
.. the same approach has been applied to RideWithGPS, Cycling Analytics
Selfloops
.. commented out Garmin as its not supported yet
.. because QScriptEngine crashes
.. because QJsonDocument isn't available till QT5 and
we still make windows builds with QT4
.. because we're just processing small response documents
from Strava (and maybe others) that are NOT complex
This code has been snaffled up from Victor Laskin's blog
and is 100% Copyright (C) 2013 Victor Laskin (victor.laskin@gmail.com)
details available here: http://vitiy.info/?p=102
The code is slightly modified to fit in with GC and also to fix
some compiler nits; no namespaces, replace() removed as caused an
unneccessary stdlib exception and size_t used in a number of places
instead of int.
Need to be able to add parameters for users to adjust their drag factors
numbers currently work out not too bad for me but needs testing with
more ride files. I have tried it with Mark's Marmotte file and it
doesn't do too bad.
Please feel free to rip it apart and tell me it is wrong - its a good
start hopefully.
... be less restrictive for 'TextEdit' and 'LineEdit' field, jus set
'Read Only' to still allow mainly scrolling (which is otherwise blocked)
... mainly for 'Change Log' and 'Calendar Text'
.. if we cannot start due to permissions / create library folder
we now output a dialog rather than a qDebug -- this is better
for Windows or those that start from a menu etc
.. if the default athlete weight is changed then all ride
metrics need to be recalculated to reflect the new default
.. any cached values need to be invalidated so interval metrics
reflect the new weight (if needed)
It would be better for users to maintain weight either against the
ride in the "Weight" field, or via Withings !
.. attempting to fix the strava upload problems, this is
a set of changes to look at that, but not able to test
if it fixes the problem
.. also fixed the vomitlist of compiler warning messages
.. only show them on power plots
.. don't show text
.. make them /really/ faint
NOTE: This is because crank based powermeters (e.g. SRM) will send
calibration messages every time you freewheel for 3 secs or more and
modern headunits (e.g. Nav2Coach) will record and adopt them.
As you can guess, I have an N2C + SRMs and get > 20 or 30 calibrations
every ride with the latest N2C firmware, so this one is for me.
... the .toUTF8() conversion used with QT5.3.x to handle special
characters (e.g. german Umlaute) in column chooser does not work for QT
4.8.6 (at least not for the Windows) - as a result (Drag&Drop from those
fields into Columns or Search Field is not working)
... following the approach other places, changed approach to
"serialization" of the info for "Drag&Drop" - so work independent on any
QT conversions (which seem to depend on other conditions - change over
time)
... second part: 2nd part ("-Layout.XML") translation
... "Mapping Table generation" provided as a new LTMTool routine (to
avoid duplicate code)
... mapping to HomeWindow::restoreState(bool useDefault) for the LTM
Window type charts added
... metricUnit considered in getting the mapping texts for "unit"
... some more tr() (LTMTool, LTMSetting)
... for Lx/Hx in Time and unit "seconds" translation not working in
constructor, therefore moved to "initialization" for both HR and Power
(similar to the translated metric names) (HrTimeInZone, TimeInZone)
... in RC2 - Windows (name with "umlaut") not displayed in official
build (adjusted to be handled like the one name with umlauts already
defined)
.. previously we have computed below cp work as only that
work when power was at or below CP
.. since we want to track energy from CP and W' it makes more
sense to make below CP work include all work not from W' stores.
.. when computing W'bal decay -- since we know the half-life
for the decay we might as well use it rather than a pretty
big constant of 1 hour !
.. it saves about 35% of time to compute metrics
.. we can now drag and move the GProgressDialog around
.. if user hits ESC we trap and ignore it (otherwise it would
triggers a close event that causes a crash)
datacnt is 16bits so it overflows easily for large files (9 hours with
0.5sec recint).
I've also seen datacnt and block sum to be inconsistent in other cases.
To handle this more graceful, we're now taking the max of both counts and
let the EOF detection do it's job when one of them is wrong.
We do have to use one of these limits as some SRM files have junk after
their last chunk (so, just reading chunks till we get EOF retunrs this
junk, too).
code was blindly trusting datacnt... and kept reading past EOF. That's bad
as datacnt occasionally isn't matching the available data (overflow,
corruption, ...)
<stringname="emergency_contact_dialog_note">Should a text messesage be sent on ride start and periodically to let your emergency contact know you are alright?</string>
public void onNewPedalPowerBalance(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final boolean rightPedalIndicator, final int pedalPowerPercentage)
public void onNewRawWheelTorqueData(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long wheelTorqueUpdateEventCount, final long accumulatedWheelTicks, final BigDecimal accumulatedWheelPeriod, final BigDecimal accumulatedWheelTorque)
public void onNewRawCrankTorqueData(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long crankTorqueUpdateEventCount, final long accumulatedCrankTicks, final BigDecimal accumulatedCrankPeriod, final BigDecimal accumulatedCrankTorque)
public void onNewTorqueEffectiveness(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long powerOnlyUpdateEventCount, final BigDecimal leftTorqueEffectiveness, final BigDecimal rightTorqueEffectiveness)
public void onNewPedalSmoothness(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long powerOnlyUpdateEventCount, final boolean separatePedalSmoothnessSupport, final BigDecimal leftOrCombinedPedalSmoothness, final BigDecimal rightPedalSmoothness)
We are proud to announce that GoldenCheetah v3.1 was released today.
It can be downloaded from our new website[http://www.goldencheetah.org/index.html#section-download]
We have recorded a video[https://vimeo.com/99817526] to explain the main changes, and the user guide[https://github.com/GoldenCheetah/GoldenCheetah/wiki/Main-Page_Users-Guide] has been overhauled to cover all the main features along with an updated FAQ[https://github.com/GoldenCheetah/GoldenCheetah/wiki/FAQ].
We have also added a section on the science of GoldenCheetah[http://www.goldencheetah.org/index.html#section-science] to help users new to power training and analysis.
MAJOR NEW FEATURES
1. Compare Mode
* Across Summary, Ride, QA, CP, Histogram, Metric charts
* Compare Athletes, Seasons, Rides, Intervals
* Easy and intuitive user interface
2. Additional Power Duration Models
* Multiple PD models now available
* Track changes in model estimates for W', CP, P-Max, FTP over time
* Track changes in model estimates for any duration over time
2. Merge data from multiple rides into a single ride
3. Share Dialog to upload to multiple services in one click
OTHER SELECTED HIGHLIGHTS
* Open Athletes in Tabs
* Redesign Tabbed mode with a ChartBar
* Themes and better support for color customisation
* Improved Interactivity (axes, interval hover)
Device enhancements
* Fixed up Tacx Fortius Support
* Pedal Smoothness / Torque Effectiveness support
Metrics and new science
* Plot best x power
* Plot estimated W', CP, FTP et al
* W'bal implemented with metrics
Charts
* Improved UX for chart configuration and setup
* Export data for MMP curves, trends data
* Over 50 new charting options (heat, stack, labels etc etc)
Work on 3.11 starts today, focusing on indoor training.
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.