Simpler and more robust lap alignment
Fixed for empty lengths due to false starts and
pauses in some devices s.t. Garmin 910xt
Added 2 contributed test files
... align terminology (upload/download vs. import/publish)
... make pushbuttons right-aligned (in sync with most GC dialogs)
... ask for confirmation before finally deleting a chart from CloudDB
.. use GcChartWindow as the base class for all charts -- so
we can truly upload *any* chart to the cloudDB
.. miscellaneous charts that were still defined as GcWindow
have been converted to GcChartWindow
.. GcChartWindow layout issues (using QGridLayout insted of
a QStackedLayout) are fixed which will also resolve a few
rendering issues related to NOWEBKIT.
.. Aerolab needed lots of cosmetic fixups once it became
a GcChartWindow
.. Added 'Upload Chart...' to mirror the 'Download Chart..'
option on the hamburger menu as users will instinctively
look for the option there instead of under the chart menu.
... add "Sport" metadata as filter option
... move "Import" from main menue to "add chart"
... make chart lists context sensitive on home, activities and diary
... import directly - without extra dialog
... add export support for the new .gchart format (allowing to post all chart types to CloudDB)
... add import in main menu for the new .gchart format
... allow to import multiple charts at once
... remove specific LTM Chart support (menu, db,... -since this is covered by general .gchart format)
.. you can now fetch activities as a list and split them
based upon gaps in recording (recording anomalies).
.. this is to support trackeR; data should already be cleaned
by the user, but thats not always the case (!)
.. completes the updates to RTool.cpp
.. as predicted by forming the pmc data.frame via an S3
list instead of a pair list the merge() function works
properly and column names are retained.
.. we should use a list not an old pair list when constructing
lists and data.frames.
.. to ensure better compatibility with coercion functions in R
and also possibly to resolve known issues with merge()
.. this is part 1 of 2, breaking up the mass changes to the many
data wrangling functions in RTool.cpp
.. it also contains an update to RLibrary to resolve the functions
used when working with lists (SET_VECTOR_ELT).
.. allow user to select target view for trends/diary charts
since they can be used on either
.. don't just add when only 1 chart imported, always let the
user confirm and adjust
.. use translated names for the views so they are more meaningful
to the end user
.. the default methods in QGraphicsView handle these
events; we don't want this since we handle them in
mainwindow
.. fixes drag-n-drop onto mainwindow as well as working
with the compare pane 'auto-open'.
.. A single .gchart file being dropped into MainWindow will
add and select it on the view.
.. still need to add a dialog when dropping multiple charts
to let user control if they want them all.
.. using mvjson not Qt Json classes, to avoid a dependency on
Qt5. The format was kept simple specifically to avoid that.
.. the chart ultimately is defined a list of properties with
a key and value.
.. export any chart to a file for sharing with others
.. the import functionality will come next (and will need to
determine property formats by querying the newly created
chart metatypes).
.. the ability to apply a datafilter to the data retrieved
is extended to the season.metrics, season.meanmax and
season.peaks methods
.. this helps to let GC filter out e.g. power data is present
before we do anything in R since GC is faster and it also
reduces the data being passed back etc.
.. clean it up, rather than resolve source (there is still a
problem in there somewhere).
.. at least now interval plots and model fits aren't skewed
by a trailing zero value
.. we really don't need 10k history on errors in the rchart
.. this is a hangover from the early development that should
have been reduced before being published
.. You can now specify which activity to retrieve by passing
a POSIXct date time representing the start time of the ride
.. this is mostly useful when used in conjunction with
GC.activities(filter=...) to select ride dates.
.. allow user to pass a data filter to evaluate when getting
a list of activities.
.. e.g. GC.activities('Workout_Code = "1L2")
will get a list of activity start times where the workout
code is 1L2.
.. when returning values we honour whatever filter is active
at the time from home sidebar or the search box
.. it is applied regardless of which view the chart is on.
This commit fixes the issue that the interval bars (in AllPlotInterval) are not correctly aligned
with the interval sections in the main plot (AllPlot). This is done by calculating the margins from
the main plotting area to the border and setting left and right margin of the interval plot
accordingly.
.. Add option to disable embedded R in preferences
.. Better diagnostics if load fails
.. If we find it in the usual place we load and set R_HOME
automatically without requiring R_HOME or config
.. The config option overrides R_HOME not the other way around
Use total duration for both length and lap messages to synch them,
even when using drill mode. Tested with Garmin Swim and 920xt files.
Garmin 310xt is special cased since it doesn't generate rest length messages
Add Pool Length in meters as metadata
.. added a checksum metric for an activity that can be used as a key
in R scripts to invalidate / reuse caches.
.. when R scripts are computationally expensive we can store the
results in a cache with a key for the activity involved -- then
the cache is tied to a particular activity (and state).
.. since caching in R has many options we may develop a 'basic'
cache function that can be guaranteed to be available to any
script so they can be shared.
.. get runtime version loaded and show on crash dialog and console
since the runtime may be different from compile time as it is
now dynamically loaded.
.. no need to define GC_WANT_R_DYNAMIC any more since it is now
working across all 3 supported platforms.
.. we need to improve the way R_HOME is configured and validated
for non-technical users.
.. fixed up to work on Windows too.
.. needed to add a couple of functions used by Windows;
getRUser(), get_R_HOME() and getDLLVersion().
.. also needed to add a path to the DLL that included the
address space (x64 or i386).
.. we can now load the installed dynamic library rather than
distributing with the version we built with.
.. the lib is loaded and symbols resolved at runtime.
.. need to fixup for Windows and remove GC_WANT_R_DYNAMIC option
and make it the way we integrate R for GC_WANT_R
.. add Graphics device entry points and almost done with defining
proxy functions to call at runtime
.. will need to create a QLibrary object to load and resolve
symbols for the proxies to call next.
.. if you add GC_WANT_R_DYNAMIC to gcconfig.pri it enables
this, but it will crash, this is a wip.
.. get peak values across rides in a season.
.. series="power", or series=c("power", "heart.rate") and
duration=1 or duration=c(1,10,100)
.. where series is a mean maximal series in the ride file cache
and duration is in seconds
.. will make this compare aware shortly.
.. get a dataframe with season details
.. all lists all seasons, compare lists those being compared and
if neither true returns the currently selected season
.. also renamed functions so we now have
GC.season.metrics -> GC.metrics
GC.season.pmc -> GC.pmc
but he old GC.metrics/pmc are retained for backward compatibility
.. some users get confused, so make the splitter sit
in the middle (ish) to help them
.. need to still fixup save/restore splitter position
to chart config.
.. instead of hacking the text to avoid a global world
transform we now transform y ourselves
.. it looks like text needs to be centered will test and
fix shortly.
.. was using invertColor and resulted in white on dark for the
default setup and was very jarring. The color is toned down
to a gray if it results in white.
.. add a new method to fetch a data.frame of PMC data
for the passed metric, by default it returns for the
selected date range, all=TRUE will fetch all dates.
.. GC.activity(compare=TRUE) will return a list of compares
.. If you are not in compare mode it will be 1 element long
and represent the currently selected ride
.. otherwise it will have one entry for each activity dropped
into the compare pane
.. each element has a $activity and a $color
Example:
df <- GC.activity()
.. do plot ..
Now:
compares <- GC.activity(compare=TRUE)
for (compare in compares) {
df <- compare$activity
col <- compare$color
.. do plot ...
}
.. you can pass all=TRUE|FALSE to GC.metrics if you want to
override the date range selection
.. also added connect to daterange select so a trend chart
will refresh when you select a date range
.. set a script to run when an activity is selected
.. this allows a plot to be generated and displayed when
you select a ride in analysis view
.. the script is stored with the chart settings
.. it now builds and runs on Windows
.. there is a runtime crash when embedded R is initialised
that needs to be reolved
** NOTE **
R is not distributed with a .lib that can be linked to
with the MS VC linker. Instead, we need to generate a
lib and exp file from the dll:
1. dumpbin /exports R.dll > R.def
2. edit the .def output to have EXPORTS at the top and
a list of functions only (last column, delete the rest)
3. lib /machine:x64 /def:R.def
After linking remember to copy the DLLs to the GoldenCheetah
build directory from the $R_HOME/bin/x64/*.dll
.. and a few more tidy ups.
.. never cease to be amazed at how some developers
will feel its OK to define generic symbols like
TRUE and FALSE in their code (!!)
.. R is a mess.
.. mostly startup issues when R_HOME is not known
.. need to think carefully about how we get the user to
register the R home. We could let them select the R
binary so we can run `R RHOME` and apply that (?)
.. we no longer need RInside or Rcpp as we use
100% R API calls to embed
.. the following need to be resolved:
1. R_HOME / Options *must* be set to startup
embedded R but we don't check / restart or
default via system("R HOME")
2. Output is not trapped - all output is sent
directly to the console you started GC on
.. will fixup the 2 above before finally:
3. Build for Windows using MSVC !
.. we can register routines when embedding via the
R_getEmbeddingDLLInfo()
.. so we just register our functions directly now
in RTool rather than needing a dynamic library.
.. its cleaner and there are no nasty casts and build
settings required
.. reimplemented with native R API
.. switched to .Call in R function since .C means all functions
return void and must return by a pass by reference parameter.
.. its not needed as the workaround of using an extern "C" function
to perform the function pointer cast conforms to standard.
.. this just simplifies src.pro that was getting heavy
.. fixup R SHLIB build and integration to work on OSX
**** WARNING ****
If you build for OSX with GC_WANT_R You will need to
manually copy RGoldenCheetah.so into the app bundle.
$ cp RGoldenCheetah.so ./GoldenCheetah.app/Contents/MacOS
*****************
.. phew. that was hard.
.. To register routines with R you need to place them in a shared
library.
.. The routines we want to register are part of the GC codebase so
cannot be linked into that shared library (it would be the whole
of GC).
.. So; we have a shared library (RGoldenCheetah.cpp) which has stubs
for all the registered functions and an array of pointers to the
actual functions.
.. We load the library (once R is embedded it is loaded in main.cpp)
.. After the library is loaded we then call one of its public
functions (GCInitialiseFunctions) to tell it where all the GC
functions are (we only have GCdisplay at present for this proof
of the concept).
.. Along the way we need to deref/cast DL_FUNC in RTool.cpp which
is not permitted in ISO C, so we also update qmake to add a
special rule to compile `dodgy' sources with -fpermissive. And
the only dodgy source is RTool.cpp.
.. This commmit will break GC_WANT_R builds on OSX, and will be
fixed up shortly.
.. The motivation behind this is to avoid RInside/Rcpp for Windows
builds -- enabling R support (which is not currently possible).
.. to use the R C API for to avoid use of Rcpp and RInside
.. the shlib doesn't do anything and isn't loaded in RTool
at this point. Need to get this working cross-platform
and iron out the build time nits.
.. so don't even try to build and warn via qmake
.. RInside/Rcpp do not suport MSVC
.. Microsoft Open R may help, but doesn't at this point
.. we can revisit at a later date.
.. not complete, but we now have a canvas (QGraphicsView)
to plot the R output without needing to use x11() or
quartz(), window() etc.
.. the primitives do not honour the graphic engine context so
all lines etc are white on black.
.. will fix and improve in followup commits, need to test
with QT4.8 and cross-platform.
.. since the R runtime is shared by charts we offer the ability
to prefix variables with $$ to ensure they don't conflict
across multiple RCharts.
.. $$d <- GC.activity() would actually be parsed within R as
gc0d <- GC.activity(). The next chart would get gc1 and so
on.
.. it is optional, so charts could share data structures (but
wonder why you might do that)
.. we still need to encapsulate the code to plot within a
script to ensure it is refreshed when the chart is selected
or underlying data changes.
.. believe it or not the R base code for plot (plot.c)
skipped plotting circles if they were white on white.
.. took me 4 hours to fix this by setting startcol and
startfill in DevDesc for the device.
.. But at least the R driver now works properly -- we can
now integrate with a qt widget.
.. the R graphics device now gets called for hist() so we can
work on the interaction with a QT widget now.
.. still have other problems to deal with (!)
.. GoldenCheetahGD is instantiated
.. GC.display() to create new GD
GC.activate() to activate the GD
NOTE: a fair amount of qDebug() in at present as
the graphics functions are being created.
.. don't crash when cannot initialise (e.g. when RInside not
available or R is not installed)
.. handle messaging via signals to trap 'late' messages from
the R Runtime
.. refactoring code to introduce an RTool for working
with RInside and Rcpp and move code away from main.cpp
.. get ready to write all the data accessors in a way
that supports multiple athlete windows.
.. now have a console in the RChart to issue R commands.
Its very basic and doesn't handle multi-line commands
well nor support up/down to cursor through history.
.. added a "GC" object with 3 variables
GC.version - a version string
GC.build - build id, later always higher
GC.home - root of all athlete directories
.. No access yet to athlete, metrics, models and rides.
This will come very shortly; need to decide on best
way to handle accessing different athletes within
a single global context.
.. of you cancel before opening an athlete you get a SEGV
on some platforms under some conditions (threads)
.. we now tidy up a little better and avoid deleting static
objects when application->exec() has not been called.
.. still working on the build/configuration to get things
started. main.cpp now creates an instance of RInside
that is shared by all athletes/charts.
.. not clear if this is going to work (!)
.. pushing to repo to test cross-platform support during
development. It /should/ not impact any code since it
will be an optional dependency.
.. first part just to get the configuration ready to
build out a chart for the trend and activity view
.. src.pro and gcconfig.pri are updated to link in with
the RInside/Rcpp package install (new dependency)
.. there is a script in util called install-packages.R
which can be run to install the packages so long as
R is available:
$ R CMD BATCH util/install-packages.R
.. if NOWEBKIT is set in gcconfig.pri when QT < 5 we unset it, since
it is only supported for QT versions > 5.0 where QWebEngine is
available
.. gcconfig.pri.in has also been updated to have a line to set
NOWEBKIT as a signpost to the user
.. we /could/ use the sed s/#DEFINES/DEFINES technique in .travis.yml
now to set NOWEBKIT always and it will only take effect if building
with QT5
... using AppVeyor.com
... only 64Bit builds with QT 5.6.0 / MSVC2015
... all libraries included (pre-compiled)
... using QtWebEngine configuration, not QtWebKit
When there are (planned) activities with future days it is
annoying to start at the latest planned activity, this change
try to select the latest which is not in the future.
.. in RideSummaryWindow we update to show
progress of the model estimates, but it
errors if the html is not set or is blank
and does not contain the div 'modhead'.
The following will always be located in the
source directories so we can find them across
the different trees:
* ../lib/libqwt.a
* ../kqoauth/libkqoauth.a (linux only)
* ./Resources
The references are made via $${PWD} which is
the directory for the currently processed
.pro file.
.. LYC set the date to 2000 from 2016 !
.. we check the date when downloading from a CERVO and if the year
is set to 2000 we set it to the current year.
.. if the date resulting is in the future (e.g download a ride in Jan
2017 from a ride in Dec 2016) then we subtract a year.
.. it will be interesting to see what happens in 2017 !
.. remove Webkit dependency if the user adds the following
to their gcconfig.pri: DEFINES += NOWEBKIT
.. at present the build disables:
* Bing map
* Google map
* Ride Window
* Street View
.. since QT 5.6 enables c++11 dependent libs may no longer
compile with c++11 enabled (e.g. qwtplot3d)
.. this is experimental and in place to enable further work
on deprecating the webkit dependency in GoldenCheetah v4.0
.. notably c++11 needed which breaks a few dependencies
.. WebKit is not available and breaks our builds
.. we will likely need to fixup WebEngine and c++11 in some
fashion. This may mean we deprecate qwtplot3d and we
pre-build WebKit for builds
.. there is a fixup for this in Qt 5.6 but not prior and
it causes horrible performance problems on the QXT
span slider on Linux, which is irritating when trying
to zoom into an area of a ride.
.. when searching for weight in withings readings there will
be measurements that do not include weight -- these are
now skipped to avoid returing a 0kg weight.
.. don't paint dots for cost > 100kJ. It was good for debugging
and checking the solver, but now its just distracting and a
very large performance overhead.
.. probability(), temperature() and neighbour() functions were
not implemented for a correct SA implementation.
.. results still need to be constrained to avoid solutions that
are implausible for the athlete status or history
.. added a solver using a simulated annealing algorithm.
.. the solver is constrained to physiologically plausible
values, but these may not be valid for the athlete. So
a second update is required to allow the user to constrain
the solver.
.. secondly, the algorithm cannot be halted and doesn't use
multiple CPUs/threads should they be available this should
be in a second update to part 2
.. finally, a visualisation is needed to show the solver progress
across the search space to give the user an indication of
where the best solutions were found (especially if they don't
constrain it themselves).
.. add the dialog to mainwindow, but not functioning.
.. Part 2 will add the Solver and Part 3 will add the
progress visualisation.
[this is a recommit after reverting the previous one
that borked line endings to MSDOS crlf]
For builtin metrics it shows the newly added description if available
and refers to the Glossary otherwise
For user defined metrics it is the text provided by the user
Complete descriptions for Running and Swimming metrics and partial
update for BasicMetrics, it defaults to a message referring to the wiki.
Fixes#1850
.. rather than only build with Google Drive support if
using QT5.4 just adapt the code to avoid issues with
QJsonObject -> operator present in QT5.x < 5.4.
.. see https://bugreports.qt.io/browse/QTBUG-29573
.. when saving weight/height the saveClicked() function was using the
value in context->athlete->useMetricUnits to decide if to perform
conversion of the values stored in the widgets -- BUT -- it will
reflect the value BEFORE our update since it has not been updated
yet (via the configChanged() signal.
.. instead we look at the pending value when deciding if the values
need conversion.
Fixes#1868
.. previously it was disabled via VLC, but if you're not running
with video then the screensaver will kick in on Windows.
.. we now disable it via the Windows API too
Fixes#1859
Introducing a directory structure to make it a bit less
daunting for new developers and perhaps even old hands.
The main folders all start with an upper character, so src
files are now located in;
* Core - Core data structures
* Gui - Main GUI elements
* Metrics - Models and Metrics
* FileIO - Device and File I/O
* Charts - All the chart types
* Cloud - Working with Web Resources
* Train - Anything Train View specific
* ANT - Our ANT+ Stack
* Resources - Images, Translations, Web etc
Apologies to anyone who needs to merge across this update.
.. using scatter plot of metrics as a basis to develop a class
hierarchy to replace all chart 'types' by a single suite of
classes
.. this is to enable easier additions of features like interval
analysis and UX as well as greater consistency (data that is
available, functions etc)
.. but for v4.0 we will just use this to introduce a scatter plot
for the trends view and develop it further in v4.1
.. this is the initial class design.
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]
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.