.. improved performance when switching between tab/tiled mode
which is especially important in train view (and also when
resizing or entering/exiting full screen mode there).
.. removed the title at the top of a chart, when the same info
is already in the name of a tab, saving some real estate.
.. Dial window stop setting fonts via pixel size (its horribly
slow on Qt with hi-dpi displays
.. some other perspective fixups for performance and also added
some debug for stack tracing (disabled in the commit).
.. the view (e.g. trends view) should set its tab/tile status on
the basis of the current perspective.
this fixes an issue where toggle style got out of whack with
what was on screen.
.. train view resize performance was terrible because each time
a telemetry item was resized it would recalculate the right
pixel size for the font.
this was only a problem in hidpi displays, but these are
becoming more and more popular.
.. standard colors now belong to groups:
* Chart - chart decorations e.g. grid lines
* Data - data series e.g. Power
* Gui - Gui elements e.g. toolbar background
.. when selecting colors in user and trends charts we
now filter out any colors that are not data related
to make it easier for users to find a standard color.
.. when enter/leave full screen mode the view sidebar is
hidden and shown to increase screen real estate (and
especially useful in train view).
.. since the user may want to show/hide for other reasons
the view menu now also has an option to show/hide the
view sidebar selector too.
.. the renumbering of columns removed empty columns. This was not
desirable since in some instances where spanning tiles are used
the user may have deliberately done this.
.. thanks to Alan Benstead at the forums for an example chart to
test this fix against.
.. when a spanning tile moves the layout needs to restart to
take into account its new position (since it will displace
other tiles).
.. to enable us to restart the layout we needed to refactor
the updateGeometry() method to separate out the creation
of animations from layout changes (because an item may be
moved several times as spanners take precedence).
.. tile column numbers also need to be renumbered from 0 when
arranging since it is possible to get out of sync as items
are dragged around.
.. this refactor should also make it slightly easier to fix
any other layout tweaks (now the previous issues have been
resolved).
This reverts commit a023e0efc0.
There are a number of issues with this commit that need
more work and further testing, most notably:
* moving an item causes jarring and unneccessary updates
* moving an item to before the first column causes a SEGV
.. when a spanning tile moves the layout needs to restart to
take into account its new position (since it will displace
other tiles).
.. to enable us to restart the layout we needed to refactor
the updateGeometry() method to separate out the creation
of animations from layout changes (because an item may be
moved several times as spanners take precedence).
.. this refactor should also make it slightly easier to fix
any other layout tweaks.
.. annoying heritage issue with metric names that contain an
apostrophe (') breaking the parser. So we need to add them
as special cases to the lexer.
Fixes#4057
Add support for FTMS devices with Power and Slope control plus Power, Cadence and Speed telemetry
Implement a priority for controllable devices
Avoid connecting Cycling Power Service if there's another source
When CdA is not set, it is estimated at every sample, using cadence. Beforehand, it was computed with the first sample
Co-authored-by: Peret <mail@mail.com>
.. a new checkbox setting for the user chart to refresh when interval
selection changes.
since there is a performance overhead the user must select this
if they are plotting intervals-- most of the time it is not needed.
.. the defaults for opacity was set to 1% and line width of 0px
when adding a series to a user chart were inappropriate.
Some users wouldn't notice and wonder why curves rendered in
a ghostly manner.
Also made worse by the fact that when opengl rendering is
enabled for a series (fast graphics) the opacity and width
are ignored.
This led to a false diagnosis of rendering issues
when the root cause was the configuration of the curve.
.. disable forcing of ANGLE for rendering, which helps where folks
have multiple GPUs but cannot configure them for use in GC.
.. some reports in the forums of issues related to this.
.. add a linear regression to the plot for the current series.
style is solid, dash, dot, dashdot or dashdotdot
"colorname" is a color e.g. "red" or a hex rgb "#fefefe"
DataFilter evaluation requires an activity to get context,
so don't try to evaluate one when there is no current activity
to avoid crashes. It is a marginal edge case without practical
value, but better don't crash when a new user is playing around.
Reported at the forum, easily reproducible creating a KPI tile
in Trends Overview Chart.
The added check is already present in remaining evaluate versions.
.. annotate(hline|vline, "text", style, value) to add a horizontal or
vertical line to the plot for the current series on a UserChart.
style is one of solid, dash, dot, dashdot or dashdotdot which are
the standard Qt pen styles for drawing lines.
I also took the opportunity to refactor how annotations are passed
from the datafilter down to the generic plot. This should make it
far easier to add annotations in the future.
.. fixed a SEGV in the voronoi annotation, which was related to memory
management and the sqrt_nsites variable (honestly, I am amazed it
ever worked).
.. labels in Python and R charts are now broken, will fixup shortly when
worked out how it should work (annotations are related to a series).
To enable source file names and line numbers in stack traces
generated after crashes in crash*.log files.
Intended to make crash report from users easier to analyze.
[skip AppVeyor]
Install gsl and srmio from source
Install R and awscli using official installers
Disabled libsamplerate
This is a workaround to avoid a brew update which would force
the use of Qt 5.15 triggering #3611
[publish binaries]
.. run make in src/doc/doxygen to generate documentation for the
source code in html and latex format.
.. doing this to get some basic docs going, since the codebase is
now so large its getting difficult for even the core team to
remember.
.. the subdirectories generated are ignored (see .gitignore)
[skip ci]
Use --no-verbose in order to avoid having a lot of wget progress
information in the travis logs, since the logs seems to be sometimes
becoming larger than 4 MB which results in aborted jobs.
.. refactor to introduce Generic Plot annotations that
can draw onto the chart scene, but managed by our
own controller so we can add/remove without affecting
or interacting with the QtCharts code.
.. legend item spacing and linewidth is now proportional to the
text height, which resolves the jarring sizes when not scaled.
.. there was a bug related to the height calculation that did not
take into account the space left below the colored line which
made it overlap the text.
.. bracket matching code for ( and ) fixed up as well as adding
support for matching [ and ].
.. helps to highlight errors in code when it starts to get a
little complex.
.. added a new variant for annotations to plot a voronoi diagram
via a datafilter.
the centers are as returned by the kmeans() function so the
x and y values follow each other (i.e. x1 x2 x3 y1 y2 y3)
.. it is ingrated into the userchart and down to the genericplot
for the series it arrives in.
.. next commit will add the drawing code to generic plot.
.. updated to have a more Qt/C++ friendly interface:
Voronoi *test = new Voronoi();
test->addSite(QPointF(2,5));
test->addSite(QPointF(3,2));
test->addSite(QPointF(6,4));
test->run(QRectF());
delete test;
the output is still written to standard out as a
series of points, lines, vertexes and edges. This
was to enable validation against the original
c program.
.. whilst the original functionality is now embedded a
further update will need to convert the output into
a vector of lines to draw.
will do this as part of adding it to a plot as an
annotation.
.. from C to a C++ class.
Moved the original code to a sundirectory for reference and
moved all the global variables and methods into a new class
called Voronoi.
.. the code still needs more work but wanted to remove the global
variables as there were lots and a big risk they interact
with other parts of the codebase and libraries.
.. last commit introduced a compiler error on missing global variables.
the intention here is to take future's algorithm, embed into a class
and add wrappers for user charts / datafilters.
.. kmeans(centers|assignments, k, dim1, dim2 .. dimn)
perform a k means cluster on data with multiple dimensions
and return the centers, or the assignments.
the return values are ordered so they can be displayed
easily in an overview table e.g.
values {
kmeans(centers, 3, metrics(TSS), metrics(IF));
}
.. will look at how we might plot these in charts with either
color coding of points or perhaps voronoi diagrams.
.. with grateful thanks to Greg Hamerly
A fast kmeans algorithm described here:
https://epubs.siam.org/doi/10.1137/1.9781611972801.12
The source repository is also here:
https://github.com/ghamerly/fast-kmeans
NOTE:
The original source has been included largely as-is with
a view to writing a wrapper around it using Qt semantics
for use in GoldenCheetah (e.g. via datafilter)
The original source included multiple kmeans algorithms
we have only kept the `fast' Hamerly variant.
Only the first 10 examples are reported to avoid anomalies log flooding.
This anomalies can be easily fixed using Fix Speed from Distance tool
with moving average windows set to 1.
.. renamed pdf/cdf to pdfnormal and cdfnormal as they returned
a pdf for a guassian.
.. added pdfbeta(a,b,x) and cdfbeta(a,b,x) for working with
beta distributions.
.. save to .gchart when a user chart is on an overview.
rather annoyingly the scaling is preserved which should
ideally be defaulted on import depending upon context.
we should fix that.
.. Create a new tile on an overview by importing the XML .gchart.
The importer checks the chart is a user chart and also that
it was created for the current view (Analysis vs Trends).
.. Data table and Interval Bubble generate and respond to
interval signals like hover and select.
.. a compromise to help users navigate the data when it
is not possible to clickthru for intervals
.. the data table now accepts a new function i {} which
returns the names of the intervals for each row in
a similar way to f {} for activities.
.. time_to_string is for formatting durations, so it will
use as few characters as possible (e.g 10s, 1:00).
since the interval time is a time of day we want the
full hh:mm:ss format.
.. all matches were being returned, which was not the documented
behaviour, nor generally the desired result
i.e.
match(c(1,2,3), c(1,2,3,1,2,3,1,2,3));
would return
[ 0, 3, 6, 1, 4, 7, 2, 5, 8 ]
but should have returned
[ 0, 1, 2 ]
.. there are likely two things users would like to be able to
control that could be added in the future:
- match all occurences (this commit stops that now)
- return NA or -1 for items that are note found
.. hue goes red-yellow-green-cyan-blue-magenta-purple-red
we only really want the first half of that range for our
heatmap, which effectively makes it red-amber-green with
cyan for very low numbers.
As a palette it will make a lot more sense to the majority
of users.
We may look to add multiple schemes, for example limit to
a single color range or brown/blue etc etc.
.. horrible nested scrolling- when in a data table and there
are multiple rows any wheel event will scroll whilst the
mouse cursor is over the table.
.. we do check that the mouse moved too, so if just scrolling
with the mouse wheel it won't trigger until the mouse
is moved (but most folks aren't that steady on the mouse!).
.. if you assign to a vector using indexes it was only setting
with a single value. But it should be possible to assign
a vector and have it repeat
e.g.
a <- c(1,2,3,4,5,6);
indexes <- c(3,4,5);
a[indexes] <- c(9,10);
# a now contains [ 1, 2, 9, 10, 9, 6 ]
.. also as part of the data table click thru, the highlight
that a row can be clicked to navigate to the ride
should only be shown if that row has a file name.
.. both fixups are related to listing PMC data in an overview
data table and allowing click through for the rows that
have a ride associated, the code looks like this:
f {
# find dates that contain rides
ridedates <- metrics(date);
pmcdates <- pmc(BikeStress,date);
index <- match(ridedates, pmcdates);
# returning all blanks for filenames
# except where there is a ride on that date
returning <- rep("", length(pmcdates));
returning[index] <- filename();
returning;
}
.. tweaking the names from the last couple of commits
* to return heatmap values (between 0 and 1) the
Data Table function "h" is now called "heat".
* the data filter function that does the unity based
normalization is renamed from "heat" to "normalize".
.. did this since normalize() is more accurate and
will be more appropriate when adapting data to
use other algorithms in the future.
.. activities legacy program reinstated and also sets the h {}
function for the activity list.
.. the DataOverviewItem::setDateRange() method now calls h {}
if it is present (forgot in last commit)
.. added a heat(min,max,value) data filter function to convert
values to a heat value between 0 and 1
e.g. heat(0,config(pmax),Average_Power)
.. added Utils::heatcolor(x) method to convert a heat value
from 0-1 to a hue/saturation value color
.. the overview program now has another user definable function
called h {} which returns the heat values. If it is not
present no heat coloring takes place.
.. added h {} to the legacy intervals program, it adds the
h {} function but calling heat() with 0 for min and max
which ultimately makes it do nothing-- crucially the
user can adapt the min and max values to meet their
requirements
.. mostly to make using the activities() function a lot
simpler. A parameter can include a block of code that
should be evaluated as a parameter.
e.g:
activities("isRun", { xx <- metrics(date);
yy <- metrics(Pace); } );
this avoids having to declare a function and call it
just so we can pass as a function parameter.
.. it was always rather dodgy, but caused issues when charts
recreated on config changed (like interacts badly with
the setUpdatesEnabled() call.
.. has a nice effect of stopping the jarring repaints too
which were horrible when themes changed.
Fixes#4029
.. aggmetricstrings() and aggmetrics()
data filter functions that return aggregated values as
opposed to all values for the activities.
.. asaggstrings()
data filter function that returns aggregated values for
the list of metrics provided (primarily used in data
tables).
.. the next commit includes an update to the data table
settings tool to use asaggstrings on trends view.
.. lots of problems related to this, notably:
* UserChart is no longer a GcWindow so doesn't have any
properties registered.
* Even if it was the property was not being registered
by GcWindow or GcChartWindow anyway
* The value was not being initialised so checking for
NULL was kinda pointless (groan)
* OverviewItems looked up the property and never found
it, so crashes were avoided by accident.
.. One interesting point that was revealed during testing
and debugging-- the UserChart program does not honor
any filtering EXCEPT for the activity{ } function, which
although it is not by design, is quite useful.
Fixes#4021
.. returns the powerindex for the given power and duration
which can be vectors.
.. useful to transform meanmax power to strengths and
weakness rating.
.. when moving the scaling slider the charts get updated
immediately, this causes a SEGV as charts are deleted
whilst they are being updated.
.. we now block updates whilst critical processing is
happenning to avoid this.
Fixes#4026
.. the side bar, bottom bar and related buttons were still
following a skeuomorphic design that has long since
fallen into disuse.
.. now have a more muted feel with hover/press colors active
on mouse events.
.. moved the whatsthis button to the far right since this
is quite a common placement in other apps.
.. it is noticeable how we use many many different schemes
for hover/pressed colors across the UI- at some point
this should be unified.
.. also deprecated the segmentcontrol.
.. scaling maximum increased to x10 which helps on hi-dpi
displays and the overview
.. slightly reduce the border on overview to make more of
the available screen real estate.
.. default to 5s smoothing for plotting time series (second by
second samples).
.. if smoothing is applied we sample the smoothed data every
3 seconds.
.. this reduces the number of points to plot to a 3rd and has
a significant impact on plot/paint performance.
.. for those users that care about resolution they can set
the smoothing to none, for those that don't they will
get faster performance.
.. regression from 1297d76ee4 where the data table
doesn't update on scrollbar moves.
.. this was because we optimised out unneccessary paints
on mouse moves. But when we move the scrollbar we
need to repaint the data table at the right position.
.. the base class method ChartSpaceItem::sceneEvent() generates
lots of paint events when the mouse moves about, and its
mostly to repaint the top right corner.
.. for user charts this generates a lot of overhead that is
99.99% unneccessary - so we now override this and do
nothing.
.. we know that opengl drivers for windows can be sketchy, so rather
than not use opengl at all we insist on ANGLE at startup.
.. this is experimental and has been included as a single commit
in the hope it will remain, but may be reverted if there are
significant issues.
.. as reported on the forums, translations can rename metric
names inadvertently. We avoid this by using the untranslated
names in datafilter expressions.
.. if a tile moves because it clashes with a spanning tile we need
to repeat the process in case it clashes with another after it
has been moved.
.. previously we moved on the first clash, but ignored any others.
.. when sorting the table we sorted all the columns that are
visible to the user, but not the associated filenames
that are used by clickthru, so clickthru would jump to the
wrong activity.
.. added configChanged() to base class
.. added calling configChanged() when preferences are
changed and when the items config is updated.
.. updated MetaOverviewItem to use this, but also need
to update the Zone and Best tiles too.
.. the irony that adding a __LAST__ property to ensure we
had well formed JSON made sure it was /always/ invalid.
.. see fd546b4da for impact (almost none, but hey).
.. when adding an overview chart it configures from a .gchart
file built in via application.qrc
.. to update the default config all the developer needs to do
is design using GC then export the .gchart into the
appropriate src/Resources/charts/file.gchart
.. NOTE: the exported file has an errant comma (,) after the
__LAST__ element. This is invalid JSON and should
be fixed. It needs to be removed manually right now
otherwise the JSON does not parse.
.. progressively boldens as you hover and overlays contents
to avoid taking screen real estate and being a distraction.
.. only watches mouse events and ignores wheel events since
these clash with chartspace scrolling.
Fixes#4006.
.. commit 91f2c46 introduced a regression where the selector
is not updated when the perspectives are changed (via
the manage/add perspective functions).
.. this was because resetPerspective() returned if the
athlete/view combination was last used to set the
selector -- we now override this, but only when the
perspectives config is changed.
.. datestring() was using 2 digit years and Overview data table
sorting only expected 4 digit years.
.. datestring() now uses 4 digit years in line with everywhere
else in the code.
.. data table sorting now supports 2 digit years and xx/xx/xx
style dates too (just in case).
.. slightly improved category labels on a bar chart when groupby
and date range is used. Labels for week, month and year are now
specific e.g. 23/5, May and 2021 labels are applied respectively.
.. axis settings updated to enable users to smooth and group by
for data series on the axis.
.. since group by needs to aggregate the series also have a new
config term to define the aggregation method (Average, Total,
Peak et al).
.. grouping and smoothing is applied in UserChart not the Generic
chart or plot, so this functionality will not be available from
Python and R charts (mostly because axis management and config
is done differently).
Fixes#3999.
It behaves as before: current view layout is discarded and default
layout with perspectives is fetched from goldencheetah.org first and,
if not available, baked in layout is used.
Website defaults are not updated yet, so baked in layouts are used now.
Renamed Resouces/xml/*-layout.xml files to Resources/xml/*-perspectives.xml
Removed deprecated Summary from Activities and Trends, and added default Overview to Trends
Added enclosing <Layouts></Layouts> and General perspective with proper type to each one
This provides default layouts for newly created athletes.
We still need to update layouts before release and to enable Reset Layout.
.. along the way renamed AthleteTab related methods in MainWindow
to reflect the last commit renaming the classes.
.. there are also a handful of fixups to SEGV when no ride is
selected in DataFilter (triggered by opening a second athlete
and switching to trends view, which need to recreate the athlete
switch bug that is also part of #3997).
.. and the logic to reset perspectives is changed in MainWindow
with a special method resetPerspective that is called everywhere
but will check the athlete/view combination has not already
been set (to avoid multiple passes).
.. multi-athlete and perspectives need better testing as there are
probably more SEGV in there, and if we fix them we could also
remove the requirement for the opening view to always be Analysis.
Fixes#3997.
.. Tab becomes AthleteTab - since Tab is almost meaningless
TabView becomes AbstractView - since its the base for all the views
there are no functional changes or fixes in this commit.
.. honour the sort order when refreshing (e.g. select new daterange or
a new activity).
.. thin line to separate headings from data to make easier to read.
.. by clicking the header column the user can toggle sorting of
the contents.
.. we try to infer the type of data in the column for sorting which
probably works 80/20, but is better than adding yet more of a
burden on the program that supplies the data.
.. add legacy program to analysis view for an interval table.
.. highlight row in data table when mouse hovers over a row, but
only when not using clickthru, since that already highlights
the row to indicate click is available.
intervals(symbol|name|start|stop|type|test|color|route|selected|date|filename [,start [,stop]])
returns a vector of values for the metric or field specified for each interval
if no start/stop is supplied it uses the currently selected date range, or activity when no date range.
intervalstring(symbol|name|start|stop|type|test|color|route|selected|date|filename [,start [,stop]])
same as intervals above but instead of returning a vector of numbers, the values
are converted to strings as appropriate for the metric (e.g. Pace_Rowing mm:ss/500m).
Both metricname and metricunit now support name, start, stop, type, test, color, route, selected, date, filename,
in addition to metric names and date, to get corresponding localized string.
Example program to build an intervals table in Activities displaying all intervals for selected activity,
similar to the one in RideSummary:
{
names {
metricname(name,
Duration,
Distance,
Pace,
xPace,
Average_Heart_Rate
);
}
units {
metricunit(name,
Duration,
Distance,
Pace,
xPace,
Average_Heart_Rate
);
}
values {
c(
intervalstrings(name),
intervalstrings(Duration),
intervalstrings(Distance),
intervalstrings(Pace),
intervalstrings(xPace),
intervalstrings(Average_Heart_Rate)
);
}
}
Fixes#3626
.. when embedding json in xml element attributes the string
decoding mangles results.
this is because of the way \ and " are handled at each
pass, causing combinations to be lost early when decoding.
This is largely a non-issue, except the user chart config
is stored in perspectives.xml and worse, when embedded on
an overview is encoded as .gcchart (xml) before being
encoded in the perspective.xml.
To avoid this issue, specifically with user charts and
to leave all other json string encoding and decoding
unaffected (e.g. ridefile.json) a new protect/unprotect
method has been introduced.
Utils::jsonprotect2() and Utils::jsonunprotect2() will
still decode older style encoding for backwards
compatibility, but now will translate \ and " in the
encoded string with :sl: and :qu:
This means that, for example, the following substitutions
will be made:
newline (\n) -> :sl:n
cr (\r) -> :sl:r
\ -> :sl:
" -> :qu:
If users add text with these characters (e.g. :sl:) then
it will be decoded to a slash, but it is highly unlikely
they will do this, and if they do, it should be harmless
as these text strings aren't part of the the datafilter
syntax.
Fixes#3996
.. since axis min and max values were not initialised the
visualisation would fail to refresh and was generally
unpredictable.
.. we now set initial values and check when updating.
.. activities("Workout_Code=\"FTP\"", metrics(BikeStress))
A new function that provides an activities filter
to apply as a closure to an expression, following the
same approach as the daterange() function.
In the example above metrics() will only return values where the
activity has a workout code "FTP".
.. unescape datafilter strings since the lexer supports that
but they are not parsed.
.. Only supports \n, \r and \" for now, but that should be
enough.
Formula doesn't change.
When date range is set Trends View is assumed and we use the sport of included
activities with default to Bike (Run for Pace) when mixed, and date is the end
date for the date range.
Otherwise we use activity sport and date as before.
.. click thru from the data row to the trends view to
view it on the activity view.
.. Added a function "f {}" that returns the activity
filenames- the same semantics used in the user chart.
.. the mechanism used in the overview items to click thru
from the itemPaint function is dropped and we now
do it from the mouse release event.
.. see issue #3993 which will get fixed using the same
scheme as this one.
.. when a userchart is embedded into an overview mouse events
do not propagate in their entirety- as a result the legend
widgets do not see MouseRelease (even though they see
MousePress).
So the click to show/hide when hovering over a legend item
responds to the press not the release.
.. User charts can be scaled (lines, texts, markers, legend)
.. Plot area background color honours overview card color
when we're on an overview.
.. when adding a user chart to an overview make it span a couple
of columns and 3 times deeper than a metric tile.
NOTE:
There are two bugs that need to be squashed individually
and are related to user charts on overview:
1. Mouse event handling seems to be broken for user
charts in Overview.
2. User chart axis colors are always black when the series
are configured to use named colors.
zones(hr|power|pace|fatigue, name|description|low|high|units|time|percent)
applies to the currently selected activity and sport is implicit.
Also changed name() by metricname() and unit() by metricunit() in script comments.
.. You can now add a user chart to the overview dashboard
using a new tile UserChartOverviewItem.
.. Had to refactor UserChart away from a GcChartWindow and
into a QWidget so the QGraphicsProxyWidget would play
along.
.. A new UserChartWindow has been added to manage adding
a UserChart to a perspective.
.. fixed chartspace item config widgets being destroyed across
the add wizard and config dialog (existing bug).
.. fixed initialisation of items when added via wizard
NOTE the following issues/todo:
.. mouse click events are squiffy for some reason
.. need to add a way to scale as the text is tiny
.. legend has a performance issue (see #3989)
.. overall performance is good even tho we are using
a QGraphicsProxyWidget- might need to reevaluate
this later and embed the QChart directly into the
QGraphicsScene. To be reviewed.
.. a new zones datafilter function to retrieve zone info
and metrics for the current activity.
.. zones(sport, series, field)
sport is one of run, bike, swim
series is one of power, hr, pace
field is one of
* name - zone name (e.g. L1)
* description - zone desc (e.g. Active Recovery)
* low - the low mark for the zone (e.g. 0)
* high - the high mark for the zone (e.g. 100)
* unit - units for low/high (e.g watts)
* time - time spent in zone
* percent - time spent in zone as a percentage
each call will return a vector of strings for all
zones available.
.. to support the syntax the old functions 'name' and
'unit' have been renamed to 'metricname' and
'metricunit' to avoid clashing with symbols and
were bad choices in the first place.
.. the motivation for this function is mostly about the
overview data table, where we might create a tile
with the following program to display the zone
table that was previously available on RideSummary
names {
c("Name","Description","Low","High","Time","%");
}
units {
c("", "",
zones(bike,power,units),
zones(bike,power,units),
"", "");
}
values {
c(zones(bike,power,name),
zones(bike,power,description),
zones(bike,power,low),
zones(bike,power,high),
zones(bike,power,time),
zones(bike,power,percent));
}
.. we have a filter box on most trends charts config dialogs
and elsewhere. But when you resized the dialog the filter
box would also stretch (even though it is a QLineEdit).
.. this commit sets the vertical size policy to fixed to stop
this ugly behaviour.
.. when a column contains no tiles it may still be spanned
by a tile (since we add that feature).
.. this means we should check if the column contains a spanned
tile before shifting all remaining tiles left.
.. also enabled dropping into an empty column which was
not possible previoisly (impossible to have an empty
column)
A new overview tile that can be placed on trends or activity view to
display a table of data.
.. It uses a program to fetch the data to display via 3 functions:
* names() returns a list of column names
* units() returns a list of column unit names
* values() returns a list of values to show
.. If there are more values than names then it is assumed there
are multiple rows to be shown.
.. When adding a data tile an example program is provided to
demonstrate how this works (will need to also document this
on the wiki, or possibly a video tutorial).
Since time in zone is computed using the active zones for the series according
to sport and date, there is no good choice of limits to show in the general case.
This is part 4 of #3911
Power, HR and Pace use separate scales now.
This is part 3 and fixes#3911
The sport used to select zones in rangemode needs an update,
this will be included in a separate commit.
.. some new functions to help prepare data for the new overview
data table item. Possibly useful in other contexts too.
datestring(v) - returns v converted to a string date where
v can be a single value or vector of values, as days since
01/01/1900. e.g. datestring(Date)
timestring(v) - returns v converted to a string time
where v can be a single value or vector of values.
name(metric1 ... metricn) - returns the metric name in
the local language
units(metric1 ... metricn) - returns the metric unit name
in the local language
.. resize an overview item column width whilst holding down the shift key
to make it span columns, it will expand across and back.
.. this is largely to support the data table overview item type that
is pending, but also may be useful in the future when items can
contain charts (not planned for v3.6).
.. train plot background color is now honored more completely
with the backgrounds, sidebars and tabs all taking the
right color.
.. additionally, when applying any theme the train view will
always be set to a black background since it works best
like that (but users are still free to change it).
.. based upon current background plot color, so those with a
preference for dark themes get the new dark theme and those
with a preference for light get the new light theme.
.. making it mandatory will likely annoy some users but for the
most part it will mean the UI will get updated to a more
thoughtful color scheme.
.. the ride summary on analysis and trends is now replaced by
the overview dashboard.
.. since RideSummaryWindow uses html to deliver content via
an embedded web browser it had become unwieldy and the
UX was klunky and static.
.. additionally the code was unwieldy and difficult to
maintain and update when new feature were introduced.
.. this is a happy day, goodbye and farewell.
.. applies to all charts in the perspective, so you can create
a perspective called "Running" and set the filter to "isRun"
and all charts in the perspective will only show data from
runs.
.. updated charts on Trends view to honor the perspective
filter, as below:
* Overview
* Trends
* User Chart
* Treemap
* Critical Power
* R Chart
* Python Chart
* Histogram - for metrics
* Summary - no change as deprecating shortly
.. renamed the HomeView to TrendsView in line with some of the
other recent name changes. The class names were set over 10
years ago and no longer reflect the UI concepts.
.. New signal: GcWindow::perspectiveChanged(Perspective *)
When the chart is moved from one perspective to another, likely does
not need to do anything on Analysis view, but on Trends view its
quite likely the filter has changed, so refresh is needed.
.. New signal: GcWindow::perspectiveFilterChanged(QString)
When the perspective filter is updated this signal is called but
only on trends view since it doesn't really matter on Analysis
from the charts point of view.
.. at startup the perspective selection logic for analysis
view was not called and just defaulting to the first
available perspective in the analysis view.
.. when creating a perspective you can now add an expression
that will be evaluated when a ride is selected in the sidebar.
.. For example you can create a perspective "Running" with an
expression "isRun". When a run is selected on the sidebar
we automatically switch to the running perspective.
If now, whilst on the "Running" perspective you select say
a cycling activity, the expression will evaluate to false,
so we will look for another perspective to switch to.
If no expression is found to switch to, and the current
perspective has an expression that is evaluating to false
then we just switch back to the first perspective in the
list (you can reorder them if needed).
.. the perspective type is added to the xml when exporting and
also when saving state.
.. on import the perspective type is checked to make sure we
don't import trends views into activities and vice versa.
.. User Chart annotation labels now work when a standard color
has been selected.
.. The name of the standard color "CP Curve" has been renamed
to "Mean-maximal Power" to more accurately reflect how it
is used in the Critical Power standard charts.
.. there are lots of standard colors and they're hard to scroll
through. A new search box makes it easier to find them.
.. this is in anticipation of adding a lot more standard colors
for things like W', Pmax, Weight yada yada
.. New dialog to rename, add and remove perspectives, re-order them
and move charts from one perspective to another.
.. The focus is on managing perspectives and not the general UI
layout (ie. add/remove charts and rename things etc) this is
likely to be something this morphs into, but for now lets
keep it simple (this was complicated enough !)
.. also found a SEGV in CP chart when hover in allplot before the
CP chart has been notified in another perspective-- there are
likely to be a few of these kinds of bugs around.
When you start with a single click the workout is represented graphically
as a ramp from zero, but the qwkcode and erg code generated starts with a block.
Additionally an initial ramp starting from zero neither works.
This was reported at the forum and, although it is mostly cosmetic, it can be
annoying, so this change fixes both.
Difference between R Chart in Activities and Trends is a blank at the end
of the name, which is not preserved in German translation so new R Charts in
Trends are created as Activities charts.
Fixes#3427
It is unnecessary, since Train mode supports only 1 workout at a time,
and single selection makes it easier to scroll the list in tablet mode.
Related to #3268
Current GC root can be different from athlete library setting
due to GC startup logic and the spurious warning is confusing.
Revert to previous value, not current GC root, if the user chooses to.
Fixes#3903
.. Perspectives can now be added and are saved and restored on
startup and close.
.. A new config file 'xxx-perspectives.xml' replaces the old
'xxx-layout.xml'.
.. HomeWindow has been renamed Perspective across the code.
With TabView now taking responsibility for loading and
saving configuration.
.. This is a fairly big refactor that touches upon a number
of events at startup, including how sidebar events are
propagated across charts and tabs. And will need a reasonable
amount of testing before release.
.. Separately, I also fixed a SEGV in the Python chart when
no ride is selected (an old bug not related to this).
The user will be able to create collections of charts as opposed to
the single long list of charts in each of the four views.
This first update:
.. update toolbar to include a perspective selector
.. also updated aesthetics of toolbar (mostly icons on hidpi)
Further updates pending will:
.. part 2 will introduce code to add, save and restore perspectives
.. part 3 will introduce code to manage and rename perspectives
.. part 4 will introduce new defaults for each perspective
A future enhancement may allow the perspective to be aligned to a
specific sport in activity view, so the perspective can be selected
based upon the sport of the activity being analysed. But that will
not be part of these changes.
MapQuest API Key is a new DP parameter to allow users to enter one
and have personal transaction limits.
When empty it defaults to GoldenCheetah API key as before.
Fixes#3900
Any sport present in the list of possible Sport field values
can have its own HR and/or Power zones like Run before.
Otherwise Bike zones are used as default for backward compatibility.
Fixes#3280 combined with last 3 previous commits.
[publish binaries]
All sports defined as values for Sport metadata field can have
specifics Power Zones and default to Bike zones otherwise.
Similar to current power zones for Run.
Part 3 of #3280
All sports defined as values for Sport metadata field can have
specifics HR Zones and default to Bike zones otherwise.
Similar to current HR zones for Run.
Part 2 of #3280
.. the alpha channel was too agressive for light backgrounds and
was washed out and unpleasant on the eye.
.. reduced the alpha blend to make it flatter and cleaner.
.. showEfforts was not being initialised when the plot was created
which resulted in sustained efforts always being shown regardless
of the chart setting.
.. themes are now either light or dark, which selects the default
color set used to set the standard colors.
.. users can of course maintain them, but when applying a theme
there is no need to adjust now (some of the default colors looked
poor on a light background).
.. there is a line of code in main.cpp to dump the current colors to
stderr so it can be cut and paste into colors.cpp -- this makes it
much easier to use the UI to maintain colors and update the code.
this is obviously just for developers.
.. letting users define their own themes could be done later, but feels
like overkill at this point.
.. When creating user charts we can now select a standard color as
configured in appearances.
.. This means users can select e.g. the "Power color" when plotting a
power series.
.. The second part of this commit will update the themes to ensure that
the standard color settings are appropriate for the background (as
they are inappropriate currently. e.g. Critical power is always
yellow, even on a light background).
.. mostly straight replacement as qt5 containers are templated
and qSort semantics are the same as std::sort
.. prepping for Qt6.2 which is due late 2021.
Signed-off-by: Mark Liversedge <liversedge@gmail.com>
Continuation of previous commit. Caveat is value argument is string
so the user is resposible of providing proper string representation
of the value for overrides and numeric metadata.
For Metadata handling in Python Data Processors, similar to set/unset/isset
in formulas, but no metric overrides for now.
- setTag(name, value[, activity])
- delTag(name[, activity])
- hasTag(name[, activity])
All return boolean success indicator and activity is optional,
defaulting to current activity.
setTag and delTag are enabled only in Python Data Processors, mark
the activiy as modified and notify metadata has changed on success.
Fixes#3639
.. Makes it easier to identify code that has been snaffled in from
other repositories and check licensing
.. The httpserver is now no longer optional, since it is delivered
as contributed source.
Variable row height, depending on activity calendar text being empty or not,
provokes refresh issues when calendar text changes from empty to not, or
viceversa.
Instead to try to solve this issue with specific code, I think it is
simpler, and more regular from UX point of view, to have a uniform row height.
After this change row height depends on metadata config only:
1) a new RideMetadata method is introduced (hasCalendarText) to check if
Calendar Text can be non empty, i.e. if some field has diary checked.
2) RideNavigator uses this method when config changes to set hasCalendarText
member used to determine row height for all activities.
Fixes#3074
Configurable in Train Preferences, defaults to 0, which is current behavior.
When countdown > 0, start is delayed and countdown is displayed in
notifications panel.
Fixes#3632
Since a simple metric name is the most common use case for PMC functions,
it is useful to avoid the need to call the expression evaluator at refresh
time, for better performance and to sidestep #3788.
This is a continuation of previous commit, since x-axis change affects
the is blank status we need a full replot to consider cases when the
selected activity lacks time or distance.
This change remove deviceType_ private member from RideFile
replacing its use by access to "Device" metadata field.
The objective is to remove limitations s.t. update using set
in formulas and ride navigator immediate refresh.
Fixes#3760
.. when trying to find the right values for the measures() datafilter
function e.g. measures("Body", "weight") it was not clear why this
was failing. Added more information to the error message.
A new Trainer metadata field is included in metadata.xml
On upload a checked Trainer metadata field, or the presence of
TRAIN XData series, marks the activity as trainer.
On download the trainer flag is used to update Trainer metadata field.
This is a complement of 5a1bd1a, a user is reporting a crash in
Widget::setSyleSheet on Windows at startup after that commit.
I cannot reproduce the issue, but since that change was modeled
after LTMSidebar, lets try to avoide the issue making it even more
similar. This way, the widget already has a proper parent when
HelpWhatsThis is added.
Add recommendation to pair only FE-C sensor for FE-C devices
Group Custom Virtual Power settings, move Name and Create button,
rename for clarity and enable only when Name is not empty.
Remove compiler warnings.
Fixes#3697
deriveExtCPParameters established Initial parameters estimates before
the data verification steps so when data don't meet the minimum
criteria for estimation those initial parameters are returned.
This change moves the initialization step after data verification,
similar to what deriveCPParameters does for the envelope fitting case.
Fixes#3862
A new logging category is added gc.usb, inactive by default, to log all the USB transfers between GC and the USB trainers. It can be activated by changing the logging filter with the --debug-rules option.
This change adds some useful defaults for Tile Servers A/B/C when not set
and allows to enter full urls including apikey, s.t.:
https://tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=<your-apikey-here>
so use OpenCycleMap with your own apikey.
[publish binaries]
Leaflet.js API uses the upper left corner as reference point while
GoldenCheetah icons, designed for Google Maps API, uses bottom center.
Since all marker icons are fixed size 32x37, this change adds the attribute
iconAnchor:[16,37] to fix positioning.
Fixes#3193
This change allows the user to independently via the new chart checkboxes to:
- ignore any Power Shading Zones and always draw the red line (Hide Shaded Zones)
- remove the route background yellow line (Hide Yellow Line)
For Pace related metrics converting back from toString using toDouble
fails and then sparkline, up/down, etc. are not displayed.
This change avoids that conversion to fix this issue and to make code simpler.
Add declaration for variable v inside the loop used to compute avg/min/max
to avoid affecting variable v in the outer scope, this is the minimum change
to fix the problem and the same pattern is present in other tiles.
Without this change up/down is based on the first activity of the same sport
in the previous 30 days, instead of the current one.
Adds a “Polarized” option to Overview Zone tile to chart HR/Power/Pace as 3 zones histogram, it has no effect on Fatigue/WBal zones.
Complements #2555
[publish binaries]
Decimal watts, which tipically happens when a workout is scaled,
play havoc with qwkcode, so lets avoid them.
Text cues are not supported either in qwkcode yet, adding them
was my mistake, so I commented out them for now.
Fixes#3846
* Add debugging options to select the log file, format and rules, and redirect stderr even on Windows
* unistd.h does not exist on Windows use io.h instead
* STDERR_FILENO does not exist on Windows
* Different strategies and much error checking to redirect stderr on Windows
* Synchronize cerr and stderr with filedes 2 and STD_ERROR_HANDLE
* Some functions like write in Linux and Win32 have slightly different signatures
* Code cleanup, final test to check that fd=2, stderr, qDebug and cerr are redirected
* Remove the file and line number from the default logging format in release mode
Once Ubuntu 16.04 reached EOL we will switch Travis-ci builds to 18.04,
this guide is intended to help new developers setting up a local build
environment.
To allow duplicate keys happening when the same metric/measure or
Best/PMC/Banister combination is used in more than one curve.
This is useful when the curves have different filters or trendlines,
for example, and avoids a weird behavior in these cases.
Fixes#2185
In total 18 new metrics are added and 6 new charts using them are
included in charts.xml (existing users needs to remove their local
copy in config/charts.xml to activate them, reset doesn't work since
it retrieves the server copy which is v3.5 yet.)
Fixes#2555
[publish binaries]
Change CVPage to include AeT Velocity/Pace
Default to 90% CV for runs and 97.5% CV for swims
Used to delimit Polarized Zones I and II
Add config(aetv) to formulas
Add aetv to R/Pyhton/Rest APIs
Fixed column widths to fit contents
Part 3 of #2555
Change CPPage to include AeT Power
Default to 85% CP, used to delimit Polarized Zones I and II
Add config(aetp) to formulas
Add AeTP to R/Pyhton/Rest APIs
Fix W' col resize bug in Power Zones settings #2661
Part 2 of #2555
Change LTPage to include AeT HR and look like CPPage and CVPage
Default to 90% LTHR, used to delimit Polarized Zones I and II
Add config(aethr) to formulas
Add AeTHR to R/Pyhton/Rest APIs
Part 1 of #2555
It should be closer to current offset than the fixed default.
Users having issues with calibration can change default value adding:
[srm]
offset=400
to configglobal-trainmode.ini
When exiting, GC complains that the Web Profile is released before Web pages that refer to it with the message: "Release of profile requested but WebEnginePage still not deleted. Expect troubles !".
The Web pages are now released explicitly in the destructor to insure that they are freed earlier than the Profile.
Fixes#3844
When any change is detected, _userMetrics are reloaded and updated in Metrics
factory, but metric recomputation still depends on fingerprint field to avoid
unnecessary recomputation.
Fixes#3838
It copies xml config files from the selected template athlete, if any.
Together with Athlete > Open > New Athlete, Athlete > Delete and
the new Athlete view should make multiple athletes management easier.
Fixes#308
[publish binaries]
Allows to delete a closed athlete without the need to exit the program,
it re-uses the logic in ChooseCyclistDialog and removes the AthleteCard
from AthleteView.
Objective is to allow creation of new athletes, without the need to
exit GoldenCheetah, using Athlete > Open > New Athlete like in v3.5
When a new athlete is created MainWindow emits newAthlete signal
so AthleteView can create the corresponding AthleteCard.
The Sigmasport ROX devices do not set a product ID, hence GC shows any Sigmasport fit import as "Sigmasport ROX". The Sigmasport wearable "iD.FREE", however, sets a product ID of 45. This adds specific logic to the fit ride file detection logic, while leaving the ROX default for backwards compatibility.
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Fix VLC Hangs with Intentional State and Ordered Async Dispatch
Two main parts to this change.
- a thread locked managed player state
Fixes issue where calls to player could occur in wrong order
- all calls to VLC are made via an ordered Async dispatch.
Fixes issue where qt must process widgets after stop is called.
By moving stop off the qt gui thread this permits qt to shutdown
widgets which eventually allows vlc to stop.
Since vlc stop is async, and we wish vlc operations to be ordered
we are forced to put all other vlc operations on the same async
queue.
Fix#3756
to force Strava upload of altitude data.
The user can revert to Strava basemap on Strava.
Upload to Garmin Connect was tested for regresion.
Fixes#3824
I noticed zoom configured in xml file is ignored, and code is always starting with a value of 16 for thee zoom of thee live map widget.
This change uses field of the xml; it was already being parsed but not used, so using it is simple and straightforward
Co-authored-by: Peret <mail@mail.com>
* when CRS workout files are read, the altitude is already derived and precomputed from the gradient for all formats handled. A new function was added, altitudeAt, that accesses this value, avoiding to derive anew the altitude from the gradient in the TrainSidebar main loop, and getting the correct altitude value when FastForward.
* Replaced assert by qDebug in ErgFile.cpp because asserts would needlessly kill the program
Fixes#3805
* Fix the request - reply interactions with the Fortius
The open command is in fact to get a reply with the version. However, some already queued messages need to be skipped, before the well formed reply message is received. The open command is sent initially, and each time the device is disconnected and reconnected. The procedure to open the device and get the version was then put in a separate function.
When the run command is sent with a specified force, a reply comes back with the force echoed. However, here again, some messages may need to be
skipped before the correct reply comes back.
* Updates based on comments
The first reply is always skipped on the T1932 (64 bytes reply). A notification about the motor not turned on is sent when the version number cannot be read.
* Add a comment for a non obvious if condition
Added calibration trainer command, delayed check for user stopped pedaling with visual feedback on progress and saved calibration for next use on success.
The crash is reproducible on Linux starting an Erg workout after another
and it is caused by an array index error due to average arrays not being
cleared on start.
* Initial correction of force/speed/power calculations for Fortius using information from https://github.com/totalreverse/ttyT1941/wiki
* Use wind speed, rolling resistance and wind resistance value from trainer interface, if provided
* Added FortiusANT's AvoidCycleOfDeath() routine from https://github.com/WouterJD/FortiusANT to limit trainer resistance at low wheel speed
LRBalance is left side contribution while the ANT+ messages carries
right side pedalPower contribution, so it needs to be converted.
When not available RideFile::NA is used since 0 means 100% right.
Complementes b29f72d, Fixes#3017
Add support for 8008 TRS and, using the profile string, delay and sound can be configured
This adds the following functionality for daum:
* if the profile string contains a number or the string sound,
no automatic cockpit configuration is done, but the information from
the profile string is used
* if the string sound is present, play the sound when connecting
* if a number is present, use this number as the delay in milliseconds
between commands. A reasonable number to start with is 50 in case of
connection problems
This also solves the problem, if the cockpit id is not known by
GoldenCheetah. In this case the profile string can be just set to
e.g. 50_sound and the unknown cockpit id is ignored.
Athletes with default config can be safely skiped without loss of
information in the same way as non athlete folders.
Fixes#3735 for new cases, but users previously affected by this bug
need to manually delete metadata.xml from GC root folder, it doesn't
seem a problem common enough to merit an special treatement.
[publish binaries]
Default is checked to preserve current behavior, when cleared
the choose athlete dialog will be presented at start.
Workout library setting was moved to Train preferences
page to reduce clutter in General settings page.
[publish binaries]
* Daum: Remove redundant virtual keywords
These function were not involved in any inheritance, so the virtual
keyword is removed.
* Daum: Remove unused parent member
* Daum: Remove redundant destructor
* Daum: Remove default values for contructor parameters
This circumvents problems where e.g. explicit would be necessary.
The constructor is actually only used when all parameters are given.
* Daum: Remove redundant this->
* Daum: Ensure timer only allocated once
Also use nullptr instead of 0.
* Daum: Remove unused includes
* Daum: daumDevice is now a private instance member
There is no need for it to be a pointer or public.
CTRL+Click on a selected media file allows to clear the selection,
lets honor this action to have a way to train without video after
a media file has been selected.
[publish binaries]
For this a 50 msec delay is introduced before sending each serial
command. This is tested on hardware ond also used be jergotrainer.
Also during initialization there is a delay between each command, so
even slow devices can keep up. As soon as the cockpit type is known,
the delay is set according to the cockpit type.
Create ergfile finalize for every parser to call.
Consolidate lap init into ergfile finalize.
Consolidate lap distance updates into a single method.
Laps now sorted by location.
Workout with no lap is given bracketing laps.
Fix handling of final lap (falls back on route distance).
FFwd lap on final lap no longer jumps to route start.
AddLap button now actually creates a new lap in lap list,
making it reachable using nextLap and prevLap.
Remove the displayLap field as it serves no purpose.
Improve Virtual Power in Presence of Acceleration
Part 1: Rotational Inertial for Custom Virtual Power
This change is only enabled when device is defined with non-zero
Inertial Moment. When Inertial Moment is not defined or is
zero then this change has no effect.
Change adds field to device to hold trainer's inertial moment
in (KG M^2).
This allows power calculation to track energy that passes in
and out of trainer's flywheel so that acceleration and
deceleration power can be reported immediately.
Whenever device sets a new rpm sample a time is
recorded alongside which allows the common controller
to compute change in rpm over time, which allows
calculation of kinetic energy that has entered or
left the trainers flywheels during the duration.
It is a bit of math to determine a correct I for a trainer's
flywheels, especially if the flywheels have different rpms,
hopefully we can add the I values for the current built-in
virtual power trainers.
Part 2: Use average power instead of point power.
Moved numerical integration into its own header, its now used by
bicyclesim and by virtual power. Changed default integrator to
Kahan-Li since in my testing it is stable and converges fastest.
Virtual Power now computes average power since previous sample,
which has the effect of reducing reported power during acceleration
and deceleration.
New advanced virtual power is on with this commit. It seems to work
very well in my testing.
Fixes#3650
Fractional watts are not supported by Workout Editor and they
are trucanted for most import formats, this fixes remaining
cases reported by users.
Fixes#3675
Current route tile looks off compared to the map one is more used to,
because it is lacking mercator projection. This commit adds the
spherical pseudo-mercator projection as described on
https://wiki.openstreetmap.org/wiki/Mercator. As mentioned there, the
true elliptical projection is avoided for being more computation
intensive. This is also the case in OpenStreetMap and thus in the full
map view in GoldenCheetah. With this commit, those views match up again.
This is an experimental feature, the primitive was available
but currently unused, it seems to have been available from
Computrainer HDC in former versions.
When used with videosync it does a naive extension of the FFwd
implementation, but it seems less precise than without videosync,
some tuning may be required.
* Teach ttsreader to process routes and segments
TTS reader previously ignored routes, segments and strings.
With this change the route name, route description, segments,
segment descriptions are now all parsed into ttsreader object.
With this change the route name and description are assigned to
the ergfile, so route name now appears while riding a tts file.
With this change there is still no place to put segments in ergfile.
With this change none of the new information is assigned into the
activity file.
The segments and segment descriptions are used by tacx software
so user can select a named region of a long ride. Example ride
was >200km long and contained 12 named segments, each with a nice
description. Would be nice to bubble that info up to train mode.
* Translate tts segments into ergfile laps.
Also fix old issues with how laps work in slope mode, especially
with ffwd and rwnd.
Also lap markers are double.
As far as I can tell laps work ok now.
Simplified the meterwidget elevation display loop, bug was that it
was skipping the final route point.
Add minY to ergfile so range of y can be obtained without computing
each time, so can remove search loop from meterwidget.
Fixes for power adjustment:
Fully populate new point from old before rewriting fields.
Prevent power from reducing to zero since after it is zero you
cannot increase it again...
* remove unused CompareDateRange::days
* remove unused Season::days
* ensure Season limits are only accessed via accessors
* remove unused Seasons::seasonFor
* add SeasonLength to create relative seasons that end today
* save Season::_length and use it instead of Season::prior
* add SeasonOffset for the start of relative seasons that don't end today
only functional difference: "All Dates" is now aligned on the beginning
of a year instead of starting on the same day and month as today
* use _offset+_length instead of _start+_end for relative season
functional differences:
- in CriticalPowerWindow, relative seasons that don't end today ("All
Dates", "Last Week", etc) were previously computed with respect to
QDate.today(); they are now computed with respect to
myRideItem->dateTime.date(), as other relative seasons ("Last 7 days",
etc); this is technically a bug fix, but there probably was no one
using these relative seasons for CriticalPowerWindow anyway
- every call to Season::getStart and Season::getEnd computes a fresh
value (based on the offset and length specified for the season), so
relative date ranges refresh when the display refreshes, e.g. when GC
is open for multiple days (fixes#1751)
* add comments for SeasonOffset/SeasonLength
* Use Season accessors in AthletePages
* when looking for events, consider all seasons that intersect the date range
seasons starting before and ending after were not considered
Fixes#2620
* center event labels on the event mark
if the labels are to the right of the mark, the label of an event at the
end of a date range will not be shown
* code cleaning
loop only once over seasons, instead of twice
Before this change, when looking at an activity, the routes seemed to
appear in order of creation in the interval section. This patch instead
sorts them by their start time in the activity instead (or by their end
time if the start times are the same).
Note that the routes are also known as segments.
Fixes#2132.
Fixes the problem happening when a ride crosses the start point of a segment but diverges for some reason then at some point later in the ride the segment is ridden for real. It introduces boolean "resetroute" and sets it to true in two places where where the code needs to reset the segment point and break out of the ride point loop in the case where diverge is found. Then check for this condition at the bottom. Reset the segment index to -1.
To avoid the script running twice on ride selection and
interval edition/deletion.
Caveat is when intervals are created via find intervals
the script is not notified until interval or ride selection changes.
Overview chart needs to do computations with metric values converted
to selected units and format results accordingly, for this purpose
RideMetric::toString(useMetricUnits, value) should not do the units
conversion again, so it is changed to do formatting only and useMetricUnits
parameter is removed.
The original meaning is used only in RideItem where it is replaced by
the composition of toString with value.
Fixes#3647
[skip appveyor]
transfer.sh service has become very unreliable and it is being
phased out on oct-30, according to the public site announcement.
free.keep.sh offers free uploads up to 500MB with a similar service,
limited to 24hr storage, enough to download build artifacts.
This is the Same fix applied to the Computrainer a few months ago to remove the modal dialog that would be issued in a loop upon connection problems. The modal dialog loop made the interface completely unusable. Now a notification is emitted but the interface remains available.
Similar to other DPs, it is what the users expect and it is easier
to try with different parameters.
When called automatically existing watts are preserved
to avoid accidental overwrite.
More recent first intended to avoid the need to scroll to the end
Fingerprint changed to include time to detect changes when adding
more than one on the same day.
Fix inconsistent use of local/UTC dates.
.. MacOS Qt crashes when destroying it, OpenGL is *that*
broken by Apple.
.. applied to Windows too, despite it not being an issue
reported there is no value in doing it so removed.
[publish binaries]
.. saves/loads values to athlete global area, particularly useful when
modelling as you can save away parameter estimates that may have
been expensive to compute, and re-use them across series in a
user chart.
.. they are not saved across restarts, but we could fix that later if
they become more useful
.. store("name", value) and fetch("name"). if the named value does
not exist 0 is returned.
[publish binaries]
Fix the slope and power values in the Fortius Slope mode
Users have complained about incorrect slope and power values for the Fortius. This was due to a few problems. This commit greatly improves the situation with the fixes that solve the following problems:
- The Fortius protocol is better documented in the comments.
- The pedal sensor is on byte 42, not 46, this prevented the pedal sensor echo to keep the trainer operating normally.
- The slope was converted to uint before being scaled, losing the fraction.
- The trainer most likely reports the torque. It must be multiplied by the speed to get the power.
- The scaling factor for the slope was 2x too high but this did not show earlier because of the pedal sensor problem.
- The period for retrieving data was too fast, most packets were empty, the period was changed from 10ms to 50ms (Tacx software uses 100ms).
GoldenCheetah is now quite usable on my Fortius with those changes. The slope appears too easy and the power overestimated but this is similar to the behavior of this trainer with the Tacx software. It would be interesting to get feedback from users with powermeters to refine some of the coefficients involved.
.. MacOS support for OpenGL is unreliable and there are user reports
of issues. We will need to wait till Qt 6 for hardware acceleration
on Metal.
.. Windows support for OpenGL is ok if you use Nvidia GPUs but the
AMD OpenGL driver is slow and broken. So we disable OpenGL here
although Nvidia users are potentially being short changed.
.. Hardware rendering really needs to wait for Qt6 for a more complete
and reliable implementation that has cross platform support.
Fixes#3594
.. the concept of a new gui as a replacement for MainWindow was dropped
in preference for gradually adjusting MainWindow to the new design.
.. this is still in progress, but the 'newgui' concept is dead.
.. Fetch the version of OpenGL available at startup and use it in
ChartSpace to decide if we want to enable openGL rendering.
.. some fixups for X11 builds, which are not needed on the main
OS combinations we use (Linux, Mac, Windows) but may prove
useful when building for X11 vs Wayland in the future
The weight has a direct impact on how fast you climb for a given power.
Other parameters like the wind resistance and the rolling resistance do
not change as much but should still be communicated to devices which can
take them into account. All the needed values were already present in
the BicycleSim and DeviceConfiguration modules. It is simply a matter of
communicating those values in the RealtimeController interface, just like
the gradient.
.. xdata("name", "series" | km | secs) - returns a vector of xdata.
.. no resampling or interpolation is applied since the user can
do this with the resample() and interpolate() functions.
This has been reported to produce garbled output on Windows and,
according to https://doc.qt.io/qt-5/qtglobal.html#qPrintable,
it is dangerous since the array returned by QString::toLocal8Bit()
will fall out of scope, so lets use a safer version to avoid
the risk of crashes hard to debug.
[publish binaries]
For the same reason metadata.xml is now global.
Also load default measures groups even when measures.ini is present,
this may change when we provide an UI to edit measures.ini, but for now
it avoids users breaking body and hrv features.
[publish binaries]
.. Global settings (themes, metadata etc) are now maintained
in the config dialog as in the past, whilst athlete settings
(such as zones, measures etc) are now maintained in a new
config dialog accessible from the athlete view (gear icon).
.. Config changes are communicated via two signals;
* Context::configChanged(qint32)
* GlobalContext::configChanged(qint32)
Crucially, all global context signals are cascaded through
the athlete contexts-- so athlete specific widgets only
need to connect to the athlete context signal (and will get
athlete and global config change notifications).
Whilst global widgets such as the sidebar and mainwindow
need only connect to the globalcontext signal since they
are not interested in athlete specific details.
[publish binaries]
.. Ride metadata was associated to the athlete rather than a
global setting. This was a serious design flaw since user
metrics can reference metadata.
.. A global metadata.xml file is generated on startup by
consolidating all athlete level settings into a single
configuration.
.. Other dependencies were also moved; SpecialFields,
ColorEngine and UseMetricUnits.
.. We should now be able to remove athlete configuration
from the config dialog and put it into the athlete view
instead.
This will also fixe a long standing issue with
configuring athlete settings when multiple athletes are
open.
[publish binaries]
.. the 'Details' chart now combines editing the metada fields such as
workout, sport, notes and so on, with an additional tab 'Raw Data'
that contains the RideEditor.
.. it is now no longer possible to add Editor inidividually and the
Summary and Details chart is deprecated (Summary will also be
removed once Overview has enough functionality to replace it).
This reverts commit 6bc48200e7.
It is crashing on Windows 8, I can't debug on that version
and it is not that useful feature, --debug gives more information.
[publish binaries]
.. the views were not being deleted, so the global context connection
to configChanged signal was still called, but the athlete and
context were long gone - so SEGV (!)
.. the reason this didn't get triggered in earlier releases is due to
the fact the event was disconnected when the athlete context was
deleted.
.. move thread based load of ridecache into ridecache, this fixes a
serious regression.
.. previously because the ridecache was created in a thread it could
not attach to the events from the main gui event loop.
.. we now load the RideDB.json file in a worker thread, but the
ridecache, and its items are created in the main thread.
Since F3 was assigned to Calibration, its use as modifier was deprecated.
Also nextDisplay is not implemented so we can do some cleanup.
F1 is restored to their original function: start/pause and F2 is used
for new lap, in both cases with debouncing to avoid false activations.
This way the same functions enabled for ANT+ remotes are available via HBC:
Start&Pause: F1
Lap/Interval: F2
Load increase/decrease: +/-
Calibration: F3
measures.ini is looked for in Athlete's config folder,
it should have a section for each measures group,
nutrition data with Energy and Macros is provided as example.
Moved default weight to About and removed RiderPhysPage and created
a tab for each measures group under Measures.
MeasuresPage handles conversion between metric and imperial units
Generalized CSV import with configurable headers.
MeasuresDownload enables download from Withings/Todays Plan only for Body
measures.
This is Part 1/2 of #2872
.. GlobalContext::context() provides a global context that is not
tied to an athlete or MainWindow.
.. At present it just offers signals for config changes but will
likely see more context move across as the application preferences
and athlete configuration are separated as we enhance support
for multiple athletes.
Similar to Linux/macOS builds, messages are redirected to goldencheetah.log
when not output to console is requested, but instead of relying on low level
stderr redirection a message handler logging directly to the file is installed.
[publish binaries]
configdialog_ptr is already maintained to handle raise event,
cleanup is moved to destructor to ensure it is always called,
and it is used to ensure:
1) only one instance is created from MainWindow
2) it is closed on MainWindow destructor
Fixes#1918
The logic to generate synthetic speed/distance/cadence sample data
from length records was removed from FitRideFile, and Fix Lap Swim
data processor is now used for that task, this is simpler, avoids
code duplication and preserves other data s.t. HR and Temp
Fixes#3545
total_timer_time is used as length duration instead of total_elapsed_time
to support Suunto lap swim files
Fixes#3272
.. since the context of the first athlete is used as a partial
application context across the code we now prohibit closing
the first athlete opened.
.. we will separate out the app and athlete context shortly
but this will at least protect against SEGV.
[publish binaries]
.. Show days since last activity and disable config icon since there
isn't an appropriate action for now
.. Athletes can be opened and closed via the tiles and a reusable
'Button' overview widget is available for re-use elsewhere.
.. Part 3 will enable checking for downloadable data to show an
indicator on the tile for e.g. coaches with multiple athletes.
NOTE:
There are a few issues regarding application context separation
from athlete context that need fixing up (if you close the first
athlete loaded expect crashes). Will look at this as a separate
update since its been there for some time and is not related to
the new view per se.
.. modern light now uses the Fiori Belize Blue theme.
.. this means that the overview (chartspace) background is now also
configurable, so the existing themes could be updated.
.. probably need to revisit all the themes tbh.
There has been some reports about performance issues on Windows,
and this was a debug tool for a feature which has been stable
for years, so we can remove it to avoid the overhead.
[publish binaries]
.. string manipulation using raw C since its simple character
replacement, halved time over previous approach.
.. lookup rideitem in ridecache via binary search (lower_bound)
rather than serial. Minor speed up.
.. Overall, loading should be noticeably quicker for most users.
.. introducing the athlete view
.. at startup the first athlete is loaded as normal, but once the
mainwindow is open the athletes are managed from the athlete view
.. athlete ride cache restore happen in background (via a thread) to
enable the GUI to remain responsive whilst it takes place (since
for most non-trivial cases it can take 30 seconds or more).
.. multiple mainwindows has been deprecated and whilst each open
athlete is selected via a tab, this will change to a combobox
in later commits.
.. the tiles in the athlete view do very little apart from show the
avatar and progress/load status when an athlete is being loaded.
.. future commits will introduce more detail and actions for the
athlete tile and deprecate the athlete tab bar for a combo on
the toolbar (amongst other things).
.. Scatter chart click thru from trends.
.. Need to decide how click thru will work from a line chart as the UX
doesn't quite work as the auto hover points are elusive (they move
when you go to click on them). Will review and fixup shortly.
.. Enable click through from the data points on a generic chart
when on trends view.
.. This commit includes the 'addCurve' bindings to pass the
activity filenames from R, Python and the User Chart.
.. It also includes a new DataFilter function 'filename' to
get a vector of strings that are the filenames for the
activities in the selected date range (or the filename
for the currently selected activity).
.. The second commit will include the interaction code for
GenericPlot to click-thru a selection.
Import Texts from Erg files in TrainerRoad format, Zwo files and
from Lap names in json files.
Display texts on TrainBottom for both, erg and slope mode, at the
corresponding time/distance for the specified duration.
Export Texts in erg, mrc and zwo formats.
Fixes#1118Fixes#2967
Prerequisite for #2098
.. adding some new functions for working with strings:
trim(p) - trim whitespace
tolower/toupper(p) - convert case
split(p, sep) - split a string into a vector
join(p,sep) - join a vector into a string
replace(p, s1,s2) - replace s1 with s2 in string or vector
.. this is the last of the first wave of commits to support
strings, but more will come as we work with categorical
data, factors and so on.
[publish binaries]
.. show/hide sidebar setting is reinstated on restart, is specific to
each view and now the menu check stays in sync with user selection.
.. another old glitch thats taken a while to get resolved !
.. metadata("name") returns the value for the metadata field on analysis
view or a vector of values if on trends view.
.. also fixed a few nits when working with category data on the user
chart; sort/multisort had bugs, blank labels and pie chart legend.
.. since we can now set category data using string vectors we can
support bar and pie charts in the user chart.
.. there were a few issues switching between bar and pie charts
related to the way axes were being configured that have been
resolved in this commit.
.. Update builtin functions to support working with strings as well
as numeric vectors; e.g. sort, uniq, aggregate
.. next commit will add some new functions that are specific to
working with strings; e.g. tolower/upper, split, replace.
.. Update operators to support string vectors; compare, assign, index,
select, contains and so on.
Most maths operators make no sense apart from '+' which concatenates
strings and arrays together.
.. next commit will update functions where they are appropriate for
strings and string vectors; sort, uniq etc.
.. Strings and vectors of strings are useful for plotting bar charts
or wherever category variables are needed, they are also useful
when working with xdata names and metadata within ride files.
.. Full support for strings will be introduced over the next 4
commits, including this one (1 of 4):
1 - Basics - Create, Assign, Coerce, isString
2 - Operators - Logical, Math etc
3 - Functions - sort, uniq, aggregate etc
4 - String Functions - cat, split, toupper/lower etc
.. Will wait until all 4 commits are completed and string support
is feature complete before updating the wiki.
[skip appveyor]
Homebrew upgraded to python to 3.8, switched back to the 3.7.5
included with the Travis image until we decided to upgrade.
Changing to 3.8 requires to upgrade SIP to 5.x and testing.
.. click on item in list to select it and click thru to analysis view.
.. also implemented a hotspot() method in chartspaceitem to tell the
chartspace to stop stealing events when in our hotspot-- in this
case it was the area where we paint the list.
.. stackpointer increment before redo and indexing into the stack
when stackpoint is -1 in NavigationModel::forward().
.. introduced in the last commit.
.. clicking on an activity in the trend overview bubble chart will
switch to analysis view to look at it.
.. to support this all the underlying changes to navigation model
and related have been updated to force view change and allow
going back and forth in the navigation model.
.. along the way a couple of bugs were also squased. The worst was
a SEGV related to Tab::rideSelected() calling MainWindow::sidebar.
.. now the main foundational code is in place we can add more click
through opportunities; e.g. top N on overview, user chart.
.. back and forward buttons to navigate between views and selections.
.. currently limited to just rides, date ranges and views.
.. next step is to enable click to select from trends overviews to allow
users to drill down from the season overview into activities and
back again.
.. part of the shift from searching through lists to analyse data to
exploring data visually with drill down and click through.
.. the buttons are very basic and there is no way to explore the
history / recently viewed items etc. these will come later.
Fixes#3529
.. the user can configure the colour of toolbars and sidebars, so this
is honored in the sidebar painting,
.. we should look at separating out the way theme colors are edited;
the core colors are more important than the pallete colors like
CPOWER etc (and as an aside the palette colors should be usable
from user chart config too).
.. gap between ride list and sidebar color didn't get reset when change
color theme in preferences. (was a nightmare to find the fix).
.. overview default backgrounds when changing themes were also really
bad choices and toned down. quite why we have to change in pages.cpp
and colors.cpp is a bit tedious.
.. new metric 'Activity Date' which is days since 1900/01/01 as a metric
so can use wherever metrics are used.
.. added RideMetric::isDate() so we can mark as a date and honor setting
in RideMetric::toString()
.. updated BubbleViz to support Dates by using xoff and yoff to truncate
the values used when days since values.
.. changed the default config for a trends view bubble viz in overview
to use activity date as the x-axis.
.. thanks to Ale for the original idea behind this.
.. repurpose the interval bubble to show activities instead of
intervals.
.. changed the animation/transition to work better when looking at
seasons by resizing the axes before updating the points.
[skip appveyor]
Not a great difference, but we are too close to 50' limit
Also reduce curl max time to avoid timouts.
For Linux buils remove --silent build to avoid the job being cancelled
The block was introduced in bb6d2552c0 to
avoid the upload of charts without configuration, now configuration is
possible and it will be interesting to see what layouts users share.
The y scale is computed from the font instead of only from the current content, to avoid having different scales between different Text widgets of the same size. For example, "kph" has a high k and low p, resulting in a text widget with bigger bounding box, and thus smaller scale than a text widget with "watts". Options are added for alignment and for text width, to help align the different entries. The formatting of metrics with the integer part as Text and fraction as AltText is more systematic and it is possible to add an AltTextSuffix, to specify the units when they are not provided in VideoWindow. The visibility of the BoundingRect and Background car be controlled.
.. its much faster to vectorize and use the samples() function in init
or value function when working with user metrics.
for example this code:
sample {
work <- work + (POWER * recIntSecs);
}
value { work; }
count { Duration; }
should be refactored to:
value {
work <- sum(samples(power) * recIntSecs);
}
count { Duration; }
To be used as workouts and videosync with free Ergo Planet Videos
EPM files contain video sync plus geolocation information in XML format
Library of free rides: http://wiki.ergoplanet.de/myor/roadmovie-galerie
The problem is altitude set to zero in those examples, likely because it is
redundant when you resort to the EPP (Ergo Planet Program) for slope data,
but the EPP is an unpublished binary format we don't support directly.
So the workflow to use the those synchronized videos is:
1) Import the .epm file to GoldenCheetah as an activity
2) Use Fix Elevation and Fix GPS to add and smooth elevation and route data
3) Export the conditioned activity to GoldenCheetah JSON format
4) Import the .json file as Workout and VideoSync files,
plus the .avi as media in GC Train mode using Scan Workouts and Media
5) Train using a Video Window with overlay widgets and simulated speed for
better experience.
Fix base class toString 2 parameters bug
Use toString(metric, value) in getStringForSymbol to avoid setting the value
Use toString(metric, value) in MetricOverviewItem::setDateRange for testing
Any other activity file format GC supports can be imported,
conditioned using Fix Elevation, Fix GPS, etc. and exported
to GoldenCheetah .json format to be used for simulated rides
with synchronized video and position tracking.
Complements #3469, Fixes#3376
.. shows a little medal on the metric tile if it is a best for the
period. Shows if top 3, in order:
- all time, including the future
- all time till today
- last year
- last 90 days
- last 30 days
.. helps to highlight positives from most activities.
Initial implementation of #3482
LiveMap is hidden when GPS data is not available
New layout including Live Map and graphical widgets
added to video-layout.xml, zoom can be configured there.
The video layout file is extended to contain possibly several named
layouts. The file is read to list the layouts and offer a selection in
the Video Player chart settings menu. The file is then read again to
instantiate the selected layout.
* Base work for dynamic speed power curves.
* Add test for spindown - proof templates.
* Dialog for adding virtual power curve
* Finished.
* Potential typename fix.
* Fix another typename problem.
* const typename reorder
* Missing header in clang build.
* Fix error with static init order.
* Forgot to set id for known devices.
.. plot metric by category as a donut (pie) chart.
.. particularly useful as an overview of sport or workout codes for
multisport athletes.
.. also fixed up metadata selection which was broken (!)
.. layouts mucked up a bit, needed stretches
.. the filterset wasn't updated correctly, causing filtering to not
work in the way anticipated.
.. Activities metric should be a MetricType::Total, which will become
more popular on Metric tiles with filters (e.g. how many activities
> 0.85 IF etc).
But to check for errors.isEmpty() is overkill, when the returned value
is not NULL, they can be warnings according to RideFileImport interpretation.
Fixes#3479
.. updated the overview chart to support trend view and summarise
a season or date range.
.. scope now meaningful in the item registry.
.. added a new TopNOverviewItem to view a ranked list of activities
by metric.
.. updated sparkline to plot variable range (>30days)
.. sort and multisort datafilter functions adjusted as caused a
SEGV during testing (sorry not in separate commit).
Some accuracy was lost in an integer divison for speed and cadence in
getCadence and getWheelRPM, the expression was correct but non obvious
in setWheelRPM, and the speed was not reset upon disconnection for
CyclingPower while this service is used for power and speed when present.
All the commands to set the different parameters (weight, wheel size,
gradient or load, wind speed...) are added to BT40Device and
BT40Controller. A separate pull request will add support to actually
take advantage of these parameters, like the cyclist weight, now
available in this and other devices like the Fortius.
[skip appveyor]
Fallback to previous Qt and Python versions available on Homebrew
to until we can compile Qwt with Qt 5.15
Python comes back to 3.7.5 since the upgrade to 3.7.7 triggers a Qt upgrade.
Qt comes back to 5.13.2
Currently, size is computed from the QWidget geometry height in pixels and then used to set the font size in points. In many cases the result is not that bad because, depending on the screen size and resolution, the pizel size is not that far from one point. We now convert from pixels to inch (DPI) and then from inches to points (72 points/inch). This solves the problem of the text being clipped sometimes or the margin being too large.
Since they reset the brackets, defeating their use by wattsAt and
forcing all searches start from the beggining, and generating
problems with ErgTimeRemaining, which depends on rightPoint.
This problems was introduced by 1402f6ad6aFixes#3491
Some nits from recent Overview updates:
* compiler error using 'and' instead of '&&', gcc happy, msvc not.
* kpi overview item default set to CP estimate
* add chart wizard formatting of final page.
.. uses a datafilter program to calculate a kpi and displayed alongside
a progressbar that shows how the value is progressing to a goal.
.. its really useful to compute across estimates, mmp etc without having
to write a custom metric
.. one simple example is to show CP estimates and progress towards
a target CP or 5 minute best, or perhaps weight.
A program to display the internally generated CP estimate using
the Morton 3 parameter model would be:
{ round(estimate(cp3,cp)); }
.. allow edit and remove of existing items on the overview.
.. due to the way widgets are managed by layouts we create the
configuration widgets on demand and they will be deleted
once the dialogs close.
.. this is fine for overview, but will require a significant
level of refactoring once we start adding charts such as
allplot, trends etc to be added to a chartspace.
[publish binaries]
.. 'Add Tile' added to the overview menu - to enable users to
choose and configure tiles to add to the dashboard.
.. ChartSpaceItems should now be registered to a new chart
space item registry, which will eventually replace the
current window registry
.. ChartSpaceItems need to register a method to create new
items with default settings and provide a widget for
configuring themselves.
.. A new config widget has been created to cover the
overview tiles and some gui components for selecting
metrics, metadata fields and ride series have also
been added.
.. In part 2 we need to add the ability to configure
existing tiles and also remove them.
.. still have a problem with chartspaces that have zero items that we
will need to address, but this at least means when we add an overview
it isn't blank.
Fixes#3476
This gives a more Unix-like behavior when GC is launched from
cmd or PowerShell, including --debug output, on release builds.
Fixed#3481
[skip travis]
[publish binaries]
.. context menu action and processing in event loop deletes the widgets
whilst events are being processed for it. So in event processing we
now return immediately after triggering context menus.
.. when editing a series the de-dup check included the series we are
in the process of editing- which of course led to it always detecting
a duplicate.
.. we now exclude the series being edited from being checked as a dupe.
.. duplicate series names cause all sorts of problems with the
internal maps and lookups and must not be allowed.
.. if the user creates/edits to create a duplicate series name
we append '_n' (where n is any number from 1 upwards) to
guarantee we never habe duplicates.
.. commit 28b2428 introduced a regression whereby the searchbox will
expand to fill space which was jarring in chart settings.
.. this commit reinstates a fixed height, but slightly larger to
remain compatible with the mainwindow toolbar.
.. from now charts that add custom actions will need to also add the
action to pull up the chart settings - since it is assumed the
custom actions are overriding the standard approach.
.. fixes a regression from the chartbar context menu on tabs commit
where it is not possible to edit the setting for a trends or a
critical power chart.
The "Ignoring the CSC service for device..." was intended to notify when power
sensor is present the CSC service is ignored since it is redundant and may
cause problems, but it is misleading when there is no CSC or Power service.
Reported in #3471
.. instead of the 'More...' button in the top left of a chart when in
tabbed mode we now have a menu button when you hover over a tab.
.. the menu button activates the chart menu for now, till we refactor
to using a chart space.
.. the 'More...' menu is still available when in tiled mode (we need to
decide what to do there).
Unlike for the cadence value which uses 1/1024 second units, the wheel
revolution value is based on 1/2048 second units [1]. It is easy to
notice the problem when you ride downhill at 25 kph instead of 50kph! In
addition, the speed was initially incorrect because the previous wheel
position value was stale. This would sometimes give the speed of a
rocket for the initial interval and make a jump on the distance of
several km.
[1] Cycling Power Service, Bluetooth Service Specification, Date 2016-05-03, Revision CPS_v1.1, Prepared By Sports and Fitness Working Group, head of page 15.
https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=412770,
When parsing a "distance slope wind" type, a truncate to integers was done
after computation to meters. This involved rounding issues that were
accumulated, and were quite visible when such a file was used to synchronized
with an RLV video (the slope changes happened "too early").
.. the OverviewWindow class has been refactored to extract out the
core dashboard UX/UI into a new class ChartSpace.
.. additionally, a ChartSpace contains a set of ChartSpaceItem which
need to be subclassed by the developer.
.. for the Overview a set of OverwiewItem classes have been introduced
such as RPEOverviewItem, MetricOverviewItem and so on. These are
subclasses of the ChartSpaceItem.
.. The overview window implementation is now mostly configuration and
assembly of a dashboard using OverviewItems and the ChartSpace.
.. This refactor is to enable the ChartSpace to be used as a drop in
replacement for the existing TabView.
.. There are no functional enhancements in this commit, but the
overview chart shouls appear to be unchanged by the user.
Switching from start_index to start_date_local fixes#3457
Since Duration is End-Start+1, End is decremented to match elapsed_time.
fixLapSwims don't rely on Smart Recording being enabled and,
since km is distance at the end of the sample, a correction is added.
Michael Dagenais found this change makes the widgets to play nicer with
Windows Managers and avoids them to get on top of other programs windows.
Minimize and Restore is automatically handled now, so this commit partially
reverts b89019264e, removing MainWindow
state changes tracking, but keeping VideoWindow position tracking.
This is a clean up to remove conditional compilation for all Qt versions
older than the last known to work: Qt 5.9 with Qt WebEngine and Qt Charts.
Includes an update note to INSTALL documents.
When the video widget is scrolled, the MeterWidget windows appeared on
top of the Main Window user interface. Now the visible portion of the
Video Window is tracked and used as a clipping region. This avoids
blocking the controls on bottom toolbar.
Interpolation math fixes: Slope and interpolation behave correctly when
ride point location doesnt change.
In gpx read: do not open same file twice with different read flags.
When the main window is minimized on Linux, the MeterWidgets stay on the desktop.
A signal were added to the main window for state changes.
The VideoWindow connects to that signal and hide/shows the MeterWidgets accordingly.
Currently, when you move the main window, the MeterWidgets do not follow
and become out of place.
On every Telemetry update, check if the real position on screen of the
video window has changed in order to update the position of the meter
widgets. The Video Window can move for several reasons like when
scrolled or when the Main Window is moved. The Meter Widgets are not
clipped like the Video Window by its scroll area parent though.
Elevation widget was showing progress based on distance, which is workout distance and didn't accout for distance change due to skip forward/skip back.
Add routedistance to realtimedata so elevation widget can access it
elevation using routedistance to show progress
Fix uninit iterator in elevation widget paint
Draw route distance in elevation widget
.. estimates(model, cp|ftp|w'|pmax|x|date) - returns a vector of values
for the model selected.
As with the estimate() function, passing a duration value 'x' will
return the PD model estimate for that duration.
.. also removed hard coded model names.
Enable Meter Widgets overlaid on Video Window for Linux
Meter Widgets, with a transparent background over the video window, use
little screen estate while providing all the needed information. They
were added for WIN32 first but actually work fine on Linux with minor
flag adjustments.
.. tests(user|bests, duration|power) - with no parameters will just
return the number of tests in a ride/date range, or with 2 parameters
will retrieve user defined or bests found by algorithm the last
parameter defines if duration (secs) or power (watts) values are
returned.
After this change:
QtMacVideoWindow.h is used only for native macOS video options:
GC_VIDEO_AV (incomplete)
GC_VIDEO_QUICKTIME (obsolete)
Otherwise standard VideoWindow.h is included with the same options for
the three supported OS:
GC_VIDEO_NONE: placeholder for no video, currently used for macOS builds
GC_VIDEO_VLC: basic video control plus videosync, macOS experimental
GC_VIDEO_QT5: basic video control only, macOS experimental
Overlay Widgets only works on Windows with VLC.
Tested with VLC 3.0.8 on the 3 Operating Systems.
.. resample(old, new, yvector) - returns yvector resampled from old
sample rate to new sample rate. Assumes yvector has already been
interpolated or smoothed as needed (see the interpolate function)
For example, resampling to 10s power samples in a user chart:
{
finalise {
t <- samples(SECS);
xx <- seq(head(t,1),tail(t,1),10);
yy <- resample(RECINTSECS, 10, samples(POWER));
}
x { xx; }
y { yy; }
}
.. interpolate(linear|cubic|akima|steffen, x,y, xvalues) - returns a
vector of yvalues for each element in xvalues where the points
in x,y are interpolated using the selected algorithm passed
in the first parameter. e.g:
xx <- samples(SECS);
yy <- samples(POWER);
first <- head(xx,1);
last <- tail(xx,1);
zxx <- seq(first, last, 0.1); # 10ths of a second
zyy <- interpolate(cubic, xx, yy, zxx);
For Windows we use Python embeddable distribution
For Linux the relocatable Python AppImage
Packages included: sip, numpy, pandas, scipy, lmfit and plotly
[publish binaries]
.. added WBAL and WBALSECS as options for the samples() function to
retreive the w'bal value (in joules) and the secs too.
.. seconds are potentially different to the samples(SECS) values as
the w'bal series is always in 1s samples with gaps in recording
accounted for as part of the calculation.
[skip appveyor]
Initially: sip, numpy, pandas, scipy, lmfit and plotly
Deployed Python added to search path
Binaries reference the Python library on Cellar
Related to 2c0ce8f5c5
.. bin(data, bins) - returns a vector of the data binned into bins, any
data less than the first bin will be discarded, and data greater than
the last bin will be included in the last bin.
the returned bin is based upon counts, so will need to be scaled
if want duration in seconds.
e.g:
b <- bins(data, quantiles(data, c(0,0.25,5,0.75,1))) * RECINTSECS;
.. annotate - didn't validate parameters - seemingly inocuous but there
are multiple validators that update leaf->seriesType. When this did
not happen a) syntax errors were ignored (and caused a crash) and
b) functions like samples(POWER) returned the wrong data.
.. annotate - assumed parameters were numeric or string but did not
support vectors.
.. lots of use of 'it' as a variable, overriding the scope of the
DataFilter::eval() function parameter which in a couple of cases
led to SEGV ('it' is used when indexing vectors).
.. quantile(vector, quantiles) - returns quantile values for the vector
passed. quantiles can be a single value, or vector of values. The
quantile is expressed as a value between 0 and 1, where 0.5 would
represent the median. Values outside this range are truncated to
0 or 1.
.. daterange(from, to, expression) - executes the expression setting the
selected daterange as from-to.
.. any expression that honours the trend view date selection will use
the from-to dates provided.
.. for example, to get weight data for a specific daterange:
measures <- daterange("2020/01/01", "2020/05/01",
measures("Body", "WeightKg"));
.. meanmax(SERIES [, start, stop]) - now allows the user to provide a
date range for the meanmax data to collect. This is so you can, for
example, plot a 'last 90 days' curve:
{
finalise {
yy <- meanmax(POWER, Date-90, Date);
xx <- seq(1, length(yy), 1);
}
x { xx; }
y { yy; }
}
.. meanmax(xvector, yvector) - returns a mean-maximal curve in 1s
intervals from the x,y pair passed in.
the data will be truncated where xvector and yvector are different
lengths, negative y values are set to 0 and the entire dataset
will be interpolated where there are gaps (i.e. the data is not
presented in 1s intervals).
.. the vectorized version of best() - returns a vector of either dates
or peak values for given duration, usage:
bests(SERIES, duration [,start [,stop]]) - get the peak values for
the given duration and optional date range
bests(date [, start [, stop]]) - get the dates of the peak values
but no duration needed but can still proved an optional date range.
.. when you use a selection for a vector e.g. vector[x>0] the vector
that is returned does not set result.number to the sum. This breaks
most of the vectorized functions.
.. for example; mean(samples(POWER)[x>0]) should compute NZAP or
non-zero average power, but instead it calculates as 0 due to
the selection sum bug.
.. get the ridefilecach distributions, precomputed distributions of the
main data series (but not all).
.. dist(series, data|bins) - returns vectors of the series data (count
of points for each interval) or the bins.
.. nozero(v1) returns a vector of indexes into v1 for non-zero values.
Whilst it is possible to do this with sapply() this convenience
function is faster - and the use-case crops up very often.
.. the generic plot didn't register quadtrees if it thought they didn't
contain any nodes, but didn't take into account the fact the root
node could contain up to 25 points.
.. last commit didn't avoid the detach() derefernce in a thread because
it used the [] operator which is non-const, instead we should use
QVector::at(int)
.. A few situations that cause race conditions and crashes when metrics
are being refreshed, found whilst testint user metrics.
1. access to QString is not thread-safe, fixed with a const
2. metric vector resizing is needed even if all metrics are zero
3. entire ride interval needs to be computed, assignment in thread
is not thread-safe and was incomplete anyway.
.. match(vector1, vector2) - returns an index of values; for each value
in vector1 it will return the index into vector2 if there. if the
element in vector1 is not found in vector2 no entry will be added to
the returned index.
.. e.g:
a <- c(4,6,9);
b <- c(1,2,3,4,5,6,7,8,9);
d <- match(a,b);
# d now contains 3,5,8 since indexes start from 0
.. mlr(yvector, xvector1 .. xvectorn) - perform a multiple linear
regression and return a vector of coefficients for each x.
.. under the covers the covariance matrix and chi-squared are both
calculated, but discarded. We should make these available to the
user at some point.
.. requires the GNU scientific library, which will become a mandatory
dependency at some point soon.
.. will become a first class dependency, but for now, whilst we
update the build systems it is optional.
.. to enable update gcconfig.pri with
DEFINES += GC_WANT_GSL ## switch GSL support on
GSL_INCLUDES = ## the include path (no -I)
GCL_LIBS = ## -Lpath and -lgsl -lgslcblas -lm or others
.. see gcconfig.pri.in for examples, Linux has been tested.
.. to install this new depdendency:
Linux: sudo apt-get install libgsl-dev
MacOS: brew install gsl
Windows: vcpkg install gsl
.. if there is a python chart in the view, it will crash as setWeb
does not check to see if embedding worked, and is called via the
property system so must always check.
.. due to qt-bug 62285 we need to use local time not UTC for timespec
since qt charts converts to local time internally.
.. this fixes axes starting at 1hr instead of 0h.
* 1 - Add forceSquareRatio to MeterWidget
* 2 - Adjust default colors and add background text.
* 3 - Add Elevation widget, included in default layout visible only on slope mode.
Based on the work done by Vianney Voyer
Co-authored-by: Peter <pkanatselis@gmail.com>
.. RideWindow is no longer required and brings in artefacts that have
security alerts. This code should have been deprecated previously
and was retained in error.
Fixes#3426
* Add VO2 and Ventilation graphs to WorkoutWidget and add settings
* When running tests with VO2 measurements, it can be useful to see a
graph of at least VO2 but also Ventilation to determine when e.g. a
ramp test results in a plateau and can be considered done.
* Make the color of some VO2 measurements configurable.
* Add chart settings to WorkoutWindow, so that plots can be enabled or
disabled. Also add the possiblity to do averaging.
* Use the term Ventilation instead of Respiratory Minute Volume
* Rework to not affect RideFile
Move from using SeriesType from RideFile in order to allow more series
to be added without modifying RideFile.
In recent Qt versions there's support for BLE on Windows, so remove the
check that disables it.
In Qt 5.14.2 and earlier there's a bug which causes problem if you do
certain things in the context that the signals are emitted. This is only
on Windows, and might be fixed in later versions, but use
Qt:QueuedConnection for now to avoid this.
Some more details of this can be found in Qt bugzilla:
https://bugreports.qt.io/browse/QTBUG-78488
.. the while loop limit of 10000 loops is too low, especially when
looping over ride samples.
.. the pd model short names contain spaces and will never work with
the datafilter estimates() function.
.. aggregate(vector, by, sum|mean|max|min|count) - aggregate vector v
grouping by vector by (which will be repeated if too short) using
the function sum .. count to perform the aggregation.
.. returns the aggregated series, modelled on the R aggregate function.
.. week() & weekdate() - week converts a date to weeks since 1900/01/01
and weekdate() converts weeks since 1900/01/01 back to the date at
the beginning of the week.
.. month() & monthdate() - week converts a date to weeks since
1900/01/01 and weekdate() converts weeks since 1900/01/01 back to
the date at the beginning of the month.
.. basically useful for grouping by week and month or other forms
of date arithmetic.
.. for line charts when one curve is shorter than another the code for
calculating the nearest point (along x-axis) didn't account for
negative and positive results from a quick calculation.
.. just needed a little help from our friend std::fabs()
.. measure("group", "field|date") - get the measures or dates of the
measures.
.. enables us to work with measurements independent of activies, but
we probably need a way of controlling interpolation so we can
get a vector that only contains measurement points.
Copied gc-ci-libs.zip to GoldenCheetah/WindowsSDK after removing
deprecated dependencies (kQOAuth and QwtPlot3D) and adding vlc dlls.
Used --version command line option for minimal testing.
.. sorry, but the power profile colors are hardcoded (which is fine)
but they are too dark, so fixed that up.
.. also the overview (until it is configurable) doesn't show total work
or variability index. Which I've added as they are quite useful esp.
work as a proxy for load and calories.
.. working with user charts to plot configured CP versus the trend
in power indexes led to some new code and a few fixups:
* new metric PeakPowerIndex is the best PowerIndex value for the
ride based upon power mean maximal data. It is not computed for
intervals.
* overview chart default config shows the PeakPowerIndex instead
of Power Model which was blank and unimplemented.
* the overview chart was not in the window registry, it must have
been removed by accident in a cut and paste incident
* the 'activity' function is userchartdata was not called, the code
was not included (it iterates over samples, but not activities)
.. When the widget in QScrollArea resizes the position is set to origin,
which is a regression introduced sometime after Qt5.9.
.. If the chart bar was scrolled then dragging a tab would cause the
buttonbar to be resized temporarily as the item is removed from one
index and placed at another.
.. To get around this we make the buttonbar fixedWidth, which means no
resize events or processing occurs. But it means we need to adjust
as widgets are added and removed.
.. Fortunately an existing function 'tidy()' is available to do this for
us, but needed to be controlled (only resize when widgets are added
or removed).
.. If the regression is fixed this commit can be reverted, but it should
be harmless with/without any Qt fix.
.. turns out the stack in homewindow and the "buttons" on the chartbar
all need to be re-ordered to align with the tab index.
.. some poor design in here, but letting it go for now as we will be
replacing the 'HomeWindow' widget in this release cycle anyway.
.. scroll left and right jumped to front/back which assumes there isn't
more than 2 page widths of charts -- this is not always the case.
.. we now scroll a third of a screen full at a time with animation to
give some feedback to the user as we scroll.
.. remove the old scope bar in favour of a more modern sidebar as we
transition the UI to a new design.
.. the newmainwindow approach is not practical, as making 2 UX coexist
at the same time was impossible and would lead to major issues.
.. note a number of views are on the sidebar but disabled, they will
be added over time.
The 2nd parameter of RideItem::getForSymbol is a boolean for metric/imperial,
passing c selects imperial units when metrics(Symbol,...) is used in LTMPlot.
Exiting isRun/isSwim are preserved and new isRide/isXtrain added.
Use them in DataFilter to provide isRide, isRun, isSwim and isXtrain
and in RideSummary for better filtering of activities in rides, runs
swims and xtrains.
Part 1 of #3280
.. metrics(symbol) now supports an optional start and stop date
range.
.. metrics(symbol|date [, start [, stop]]) - where start and stop
are numberically days since 1900/01/01 or can be date strings
such as "2019/12/31" for 31st December 2019.
.. this is to provide an alternative way of working with metrics
that was previously supported with the '[[' and ']]' operators.
.. be consistent with dates and always work with days since
1900/01/01. That way date arithmetic is consistent in the
data filter.
.. the GenericChart converts data to MS since Epoch if the axis
is a date range, in the same way it does for Time axes.
.. basics for Mac native toolbar without title and support
for resize and full screen etc.
.. toolbar is empty and will need cocoa elements added but
will fix up when MS Windows native support is to the
same level.
.. suspect only Linux will use frameless and might move to
accepting the toolbar is present on Linux.
.. simple start just to resolve functions typically performed
by the window manager. Minimise/Maximise.
.. need to resolve resize by dragging sides/corners as well as
drag from full screen.
.. Not 100% convinced this is the right strategy (frameless
window and managing resize/drag within the mainwindow).
.. prototyping a new qmainwindow layout, will only be shown
if you pass --newgui on the command line.
.. there will be lots of commits as this develops across
different platforms and building blocks are put into
place.
.. this is likely to take 2 months or more before it becomes
something usable.
.. the --newgui is for developers only, since there will not
be any usable functionality for quite some time.
Upload/Download are similar to Export/Import in User Metrics config dialog.
Admin interfaces are similar to CloudDB charts for both user (edit/delete)
and curator (set curated/edit/delete).
Name and Description are initialized to the corresponding items for the metric
but both can be edited to provide different/more complete information for the
CloudDB interfase.
Fixes#3361
.. when you change colors in preferences the user chart didn't honor
the new plot marker color and the generic legend did not update the
background color.
.. lowerbound(v, value) - returns the index into v for the first
element that does not evaluate to < value.
This is a binary search modelled after std::lower_bound (and
uses it in the implementation too)
.. need to refresh the user program when it is edited by the user.
the last commit fixed a memory leak in this code but broke it.
.. should think about changing this piece of code and allowing the
userchartdata to accept a new program to process (instead of
it being set in the constructor).
.. curve(series, x|y|z|d|t) - retrieve the data from another curve so
we don't have to recompute it when working with user charts.
if the datafilter is not on a user chart it will return 0. User
needs to ensure the series are ordered correctly for this to work.
.. you can now use algebraic operators with vectors. If a vector
is shorter it is repeated to match, e.g.
a<-c(1,2); b<-c(1,2,3,4,5); d<- a * b;
is calculated as;
d<- c(1,2,1,2,1) * c(1,2,3,4,5) and will yield: 1,4,3,8,5
.. arguniq(list) - returns an index into unique values in the list. the
list does not need to be sorted, the returned list index always
refers to the first item in a list (not the later duplicates).
.. uniq(list [,list n]) - will de-dupe the first list by removing
duplicates. All remaining lists will have the same items removed
by index, in the same way as sort/argsort.
.. meanmax(efforts) - runs the filtering scheme used on the cp plot to
filter out submaximal data; a mixture of comparison to a LR, maximal
from same date considered as an averaging tail and use of power
index.
.. it returns a vector of indexes into the meanmax data for power;
so meanmax(POWER)[meanmax(efforts)] can be used, but since the
index starts at 0, need to add 1 to get seconds.
.. show x-avg on select at the top of a line chart, stops it overwriting
the min/max values. Especially relevant when using a time/date axis
hence limiting to a line chart where this is most common.
.. not neccessary to get out a build just yet, but cycling on the
build number and version string for any development builds
users download from travis or build themselves.
.. allow data labels for points on the chart, added to User, R and
Python chart addCurve() etc.
.. NOTE: opengl painting ignores this setting so should be disabled
for data series that want labels. We do not do this
automatically, but might consider that later.
.. GC.annotate(type="label", series="Power", label="CP=222") added to
the python chart to add a label to the legend for displaying things
like parameter estimates.
.. it does feel like annotations will need to be thought thru and likely
result in a GenericAnnotation class. But lets cross that bridge
when we get there.
.. Label annotations are enough to get started and are now present in
User, R and Python charts.
.. GC.annotate(type="label", series="Power", c("cp", cp))
Provide call for adding label annotations from R to
match the recent update for the user chart.
.. add annotation labels from within a datafilter, ultimately
gets shown alongside the legend in generic plot.
.. this only works from a user chart, so need to add an equivalent
API to call from Python and R.
.. bool(expr) - returns 0 or 1 for the expression passed. This allows a
logical expression to be used in a formula (which is useful when
fitting models).
e.g a*(x>1) is invalid, whilst a*bool(x>1) is not.
.. when editing programs the syntax errors were not being
shared with the user, just a wavy red line.
.. this commit adds the errors to the two main dialogs for
editing user metrics and user charts.
.. in addition a completer was added to the user chart
series editor to help (it already existed on the metric
editor).
.. lm(formula, xlist, ylist) - fits a formula to the x,y data using
the levenberg-marquardt OLS algorithm.
the formula is expressed as any other expression and the starting
values must be set beforehand- this is also reinforced by the fact
the parameters must exist before the formula is declared.
the fit returns a vector [ success, RMSE, CV).
.. an example, to fit the morton 3p model to meanmax would be:
# fetch mmp data
mmp <- meanmax(POWER);
secs <- seq(1,length(mmp),1);
# set starting values, then fit Morton 3p to first 20 min data
cp <- 200; W<-11000; pmax <- 1000;
fit <- lm((W / (x - (W/(cp-pmax)))) + cp,
head(secs,1200),
head(mmp,1200));
.. along the way I needed to refactor the way lmfit is managed and
also corrected banister to avoid threading issues.
.. also snuck in a sqrt() function as needed for testing and was
rather an egregious oversight.
.. when adding symbols to lines or lines to a scatter we
need to show/hide the decoration with the main series.
.. in addition if the decoration is the only thing visible
e.g. symbols for line (with no line style) then still
need to show the hover on the symbols.
.. honour both the symbol and line style settigns for curves. This
means you can have a series on a line chart that is dots and a
series on a scatter that is a line.
.. need to think about best way to manage hover, but suspect it should
only apply when a line chart has a series with no line but has
symbols -- we should hover on them. Currently they are ignored.
.. increasing the precedence for the [ ] symbols resolved the
reduce/reduce issue introduced in commit 1231f59b1a
.. as a result the new rule added in that commit has been
removed.
.. thanks to Ale Martinez for the correct fix.
.. smooth(list, ewma, alpha) - smooth data using an exponentially
weighted moving average. alpha must be between 0 and 1, if not
0.3 is used as a fallback.
.. part of a few updates to add some smoothing algorithms to apply
to vector data, this first one is just a simple moving average.
.. smooth(list, sma, centered|forward|backward, window) will apply
smoothing to the list. Note that centered doesn't use multiple
windows when the window size is even, so recommend always using
an odd number for this parameter.
.. will add ewma and maybe some others over the next few commits.
.. you can now configure if a series is shown on the legend, this is
for lines or curves that are there for illustration but do not
need to be displayed in the legend / hovered.
.. they are rather anachronistic. use of vectors across the datafilter
and the metrics() function replaces them.
.. as a by-product nested indexing works without a syntax error (yes
you could add a space, but most folks would be lost).
e.g. a[b[1]] works as you would expect.
.. expressions like a+b*c[n] were being parsed as equivalent to
(a+b*c)[n] instead of a+b+(c[n]).
.. to resolve this symbol[index] is declared first in the grammar
and whilst it will introduce reduce/reduce warnings that is
actually what we want (we declare it early to override the
definition from expr below).
.. keener yacc wizards might have a more elegant solution for
this one....
.. lr(xdata,ydata) - perform a linear regression returning the results
in a vector of 4 values [ slope, intercept, r2, see ].
.. as a by-product the slope on generic plots now show r2 and see as
they are being calculated by GenericCalculator.
.. need to transform values from MS since Epoch back to seconds
when doing the LR- since we convert when setting up the chart
as Qt wants time based axes to use MS since Epoch (they do not
offer any transformations for the axis).
.. this means that the slope/intercept are now calculated correctly
on charts that use time based axes.
.. whilst its possible to assign to a selection of elements in a
vector e.g. v[c(3,5,7)] <- 99 to assign 99 to el 3,5 and 7
I forgot to update the code to /return/ a vector e.g.;
a <- v[c(3,5,7)]
was not handled at all. This commit fixes that. It means we
can select from a vector element-wise -or- via a logical
expression.
.. sapply(list, expr) - as in R sapply returns a vector of the results
of expression applied to every element in list. Values for x and i
are made available in the expression.
.. v[ lexpr ] - returns a subset of vector v where logical expression
lexpr returned non-zero.
lexpr is evaluated for every element in the vector and has two
variables to work with 'x' is the current element value and 'i'
is the index into the vector (starting from 0).
.. additionally, positional vectors can be used in assign statements
but we did not go so far as to allow selections to do the same in
this commit. that might be fixed later.
.. changed the indexing operators [ ] to work solely with vectors.
so it is now possible to reference an element in a vector:
a<-c(1,2,3,4);
b<-a[1]
will assign the value 2 to variable b.
.. additionally you can assign to an element of a vector, following
on from above:
a[0]<-99;
will mean a how has 4 elements: [99, 2, 3, 4]
.. lastly you can use [] with an expression, so:
c(1,2,3,4)[2]
evaluates as value 3.
.. banister(metric1, metric2, series) - get a vector of banister
data where stress metric1 and performance metric2 are used and
fetch the series which is one of nte,pte,perf,cp or date.
E.g. to get the predicted CP curve using PowerIndex you would
use: banister(BikeScore, Power_Index, cp)
.. pmc(expr, series) work with PMC, generating it from an expression
that is evaluated for every ride (as a stress metric). Returns a
vector of the series specified e.g. pmc(BikeScore, lts)
.. support for axes that are time based, assuming the user has
supplied in seconds starting from 0 (which is true for an
activity).
.. since QT charts requires times to be in MS since Epoch
and we don't know if we need to convert from seconds
until the axis is configured the series data is updated
just before charts are created in GenericChart.
This means that anyone using generic plot directly will
need to do this conversion. For this reason all integration
across the GC codebase should be via GenericChart.
R, Python and now User charts integrate via Generic Chart
so this should not really be an issue.
.. now works on trend view (in rangemode).
.. needed to add daterange to eval in datafilter to provide context
for operations; e.g. meanmax return for activity or daterange.
.. fixed up a few bugs along the way. But now need to resolve the
x-axis in generic plot when using dates and to auto set to some
kind of sensible default.
.. the way data is prepared in a user chart has been redesigned, it now
follows a similar pattern to the user metric program where a number
of functions can be written and will be called at different points.
.. init { .. } can be called to initialise variables
relevant { .. } can be called to shortcut computation
sample { .. } is called for every ride sample
activity { .. } is called for every activity
finalise { .. } is called once iteration completes
x { .. } is called to get the series x values vector
y { .. } is called to get the series y values vector
z { .. } is called to get the series z values vector
d { .. } is called to get the series d values vector (dates)
t { .. } is called to get the series t values vector (times)
.. at present z,d and t serve no real purpose but will be used to
augment data points and be shown on the legend when hovering.
This is a planned future development.
.. meanmax(SERIES) - returns a meanmax array starting from 1s and
length out to longest value available for the selected season.
NOTE: the first point 0s has been removed from the array before
being returned so you do not need to ignore it or remove
it programmatically.
.. for creating and syncing ordered lists.
.. argsort(ascend|descend, list) - will return a sort index in the same
way as numpy.argsort(). It can be used to sort other lists and is in
fact also used internally by sort.
.. sort(ascend|descend, list [,list .. listn]) - sort 1 or more vectors
using the first vector as the set to sort, the remaining lists are
re-ordered together with the first.
this is useful where you may have timeseries data that is related but
in separate vectors- you can sort them together.
.. head(list, n), tail(list, n) do as you'd expect, returning a vector
of length n from the head or the tail. if n is greater than the size
of the vector the maximal sized vector will be returned.
.. samples(SERIES) will return a vector of all datapoints for the
specified series. e.g. samples(POWER) will return a vector of
3600 elements for a 1hr ride with 1s sampling.
.. to make sure it doesn't go haywire and open all ridefiles if
used in a datafilter or in a naive way by users, it will not
open a ridefile, just return an empty vector.
.. this is safe to use in user metrics; e.g. for average power
you could use value { mean(samples(POWER)); } and this would
work well as the ride is opened before calculation starts.
.. there is an added bonus that this means a datafilter:
length(samples(SECS)) will filter only those rides that are
open. A useful debug tool for memory usage from download or
ride import activity.
.. append(a, b [, pos]) follows the R convention for append and
will append b to symbol a, optionally inserting from pos. it
returns the number of elements in a rather than a copy of the
vector (it is supposed to be quick).
.. remove(a, pos, count) has no R equivalent but does what it says
calling the underlying QVector function, so should be quick. It
also bounds checks (does nothing if bound invalid). Just like
append it will also return the number of elements in a after the
operation is completed.
.. some more functions for creating vectors and working with them
.. seq(start,stop,step) - create range vector and negative
values are allowed e.g. seq(1000,1,-1)
.. rep(value, n) - create a vector repeating the same value
n times.
.. length(s) - return the length of the *vector*, so if the
parameter is a single value then the length is zero. this
might change, but for now it seems useful. An object that
is created and updated as a vector will return 1 if it
only contains one element.
.. added the c() function, same syntax as the R function it simply
creates a vector comprised of the parameters passed.
.. if one of the parameters evaluates to a string it will try and
convert to a number. We only support vectors of doubles for
simplicity and ease of implementation.
.. full for scatter, in selection rect for line. Seems a compromise
between providing useful context on a scatter and avoiding lots of
noise on a line chart.
.. mostly complete, following the Python charts lead on the
API and basic UX.
.. some nits left in there; pie/bar chart categories and labels
and an open question on whether/how we let users set the axis
color / leave it alone.
.. paint for whole chart so can compare to data outside of the
selection area (which is probably the most useful thing to
do with the slop line).
.. fixup the paint co-ords which assumed x-axis started at 0.
.. a regression from Qt5.12, native dialogs hang if threads are
in use (!). Not doubt will be fixed, but for now lets avoid
it -- need to revisit this before releasing since the Qt
dialog is horrible. Will add to github issues.
.. turns out the jsonunprotect function wasn't stripping the trailing
spaces that jsonprotect was adding. This caused axis labels to have
spaces at the end that the qt charts code stripped-- so when we went
looking for axis label texts they didn't match.
.. this commit causes jsonunprotect to strip trailing spaces. This
should not result in any regression as use of jsonunprotect is
limited to HomeWindow properties.
.. x-axis label colors
.. y-axis alignment should not be managed upstream
.. still have issue finding hover area which is not
present in the python chart.
.. basic user chart only on analysis view. Users can specify
a data filter script to prepare data for the x and y axes.
It uses the generic chart to visualise so one step closer
to a UX where all charts have the same behaviour.
.. will need to update to place on trends view, including
updating the way userdata works and possibly adding a
few new functions to support working with models and mmp
data amongst a few other things.
.. likely contains quite a few nits as most of the code
is related to configuration and is a bit thorny.
.. setUpdatesEnabled() to stop output did not help at
all with respect to the jarring effet of watching
plots added when in stack mode.
.. for some reason adding this QApplication::processEvents()
fixes that. Go figure.
Use Create Activity in Strava API when there is no samples
Fixes#3363
Also map some known sports to the Strava API equivalents,
we should think about a generalization as part of #3280
Fixup stack view a) minimum height for plots, b) added a
scroll area to manage more plots than fit on the screen
and will layout horizontally or vertically.
Stack charts now when set as an option, in which case all
data series are given their own plot.
Or alternatively, where data series have different x-axis
names, they get a plot for each x-axis.
Need to fixup a) minimum height as can get squashed and
b) scroll area needed as well as c) layout direction.
.. added GenericChart which manages a collection of plots, so
you can plot multiple series stacked (like in AllPlot).
.. additionally added option to set layout vertical or
horizontal, since its useful to layout scatter plots
horizontally where time series will be largely vertical.
.. at this point the code is slightly refactored to add
GenericChart between PythonChart and GenericPlots.
.. will shortly add code to support managing multiple plots
in layouts and adapting if settings change (.e.g the
python script is edited, settings are changed).
.. updated to support different linestyles and also legend can
now be placed above, below, left or right of the chart and
orientated to list series vertically or horizontally.
.. the vertical legend is a bit ugly as nothing lines up, will
fix up separately.
Isolate curves by hovering on axis for scatter and line
charts. Also added horizontal guide line and click to
add horizontal annotations (but not added yet).
Annotations will come later, but added as was the right
part of the code.
Also tidied up a bit of the paint code in selection tool
since it was a bit messy.
.. for some reason in earlier version of Qt Charts there are errant
items in the same area as the axes that are blank, these break
the code that derives the axes rectangles in Qt Charts <= 5.10
.. now we have the axis rectangle (previous commit) we can paint
the cursor values in the axis rather than on the canvas. Lots
of work to fix a cosmetic issue, but damn, it was worth it.
.. amongst a few other nits when a plot is resized or the chart is
being finalised we get the scene rectangle for each of the axes.
This is so we can trap when the mouse hovers over an axis and
also so we can paint the current mouse coordinates on the y-axis
in the scatter plot (they are painted on the canvas at present
and paint over each other causing a nasty artefact).
Will fixup y-value cursor tracking shortly.
Use legend to select which series are plotted by clicking to
show hide a series. Hover just shows a hover background and
does not temporarily isolate the series, this may be something
to consider for later.
Applies to scatter and line charts.
.. created separate source files for the legend and selection tool
classes and removed some of the interdependency.
.. partly because GenericPlot.h and GenericPlot.cpp were becoming
unwieldy and partly to support using the generic legend in
other charts (notably CP, LTM and AllPlot).
The scene was being updated unneccessarily when it was active but
not changing (i.e. selection rectangle was stationary etc).
Added a state variable rectchanged to the selection tool to notify
the updateScene() method that nothing has changed since the last
event. So do nothing.
Added selection on line chart, uses a range selector and
works in pretty much the same way as the scatter rectangle
selector.
I've removed a lot of the calculated values from the plot
since it gets very busy very quickly.
I also noticed there is a significant performance problem
when selections are active- suspect there are a large
number of unneccessary scene updates. Will investigate.
.. when no value present was miscalculating the nearest point to the
cursor on the x-axis because distance was calculated as a large
negative by using a series point value of 0 (when no value was
available). Fixed by just ignoring zero values.
Added hover code to line chart, so get legend values on hover
and marker points as you mouse over the series and an x-axis
label at the bottom to show current x value.
Also added Utils::removeDP() to remove decimal places from a
number string e.g. 24.000 becomes 24, 987.3440500 becomes
987.34405. This is a hack to avoid handling decimal places
in the user settings, but will keep as reduces the amount
of "digital ink" regardless.
Enable accept only when boty symbol and name are non empty
Warn on name and symbol collisions to avoid silently discarded
metrics or metrics not usable from formulas
Complements 635eccd001, related to #2279
.. recent fix to check for points on the boundary (checking with >=
and <= instead of > and <) mean't that items on the boundary
would be inserted into multiple quadrants. This wasn't much of
and issue as only using quadtree for mouse hover, but it is a
bug none the less and needed fixing.
.. compile time warning nits also tidied up for new code, to stop
errors spewing on build and hiding real issues.
The .gmetric file it is the same xml format as usermetrics.xml
with just one metric, on import only the first is imported.
Import is similar to Add with the imported settings prefilled,
so the user can change it before to effectively add it or cancel.
Fixes#2279
TODO: we should check for duplicate symbols on Add/Edit/Import
Added new legend which displays hover over value from the
prior commit. Also fixed up the quadtree issue with some
points being hard to hover.
Need to consider what to do with multiple x-axes; am tempted
to create a new chart for each x-axis since hover and general
interaction gets very messy with multiple x-axes.
Next commit will extend the current functionality onto line
charts before we move onto hover for pie and bar charts.
GoldenCheetah lacks support for splitting multisport fit files.
These files combine multiple sports recorded into a single
activity. Those sports are marked by session entries. These
session entries are parsed but ignored.
Fit files are parsed on-the-fly without caching data. This is
great in terms of memory useage but bad in terms of splitting
the activity into sessions because of the fit specification.
The specification allows session entries to appear either
grouped at the beginning of the file or at the end of the session
spread throughout the file.
We do cache the most relevant data entries along with the
session field entries. This hopefully adds as little overhead
as possible while parsing and in memory useage, but allows
us to determine if there are multiple session entries in one
file. If so, we can split the single file into multiple ones,
each representing a single sport (activity). Eg.: If a triathlon
is recorded using the multisport method it is split up into
the following activities:
- Swim
- Transition
- Bike
- Transition
- Run
This corrects the metric calculation. Prior to this change
the parsed activity is tagged as a run activity and the whole
data - swim/bike HR, bike cadence, ... - was taken into account
for the run metrics calculation. Now only the relevant part of
the file is taken into account.
Laps as well as XData records are also split up to the files
created out of a single multisport file and are aligned in time.
It turned out that it is best to treat transitions as run.
Fixes: #3211
Doing shallow copies of Objects when explicitly declaring a copy c-tor
is very dangerous.
When the object is cloned, the second to be destroyed crashes w/ double
freeing memory or/and, even worse, dangling pointers are left around.
That in turn leads to unpredictable crashes.
There's only one thing left to say, use smart pointers wherever
possible. Or simply do not use arrays of pointers. The vector class
already get it right to alloc/free memory for objects stored in it.
Hover now wired into the SelectionTool with scatter points
being highlighted as you move the mouse. The code to select
nearest neighbours looks correct, but in practice it can
be hard to select some points (this needs further investigation).
Highlighting the selected point is done in the paint method
of the selection tool (its just one dot), but zorder issues
with opengl accelerated series means it appears underneath
we may need to create a curve with one point to avoid this
(this also needs further investigation).
Need to work next on a legend widget of our own to manage
the hover display and axis interaction (and better aesthetics
than the standard offerings).
When curves are painted via openGL there are a number of limitations
regarding aesthetics, setColor() doesn't work once the series is
created, opacity is ignored etc.
So when we create a selection from an openGL enabled curve we cannot
set it gray etc. Instead, this commit will set the selection curve
to gray and use opengl rendering on the selection (on the assumption
that the user specified opengl rendering for performance and so we
should reflect that in the selection curve).
This has a dramatic improvement in performance on a scatter plot of
activity data where there are 1000s and 10000s of points in some
cases.
We should recommend that opengl is enabled for curves that have large
number of points, and indeed, the default is to enable it unless the
user specifically overrides (e.g. for better aesthetics).
Added Quadtree for identifying points on the plot when
hovering with mouse, but should also be reused for the
rect selection tool (it currently iterates over all points
for a series).
This commit just adds basic algorithm will need to follow
up with a) refactor it into the selection tool and
b) display the hover value somewhere (legend?)
The hash near constant time vs linear search in pass method
speeds up considerably operations s.t. seasonMetrics in R and Python
APIs when there are lots of activities, since they were O(n^2) otherwise.
.. the chart was being redrawn as series added because initialiseChart()
was removing axes, be waiting until finaliseChart() to do this we
avoid the flicker.
.. My eyes! My eyes! Tuft would not be impressed with all the
extraneous plotting and noise from the selection tool that
detracted from the data.
Have removed the guide lines, limited the slope line to the
selection rectangle, and toned it down as well as making the
selection rectangle more subtle when its not being manipulated.
SelectionTool now calculates a bunch of useful values
for the selected items (mean, min, max etc) and they
are plotted with guidelines on the scatter plot wehen
a selection is active.
Added a rectangle selection tool for scatter charts. Click on
the canvas and drag to highlight points of interest and click
on rectangle to drag around, resize with wheel events.
Additionally, improved some of the aesthetics on axes and labels
etc to make the chart look and feel similar to the rest of the
qwt based charts.
There are likely to be a large number of commits for part 3, to
cover auto calculation of mean/max/sum/regree for selected points
and extend to other types of selections and apply to other chart
types.
.. the qchart code is now becoming more generic, with interactivity
and generalised rendering so refactored out into its own class
before adding too much more code.
.. this is also because we will be creating a generic chart for users
to plot their own 'userdata' (currently in allplot/trends charts)
using this generic plot and want to have a common widget for this
to get a more consistent and less jarring user experience.
Support training with Tacx TTS files:
TTS distance and gradient are honored meaning training
load should exactly match tacx. Ride altitude is recomputed
based on distance and gradient, so training work will
match The Tacx Experience and might not match reality.
When TTS file contains no location, altitude is still computed
from distance and gradient but will start from 0.
Gradient during training is interpolated from distance and
altitude so will change smoothly while summing perfectly
to the correct load.
The TTS Reader source was adapted from the WattzApp
Community Edition java source.
Highly recommended that 'Use Simulated Speed' option
is enabled when riding TTS files.
This change was only tested against a small number of
dvds that I own. I would appreciate feedback and problem
reports. I would especially appreciate anyone that can
compare this behavior against Tacx as I only tested with
my Wahoo Kickr.
Issues and Future work:
I guessed about how to set starting distance and might
have got it wrong.
TTS Files contain video synchronization data. Currently
this is ignored and rlv file must be specified. I've not
even looked at the video sync data and no idea if it is
better than the rlv.
There are data fields in the TTS that Ive not investigated
and they might contain useful info, for example a starting
altitude for rides that have no location info.
Other changes:
Fix numerical stability around zero in blinn and quadratic
solvers. Improve quadratic solver accuracy.
Fix issues with computing gradient from non-uniform
cubic splines.
RideFiles now record additional altitude accuracy.
Basics now in place to plot line, scatter, pie and bar
charts. This commit finishes off the final bit of part
2, adding axes control.
A new GC api, GC.setAxis(..) has been added allowing
fine grained control on the axes added automatically.
They reference axes by name, based upon the xaxis and yaxis
parameters passed to the GC.setCurve(..) function.
GC.setAxis(..) should be called /after/ the curves are
added since it will not create axes in advance.
Fixes a copy/pase problem preventing workout import via Drag and Drop
and allows to import GPX files as workouts or activities according to
active view.
Fixes#3337
Added Pie and Bar charts with some rudimentary axes
being created automatically.
Need to follow up with mechanism to work with axes from
within the python script, likely needs a new binding.
Updating the python chart to render via a Qt Chart in addition
to the existing web page rendering.
Five aspects are planned:
1. Add QT chart option, basic rendering of Line+Scatter (this commit)
2. Add legend and axes, support for Pie and Bar charts
3. Add interactivity / hover etc
4. Add options for annotations and markers
5. Add more advanced charts and chart objects
There is an example in the tests folder, but at this point the
chart is very basic, but the main plumbing is in place.
Add support for a generic set of VO2 measurements:
* Respiratory Frequency
* Respiratory Minute Volume aka Ventilation
* Volume O2 consumed
* Volume CO2 produced
* Tidal Volume
* FeO2 (Fraction of O2 expired)
* Respiratory Exchange Rate (calculated as VCO2/VO2)
Make the new metrics usable in TrainView, and store VO2 data as XDATA
using the same pattern as for HRV data.
Add support for VM Pro by VO2Masters
The VM Pro is a BLE device, so support is added in the BT40Device class.
Since the device requires some configuration in order to be usable, such
as the size of the "User Piece" a special configuration widget is added
and shown in a separate window when the device is connected.
This window is also used to set a number of useful settings in the
device, and to show calibration progress. There's also a detailed log of
the status messages shown, and this can also be saved to file.
Allow notifications from RealtimeControllers and devices in the
notification area of Train View. In order for devices to display
information in the notification field in TrainBottom the signals need
to added and propagated from from device level via RealtimeController
to TrainSidebar and finally TrainBottom.
Fix an issue with multiple BT40Device per actual device
Currently on MacOS there will be multiple BT40Device per actual device,
since the QBluetoothDeviceDiscoveryAgent::deviceDiscovered() signal is
emitted multiple times with e.g. updated RSSI values. Avoid this by
checking the previously created devices first.
MacOS doesn't disclose the address, so QBluetoothDeviceInfo::address()
can't be used there, instead deviceUuid() is used which is instead only
valid on MacOS.
* FitRideFile: handle single values in decodeHRV()
Currently only records of type ListValue are handled, but single
RR-intervals can also come as type SingleValue. Before such records
were silently ignored.
* FitRideFile: Unify indentation of decodeHRV()
The indentation before was a mix of tabs and spaces, which made the code
quite a challenge to read. This unifies to use 4 spaces at least
throughout the function.
* Added test file
Fixes#3297
.. when a new athlete is created and opened the blankstate page
currently provides options to get data by importing files or
downloading from a device.
.. this update adds the ability to configure a cloud service and
start a sync straight away
.. this UX is introduced since cloud services are now much
more ubiquitous and v3.5 introduced broad support for a wide
range of services.
.. the authorise button on the add cloud wizard now
shows a 'Connect with Strava' icon
.. all other services continue to have a button that
is labelled 'Authorise'
.. this is needed to comply with the Strava API application
guidelines.
.. when data is downloaded from strava we now set the metadata
tag "StravaID" to the id of the activity on Strava.
.. On RideSummary a link is added at the bottom to view the activity
on Strava if the "StravaID" is set.
.. if the user clicks on the link the summary is replaced with the
strava page for the ride:
e.g. https://www.strava.com/activities/962515512
.. this is part of a couple of updates to comply with the Strava
guidelines for consumption of the Strava v3 API, see:
https://developers.strava.com/guidelines/
Some older (Tacx) RLVs do not have a sync point at the end of the course.
This work-around calculates the total distance of the course and sets a final sync point
if one does not already exist.
Revised code in VideoSyncFile::parseTacx to build syncpoint list with correct distances
when speed varies between two points
Revised code in VideoWindow::telemetryUpdate to interpolate position between 2 sync points.
Also do not update video if paused or not running.
Revised code in VideoWindow::startPlayback to set a minimal rate to start if video is
controlled by syncfile. This avoids the initial "rush" that otherwise happened and
makes for a smoother start.
Also reset distance to 0 on start.
As the rlv length now more accurately matches the workout length, we also need a check in
TrainSidebar::guiUpdate that will terminate the workout if the end of the video is reached.
This code has problems when distance is used on x-axis (#2842)
and it is redundant since there is a general mechanism to plot
any XData series as User Data in Activitiy chart.
This reverts commit f095416c5c.
* Initial implementation of Python data processors
* Add RideEditor to PyFIx script editor
* Enable write-access to activity data for python fixes
* Add GC.deleteActivitySample method
* Add GC.deleteSeries method
* Check for python fix for changes before close
* Build python fixes menu dynamically
* Make python fixes first class data processors
* Add GC.postProcess method
* Check GC_WANT_PYTHON and "Enable Python" setting for python fixes
* Add GC.createXDataSeries method
* Clean up ScriptContext ctor mess
* Support editing xdata series
* PDP: Implement xdata append/remove methods
the website appears to expect UTF8 by default, so let's send a UTF8
title (plus an explicit header)
tokens and boundaries are supposed to be ASCII, so they can keep their
latin1 encoding
GPSMap 66 can use ANT+ sensors, store in FIT format, synchronization with Garmin Connect and relevant to use with long-term activities (walk/hiking/ski).
Implement regex/hash based string substitution object to perform multiple
substitutions in 2 passes. Speeds up athlete data load by 2x.
Use QStringRef to avoid copy
Fixes#3234
Currently Device does not work on filters and set/unset/isset fail silently,
with this change Device can be used in filters as standard metadata and
the attempt to use in set/unset/isset reports an appropriate error.
We could enable these operations in the future but they require special casing.
To allow user testing, similar to linux builds.
Includes some minor fixes:
-Avoid compiler warnings for deprecated declarations to reduce the log size
-Patch GoldenCheetah.dmg to include missing libicudata.64.dylib
-fix command line error in mackdeployqt -fs option
If video config file is not present copy a default one to be used as a model
by the user. An empty video-layout.xml file disables video overlays
Fixes#2525
AddPairBTLE depends on the presence of an ANT+ dongle and sensors
to support ANT+ for detection, it looks like a copy paste of AddPair.
This works for Dual (ANT+/BTLE) sensors with an ANT+ dongle since
the sensors are detected, although is misleading since it seems to
imply you can pair them selectively, which is not true for current
BT40 GC implementation.
When an ANT+ dongle is not present (see #2771) or the sensors only
support BTLE (see #2983), the wizzard informs no sensor is dectected.
This is misleading since BT40device will dectect and use automatically
any Hr/Power/CSC sensor present at device startup.
This change replaces AddPairBTLE code with a simpler version matching
current BT40 support: it just informs the user the sensor types supported
indicating they will be autodetected on device startup.
Fixes#2771Fixes#2983
A walkthrough of building GoldenCheetah from scratch on Ubuntu linux. This walkthrough
should be largely the same for any Linux distro.
A walkthrough of building GoldenCheetah from scratch on Ubuntu linux 18.04
This walkthrough should be largely the same for any Debian derivative Linux
distro, and very similar for others using their correspoing package manager.
CONTENTS
1. BASIC INSTALLATION WITH MANDATORY DEPENDENCIES
- QT
- git
- flex
- bison
- QT
- OpenGL
- gsl
2. ADDING OPTIONAL DEPENDENCIES WHEN BUILDING VERSION 2
2. ADDING OPTIONAL DEPENDENCIES
- FTDI D2XX
- SRMIO
- liboauth
- libkml
3. ADDING OPTIONAL DEPENDENCIES WHEN BUILDING VERSION 3
- checking out the release 3 branch & building with MANDATORY dependencies
- flex
- bison
- libical - Diary window and CalDAV support (google/mobileme calendar integration)
- libvlc - Video playback in training mode
- libical - Diary window and CalDAV support (external calendar integration)
- libusb - If you want support for using USB2 sticks in Train View
- R - If you want R charts
- Python - If you want Python charts, scripts and data processors
1. BASIC INSTALLATION WITH MANDATORY DEPENDENCIES
=================================================
Installed Linux distribution of choice on platforms i386 or amd-64 (currently Debian-based distributions and Arch-based distributions are covered). You will not need to do this if you
already have a Linux distribution installed. Left this step in to highlight the
Linux distribution the commands below were executed on.
Install the Linux distribution of choice on amd64 platform (Ubuntu 18.04 is used
for this document). You will not need to do this if you already have a Linux
distribution installed. Left this step in to highlight the Linux distribution
the commands below were executed on.
login and open a terminal to get a shell prompt
Download MANDATORY DEPENDENCIES (browser)
-----------------------------------------
Install Qt
----------
Download and install the Qt SDK from http://qt-project.org/
Once that is completed test qmake is ok with: qmake --version (should report 4.7.0 or higher)
You can use a browser to download and run the interactive installer, be sure to
select version 5.14.2 or higher Qt 5 version, including at least the following modules:
- Desktop gcc 64-bit
- Qt Charts
- Qt WebEngine
Once this step is completed add the bin directory to PATH and test qmake is ok:
$ qmake --version
DEBIAN-BASED DISTRIBUTION INSTRUCTIONS
--------------------------------------
Install git with:
Install git
-----------
$ sudo apt-get install git
Said Y to prompt about all git files installed (git-gui et al)
Install FLEX and BISON
----------------------
You will need flex v2.5.9 or later
$ sudo apt-get install bison
$ sudo apt-get install flex
Install Mesa OpenGL utility library
-----------------------------------
sudo apt-get install libglu1-mesa-dev
ARCH-BASED DISTRIBUTION INSTRUCTIONS
------------------------------------
Install GSL development libraries
---------------------------------
sudo apt-get -qq install libgsl-dev
Install git:
$ sudo pacman -S git
INSTALL FLEX and BISON
----------------------
$ sudo pacman -S flex bison
NEXT STEPS
----------
$ vi gcconfig.pri
Ensure you have the following lines (which are now also in gcconfig.pri.in which has
been updated to reflect the new dependencies in version 3)
QMAKE_LEX = flex
QMAKE_YACC = bison
win32 {
QMAKE_YACC = bison --file-prefix=y -t
QMAKE_MOVE = cmd /c move
QMAKE_DEL_FILE = rm -f
}
Build!
------
$ make clean
$ qmake
$ make
You will now have a release3 binary but with none of the release3 dependencies compiled in.
Issue tracker is **only** for Bugs and Features, before to open a new issue please read the Contributing document (link at the right) and use the forums if you need help.
Issue tracker is **only** for Bugs and Features, please don't open issues for questions or technical support. Before to open a new issue please read the contributing guidelines (link below).
If you have questions, please read the FAQs and User's/Developer's Guide:
GoldenCheetah is an open-source data analysis tool primarily written in C++
with Qt for cyclists and triathletes
with support for training as well.
GoldenCheetah can connect with indoor trainers and cycling equipment such
as cycling computers and power meters to import data.
In addition, GoldenCheetah can connect to cloud services.
It can then manipulate and view the data, as well as analyze it.
GoldenCheetah is a desktop application for cyclists and triathletes and coaches, providing a rich set of tools and models to analyse, track and predict performance, optimise aerodynamics and train indoors.
GoldenCheetah integrates with most popular cloud services like Strava and Todays Plan, imports data from bike computers, imports downloads from any website like TrainingPeaks and Garmin and will also connect to smart trainers using ANT+ and Bluetooth.
GoldenCheetah is free for everyone to use and modify, released under the GPL v2 open source license with pre-built binaries for Mac, Windows and Linux.
## Installing
@@ -29,12 +22,15 @@ INSTALL-LINUX For building on Linux
macOS and Linux: [](https://app.travis-ci.com/GoldenCheetah/GoldenCheetah)
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.