Compare commits

..

62 Commits

Author SHA1 Message Date
Mark Liversedge
f07163689b V3.1 SP1 (3.0.1) released
.. updated versioning and upgrade ids.
2013-12-21 18:27:26 +00:00
Mark Liversedge
c1cca280c3 Fix SEGV if metric not available
.. in RideSummaryWindow if a metric is specified that
   doesn't exist .. because you configured it in a future
   release (e.g. 3.1)
2013-12-21 18:26:05 +00:00
Mark Liversedge
f9ad0c4da2 Fix 3d grid when users specify background colors 2013-12-16 23:34:54 -05:00
Mark Liversedge
a82909062f Batch Export remembers last format/dir
.. but will only default to the last used dir
   if it still exists.
2013-12-16 23:23:41 -05:00
Christian Stade-Schuldt
72d1714e5a Updated Tacx Satori Virtual Power values 2013-12-16 23:17:02 -05:00
Mark Liversedge
3d66855a2e Merge branch 'release_3.0.0' of https://github.com/GoldenCheetah/GoldenCheetah into release_3.0.0 2013-12-08 20:17:24 +00:00
Damien
74fb7f31f5 FitRideFile: - Add Left/Right TorqueEff and Left/Rigth PedalSmooth
- Open Truncated file
2013-12-08 20:08:29 +00:00
Jon Escombe
155f7b4fe7 Don't reset ANT channel settings on search timeout
Wiping out these settings prevents a successful reconnection
of the device if it comes back into range

Fixes #514
2013-12-07 16:29:47 -05:00
Jon Escombe
87cef3f412 Don't reset ANT channel settings on search timeout
Wiping out these settings prevents a successful reconnection
of the device if it comes back into range

Fixes #514
2013-12-07 21:19:39 +00:00
Mark Liversedge
a83c3bfeee Fix findBests when no speed/gps
.. flawed logic. Same fix also applied to master.
2013-12-06 22:52:23 +00:00
Mark Liversedge
96e006be90 Fix LC_LOCALE on Xcode 5
by including "locale.h".

Fixes #734
2013-12-05 20:57:45 -05:00
Damien
2318ea0b08 FitRideFile: Correction for last Garmin firmware updates
In last Garmin firmware there is some (unknow) fields with multiples values

Fixes #724
2013-12-02 19:04:01 +01:00
Mark Liversedge
680adb2421 V3.0 SP1 RC1 Update
.. cleans out index and metricDBv3 to get a rebuild as
   there is a conflict between the version of clucene used
   in the v3 sp1 build
2013-12-01 19:41:09 +01:00
gcoco
843ac13a98 Add Garmin Forerunner 910XT 2013-11-21 07:47:15 -05:00
Damien
3b62333880 ShareDialog: Add upload to CyclingAnalytics and SelfLoops 2013-11-02 23:13:48 +01:00
Mark Liversedge
7ef01eacd8 Merge pull request #713 from gcoco/qwt-fix
Get rid of qwt compile error about format string.
2013-11-01 10:07:12 -07:00
gcoco
83a89c2b9f Get rid of qwt compile error about format string.
Author: KURASHIKI Satoru <lurdan@gmail.com>

Taken from Debian patches for GC 3.0.3
2013-11-01 11:44:43 -04:00
Mark Liversedge
e880b6adba Add /dev/cu.usbserial as a serial device
Useful on Mac with Sewell adapter for the CT.
2013-10-29 15:34:15 +00:00
Mark Liversedge
6591d09f58 Interval Summary Off By 1 Error
Intervals are off by 1 sample because when the temporary
ride is created it stops short of the last sample in both
the ride and interval summary window code.

Fixes #623.
2013-10-29 15:34:02 +00:00
Gareth Coco
4fdc533491 Update translation source files 2013-10-29 00:26:54 -04:00
Mark Liversedge
b4d7731f2d Truncate Altitude values
We know the highesst point on Earth, so any activity that
contains an altitude greater than that is definitely incorrect.

This patch truncates the altitude to the maximum possible, this
has the happy by product of curing a major mem alloc crash in QWT
when trying to plot altitudes with very large values.

Fixes #700

[cherry-picked from master cc2a0efe3e]
2013-10-27 20:12:11 +00:00
Damien
9527161f9b ShareDialog: Manage null error message 2013-10-27 00:08:23 +02:00
Damien
33e0702b35 OAuthDialog: Remove qDebug() 2013-10-21 22:23:50 +02:00
Damien
095a8a9290 AllPlot: plot references lines 2013-10-21 00:09:36 +02:00
Damien
2fc23b7041 Correction for release_3.0.0 branch 2013-10-20 23:38:17 +02:00
Damien
40818876e8 FitRideFile: Add Calibration Event parsing 2013-10-20 23:32:44 +02:00
Damien
851ad96801 ShareDialog 2/3 : For version 3.0.1 2013-10-20 17:13:56 +02:00
G Coco
91789a3dca Merge StraveDialog and RideWithGPSDialog
Add OAuth for Strava (Release version only)

Based on the work by D Grauser in commits #f0c2c2b840 and #3a1449231c
2013-10-20 16:44:30 +02:00
Damien
c5b3d56198 GoogleMap: Little fix 2013-10-14 21:32:54 -04:00
Damien
506caf89dc Aerolab: Add a constant altitude option 2013-09-26 07:12:51 -04:00
Damien
847fd004e1 JouleDevice: Remove debug lines 2013-09-25 22:47:42 -04:00
Damien
5b69552f4f JouleDevice: Remove debug lines 2013-09-25 22:47:19 -04:00
Mark Liversedge
7588eb6a28 Merge pull request #694 from gcoco/release_3.0.0
assert cleanup
2013-09-24 12:24:12 -07:00
Gareth Coco
03509108b6 assert cleanup
Based on commit# a2a962120c
2013-09-24 04:37:30 -04:00
Jon Escombe
cc566e92ab Detach kernel driver before claiming USB2 ANT+ interface.
Kernel 3.11 exposes the Suunto ANT+ stick as a USB serial device,
this prevents GC from opening it in training mode unless the
kernel driver is detached first.

Only detach kernel driver if compiling under Linux (not a portable function)..
2013-09-22 22:07:03 -04:00
Eric Johnson
eebc36a618 Use float division when converting wheel size
In training mode, calculations of speed using wheel size and RPM from
a speed sensor used integer division. This truncated all wheel
circumferences to an integral number of meters. 2100mm wheels were
treated as 2 meters and 1960mm wheels were treated as 1 meter,
effectively reducing calculated speeds by roughly 5% and 50%
respectively.

Fixes #585
Fixes #651
Fixes #669
2013-09-22 00:33:20 -04:00
Walter Bürki
7b91f18d86 adding hr,cad,power,temp of Suunto Ambit gpx files 2013-09-19 15:04:04 -04:00
gcoco
dd6eaf0bd0 Kurt Kinetic Road Machine PowerCurve fix
Fixes #685
2013-09-19 14:34:11 -04:00
Damien
a4db59e422 Bin2RideFile: correct bug for some GPS data 2013-09-18 14:44:48 -04:00
G Coco
eea7776260 Reinstate Twitter functionality
Fixes #
2013-09-14 22:51:13 -04:00
Dave Waterworth
5fbda61a90 More Fortius Fixes
Including:
   * Fixed a type with slope mode updating the wrong byte array
   * Transposed bytes in the definition of the erg and slope messages
   * Added power smoothing

Note:
   It appears the Fortius is supplying torque not power, some more
   testing is being performed but expect to see an update shortly
   once this has been fully tested.
2013-09-14 21:30:28 -04:00
Dave Waterworth
7ca196481e Fix Tacx Fortius Device Support
Multiple fixups for Tacx Support -- as a result the support
is now pencilled in for full support in 3.0 SP1.

Fixes #24.
2013-09-14 21:29:39 -04:00
Jaime
b71be203f8 Work around to ensure controller key presses aren't missed. Borrowed from Fortius.cpp 2013-09-12 02:42:50 -04:00
Rainer Clasen
c81f899d18 use pwx for Trainingstagebuch upload
as current tcx writer currently doesn't support laps (and tcx doesn't
allow non-linear/overlapping intervals, at all) this patch makes GC upload
exercises as pwx.
2013-09-12 02:41:37 -04:00
Rainer Clasen
4dbe3960b8 PWX: read/write temperature
added temperature to read/write
2013-08-27 07:12:23 -04:00
Rainer Clasen
a84869ad76 PWX export: keep timestamp + distance precision
Pwx does support for arbitrary sample lengths. No need to chop off
timestamp precision and introduce bad data + jitter.

Instead we should look at fixing data import and consider resampling on
read.

Distance is defined as double, aswell - so, let's keep the precision,
aswell.
2013-08-27 07:12:23 -04:00
Rainer Clasen
527e8e01fd fix PWX export: always write summarydata
xml schema is requiring summarydata to exist. Otherwise upload to
trainingpeaks fails.

Block was omitted when no intervals were defined.
2013-08-27 07:12:23 -04:00
Rainer Clasen
ee4b2221f7 fix PWX export: handle end of gaps gracefully.
As I got it pwx by itself has no concept of recording intervals. "smart
recording" and other strange data require variable recoring intervals.

On the other hand it's not recording the duration of a sample explicitly.
This means the duration needs to be derived from the previous samples
timestamp (assuming the sample timestamps are referring to the end of the
sampled period).

This diff writes an empty timestamp at the end of each gap so that the
next real sample/ridepoint can calculate the correct duration.

Please note that this may unhide some deficiencies in GCs file reading in
exports.
2013-08-27 07:12:23 -04:00
Rainer Clasen
e57ab8a689 Tcx: fix speed in summary information
When exporting files to Tcx, it's writing an ActivityExtension to the end
of the file with calculated AvgSpeed and MaxSpeed. Unfortunatly it's using
the km/h values - while Tcx is using m/sec. Schema is a bit unclear about
this, as the ActivityExtension uses "double" as type for both values, but
original Tcx v2 Schema only uses m/sec, GTC exports as m/sec and some
other software is expecting m/sec, aswell.
2013-08-26 21:14:56 -04:00
Damien
8dfddb4052 Bin2RideFile: Changes in Summary pages for Data version 5 2013-08-26 20:56:42 -04:00
Damien
21449f82b2 CsvRideFile: add temperature and hill slope (%) parsing for ibike csv file 2013-08-26 20:56:13 -04:00
gcoco
758bbe4635 Twitter API change
Just matching the version in master branch.
2013-08-10 23:51:00 -04:00
gcoco
1e70b58672 Support Twitter API 1.1 2013-08-10 23:45:36 -04:00
Mark Liversedge
a9b84ad1bc Recognise Dave Waterworth
.. in the about box contributors list.
2013-07-09 20:09:15 +01:00
Mark Liversedge
868dce94d7 Fix allplot crash on daft power value
Incredibly high power value in ride file causes a memory
error when setting up plot ticks.

Fixes #658
2013-07-07 20:02:49 +01:00
Mark Liversedge
34f7498592 Deprecate Strava Support
No API v3 access.

Fixes #656.
2013-07-06 00:13:55 +01:00
Mark Liversedge
2dc2151103 Fix PWX export SEGV
fixes #654.
2013-07-01 19:15:39 +01:00
Rainer Clasen
4b19b2bb99 make srmio details in version dialog conditionally
... so that GC keeps building with older srmio versions.

[cherry picked from master]
2013-06-25 16:18:41 +01:00
Mark Liversedge
d8a5a62f71 Fixup Fit File issue
Fixes #646

- not cherry picked from master because there is a small
  update in the patch related to a 3.1 development.
2013-06-23 16:57:33 +01:00
Rainer Clasen
7831d01c1a inlude srmio version + commit in about dialog 2013-06-23 16:56:27 +01:00
Rainer Clasen
51669b4913 SrmDevice: fix writing srmio data
fopen() was missing 'b' flag, so that mingw and other platforms doing
LF/CR translation screwed data.

This is fixing the astronomic values of direct SRM downloads.
2013-06-23 16:56:00 +01:00
Gareth Coco
d8f3f58fd3 Website updates for Version 3.0
(cherry picked from commit fb339a527b)
2013-06-10 09:46:39 +01:00
1315 changed files with 78764 additions and 1438412 deletions

25
.gitignore vendored
View File

@@ -1,33 +1,8 @@
Makefile
.qmake.stash
# old skool
.svn
*.pri
# osx noise
.DS_Store
profile
moc/
obj/
lib/
bin/
plugins/
resources/
src/debug/
src/release/
qwt/src/debug/
qwt/src/release/
src/Makefile.Debug
src/Makefile.Release
src/object_script.GoldenCheetah.Debug
src/object_script.GoldenCheetah.Release
qwt/src/object_script.libqwt.Release
qwt/src/object_script.libqwtd.Debug
qwt/src/Makefile.Release
qwt/src/Makefile.Debug
qwt/textengines/mathml/debug/
qwt/textengines/mathml/release/
build.pro.user

View File

@@ -1,116 +0,0 @@
branches:
- master
language:
- objective-c
compiler:
- clang
- gcc
env:
matrix:
## Test 4.8 or 5.4.2
- BRANCH=master QT=qt4 QT_PATH=qt
- BRANCH=master QT=qt5 QT_PATH=qt5
global:
- secure: iqYW7f3//ZkMVzeCEarYn0S0DqKjFU9juBh0KF6WTlUsKX902Jtsk7dFoJlNDYBf63HLgV+wW2Hc6MxI9sGiUkom0gY9/To/aeGIJFGEX2sLm/e0Ok3qN521FA0Q/OiCFsD0RC6J+yrHxzI+rf8Z1rujceUsz2KgsrfAjYYv+BY=
- secure: C6f58PXwvvHeVOjCLbyDRjgyF0tk+bXjCNUDur8VJLhJEGNdnrt+rH+d3azYaX0n348ZnQZ14as4M4rHjN1A/3DRbdUdOS7PQZrkj/n363ck1tvYOG/tzYqkEcVoQyjIJ7ZoTuBXDQry/VJmLxQjM0glTa2upNFHMOMwqZNkF+I=
- secure: mgf181ok4rJTHxAdSaeIb/OzUx7PQc6UjJYfhJQcZDjN1Nou+Um6OHpnooMHeEq0CdGuLSiv2xVmuQnRjI5MfG5re/a3l39hSzi9tPLWi1y7uOLCtQFooJw3H+LhiKZcgAtEnkTmEhUCEu5uZ7cp4lWhrQZWCR5mCDNtJrGHjiw=
- secure: UkW6SpgeACb6enGZADTAtPPRe23Tffne/SRQoBsZ3kGbKzgv8kTCLY0G5N71B1xEGdLB/36piOa0yji2SMW1jbflxR7tdOsiNpfd9R5qYqWVZRulY0qite8ZCwU5dqgy87pp4ECC1hNSOTq17aa4Sc4G4egg9AOy8cntLBTtxJA=
- secure: rb/MKPHEK8yOK5uYpXq2o+MQ7h65ft+c/xE9XmLFk1jLnK0oxe6+KeoSFlQ0n5UwLSsHrytMXVaUHex6EEt0TheXFlohi7BcNFWRWXr+wLucuaPjMnU49VErrSigjJ5VW/rcR7fORmnDwn5y06r3Rer9SC1hImCxf/pqF8hFZps=
- secure: FXJzm98lwbc1R2eh9/CvVReVRHEPLDm+sCRjiV9HJgeCveIUauLasp9Skamz0c6OKLmkjLY8JERPT491ZgCG8YcQ9x1bM8HGbmRqnn9xSUxINIRzVmyTiLMBoT/ibHHeFjFpyiGfukOAkHwMNNsrSrbaekhiJuekaXo7iTwYQB0=
before_install:
- date
- brew update
##- sh travis/install-qt.sh
- brew install $QT
- brew install libical
- brew install libusb libusb-compat
- brew install srmio
- brew install libsamplerate
## Disable KML for now
##- brew install --HEAD travis/libkml.rb
- sudo chmod -R +w /usr/local
- curl -O http://www.ftdichip.com/Drivers/D2XX/MacOSX/D2XX1.2.2.dmg
- git clone --depth 1 https://github.com/sintegrial/qwtplot3d.git qwtplot3d
- cd qwtplot3d
- CC=clang CXX=clang++ /usr/local/opt/$QT_PATH/bin/qmake -makefile -recursive QMAKE_CXXFLAGS_WARN_ON+=-Wno-unused-private-field
- CC=clang CXX=clang++ make -j2
- cd ..
- git clone --branch 0.98 https://github.com/kypeli/kQOAuth.git kQOAuth-0.98
- cd kQOAuth-0.98
- CC=clang CXX=clang++ /usr/local/opt/$QT_PATH/bin/qmake -makefile -recursive QMAKE_CXXFLAGS_WARN_ON+=-Wno-unused-private-field
- CC=clang CXX=clang++ make -j2 qmake_all
- CC=clang CXX=clang++ sudo make install
- cd ..
- hdiutil mount D2XX1.2.2.dmg
before_script:
- mkdir D2XX
- cp /Volumes/release/D2XX/Object/10.5-10.7/x86_64/libftd2xx.1.2.2.dylib D2XX
- sudo cp /Volumes/release/D2XX/Object/10.5-10.7/x86_64/libftd2xx.1.2.2.dylib /usr/local/lib
- cp /Volumes/release/D2XX/bin/*.h D2XX
- sed -i "" "s|libftd2xx.dylib|@executable_path/../Frameworks/libftd2xx.1.2.2.dylib|"
src/D2XX.cpp
- cp qwt/qwtconfig.pri.in qwt/qwtconfig.pri
- cp src/gcconfig.pri.in src/gcconfig.pri
- /usr/local/opt/$QT_PATH/bin/lupdate src/src.pro
- sed -i "" "s|#\(CONFIG += release.*\)|\1 static |" src/gcconfig.pri
- sed -i "" "s|#\(QMAKE_LRELEASE\).*|\1 += /usr/local/opt/$QT_PATH/bin/lrelease|"
src/gcconfig.pri
- sed -i "" "s|#\(QMAKE_CXXFLAGS\).*|\1_RELEASE += -mmacosx-version-min=10.7 -arch
x86_64|" src/gcconfig.pri
- sed -i "" "s|#\(SRMIO_INSTALL =.*\)|\1 /usr/local|" src/gcconfig.pri
- sed -i "" "s|#\(D2XX_INCLUDE =.*\)|\1 ../D2XX|" src/gcconfig.pri
- sed -i "" "s|#\(D2XX_LIBS =.*\)|\1 -L../D2XX -lftd2xx.1.2.2|" src/gcconfig.pri
- sed -i "" "s|#\(KQOAUTH_INSTALL =.*\)|\1 /usr/local|" src/gcconfig.pri
- sed -i "" "s|#\(KQOAUTH_INCLUDE =.*\)|\1 \$\$[QT_INSTALL_LIBS]/kqoauth.framework/Headers|"
src/gcconfig.pri
- sed -i "" "s|#\(KQOAUTH_LIBS =.*\)|\1 -F\$\$[QT_INSTALL_LIBS] -framework kqoauth|"
src/gcconfig.pri
- sed -i "" "s|#\(QWT3D_INSTALL =.*\)|\1 ../qwtplot3d|" src/gcconfig.pri
## Disable KML for now
##- sed -i "" "s|#\(KML_INSTALL =\).*|\1 /usr/local|" src/gcconfig.pri
##- sed -i "" "s|#\(KML_LIBS =.*\)|\1 -L/usr/local/lib -lkmlxsd -lkmlregionator -lkmldom
## -lkmlconvenience -lkmlengine -lkmlbase|" src/gcconfig.pri
- sed -i "" "s|#\(ICAL_INSTALL =.*\)|\1 /usr/local|" src/gcconfig.pri
- sed -i "" "s|#\(ICAL_LIBS =.*\)|\1 -L/usr/local/lib -lical|" src/gcconfig.pri
- sed -i "" "s|#\(LIBUSB_INSTALL =\).*|\1 /usr/local|" src/gcconfig.pri
- sed -i "" "s|#\(LIBUSB_LIBS =.*\)|\1 -L/usr/local/lib -lusb|" src/gcconfig.pri
- sed -i "" "s|#\(SAMPLERATE_INSTALL =\).*|\1 /usr/local|" src/gcconfig.pri
- sed -i "" "s|#\(SAMPLERATE_LIBS =\).*|\1 -L/usr/local/lib -lsamplerate|" src/gcconfig.pri
- sed -i "" "s|#\(DEFINES += GC_HAVE_LION*\)|\1|" src/gcconfig.pri
- sed -i "" "s|#\(HTPATH = ../httpserver.*\)|\1 |" src/gcconfig.pri
- sed -i "" "s|#\(DEFINES += GC_WANT_ROBOT.*\)|\1 |" src/gcconfig.pri
- sed -i "" "s|\(DEFINES += GC_VIDEO_NONE.*\)|#\1 |" src/gcconfig.pri
- sed -i "" "s|#\(DEFINES += GC_VIDEO_QUICKTIME.*\)|\1 |" src/gcconfig.pri
- echo "QMAKE_CFLAGS_RELEASE += -mmacosx-version-min=10.7 -arch x86_64" >> src/gcconfig.pri
- sed -i "" "s/__GC_GOOGLE_CALENDAR_CLIENT_SECRET__/"$GC_GOOGLE_CALENDAR_CLIENT_SECRET"/" src/Secrets.h
- sed -i "" "s/__GC_STRAVA_CLIENT_SECRET__/"$GC_STRAVA_CLIENT_SECRET"/" src/Secrets.h
- sed -i "" "s/__GC_DROPBOX_CLIENT_SECRET__/"$GC_DROPBOX_CLIENT_SECRET"/" src/Secrets.h
- sed -i "" "s/__GC_CYCLINGANALYTICS_CLIENT_SECRET__/"$GC_CYCLINGANALYTICS_CLIENT_SECRET"/" src/Secrets.h
- sed -i "" "s/__GC_TWITTER_CONSUMER_SECRET__/"$GC_TWITTER_CONSUMER_SECRET"/" src/Secrets.h
- cat src/gcconfig.pri
script:
- CC=clang CXX=clang++ /usr/local/opt/$QT_PATH/bin/qmake -makefile -recursive QMAKE_CXXFLAGS_WARN_ON+=-Wno-unused-private-field
- CC=clang CXX=clang++ make qmake_all
- CC=clang CXX=clang++ make -j4 sub-qwt --silent
- CC=clang CXX=clang++ make -j4 sub-src
after_success:
- cd src
- ls -laR GoldenCheetah.app
- sh ../travis/check-gc.sh
- /usr/local/opt/$QT_PATH/bin/macdeployqt GoldenCheetah.app -verbose=2 -dmg
## fix up the bundle with macdeployqtfix
- python ../travis/macdeployqtfix.py GoldenCheetah.app /usr/local/opt/$QT_PATH
- brew remove $QT
- mv GoldenCheetah.dmg GoldenCheetah_$QT.dmg
- hdiutil mount GoldenCheetah_$QT.dmg
- cd /Volumes/GoldenCheetah
- ls -laR GoldenCheetah.app
- GoldenCheetah.app/Contents/MacOS/GoldenCheetah --help
deploy:
provider: releases
api_key: $GH_OAUTH_TOKEN
file: GoldenCheetah_$QT.dmg
skip_cleanup: true
on:
tags: true

View File

@@ -5,8 +5,8 @@
Mark Liversedge
John Ehrlinger
Jan 2015
Version 1.2
May 2011
Version 1.1
A walkthrough of building GoldenCheetah from scratch on Ubuntu linux. This walkthrough
should be largely the same for any Linux distro.
@@ -30,6 +30,8 @@ CONTENTS
- bison
- libical - Diary window and CalDAV support (google/mobileme calendar integration)
- libvlc - Video playback in training mode
- clucene - Indexing/Searching ride files
1. BASIC INSTALLATION WITH MANDATORY DEPENDENCIES
=================================================
@@ -371,3 +373,29 @@ VLC_INSTALL = /usr/include/vlc/
$ make clean
$ qmake
$ make
CLUCENE - Indexing and Searching ride files (search box)
--------------------------------------------------------
You will need clucene runtime and core libraries, we developed against 0.9.21b-2 but
any 0.9 branch should work fine, let us know if you experience any issues. You may find
that the libclucene0ldbl runtime is already installed, this is fine and typical since
clucene is a very popular search library.
$ sudo apt-get install libclucene-dev
$ sudo apt-get install libclucene0ldbl
By default, and this is deliberate, the clucene install places the config headers into
a platform specific location. For my install I just copy the platform (linux) specific
header config into the normal /usr/include/CLucene directory with the following:
$ sudo cp /usr/lib/CLucene/clucene-config.h /usr/include/CLucene
Next we need to comment out the two CLUCENE lines in gcconfig.pri and they should read:
CLUCENE_INCLUDE = /usr/include/CLucene
CLUCENE_LIBS = -lclucene
$ make clean
$ qmake
$ make

View File

@@ -4,8 +4,8 @@
Mark Liversedge
Jan 2015
Version 1.2
Nov 2011
Version 1.1
A walkthrough of building GoldenCheetah from scratch on Mac OSX. This was performed
on Mac OSX Lion (10.7) but the instructions are largely the same for all versions of
@@ -25,6 +25,7 @@ CONTENTS
- libkml
- libusb
- libical
- libclucene
1. BASIC INSTALLATION WITH MANDATORY DEPENDENCIES
@@ -296,3 +297,15 @@ libical (0.46)
first run autogen.sh
then
./configure CFLAGS="-isysroot /Developer/SDKs/MacOSX10.7.sdk -arch x86_64" --disable-dependency-tracking
2.7 clucene
-----------
DO NOT USE THE MACPORTS VERSION (0.9.23) IT DOES NOT WORK.
git clone git://clucene.git.sourceforge.net/gitroot/clucene/clucene
cmake -G "Unix Makefiles"
make
sudo make install
will install clucene into /usr/local/include/clucene and /usr/local/lib

View File

@@ -2,14 +2,8 @@ Golden Cheetah install and build instructions are documented
for each platform;
INSTALL-WIN32 For building on Microsoft Windows
INSTALL-LINUX For building on Ubuntu Linux
INSTALL-MAC For building on Apple OS X
[![Build Status](https://travis-ci.org/GoldenCheetah/GoldenCheetah.svg?branch=master)](https://travis-ci.org/GoldenCheetah/GoldenCheetah)
Alternatively official builds are available from http://www.goldencheetah.org
whilst latest developer builds are available from http://goldencheetah.stand2surf.net

View File

@@ -1,316 +0,0 @@
From 7be04e65a53b22ce382d640a6c409b5d3bfe5645 Mon Sep 17 00:00:00 2001
From: Joern <joern.rm@gmail.com>
Date: Sat, 20 Dec 2014 12:42:37 +0100
Subject: [PATCH] Patch-Windows-MingGW-subset for GC
... reduce the libs in Make to what GoldenCheetah needs
... add two functions missing in MingGW standard libs
---
Makefile.am | 2 +-
configure.ac | 44 -------------------
src/Makefile.am | 2 +-
src/kml/base/file_posix.cc | 102 ++++++++++++++++++++++++++++++++++++++++++++
src/kml/base/string_util.cc | 17 ++++++++
third_party/Makefile.am | 42 +++---------------
6 files changed, 126 insertions(+), 83 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 2be0803..e29201e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
ACLOCAL_AMFLAGS = -I m4
# Order is important:
-SUBDIRS = third_party src testdata examples msvc xcode
+SUBDIRS = third_party src
EXTRA_DIST = \
AUTHORS \
diff --git a/configure.ac b/configure.ac
index d5fa75f..033128b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -203,23 +203,6 @@ AC_CHECK_LIB(pthread, pthread_create,,
AC_CONFIG_FILES([
Makefile
- examples/Makefile
- examples/domviewer/Makefile
- examples/engine/Makefile
- examples/gpx/Makefile
- examples/gx/Makefile
- examples/hellonet/Makefile
- examples/helloworld/Makefile
- examples/java/Makefile
- examples/kml/Makefile
- examples/python/Makefile
- examples/regionator/Makefile
- examples/wxregionator/Makefile
- examples/wxviewer/Makefile
- examples/xsd/Makefile
- msvc/Makefile
- msvc/examples/Makefile
- msvc/tests/Makefile
src/Makefile
src/kml/Makefile
src/kml/convenience/Makefile
@@ -228,34 +211,7 @@ AC_CONFIG_FILES([
src/kml/regionator/Makefile
src/kml/base/Makefile
src/kml/xsd/Makefile
- src/swig/Makefile
- src/swig/java/Makefile
- src/swig/python/Makefile
- testdata/Makefile
- testdata/atom/Makefile
- testdata/balloon/Makefile
- testdata/csv/Makefile
- testdata/deprecated/Makefile
- testdata/gdata/Makefile
- testdata/gmaps/Makefile
- testdata/gpx/Makefile
- testdata/gx/Makefile
- testdata/kml/Makefile
- testdata/kmz/Makefile
- testdata/kmz/files/Makefile
- testdata/kmz/kmzfiles/Makefile
- testdata/kmz/rumsey/Makefile
- testdata/kmz/rumsey/kml/Makefile
- testdata/kmz/rumsey/imagery/Makefile
- testdata/links/Makefile
- testdata/style/Makefile
- testdata/style/weather/Makefile
- testdata/update/Makefile
- testdata/xal/Makefile
- testdata/xsd/Makefile
third_party/Makefile
- xcode/Makefile
- xcode/LibKML/Makefile
])
AC_OUTPUT
diff --git a/src/Makefile.am b/src/Makefile.am
index 0bf15ac..721209e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = kml swig
+SUBDIRS = kml
# TODO: use the phc files in msvc.
EXTRA_DIST = \
diff --git a/src/kml/base/file_posix.cc b/src/kml/base/file_posix.cc
index b9461c0..920a996 100644
--- a/src/kml/base/file_posix.cc
+++ b/src/kml/base/file_posix.cc
@@ -33,8 +33,110 @@
#include <sys/stat.h>
#include <unistd.h> // For unlink, close.
+// START PATCH
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+// END PATCH
+
namespace kmlbase {
+// START PATCH
+// Implementation of missing functions
+
+/* mkstemp extracted from libc/sysdeps/posix/tempname.c. Copyright
+ (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version. */
+
+static const char letters[] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a temporary file name based on TMPL. TMPL must match the
+ rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
+ does not exist at the time of the call to mkstemp. TMPL is
+ overwritten with the result. */
+int
+mkstemp (char *tmpl)
+{
+ int len;
+ char *XXXXXX;
+ static unsigned long value;
+ unsigned long random_time_bits;
+ unsigned int count;
+ int fd = -1;
+ int save_errno = errno;
+
+ /* A lower bound on the number of temporary files to attempt to
+ generate. The maximum total number of temporary file names that
+ can exist for a given template is 62**6. It should never be
+ necessary to try all these combinations. Instead if a reasonable
+ number of names is tried (we define reasonable as 62**3) fail to
+ give the system administrator the chance to remove the problems. */
+#define ATTEMPTS_MIN (62 * 62 * 62)
+
+ /* The number of times to attempt to generate a temporary file. To
+ conform to POSIX, this must be no smaller than TMP_MAX. */
+#if ATTEMPTS_MIN < TMP_MAX
+ unsigned int attempts = TMP_MAX;
+#else
+ unsigned int attempts = ATTEMPTS_MIN;
+#endif
+
+ len = strlen (tmpl);
+ if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+/* This is where the Xs start. */
+ XXXXXX = &tmpl[len - 6];
+
+ /* Get some more or less random data. */
+ {
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
+ }
+ value += random_time_bits ^ getpid ();
+
+ for (count = 0; count < attempts; value += 7777, ++count)
+ {
+ unsigned long v = value;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, _S_IREAD | _S_IWRITE);
+ if (fd >= 0)
+ {
+ errno = save_errno;
+ return fd;
+ }
+ else if (errno != EEXIST)
+ return -1;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ errno = EEXIST;
+ return -1;
+}
+// END PATCH
+
// Internal to the POSIX File class.
static bool StatFile(const char* path, struct stat* stat_data) {
struct stat tmp;
diff --git a/src/kml/base/string_util.cc b/src/kml/base/string_util.cc
index b3a9654..3fdba2b 100644
--- a/src/kml/base/string_util.cc
+++ b/src/kml/base/string_util.cc
@@ -31,6 +31,23 @@
namespace kmlbase {
+// START PATCH
+int strncasecmp(const char *s1, const char *s2, size_t n) {
+ while (*s1 != 0 && tolower(*s1) == tolower(*s2)) {
+ ++s1;
+ ++s2;
+ }
+
+ return
+ (*s2 == 0)
+ ? (*s1 != 0)
+ : (*s1 == 0)
+ ? -1
+ : (tolower(*s1) - tolower(*s2));
+}
+
+// ENDPATCH
+
void b2a_hex(uint32_t i, char* out) {
char map[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};
diff --git a/third_party/Makefile.am b/third_party/Makefile.am
index b73dec3..fe34dea 100644
--- a/third_party/Makefile.am
+++ b/third_party/Makefile.am
@@ -12,7 +12,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/third_party/zlib-1.2.3/contrib \
-I$(top_srcdir)/third_party/gtest-1.7.0/include
lib_LTLIBRARIES = libminizip.la liburiparser.la
-noinst_LTLIBRARIES = libgtest.la libgtest_main.la
+#noinst_LTLIBRARIES = libgtest.la libgtest_main.la
libminizip_la_SOURCES = \
zlib-1.2.3/contrib/minizip/unzip.c \
@@ -83,11 +83,11 @@ libboostconfigplatforminclude_HEADERS = \
$(boost)/config/platform/linux.hpp \
$(boost)/config/platform/macos.hpp
-libgtest_la_SOURCES = \
- gtest-1.7.0/src/gtest-all.cc
+#libgtest_la_SOURCES = \
+# gtest-1.7.0/src/gtest-all.cc
-libgtest_main_la_SOURCES = gtest-1.7.0/src/gtest_main.cc
-libgtest_main_la_LIBADD = libgtest.la
+#libgtest_main_la_SOURCES = gtest-1.7.0/src/gtest_main.cc
+#libgtest_main_la_LIBADD = libgtest.la
# TODO: add the new gtest libs for windows.
# gtest-1.7.0.win32/debug/gtest.lib \
@@ -149,38 +149,6 @@ EXTRA_DIST = \
$(boost)/config/stdlib/sgi.hpp \
$(boost)/config/stdlib/stlport.hpp \
$(boost)/config/stdlib/vacpp.hpp \
- gtest-1.7.0/include/gtest/gtest-death-test.h \
- gtest-1.7.0/include/gtest/gtest-message.h \
- gtest-1.7.0/include/gtest/gtest-param-test.h \
- gtest-1.7.0/include/gtest/gtest-param-test.h.pump \
- gtest-1.7.0/include/gtest/gtest-printers.h \
- gtest-1.7.0/include/gtest/gtest-spi.h \
- gtest-1.7.0/include/gtest/gtest-test-part.h \
- gtest-1.7.0/include/gtest/gtest-typed-test.h \
- gtest-1.7.0/include/gtest/gtest.h \
- gtest-1.7.0/include/gtest/gtest_pred_impl.h \
- gtest-1.7.0/include/gtest/gtest_prod.h \
- gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h \
- gtest-1.7.0/include/gtest/internal/gtest-filepath.h \
- gtest-1.7.0/include/gtest/internal/gtest-internal.h \
- gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h \
- gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h \
- gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h.pump \
- gtest-1.7.0/include/gtest/internal/gtest-param-util.h \
- gtest-1.7.0/include/gtest/internal/gtest-port.h \
- gtest-1.7.0/include/gtest/internal/gtest-string.h \
- gtest-1.7.0/include/gtest/internal/gtest-tuple.h \
- gtest-1.7.0/include/gtest/internal/gtest-tuple.h.pump \
- gtest-1.7.0/include/gtest/internal/gtest-type-util.h \
- gtest-1.7.0/include/gtest/internal/gtest-type-util.h.pump \
- gtest-1.7.0/src/gtest-death-test.cc \
- gtest-1.7.0/src/gtest-filepath.cc \
- gtest-1.7.0/src/gtest-internal-inl.h \
- gtest-1.7.0/src/gtest-port.cc \
- gtest-1.7.0/src/gtest-printers.cc \
- gtest-1.7.0/src/gtest-test-part.cc \
- gtest-1.7.0/src/gtest-typed-test.cc \
- gtest-1.7.0/src/gtest.cc \
uriparser-0.7.5/COPYING \
uriparser-0.7.5.win32/debug/uriparser.lib \
uriparser-0.7.5.win32/release/uriparser.lib \
--
1.9.5.github.0

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@@ -1,12 +0,0 @@
# Ignores for Eclipse
/.settings/
# Ignores for Android Projects
/bin/
/gen/
/publish/
/local.properties
/secure.properties
# Ignores for Mac machines
.DS_Store

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AndroidXML>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="auto"
package="com.ridelogger"
android:versionCode="040000"
android:versionName="4.0.0"
android:icon="@drawable/ic_launcher" >
<uses-sdk android:minSdkVersion="14"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault.Light" >
<service
android:name="com.ridelogger.RideService"
android:icon="@drawable/ic_launcher"
android:label="@string/service_name" >
</service>
<activity
android:name="com.ridelogger.StartActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.ridelogger.SettingsActivity"
android:label="@string/setting_title" >
</activity>
</application>
</manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

View File

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
</lint>

View File

@@ -1,68 +0,0 @@
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
# Optimizations: If you don't want to optimize, use the
# proguard-android.txt configuration file instead of this one, which
# turns off the optimization flags. Adding optimization introduces
# certain risks, since for example not all optimizations performed by
# ProGuard works on all versions of Dalvik. The following flags turn
# off various optimizations known to have issues, but the list may not
# be complete or up to date. (The "arithmetic" optimization can be
# used if you are only targeting Android 2.0 or later.) Make sure you
# test thoroughly if you go this route.
-optimizations code/simplification/arithmetic,code/simplification/cast,field/*,class/merging/*
-optimizationpasses 24
-allowaccessmodification
-dontpreverify
# The remainder of this file is identical to the non-optimized version
# of the Proguard configuration file (except that the other file has
# flags to turn off optimization).
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native <methods>;
}
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontwarn android.support.**
-keep public class com.ridelogger.SettingsActivity$GeneralFragment
-keep public class com.ridelogger.SettingsActivity$AntFragment
-keep public class com.ridelogger.SettingsActivity$SensorsFragment

View File

@@ -1,15 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
proguard.config=proguard-android-optimize.txt
# Project target.
target=android-21
min=android-14

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AndroidXML>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LayoutData"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:gravity="right"
/>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<preference-headers
xmlns:android="http://schemas.android.com/apk/res/android">
<header android:fragment="com.ridelogger.SettingsActivity$GeneralFragment"
android:title="@string/setting_general_title"
android:summary="@string/setting_general_note" />
<header android:fragment="com.ridelogger.SettingsActivity$AntFragment"
android:title="@string/setting_ant_title"
android:summary="@string/setting_ant_note" />
<header android:fragment="com.ridelogger.SettingsActivity$SensorsFragment"
android:title="@string/setting_sensors_title"
android:summary="@string/setting_sensors_note" />
</preference-headers>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/Start"
android:title="@string/start" />
<item android:id="@+id/Stop"
android:title="@string/stop" />
<item android:id="@+id/Settings"
android:title="@string/edit_settings"
android:showAsAction="never" />
</menu>

View File

@@ -1,97 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AndroidXML>
<resources>
<string name="app_name">Ride Logger</string>
<string name="service_name">Logging Ride</string>
<string name="emergency_contact_dialog_title">Emergency Contact</string>
<string name="emergency_contact_dialog_note">Should a text messesage be sent on ride start and periodically to let your emergency contact know you are alright?</string>
<string name="sms_period_dialog_title">Emergency Contact SMS Period</string>
<string name="sms_period_dialog_note">Period in Minutes:</string>
<string name="crash_detection_dialog_title">Crash Detection</string>
<string name="crash_detection_dialog_note">Should a text messesage be sent on crash detction to your emergency contact?</string>
<string name="emergency_contact_number_dialog_title">Emergency Contact Number</string>
<string name="emergency_contact_number_dialog_note">Emergency phone number to update position on crash detection</string>
<string name="ant_setup_title">Set Ant+</string>
<string name="ant_setup_note">Pair your Ant+ devices now?</string>
<string name="ant_pair_dialog_title">Select Ant Devices</string>
<string name="ant_pair_dialog_button_note">Pair</string>
<string name="gc_rider_name_dialog_title">Enter Rider Name</string>
<string name="gc_rider_name_dialog_note">What is your Golder Cheata Rider Name?</string>
<string name="save_setting_button">Next</string>
<string name="skip_setting_button">Skip</string>
<string name="boolean_dialog_yes">Yes</string>
<string name="boolean_dialog_no">No</string>
<string name="starting_ride">Starting Ride!</string>
<string name="stopping_ride">Stoping Ride!</string>
<string name="ride_on">Ride On</string>
<string name="building_ride">Building ride: </string>
<string name="click_to_stop"> Click to stop ride.</string>
<string name="ride_start_title">Start Ride</string>
<string name="ride_start_note">Make sure locations is turned on. Internet connection is NOT required.</string>
<string name="start">Start Logging</string>
<string name="edit_settings">Settings</string>
<string name="ride_stop_title">Ride in Progress</string>
<string name="ride_stop_note">Would you like to stop the ride or view current values.</string>
<string name="stop">Stop Logging</string>
<string name="view">View</string>
<string name="crash_warning">WARNING CRASH!</string>
<string name="crash_confirm">CRASH CONFIRMED!</string>
<string name="crash_unknow_location">Unknow location.</string>
<string name="crash_magnitude">Mag</string>
<string name="ride_start_sms">I\'m starting my ride.</string>
<string name="ride_stop_sms">I have finished my ride.</string>
<string name="riding_ok_sms">I\'m ok.</string>
<string name="setting_title">Settings</string>
<string name="setting_general_title">General</string>
<string name="setting_general_note">Settings</string>
<string name="setting_ant_title">Ant+</string>
<string name="setting_ant_note">Setup your Ant+ Devices</string>
<string name="searching_for_ants">Searching for Ant+ Devices...</string>
<string name="found_ants">Found Ant+ Devices, Press to Pair.</string>
<string name="no_found_ants">Nothing found to pair.</string>
<string name="setting_sensors_title">Display Sensors</string>
<string name="setting_sensors_note">List of Sensors Display</string>
<string name="setting_wheel_size">Wheel Circumference in Meters</string>
<string name="imperial_units_title">Imperial Units</string>
<string name="imperial_units_note">Show Measurements in Imperial Units</string>
<string name="setting_size_title">Display Text Size</string>
<string name="PREFS_NAME">RideLogger</string>
<string name="PREF_RIDER_NAME">RiderName</string>
<string name="PREF_EMERGENCY_NUMBER">EmergencyNumbuer</string>
<string name="PREF_DETECT_CRASH">DetectCrash</string>
<string name="PREF_PHONE_HOME">PhoneHome</string>
<string name="PREF_PAIRED_ANTS">PairedAnts</string>
<string name="PREF_PHONE_HOME_PERIOD">PhoneHomePeriod</string>
<string name="PREF_TRACKING_SENSORS">TrackingSensors</string>
<string name="PREF_TRACKING_SIZE">TrackingSize</string>
<string name="PREF_TRACKING_IMPERIAL_UNITS">TrackingImperialUnits</string>
<string name="PREF_WHEEL_SIZE">WheelSize</string>
</resources>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="@string/PREFS_NAME">
<MultiSelectListPreference
android:key="@string/PREF_PAIRED_ANTS"
android:title="@string/ant_pair_dialog_title"
android:summary="@string/ant_pair_dialog_button_note"
/>
<EditTextPreference
android:key="@string/PREF_WHEEL_SIZE"
android:title="@string/setting_wheel_size"
android:defaultValue="2.096"
/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="@string/PREFS_NAME"
android:persistent="true">
<EditTextPreference
android:key="@string/PREF_RIDER_NAME"
android:title="@string/gc_rider_name_dialog_title"
android:summary="@string/gc_rider_name_dialog_note" />
<EditTextPreference
android:key="@string/PREF_EMERGENCY_NUMBER"
android:title="@string/emergency_contact_number_dialog_title"
android:summary="@string/emergency_contact_number_dialog_note" />
<CheckBoxPreference
android:layout="?android:attr/preferenceLayoutChild"
android:dependency="@string/PREF_EMERGENCY_NUMBER"
android:key="@string/PREF_DETECT_CRASH"
android:title="@string/crash_detection_dialog_title"
android:summary="@string/crash_detection_dialog_note" />
<!-- The visual style of a child is defined by this styled theme attribute. -->
<CheckBoxPreference
android:layout="?android:attr/preferenceLayoutChild"
android:dependency="@string/PREF_EMERGENCY_NUMBER"
android:key="@string/PREF_PHONE_HOME"
android:title="@string/emergency_contact_dialog_title"
android:summary="@string/emergency_contact_dialog_note" />
<EditTextPreference
android:layout="?android:attr/preferenceLayoutChild"
android:dependency="@string/PREF_PHONE_HOME"
android:key="@string/PREF_PHONE_HOME_PERIOD"
android:title="@string/sms_period_dialog_title"
android:summary="@string/sms_period_dialog_note"
android:defaultValue="20" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="@string/PREFS_NAME">
<MultiSelectListPreference
android:key="@string/PREF_TRACKING_SENSORS"
android:title="@string/setting_sensors_title"
android:summary="@string/setting_sensors_note"
/>
<CheckBoxPreference
android:key="@string/PREF_TRACKING_IMPERIAL_UNITS"
android:title="@string/imperial_units_title"
android:summary="@string/imperial_units_note"
/>
<EditTextPreference
android:key="@string/PREF_TRACKING_SIZE"
android:title="@string/setting_size_title"
android:defaultValue="20"
/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -1,281 +0,0 @@
package com.ridelogger;
import java.util.Set;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.preference.PreferenceManager;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class CurrentValuesAdapter extends BaseAdapter {
private StartActivity context;
private int[] keys;
private String[] values;
private String[] keyLabels;
private int size = 20;
private boolean imperial = false;
private SharedPreferences settings = null;
private GridView layout;
public CurrentValuesAdapter(StartActivity c, GridView pLayout) {
context = c;
layout = pLayout;
layout.setBackgroundColor(Color.BLACK);
layout.setVerticalSpacing(4);
layout.setHorizontalSpacing(4);
settings = PreferenceManager.getDefaultSharedPreferences(context);
Set<String> sensors = settings.getStringSet(context.getString(R.string.PREF_TRACKING_SENSORS), null);
size = Integer.valueOf(settings.getString(context.getString(R.string.PREF_TRACKING_SIZE), "20"));
imperial = settings.getBoolean(context.getString(R.string.PREF_TRACKING_IMPERIAL_UNITS), false);
initKeys(sensors);
initKeyLables();
initValues();
settings.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String pkey) {
if(pkey == context.getString(R.string.PREF_TRACKING_SIZE)) {
size = Integer.valueOf(sharedPreferences.getString(context.getString(R.string.PREF_TRACKING_SIZE), "20"));
setupWidth();
notifyDataSetChanged();
} else if (pkey == context.getString(R.string.PREF_TRACKING_SENSORS)) {
Set<String> sensors = sharedPreferences.getStringSet(context.getString(R.string.PREF_TRACKING_SENSORS), null);
initKeys(sensors);
initKeyLables();
initValues();
layout.setAdapter(CurrentValuesAdapter.this);
notifyDataSetChanged();
} else if (pkey == context.getString(R.string.PREF_TRACKING_IMPERIAL_UNITS)) {
imperial = sharedPreferences.getBoolean(pkey, false);
initKeyLables();
initValues();
notifyDataSetChanged();
}
}
}
);
}
private void initKeys(Set<String> sensors) {
if(sensors != null && sensors.size() > 0) {
keys = new int[sensors.size()];
int i = 0;
for(String sensor : sensors) {
keys[i] = Integer.parseInt(sensor);
i++;
}
} else {
keys = new int[RideService.KEYS.length];
for (int i = 0; i < RideService.KEYS.length; i++) {
keys[i] = i;
}
}
}
private void initKeyLables() {
keyLabels = new String[keys.length];
if(!imperial) {
for(int key : keys) {
keyLabels[key] = RideService.KEYS[key].toString().toLowerCase();
}
} else {
for(int key : keys) {
switch (key) {
case RideService.ALTITUDE:
keyLabels[key] = "ft";
break;
case RideService.KPH:
keyLabels[key] = "mph";
break;
case RideService.KM:
keyLabels[key] = "m";
break;
default:
keyLabels[key] = RideService.KEYS[key].toString().toLowerCase();
break;
}
}
}
}
private void initValues() {
values = new String[keys.length];
for (int key : keys) {
if(key == RideService.SECS) {
values[key] = "00:00:00";
} else {
values[key] = "0.0";
}
}
}
private RelativeLayout newRelativeLayout(int key) {
RelativeLayout view = new RelativeLayout(context);
view.setBackgroundColor(Color.WHITE);
TextView valueView = newValueTv(key);
TextView keyView = newKeyTv(key);
RelativeLayout.LayoutParams valueLayoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
valueLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
valueLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
view.addView(valueView, valueLayoutParams);
RelativeLayout.LayoutParams keyLayoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
keyLayoutParams.addRule(RelativeLayout.BELOW, valueView.getId());
keyLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
keyLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
view.addView(keyView, keyLayoutParams);
return view;
}
private TextView newValueTv(int key){
TextView tv = new TextView(context);
tv.setTextAppearance(context, android.R.attr.textAppearanceLarge);
tv.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
tv.setText(values[key]);
tv.setId(key + 1);
return tv;
}
private TextView newKeyTv(int key){
TextView tv = new TextView(context);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
tv.setBackgroundColor(Color.LTGRAY);
tv.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
tv.setPadding(4, 1, 4, 1);
tv.setText(keyLabels[key]);
return tv;
}
@Override
public int getCount() {
return keys.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
return newRelativeLayout(keys[position]);
} else {
RelativeLayout view = (RelativeLayout) convertView;
TextView valueView = (TextView) (view.getChildAt(0));
TextView valueKey = (TextView) (view.getChildAt(1));
if(valueView.getText() != values[keys[position]])
valueView.setText(values[keys[position]]);
valueView.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
if(valueKey.getText() != keyLabels[keys[position]])
valueKey.setText(keyLabels[keys[position]]);
return convertView;
}
}
public void update(float[] current_float_values) {
for (int key: keys) {
if(key == RideService.SECS) {
int hr = (int) (current_float_values[key]/3600);
int rem = (int) (current_float_values[key]%3600);
int mn = rem/60;
int sec = rem%60;
values[key] = (hr<10 ? "0" : "") + hr + ":" + (mn<10 ? "0" : "") + mn + ":" + (sec<10 ? "0" : "")+sec;
} else if(!imperial) {
values[key] = String.format("%.1f", current_float_values[key]);
} else {
switch (key) {
case RideService.ALTITUDE:
values[key] = String.format("%.1f", current_float_values[key] * 3.28084);
break;
case RideService.KPH:
values[key] = String.format("%.1f", current_float_values[key] * 0.621371);
break;
case RideService.KM:
values[key] = String.format("%.1f", current_float_values[key] * 0.621371);
break;
default:
values[key] = String.format("%.1f", current_float_values[key]);
break;
}
}
}
notifyDataSetChanged();
}
/**
* returns the size of the cell basted on 8 chars wide and the configured size param
* @return int
*/
private void setupWidth() {
TextView tv = new TextView(context);
tv.setTextAppearance(context, android.R.attr.textAppearanceLarge);
tv.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
tv.setText(String.format("%.1f", 1111.11));
Rect bounds = new Rect();
tv.getPaint().getTextBounds("00:00:00", 0, "00:00:00".length(), bounds);
layout.setColumnWidth(bounds.width() + 16);
}
}

View File

@@ -1,28 +0,0 @@
package com.ridelogger;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
public class GzipWriter extends GZIPOutputStream {
public GzipWriter(OutputStream os) throws IOException {
super(os);
}
public void write(String data) throws IOException {
super.write(data.getBytes());
}
public void write(float data) throws IOException {
super.write(Float.floatToIntBits(data));
}
public void write(CharSequence data) throws IOException {
byte[] barr = new byte[data.length()];
for (int i = 0; i < barr.length; i++) {
barr[i] = (byte) data.charAt(i);
}
super.write(barr);
}
}

View File

@@ -1,417 +0,0 @@
package com.ridelogger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
import com.dsi.ant.plugins.antplus.pcc.defines.DeviceType;
import com.dsi.ant.plugins.utility.log.LogAnt;
import com.ridelogger.formats.BaseFormat;
import com.ridelogger.formats.JsonFormat;
import com.ridelogger.listners.Base;
import com.ridelogger.listners.Gps;
import com.ridelogger.listners.HeartRate;
import com.ridelogger.listners.Power;
import com.ridelogger.listners.Sensors;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsManager;
/**
* RideService
* @author Chet Henry
* Performs ride logging from sensors as an android service
*/
public class RideService extends Service
{
public static final int notifyID = 1; //Id of the notification in the top android bar that this class creates and alters
public static final int SECS = 0;
public static final int KPH = 1;
public static final int ALTITUDE = 2;
public static final int bearing = 3;
public static final int gpsa = 4;
public static final int LAT = 5;
public static final int LON = 6;
public static final int HR = 7;
public static final int WATTS = 8;
public static final int NM = 9;
public static final int CAD = 10;
public static final int KM = 11;
public static final int LTE = 12;
public static final int RTE = 13;
public static final int SNPLC = 14;
public static final int SNPR = 15;
public static final int ms2x = 16;
public static final int ms2y = 17;
public static final int ms2z = 18;
public static final int temp = 19;
public static final int uTx = 20;
public static final int uTy = 21;
public static final int uTz = 22;
public static final int press = 23;
public static final int lux = 24;
public static CharSequence[] KEYS = {
"SECS",
"KPH",
"ALTITUDE",
"bearing",
"gpsa",
"LAT",
"LON",
"HR",
"WATTS",
"NM",
"CAD",
"KM",
"LTE",
"RTE",
"SNPLC",
"SNPR",
"ms2x",
"ms2y",
"ms2z",
"temp",
"uTx",
"uTy",
"uTz",
"press",
"lux"
};
public GzipWriter buf; //writes to log file buffered
public long startTime; //start time of the ride
public float[] currentValues = new float[RideService.KEYS.length]; //float array of current values
private Messenger mMessenger = null; //class to send back current values if needed
private boolean rideStarted = false; //have we started logging the ride
private int sensor_index = 0; //current index of sensors
private String emergencyNumbuer; //the number to send the messages to
private Timer timer; //timer class to control the periodic messages
private Timer timerUI; //timer class to control the periodic messages
private Base<?>[] sensors; //list of sensors tracking
public BaseFormat<?> fileFormat;
/**
* starts the ride on service start
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startRide();
return Service.START_NOT_STICKY;
}
/**
* returns the messenger to talk to the app with
*/
@Override
public IBinder onBind(Intent arg0) {
mMessenger = new Messenger(new Handler() { // Handler of incoming messages from clients.
Messenger replyTo;
@Override
public void handleMessage(Message msg) {
if(timerUI != null) {
timerUI.cancel();
timerUI = null;
}
timerUI = new Timer();
if(msg.replyTo != null) {
replyTo = msg.replyTo;
timerUI.scheduleAtFixedRate(
new TimerTask() {
@Override
public void run() {
Message msg = Message.obtain(null, 2, 0, 0);
Bundle bundle = new Bundle();
bundle.putSerializable("currentValues", currentValues);
msg.setData(bundle);
try {
replyTo.send(msg);
} catch (RemoteException e) {}
}
},
1000,
1000
); //every second update the screen
}
}
}); // Target we publish for clients to send messages to IncomingHandler.
return mMessenger.getBinder();
}
/**
* releases the timer that sends messages to the app
*/
@Override
public boolean onUnbind (Intent intent) {
if(timerUI != null) {
timerUI.cancel();
timerUI = null;
}
mMessenger = null;
return true;
}
/**
* stop the ride on service stop
*/
@Override
public void onDestroy() {
stopRide();
super.onDestroy();
}
/**
* start a ride if there is not one started yet
*/
protected void startRide() {
if(rideStarted) return;
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
emergencyNumbuer = settings.getString(getString(R.string.PREF_EMERGENCY_NUMBER), "");
currentValues[SECS] = (float) 0.0;
startTime = System.currentTimeMillis();
Date startDate = new Date(startTime);
SimpleDateFormat startTimef = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
SimpleDateFormat filef = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
SimpleDateFormat month = new SimpleDateFormat("MMMMM");
SimpleDateFormat year = new SimpleDateFormat("yyyy");
SimpleDateFormat day = new SimpleDateFormat("EEEEE");
startTimef.setTimeZone(TimeZone.getTimeZone("UTC"));
filef.setTimeZone(TimeZone.getTimeZone("UTC"));
month.setTimeZone(TimeZone.getTimeZone("UTC"));
year.setTimeZone(TimeZone.getTimeZone("UTC"));
day.setTimeZone(TimeZone.getTimeZone("UTC"));
final String fileName = filef.format(startDate) + ".json.gz";
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
fileFormat = new JsonFormat(this);
fileFormat.createFile();
fileFormat.writeHeader();
LogAnt.setDebugLevel(LogAnt.DebugLevel.NONE, this);
final Set<String> pairedAnts = settings.getStringSet(getString(R.string.PREF_PAIRED_ANTS), null);
if(pairedAnts != null && !pairedAnts.isEmpty()){
sensors = new Base<?>[pairedAnts.size() + 2];
for(String deviceNumber: pairedAnts) {
DeviceType deviceType = DeviceType.getValueFromInt(settings.getInt(deviceNumber, 0));
switch (deviceType) {
case BIKE_CADENCE:
break;
case BIKE_POWER:
sensors[sensor_index++] = new Power(Integer.valueOf(deviceNumber), this);
break;
case BIKE_SPD:
break;
case BIKE_SPDCAD:
break;
case BLOOD_PRESSURE:
break;
case ENVIRONMENT:
break;
case WEIGHT_SCALE:
break;
case HEARTRATE:
sensors[sensor_index++] = new HeartRate(Integer.valueOf(deviceNumber), this);
break;
case STRIDE_SDM:
break;
case FITNESS_EQUIPMENT:
break;
case GEOCACHE:
case CONTROLLABLE_DEVICE:
break;
case UNKNOWN:
break;
default:
break;
}
}
} else {
sensors = new Base<?>[4];
sensors[sensor_index++] = new HeartRate(0, this);
sensors[sensor_index++] = new Power(0, this);
}
sensors[sensor_index++] = new Gps(this);
sensors[sensor_index++] = new Sensors(this);
}
rideStarted = true;
if(settings.getBoolean(getString(R.string.PREF_PHONE_HOME), false)) {
timer = new Timer();
int period = Integer.parseInt(settings.getString(getString(R.string.PREF_PHONE_HOME_PERIOD), "10"));
timer.scheduleAtFixedRate(
new TimerTask() {
@Override
public void run() {
phoneHome();
}
},
60000 * period,
60000 * period
); //every ten min let them know where you are at
phoneStart();
}
//build the notification in the top android drawer
NotificationCompat.Builder mBuilder = new NotificationCompat
.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(getString(R.string.ride_on))
.setContentText(getString(R.string.building_ride) + " " + fileName + " " + getString(R.string.click_to_stop))
.setProgress(0, 0, true)
.setContentIntent(
TaskStackBuilder
.create(this)
.addParentStack(StartActivity.class)
.addNextIntent(new Intent(this, StartActivity.class))
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
);
startForeground(notifyID, mBuilder.build());
}
/**
* let a love one know where you are at about every 10 min
*/
public void phoneCrash(double mag) {
smsHome(
getString(R.string.crash_warning) + "\n" + getLocationLink()
+ "\n " + getString(R.string.crash_magnitude) + ": " + String.valueOf(mag)
);
}
/**
* confirm the crash if we are not moving
*/
public void phoneCrashConfirm() {
smsHome(getString(R.string.crash_confirm) + "!\n" + getLocationLink());
}
/**
* let them know we are starting
*/
public void phoneStart() {
smsWithLocation(getString(R.string.ride_start_sms));
}
/**
* let them know we are stopping
*/
public void phoneStop() {
smsWithLocation(getString(R.string.ride_stop_sms));
}
/**
* send an sms with location
*/
public void smsWithLocation(String body) {
smsHome(body + "\n " + getLocationLink());
}
/**
* let a love one know where you are at about every 10 min
*/
public void phoneHome() {
smsWithLocation(getString(R.string.riding_ok_sms));
}
/**
* send a sms message
*/
public void smsHome(String body) {
SmsManager smsManager = SmsManager.getDefault();
if(emergencyNumbuer != null && PhoneNumberUtils.isWellFormedSmsAddress(emergencyNumbuer)) {
smsManager.sendTextMessage(emergencyNumbuer, null, body, null, null);
}
}
public String getLocationLink() {
if(currentValues[LAT] != 0.0 || currentValues[LON] != 0.0) {
return "https://www.google.com/maps/place/" + currentValues[LAT] + "," + currentValues[LON];
}
return getString(R.string.crash_unknow_location);
}
//stop the ride and clean up resources
protected void stopRide() {
if(!rideStarted) return;
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
if(settings.getBoolean(getString(R.string.PREF_PHONE_HOME), false)) {
phoneStop();
}
for(Base<?> sensor: sensors) {
if(sensor != null) {
sensor.onDestroy();
}
}
//stop the phoneHome timer if we need to.
if(timer != null) {
timer.cancel();
timer = null;
}
if(timerUI != null) {
timerUI.cancel();
timerUI = null;
}
fileFormat.writeFooter();
rideStarted = false;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(notifyID);
}
}

View File

@@ -1,274 +0,0 @@
package com.ridelogger;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import com.dsi.ant.plugins.antplus.pcc.defines.DeviceType;
import com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult;
import com.dsi.ant.plugins.antplus.pccbase.MultiDeviceSearch;
import com.dsi.ant.plugins.antplus.pccbase.MultiDeviceSearch.MultiDeviceSearchResult;
import com.dsi.ant.plugins.utility.log.LogAnt;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.preference.MultiSelectListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
public class SettingsActivity extends PreferenceActivity {
static ArrayList<MultiDeviceSearchResult> foundDevices = new ArrayList<MultiDeviceSearchResult>();
/**
* This fragment contains a second-level set of preference that you
* can get to by tapping an item in the first preferences fragment.
*/
public static class GeneralFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.general_settings);
}
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
if(((SettingsActivity) getActivity()).getServiceRunning(RideService.class) != null) {
Preference pref = findPreference(getString(R.string.PREF_RIDER_NAME));
pref.setEnabled(false);
pref = findPreference(getString(R.string.PREF_EMERGENCY_NUMBER));
pref.setEnabled(false);
}
}
}
/**
* This fragment contains a second-level set of preference that you
* can get to by tapping an item in the first preferences fragment.
*/
public static class SensorsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.sensors_settings);
MultiSelectListPreference mMultiSelectListPreference = (MultiSelectListPreference) findPreference(getString(R.string.PREF_TRACKING_SENSORS));
mMultiSelectListPreference.setEntries( RideService.KEYS );
CharSequence[] keys = new CharSequence[RideService.KEYS.length];
for (int i = 0; i < RideService.KEYS.length; i++) {
keys[i] = String.valueOf(i);
}
mMultiSelectListPreference.setEntryValues(keys);
}
}
@Override
public boolean isValidFragment(String fragment) {
return true;
}
/**
* This fragment contains a second-level set of preference that you
* can get to by tapping an item in the first preferences fragment.
*/
public static class AntFragment extends PreferenceFragment {
private MultiDeviceSearch mSearch;
private MultiSelectListPreference mMultiSelectListPreference;
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.ant_settings);
mMultiSelectListPreference = (MultiSelectListPreference) findPreference(getString(R.string.PREF_PAIRED_ANTS));
}
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
initAntSearch();
}
/**
* search for ant+ if we are not recording
*/
public void initAntSearch() {
mMultiSelectListPreference.setEnabled(false);
if(((SettingsActivity) getActivity()).getServiceRunning(RideService.class) == null) {
mMultiSelectListPreference.setSummary(R.string.searching_for_ants);
setupAnt();
Timer timer = new Timer();
final Handler handler = new Handler();
timer.schedule(
new TimerTask() {
@Override
public void run() {
if(mMultiSelectListPreference.getEntryValues().length > 0) {
handler.post(new Runnable() {
public void run() {
mMultiSelectListPreference.setEnabled(true);
mMultiSelectListPreference.setSummary(R.string.found_ants);
}
});
} else {
handler.post(new Runnable() {
public void run() {
mMultiSelectListPreference.setEnabled(true);
mMultiSelectListPreference.setSummary(R.string.no_found_ants);
}
});
}
}
},
5000
);
}
}
/**
* try to pair some ant+ devices
*/
protected void setupAnt() {
MultiDeviceSearch.SearchCallbacks mCallback;
MultiDeviceSearch.RssiCallback mRssiCallback;
updateList(foundDevices);
LogAnt.setDebugLevel(LogAnt.DebugLevel.NONE, this.getActivity());
mCallback = new MultiDeviceSearch.SearchCallbacks(){
public void onDeviceFound(final MultiDeviceSearchResult deviceFound)
{
if(!foundDevices.contains(deviceFound)) {
foundDevices.add(deviceFound);
updateList(foundDevices);
}
}
@Override
public void onSearchStopped(RequestAccessResult arg0) {}
};
mRssiCallback = new MultiDeviceSearch.RssiCallback() {
@Override
public void onRssiUpdate(final int resultId, final int rssi){}
};
// start the multi-device search
mSearch = new MultiDeviceSearch(this.getActivity(), EnumSet.allOf(DeviceType.class), mCallback, mRssiCallback);
}
/**
* dialog of soon to be paired ant devices
* @param foundDevices
*/
protected void updateList(final ArrayList<MultiDeviceSearchResult> foundDevices) {
ArrayList<CharSequence> foundDevicesString = new ArrayList<CharSequence>();
ArrayList<CharSequence> foundDevicesValues = new ArrayList<CharSequence>();
for(MultiDeviceSearchResult device : foundDevices) {
foundDevicesString.add(device.getAntDeviceType() + ": " + String.valueOf(device.getAntDeviceNumber()));
}
for(MultiDeviceSearchResult device : foundDevices) {
foundDevicesValues.add(String.valueOf(device.getAntDeviceNumber()));
}
if(mMultiSelectListPreference != null) {
mMultiSelectListPreference.setEntries(
foundDevicesString.toArray(new CharSequence[foundDevicesString.size()])
);
mMultiSelectListPreference.setEntryValues(
foundDevicesValues.toArray(new CharSequence[foundDevicesValues.size()])
);
}
}
@Override
public void onDestroy() {
if(mSearch != null) mSearch.close();
super.onDestroy();
}
}
/**
* Populate the activity with the top-level headers.
*/
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.layout.settings, target);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
settings.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String pkey) {
if (pkey == getString(R.string.PREF_PAIRED_ANTS)) {
Set<String> sensors = sharedPreferences.getStringSet(pkey, null);
if(sensors != null && sensors.size() > 0) {
Editor editor = sharedPreferences.edit();
for(MultiDeviceSearchResult result : foundDevices) {
sensors.contains(String.valueOf(result.getAntDeviceNumber()));
editor.putInt(String.valueOf(result.getAntDeviceNumber()), result.getAntDeviceType().getIntValue());
}
editor.commit();
}
}
}
}
);
}
/**
* is a service running or not
* @param serviceClass
* @return
*/
public RunningServiceInfo getServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return service;
}
}
return null;
}
}

View File

@@ -1,215 +0,0 @@
package com.ridelogger;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.GridView;
import android.widget.Toast;
public class StartActivity extends FragmentActivity
{
private MenuItem startMenu;
private MenuItem stopMenu;
private ServiceConnection mConnection;
static CurrentValuesAdapter currentValuesAdapter;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.start_activity, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
if(item.getItemId() == R.id.Settings) {
setupSettings();
} else if(item.getItemId() == R.id.Start) {
startRide();
} else {
stopRide();
}
return true;
}
/**
* start up our class
*/
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
GridView layout = (GridView) findViewById(R.id.LayoutData);
currentValuesAdapter = new CurrentValuesAdapter(this, layout);
layout.setAdapter(currentValuesAdapter);
}
@Override
protected void onResume() {
super.onResume();
bindToService();
}
@Override
protected void onPause() {
super.onPause();
unBindToService();
}
@Override
protected void onStop() {
super.onStop();
unBindToService();
}
/**
* setup the settings for the user
*/
private void setupSettings() {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
}
/**
* stop ride and clean up references
*/
private void stopRide() {
Toast toast = Toast.makeText(getApplicationContext(), getString(R.string.stopping_ride), Toast.LENGTH_LONG);
toast.show();
Intent rsi = new Intent(this, RideService.class);
this.stopService(rsi);
finish();
}
static final Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg_internal) {
updateValues(msg_internal.getData());
}
};
/**
* tell the service to start sending us messages with current values
*/
private void bindToService() {
RunningServiceInfo service = getServiceRunning(RideService.class);
if(service != null) {
mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
Messenger mService = new Messenger(service);
try {
Message msg = Message.obtain();
msg.replyTo = new Messenger(mHandler);
mService.send(msg);
} catch (RemoteException e) {
// In this case the service has crashed before we could even do anything with it
}
}
public void onServiceDisconnected(ComponentName className) {}
};
bindService(new Intent(StartActivity.this, RideService.class), mConnection, Context.BIND_AUTO_CREATE);
}
}
/**
* tell the service to stop sending us messages with current values
*/
private void unBindToService() {
if (mConnection != null) {
// Detach our existing connection.
unbindService(mConnection);
mConnection = null;
}
}
/**
* update the text fields with current values
* @param bundle
*/
private static void updateValues(Bundle bundle) {
currentValuesAdapter.update((float[]) bundle.getSerializable("currentValues"));
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
RunningServiceInfo service = getServiceRunning(RideService.class);
startMenu = menu.findItem(R.id.Start);
stopMenu = menu.findItem(R.id.Stop);
if(service == null) {
startMenu.setVisible(true);
stopMenu.setVisible(false);
} else {
startMenu.setVisible(false);
stopMenu.setVisible(true);
}
return true;
}
/**
* start the ride and notify the user of success
*/
private void startRide() {
Intent rsi = new Intent(this, RideService.class);
this.startService(rsi);
startMenu.setVisible(false);
stopMenu.setVisible(true);
bindToService();
Toast toast = Toast.makeText(getApplicationContext(), getString(R.string.starting_ride), Toast.LENGTH_LONG);
toast.show();
}
/**
* is a service running or not
* @param serviceClass
* @return
*/
private RunningServiceInfo getServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return service;
}
}
return null;
}
}

View File

@@ -1,71 +0,0 @@
package com.ridelogger.formats;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.os.Environment;
import com.ridelogger.GzipWriter;
import com.ridelogger.RideService;
public class BaseFormat<T> {
protected GzipWriter buf;
protected RideService context;
protected String subExt = "";
public BaseFormat(RideService rideService) {
context = rideService;
}
public void createFile() {
File dir = new File(
Environment.getExternalStorageDirectory(),
"Rides"
);
dir.mkdirs();
Date startDate = new Date(context.startTime);
SimpleDateFormat filef = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
String fileName = filef.format(startDate) + subExt + ".gz";
try {
buf = new GzipWriter(new BufferedOutputStream(new FileOutputStream(new File(dir, fileName))));
} catch (Exception e) {}
}
public void writeHeader(){
try {
synchronized (buf) {
for(CharSequence key : RideService.KEYS) {
buf.write(key);
buf.write(",");
}
}
} catch (Exception e) {}
}
public void writeValues() {
try {
synchronized (buf) {
for(float value : context.currentValues) {
buf.write(value);
}
}
} catch (Exception e) {}
}
public void writeFooter() {
try {
buf.close();
} catch (Exception e) {}
}
}

View File

@@ -1,93 +0,0 @@
package com.ridelogger.formats;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import com.ridelogger.R;
import com.ridelogger.RideService;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class JsonFormat extends BaseFormat<Object> {
public JsonFormat(RideService rideService) {
super(rideService);
subExt = ".json";
}
public void writeHeader() {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
Date startDate = new Date(context.startTime);
SimpleDateFormat startTimef = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
SimpleDateFormat filef = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
SimpleDateFormat month = new SimpleDateFormat("MMMMM");
SimpleDateFormat year = new SimpleDateFormat("yyyy");
SimpleDateFormat day = new SimpleDateFormat("EEEEE");
startTimef.setTimeZone(TimeZone.getTimeZone("UTC"));
filef.setTimeZone(TimeZone.getTimeZone("UTC"));
month.setTimeZone(TimeZone.getTimeZone("UTC"));
year.setTimeZone(TimeZone.getTimeZone("UTC"));
day.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
buf.write("{" +
"\"RIDE\":{" +
"\"STARTTIME\":\"" + startTimef.format(startDate) + " UTC\"," +
"\"RECINTSECS\":1," +
"\"DEVICETYPE\":\"Android\"," +
"\"IDENTIFIER\":\"\"," +
"\"TAGS\":{" +
"\"Athlete\":\"" + settings.getString(context.getString(R.string.PREF_RIDER_NAME), "") + "\"," +
"\"Calendar Text\":\"Auto Recored Android Ride\"," +
"\"Change History\":\"\"," +
"\"Data\":\"\"," +
"\"Device\":\"\"," +
"\"Device Info\":\"\"," +
"\"File Format\":\"\"," +
"\"Filename\":\"\"," +
"\"Month\":\"" + month.format(startDate) +"\"," +
"\"Notes\":\"\"," +
"\"Objective\":\"\"," +
"\"Sport\":\"Bike\"," +
"\"Weekday\":\"" + day.format(startDate) + "\"," +
"\"Workout Code\":\"\"," +
"\"Year\":\"" + year.format(startDate) + "\"" +
"}," +
"\"SAMPLES\":[{\"SECS\":0}");
} catch (Exception e) {}
}
public void writeValues() {
try {
synchronized (buf) {
buf.write(",{");
buf.write("\"");
buf.write(RideService.KEYS[0]);
buf.write("\":");
buf.write(String.format("%f", context.currentValues[0]));
for (int i = 1; i < context.currentValues.length; i++) {
buf.write(",\"");
buf.write(RideService.KEYS[i]);
buf.write("\":");
buf.write(String.format("%f", context.currentValues[i]));
}
buf.write("}");
}
} catch (Exception e) {}
}
public void writeFooter() {
try {
buf.write("]}}");
} catch (Exception e) {}
super.writeFooter();
}
}

View File

@@ -1,54 +0,0 @@
package com.ridelogger.listners;
import com.dsi.ant.plugins.antplus.pcc.defines.DeviceState;
import com.dsi.ant.plugins.antplus.pccbase.PccReleaseHandle;
import com.dsi.ant.plugins.antplus.pccbase.AntPluginPcc.IDeviceStateChangeReceiver;
import com.dsi.ant.plugins.antplus.pccbase.AntPluginPcc.IPluginAccessResultReceiver;
import com.ridelogger.RideService;
/**
* Ant
* @author Chet Henry
* Listen to and log Ant+ events base class
*/
public abstract class Ant extends Base<Object>
{
protected PccReleaseHandle<?> releaseHandle; //Handle class
public IPluginAccessResultReceiver<?> mResultReceiver; //Receiver class
protected int deviceNumber = 0;
//setup listeners and logging
public Ant(int pDeviceNumber, RideService mContext)
{
super(mContext);
deviceNumber = pDeviceNumber;
}
public IDeviceStateChangeReceiver mDeviceStateChangeReceiver = new IDeviceStateChangeReceiver()
{
@Override
public void onDeviceStateChange(final DeviceState newDeviceState){
//if we lose a device zero out its values
if(newDeviceState.equals(DeviceState.DEAD)) {
zeroReadings();
}
}
};
abstract protected void requestAccess();
@Override
public void onDestroy()
{
if(releaseHandle != null) {
releaseHandle.close();
}
}
}

View File

@@ -1,58 +0,0 @@
package com.ridelogger.listners;
import com.ridelogger.RideService;
/**
* Base
* @author Chet Henry
* Base sensor class that has methods to time stamp are write to buffer
*/
public class Base<T>
{
public RideService context;
public Base(RideService mContext) {
context = mContext;
}
public void alterCurrentData(int key, float value)
{
synchronized (context.currentValues) {
context.currentValues[RideService.SECS] = getTs();
context.currentValues[key] = value;
context.fileFormat.writeValues();
}
}
public void alterCurrentData(int[] keys, float[] values)
{
synchronized (context.currentValues) {
context.currentValues[RideService.SECS] = getTs();
int i = 0;
for (int key : keys) {
context.currentValues[key] = values[i];
i++;
}
context.fileFormat.writeValues();
}
}
//get current time stamp
public float getTs() {
return (float) ((System.currentTimeMillis() - context.startTime) / 1000.0);
}
//Clean up my listeners here
public void onDestroy() {}
//zero any of my values
public void zeroReadings() {}
}

View File

@@ -1,61 +0,0 @@
package com.ridelogger.listners;
import com.ridelogger.RideService;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
/**
* Gps
* @author henry
* Listen and log gps events
*/
public class Gps extends Base<Gps>
{
public Gps(RideService mContext)
{
super(mContext);
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//listen to gps events and log them
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
int[] keys = {
RideService.ALTITUDE,
RideService.KPH,
RideService.bearing,
RideService.gpsa,
RideService.LAT,
RideService.LON
};
float[] values = {
(float) location.getAltitude(),
location.getSpeed(),
location.getBearing(),
location.getAccuracy(),
(float) location.getLatitude(),
(float) location.getLongitude()
};
alterCurrentData(keys, values);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
}

View File

@@ -1,69 +0,0 @@
package com.ridelogger.listners;
import com.dsi.ant.plugins.antplus.pcc.AntPlusHeartRatePcc;
import com.dsi.ant.plugins.antplus.pcc.AntPlusHeartRatePcc.DataState;
import com.dsi.ant.plugins.antplus.pcc.AntPlusHeartRatePcc.IHeartRateDataReceiver;
import com.dsi.ant.plugins.antplus.pcc.defines.DeviceState;
import com.dsi.ant.plugins.antplus.pcc.defines.EventFlag;
import com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult;
import com.dsi.ant.plugins.antplus.pccbase.AntPluginPcc.IPluginAccessResultReceiver;
import com.ridelogger.RideService;
import java.math.BigDecimal;
import java.util.EnumSet;
/**
* HeartRate
* @author Chet Henry
* Listen to and log Ant+ HearRate events
*/
public class HeartRate extends Ant
{
public IPluginAccessResultReceiver<AntPlusHeartRatePcc> mResultReceiver;
public HeartRate(int pDeviceNumber, RideService mContext) {
super(pDeviceNumber, mContext);
mResultReceiver = new IPluginAccessResultReceiver<AntPlusHeartRatePcc>() {
//Handle the result, connecting to events on success or reporting failure to user.
@Override
public void onResultReceived(AntPlusHeartRatePcc result, RequestAccessResult resultCode, DeviceState initialDeviceState)
{
if(resultCode == com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult.SUCCESS) {
deviceNumber = result.getAntDeviceNumber();
result.subscribeHeartRateDataEvent(
new IHeartRateDataReceiver() {
@Override
public void onNewHeartRateData(final long estTimestamp, EnumSet<EventFlag> eventFlags, final int computedHeartRate, final long heartBeatCount, final BigDecimal heartBeatEventTime, final DataState dataState) {
alterCurrentData(RideService.HR, (float) computedHeartRate);
}
}
);
} else if(resultCode == com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult.SEARCH_TIMEOUT) {
if(deviceNumber != 0) {
requestAccess();
}
}
}
};
requestAccess();
}
@Override
protected void requestAccess() {
releaseHandle = AntPlusHeartRatePcc.requestAccess(context, deviceNumber, 0, mResultReceiver, mDeviceStateChangeReceiver);
}
@Override
public void zeroReadings()
{
alterCurrentData(RideService.HR, (float) 0.0);
}
}

View File

@@ -1,223 +0,0 @@
package com.ridelogger.listners;
import android.preference.PreferenceManager;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.CalculatedWheelDistanceReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.CalculatedWheelSpeedReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.DataSource;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.ICalculatedCrankCadenceReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.ICalculatedPowerReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.ICalculatedTorqueReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.IInstantaneousCadenceReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.IRawPowerOnlyDataReceiver;
import com.dsi.ant.plugins.antplus.pcc.defines.DeviceState;
import com.dsi.ant.plugins.antplus.pcc.defines.EventFlag;
import com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult;
import com.dsi.ant.plugins.antplus.pccbase.AntPluginPcc.IPluginAccessResultReceiver;
import com.ridelogger.R;
import com.ridelogger.RideService;
import java.math.BigDecimal;
import java.util.EnumSet;
/**
* Power
* @author Chet Henry
* Listen to and log Ant+ Power events
*/
public class Power extends Ant
{
public BigDecimal wheelCircumferenceInMeters; //size of wheel to calculate speed
public IPluginAccessResultReceiver<AntPlusBikePowerPcc> mResultReceiver;
//setup listeners and logging
public Power(int pDeviceNumber, RideService mContext) {
super(pDeviceNumber, mContext);
wheelCircumferenceInMeters = new BigDecimal(
PreferenceManager.getDefaultSharedPreferences(context).getString(context.getString(R.string.PREF_WHEEL_SIZE), "2.096")
);
//Handle messages
mResultReceiver = new IPluginAccessResultReceiver<AntPlusBikePowerPcc>() {
//Handle the result, connecting to events on success or reporting failure to user.
@Override
public void onResultReceived(AntPlusBikePowerPcc result, RequestAccessResult resultCode, DeviceState initialDeviceState) {
if(resultCode == com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult.SUCCESS) {
deviceNumber = result.getAntDeviceNumber();
result.subscribeCalculatedPowerEvent(new ICalculatedPowerReceiver() {
@Override
public void onNewCalculatedPower(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final BigDecimal calculatedPower) {
alterCurrentData(RideService.WATTS, calculatedPower.floatValue());
}
}
);
result.subscribeCalculatedTorqueEvent(
new ICalculatedTorqueReceiver() {
@Override
public void onNewCalculatedTorque(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final BigDecimal calculatedTorque) {
alterCurrentData(RideService.NM, calculatedTorque.floatValue());
}
}
);
result.subscribeCalculatedCrankCadenceEvent(
new ICalculatedCrankCadenceReceiver() {
@Override
public void onNewCalculatedCrankCadence(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final BigDecimal calculatedCrankCadence) {
alterCurrentData(RideService.CAD, calculatedCrankCadence.floatValue());
}
}
);
result.subscribeCalculatedWheelSpeedEvent(
new CalculatedWheelSpeedReceiver(wheelCircumferenceInMeters) {
@Override
public void onNewCalculatedWheelSpeed(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final BigDecimal calculatedWheelSpeed)
{
alterCurrentData(RideService.KPH, calculatedWheelSpeed.floatValue());
}
}
);
result.subscribeCalculatedWheelDistanceEvent(
new CalculatedWheelDistanceReceiver(wheelCircumferenceInMeters) {
@Override
public void onNewCalculatedWheelDistance(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final BigDecimal calculatedWheelDistance)
{
alterCurrentData(RideService.KM, calculatedWheelDistance.floatValue());
}
}
);
result.subscribeInstantaneousCadenceEvent(
new IInstantaneousCadenceReceiver() {
@Override
public void onNewInstantaneousCadence(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final int instantaneousCadence)
{
alterCurrentData(RideService.CAD, (float) instantaneousCadence);
}
}
);
result.subscribeRawPowerOnlyDataEvent(
new IRawPowerOnlyDataReceiver() {
@Override
public void onNewRawPowerOnlyData(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long powerOnlyUpdateEventCount, final int instantaneousPower, final long accumulatedPower)
{
alterCurrentData(RideService.WATTS, (float) instantaneousPower);
}
}
);
/*result.subscribePedalPowerBalanceEvent(
new IPedalPowerBalanceReceiver() {
@Override
public void onNewPedalPowerBalance(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final boolean rightPedalIndicator, final int pedalPowerPercentage)
{
alterCurrentData(RideService.LTE, pedalPowerPercentage);
}
}
);
result.subscribeRawWheelTorqueDataEvent(
new IRawWheelTorqueDataReceiver() {
@Override
public void onNewRawWheelTorqueData(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long wheelTorqueUpdateEventCount, final long accumulatedWheelTicks, final BigDecimal accumulatedWheelPeriod, final BigDecimal accumulatedWheelTorque)
{
alterCurrentData(RideService.NM, accumulatedWheelTorque);
}
}
);
result.subscribeRawCrankTorqueDataEvent(
new IRawCrankTorqueDataReceiver() {
@Override
public void onNewRawCrankTorqueData(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long crankTorqueUpdateEventCount, final long accumulatedCrankTicks, final BigDecimal accumulatedCrankPeriod, final BigDecimal accumulatedCrankTorque)
{
alterCurrentData(RideService.NM, accumulatedCrankTorque);
}
}
);
result.subscribeTorqueEffectivenessEvent(
new ITorqueEffectivenessReceiver() {
@Override
public void onNewTorqueEffectiveness(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long powerOnlyUpdateEventCount, final BigDecimal leftTorqueEffectiveness, final BigDecimal rightTorqueEffectiveness)
{
int[] keys = {
RideService.LTE,
RideService.RTE
};
float[] values = {
leftTorqueEffectiveness,
rightTorqueEffectiveness
}
alterCurrentData(keys, values);
}
}
);
result.subscribePedalSmoothnessEvent(new IPedalSmoothnessReceiver() {
@Override
public void onNewPedalSmoothness(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long powerOnlyUpdateEventCount, final boolean separatePedalSmoothnessSupport, final BigDecimal leftOrCombinedPedalSmoothness, final BigDecimal rightPedalSmoothness)
{
int[] keys = {
RideService.SNPLC,
RideService.SNPR
};
float[] values = {
leftOrCombinedPedalSmoothness,
rightPedalSmoothness
}
alterCurrentData(map);
}
}
);*/
} else if(resultCode == com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult.SEARCH_TIMEOUT) {
if(deviceNumber != 0) {
requestAccess();
}
}
}
};
requestAccess();
}
protected void requestAccess() {
releaseHandle = AntPlusBikePowerPcc.requestAccess(context, deviceNumber, 0, mResultReceiver, mDeviceStateChangeReceiver);
}
@Override
public void zeroReadings()
{
int[] keys = {
RideService.WATTS,
RideService.NM,
RideService.CAD,
RideService.KPH,
RideService.KM
};
float[] values = {
(float) 0.0,
(float) 0.0,
(float) 0.0,
(float) 0.0,
(float) 0.0
};
alterCurrentData(keys, values);
}
}

View File

@@ -1,222 +0,0 @@
package com.ridelogger.listners;
import java.util.Timer;
import java.util.TimerTask;
import com.ridelogger.R;
import com.ridelogger.RideService;
import android.content.Context;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.preference.PreferenceManager;
/**
* Sensors
* @author Chet Henry
* Listen to android sensor events and log them
*/
public class Sensors extends Base<Object>
{
public static final double CRASHMAGNITUDE = 30.0;
private SensorEventListener luxListner;
private SensorEventListener accelListner;
private SensorEventListener pressListner;
private SensorEventListener tempListner;
private SensorEventListener fieldListner;
public Sensors(RideService mContext)
{
super(mContext);
SensorManager mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
Sensor mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
Sensor mAccel = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
Sensor mPress = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
Sensor mTemp = mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
Sensor mField = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
if(mLight != null) {
luxListner = new SensorEventListener() {
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
alterCurrentData(RideService.lux, event.values[0]);
}
};
mSensorManager.registerListener(luxListner, mLight, 3000000);
}
if(mAccel != null) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
if(settings.getBoolean(context.getString(R.string.PREF_DETECT_CRASH), false)) {
accelListner = new SensorEventListener() {
private boolean crashed = false;
private Timer timer = new Timer();
private double[] St = new double[3];
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
int[] keys = {
RideService.ms2x,
RideService.ms2y,
RideService.ms2z
};
alterCurrentData(keys, event.values);
if(St.length == 0) {
St[0] = event.values[0];
St[1] = event.values[1];
St[2] = event.values[2];
}
St[0] = 0.6 * event.values[0] + 0.4 * St[0];
St[1] = 0.6 * event.values[1] + 0.4 * St[1];
St[2] = 0.6 * event.values[2] + 0.4 * St[2];
double amag = Math.sqrt(St[0]*St[0] + St[1]*St[1] + St[2]*St[2]);
if(amag > CRASHMAGNITUDE && !crashed) {
crashed = true;
context.phoneCrash(amag);
if(!Float.isNaN(context.currentValues[RideService.KPH])) {
timer.schedule(
new TimerTask() {
@Override
public void run() {
//if we are traveling less then 1km/h at 5 seconds after crash detection
// confirm the crash
if(1.0 > context.currentValues[RideService.KPH]) {
context.phoneCrashConfirm();
} else {
crashed = false;
context.phoneHome();
}
}
},
5000
); //in five sec reset
} else {
timer.schedule(
new TimerTask() {
@Override
public void run() {
crashed = false;
}
},
180000
); //in three min reset
}
}
}
};
} else {
accelListner = new SensorEventListener() {
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
int[] keys = {
RideService.ms2x,
RideService.ms2y,
RideService.ms2z
};
alterCurrentData(keys, event.values);
}
};
}
mSensorManager.registerListener(accelListner, mAccel, SensorManager.SENSOR_DELAY_NORMAL);
}
if(mPress != null) {
pressListner = new SensorEventListener() {
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
alterCurrentData(RideService.press, event.values[0]);
}
};
mSensorManager.registerListener(pressListner, mPress, 3000000);
}
if(mTemp != null) {
tempListner = new SensorEventListener() {
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
alterCurrentData(RideService.temp, event.values[0]);
}
};
mSensorManager.registerListener(tempListner, mTemp, 3000000);
}
if(mField != null) {
fieldListner = new SensorEventListener() {
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
int[] keys = {
RideService.uTx,
RideService.uTy,
RideService.uTz
};
alterCurrentData(keys, event.values);
}
};
mSensorManager.registerListener(fieldListner, mField, SensorManager.SENSOR_DELAY_NORMAL);
}
}
@Override
public void onDestroy()
{
SensorManager mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
if(luxListner != null) {
mSensorManager.unregisterListener(luxListner);
}
if(accelListner != null) {
mSensorManager.unregisterListener(accelListner);
}
if(pressListner != null) {
mSensorManager.unregisterListener(pressListner);
}
if(tempListner != null) {
mSensorManager.unregisterListener(tempListner);
}
if(fieldListner != null) {
mSensorManager.unregisterListener(fieldListner);
}
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -1,48 +0,0 @@
<mockup version="1.0" skin="sketch" fontFace="Balsamiq Sans" measuredW="591" measuredH="228" mockupW="566" mockupH="205">
<controls>
<control controlID="0" controlTypeID="com.balsamiq.mockups::Canvas" x="25" y="23" w="566" h="205" measuredW="100" measuredH="70" zOrder="0" locked="false" isInGroup="-1"/>
<control controlID="1" controlTypeID="com.balsamiq.mockups::HRule" x="31" y="37" w="560" h="-1" measuredW="100" measuredH="10" zOrder="1" locked="false" isInGroup="-1"/>
<control controlID="2" controlTypeID="com.balsamiq.mockups::Label" x="34" y="23" w="-1" h="-1" measuredW="110" measuredH="21" zOrder="2" locked="false" isInGroup="-1">
<controlProperties>
<text>Compare%20Intervals</text>
</controlProperties>
</control>
<control controlID="3" controlTypeID="com.balsamiq.mockups::CheckBox" x="40" y="191" w="-1" h="-1" measuredW="110" measuredH="22" zOrder="3" locked="false" isInGroup="-1">
<controlProperties>
<text>Compare%20Delta</text>
</controlProperties>
</control>
<control controlID="4" controlTypeID="com.balsamiq.mockups::Canvas" x="34" y="52" w="414" h="133" measuredW="100" measuredH="70" zOrder="4" locked="false" isInGroup="-1">
<controlProperties>
<borderStyle>roundedDotted</borderStyle>
</controlProperties>
</control>
<control controlID="6" controlTypeID="com.balsamiq.mockups::List" x="456" y="47" w="128" h="174" measuredW="100" measuredH="174" zOrder="5" locked="false" isInGroup="-1">
<controlProperties>
<text>May%202x20s%0ABarhatch%20Climbs%0ASub%204%20ToSH%0AMarmottes%0AAdH%20Ascents%0ABox%20Hill%202009%0ABox%20Hill%202013%0ABox%20Hill%20All</text>
</controlProperties>
</control>
<control controlID="7" controlTypeID="com.balsamiq.mockups::TextInput" x="170" y="189" w="225" h="-1" measuredW="138" measuredH="27" zOrder="6" locked="false" isInGroup="-1">
<controlProperties>
<text>Compare%20Set%20Name...</text>
</controlProperties>
</control>
<control controlID="8" controlTypeID="com.balsamiq.mockups::Button" x="402" y="189" w="-1" h="-1" measuredW="45" measuredH="27" zOrder="7" locked="false" isInGroup="-1">
<controlProperties>
<text>Add</text>
</controlProperties>
</control>
<control controlID="10" controlTypeID="com.balsamiq.mockups::RoundButton" x="569" y="24" w="15" h="18" measuredW="32" measuredH="32" zOrder="8" locked="false" isInGroup="-1">
<controlProperties>
<icon>CircledXIcon%7Cxsmall</icon>
<text/>
</controlProperties>
</control>
<control controlID="11" controlTypeID="com.balsamiq.mockups::Label" x="48" y="62" w="387" h="-1" measuredW="180" measuredH="21" zOrder="9" locked="false" isInGroup="-1">
<controlProperties>
<color>10066329</color>
<text>Drag%20and%20drop%20intervals%20here%20...</text>
</controlProperties>
</control>
</controls>
</mockup>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

View File

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -1,7 +1,7 @@
This is GC3-FAQ.info, produced by makeinfo version 5.2 from
This is GC3-FAQ.info, produced by makeinfo version 4.13 from
GC3-FAQ.texinfo.
This manual is for Golden Cheetah, version 3.1.
This manual is for Golden Cheetah, version 3.0.
Copyright (C) 2013 Mark Liversedge
@@ -11,7 +11,7 @@ File: GC3-FAQ.info, Node: Top, Next: Top, Prev: Top
title
*****
This manual is for GoldenCheetah, version 3.1.
This manual is for GoldenCheetah, version 3.0.
* Menu:
@@ -33,30 +33,29 @@ File: GC3-FAQ.info, Node: MOST COMMON QUESTIONS OF ALL, Next: GENERAL, Prev:
1.1 How do I override / manually enter TSS for a ride?
======================================================
The details chart on the analysis view allows you to override metrics on
the metrics tab. By default the most common metrics are listed,
including average HR, distance and so on. From v3.1 the default setup
The details chart on the analysis view allows you to override metrics
on the metrics tab. By default the most common metrics are listed,
including average HR, distance and so on. From v3.0 the default setup
will also include TSS as a metric you can override here.
If the metric is not there you will need to configure GoldenCheetah to
allow it to be shown. This is simple to do and described in 3.9 below.
The 3.1 upgrade process should have added it to the Metric tab if it was
not already there.
1.2 How do I add or remove a chart?
===================================
To add a new chart to the view you can select from the hamburger menu on
the right hand side of the chart bar.
To add a new chart to the view you can select from the + menu on the
right hand side of the scope bar (the scope bar is underneath the
toolbar and lets you select from Home, Analysis, Train etc).
Depending upon which view you are on the charts available will differ.
For example realtime plots only appear on the Train view, whilst charts
that work with individual rides will only appear on the analysis view.
To remove a chart, when you mouse over a chart (in tabbed or tiled mode)
the word 'More...' will appear in the top left of the chart. This is a
menu drop down, if you click on it you will see a 'Close' option. This
is the option to remove (close) the chart.
To remove a chart, when you mouse over a chart (in tabbed or tiled
mode) a small triangle will appear in the top left of the chart. This
is a menu drop down, if you click on it you will see a `Close' option.
This is the option to remove (close) the chart.
1.3 Can I enter my weight and track/plot it?
============================================
@@ -64,16 +63,16 @@ is the option to remove (close) the chart.
Weight can be maintained in 3 ways;
* Every athlete is setup with a weight value - this is the fallback
value should no other weight measure be available. It can be found
under preferences and athlete.
value should no other weight measure be available. It can be
found under preferences and athlete.
* The 'Weight' field can be maintained in the details screen. This
is found on the 'Workout' tab in the details screen by default.
Any entry here will be used for this ride ONLY.
* The 'Weight' field can be maintained in the details screen. This
is found on the 'Workout' tab in the details screen by
default. Any entry here will be used for this ride ONLY.
* You can download weight from a withings scale. This is performed
manually via the menu option Tools->Get Withings Data. This is
then used to update the local measures database.
* You can download weight from a withings scale. This is performed
manually via the menu option Tools->Get Withings Data. This is
then used to update the local measures database.
When calculating W/KG the Activity value is used if present, if not we
then fall back to the last Withing measure that was collected, and if
@@ -86,25 +85,20 @@ plotted separately in the LTM plots.
1.4 How do I plot x sec power best?
===================================
In v3.1 it is now possible to plot custom durations for any data series
on a metric trends chart in the Trends view. You will need to add a
curve for the data series and select 'Best' instead of 'Metric' or
'Estimate' on the curve settings.
For v3.0 or earlier it is still not possible to plot custom durations
for power bests. We are looking to add this in version 3.1, but for now
you can only plot 1s, 5s, 10s, 15s, 20s, 30s, 1min, 2min, 5min, 10min,
20min, 30min and 60min bests.
As of v3.0 it is still not possible to plot custom durations for power
bests. We are looking to add this in version 3.1, but for now you can
only plot 1s, 5s, 10s, 15s, 20s, 30s, 1min, 2min, 5min, 10min, 20min,
30min and 60min bests.
1.5 I can't find Aerolab / Performance Manager?
===============================================
By default we do not add these charts to the layout. Aerolab can be
added to the Analysis view via the '+' menu found to the right hand side
of the GoldenCheetah scope bar.
By default we do not add these charts to the layout. Aerolab can be
added to the Analysis view via the '+' menu found to the right hand
side of the GoldenCheetah scope bar.
Similarly, the Performance manager can be added to the Home layout via
the '+' menu. We may deprecate this chart in the near future since the
the '+' menu. We may deprecate this chart in the near future since the
LTM charts can be used to plot a PMC and we expect to implement an
interactive PMC for planning in v3.1.
@@ -113,31 +107,31 @@ interactive PMC for planning in v3.1.
It has been deprecated since the Diary view allows you to summarise by
day, week and month and add charts to the view that summarise for the
selection. As the weekly summary was fixed on specific charts and did
not handle other selections (e.g. monthly) it has been deprecated in
selection. As the weekly summary was fixed on specific charts and did
not handle other selections (e.g. monthly) it has been deprecated in
view of the diary view.
At present you can treat the Diary view as you would have the weekly
summary - they offer the same functionality. We expect the diary view
summary - they offer the same functionality. We expect the diary view
to extend to planned workouts when we implement planning functionality
in v3.1.
1.7 Where are all the chart settings?
=====================================
All chart settings can be found under the drop down menu that appears in
the top left hand corner of a chart when you mouse over it, titled
'More...'. They will appear as a popup dialog box.
All chart settings can be found under the drop down menu that appears
in the top left hand corner of a chart when you mouse over it. They
will appear as a popup dialog box.
Additionally, when you move the cursor towards the title of a chart in a
view that is tabbed (not tiled) then a small selection of the most
Additionally, when you move the cursor towards the title of a chart in
a view that is tabbed (not tiled) then a small selection of the most
important settings for the chart will appear for convenience.
1.8 Where is the preferences / options panel?
=============================================
On a Mac the configurations page can be found under 'GoldenCheetah ->
Preferences' on the main menu. Whilst on all other platforms it is
Preferences' on the main menu. Whilst on all other platforms it is
found via 'Tools -> Options'.
We do this to match the general guidelines for the operating system.
@@ -148,35 +142,15 @@ We do this to match the general guidelines for the operating system.
Activities are coloured according to keywords embedded in their details
(metadata) you can configure the field that is used and the values that
are matched and the colours they are shown in from the preferences pane
via the 'Data Fields' toolbar option then select Notes Processing. The
via the 'Data Fields' toolbar option then select Notes Processing. The
keywords and related words are scanned for to determine if the
associated colour should be used for this ride.
They are processed in the order they are defined with the first match
being returned. Take care when using values such as 'TT' and 'race'
since these can also be part of an English word (e.g. ATTEMPT contains
being returned. Take care when using values such as 'TT' and 'race'
since these can also be part of an English word (e.g. ATTEMPT contains
'TT' and graceful contains 'race'.
1.10 GoldenCheetah doesn't find my PowerTap on Ubuntu Linux.
============================================================
If you're using the USB cradle (as opposed to the older, serial one),
the FTDI driver sometimes conflicts with the braille terminal in the
default Ubuntu installation. Try unplugging the PT cradle from the
computer and uninstalling brltty: sudo apt-get remove brltty Then plug
the device back in and it should work.
1.11 GoldenCheetah.dmg installation didn't seem to work.
========================================================
Are you running OS X Snow Leopard (10.6) or later? You need to be. If
you are, and you're still having this problem, open Terminal (in
Applications -> Utilities) and type this at the prompt:
/Applications/GoldenCheetah.app/Contents/MacOS/GoldenCheetah then press
<return> and send an email to the mailing list with whatever it prints
out. We'll help you debug it.

File: GC3-FAQ.info, Node: GENERAL, Next: METRICS, Prev: MOST COMMON QUESTIONS OF ALL, Up: Top
@@ -187,31 +161,31 @@ File: GC3-FAQ.info, Node: GENERAL, Next: METRICS, Prev: MOST COMMON QUESTIONS
==========================
GoldenCheetah is primarily a program for cyclists that own a power
meter. It allows them to record, track and review their performance
against recorded data. It also allows you to ride your turbo and
meter. It allows them to record, track and review their performance
against recorded data. It also allows you to ride your turbo and
collect data as you ride.
If you do not have a power meter then some of the functionality will not
be of use to you as a cyclist. But you can still record and track
progress. We support HR based TRIMP metrics for a HR based PMC for
If you do not have a power meter then some of the functionality will
not be of use to you as a cyclist. But you can still record and track
progress. We support HR based TRIMP metrics for a HR based PMC for
example.
2.2 What is a good book or resource on training with power?
===========================================================
Unquestionably the bible for working with a power meter is Training and
Racing with a Power Meter by Hunter Allan and Andy Coggan. Make sure
Racing with a Power Meter by Hunter Allan and Andy Coggan. Make sure
you look at the 2nd edition since it is revised quite dramatically.
Whilst it is heavily biased towards WKO+ as a software package most of
Whilst it is heavily biased towards WKO+ as a software package most of
the functions of note are also available in GoldenCheetah.
2.3 Where can I download the installer for GoldenCheetah ?
==========================================================
Stable releases are available from <http://www.goldencheetah.org> whilst
the latest and greatest code build is available from
<http://goldencheetah.stand2surf.net>. Development builds are for the
brave, since they may contain bugs. In reality the development builds
Stable releases are available from `http://www.goldencheetah.org'
whilst the latest and greatest code build is available from
`http://goldencheetah.stand2surf.net'. Development builds are for the
brave, since they may contain bugs. In reality the development builds
are a changing feast and often contain latest fixes too.
2.4 Where can I get the source code?
@@ -219,23 +193,23 @@ are a changing feast and often contain latest fixes too.
The GoldenCheetah source code is hosted on github and can be cloned
using the following url;
'git://github.com/GoldenCheetah/GoldenCheetah.git'
`git://github.com/GoldenCheetah/GoldenCheetah.git'
2.5 I am a triathlete is GoldenCheetah appropriate for me?
==========================================================
GoldenCheetah is not a multi-sport program. For tracking cycling
performance it is a good choice. But if you are looking for running and
GoldenCheetah is not a multi-sport program. For tracking cycling
performance it is a good choice. But if you are looking for running and
swimming metrics and tracking then these features are not available at
present. It is an excellent choice for analysing cycling aspects of
present. It is an excellent choice for analysing cycling aspects of
triathlon, or working on the trainer.
2.6 Is there a mailing list?
============================
The mailing list for GoldenCheetah users is maintained via Google Groups
at
<http://groups.google.com/forum/?fromgroups=#forum/golden-cheetah-users>
The mailing list for GoldenCheetah users is maintained via Google
Groups at
`http://groups.google.com/forum/?fromgroups=#forum/golden-cheetah-users'
the first post you make is moderated and may take a while to appear.
Once your first post is made you can make future posts without
moderation.
@@ -243,16 +217,16 @@ moderation.
2.7 How do I report a bug or request a new feature?
===================================================
We use Github issues to record bugs and feature requests. You will need
We use Github issues to record bugs and feature requests. You will need
to create an account on github and then post a new request or bug at
<http://www.github.com/GoldenCheetah/GoldenCheetah/issues>
`http://www.github.com/GoldenCheetah/GoldenCheetah/issues'
2.8 How can I contribute?
=========================
Patches are most welcome via the mailing list or a pull request in
github. Of equal importance is the timely reporting of bugs and help in
testing fixes. We also desperately need volunteers to translate into
github. Of equal importance is the timely reporting of bugs and help in
testing fixes. We also desperately need volunteers to translate into
non-English languages and help with writing documentation including the
maintenance of this FAQ.
@@ -262,8 +236,8 @@ list.
2.9 Can I donate to the project?
================================
We are an open source project. Our software is developed by a
community. We do not have any facility to collect funding or spend it!
We are an open source project. Our software is developed by a
community. We do not have any facility to collect funding or spend it!
We would rather you spread the word if you think our software is good,
and maybe help out with documentation, tutorials or translations if you
can.
@@ -277,70 +251,70 @@ File: GC3-FAQ.info, Node: METRICS, Next: DATA, Prev: GENERAL, Up: Top
3.1 What is the difference between xPower, NP and Daniels EqP?
==============================================================
They all serve the same purpose - to express the variable power you have
generated over a given period of time as a single value. This is so you
can quantify the intensity of the ride and therefore the training stress
of the ride.
They all serve the same purpose - to express the variable power you
have generated over a given period of time as a single value. This is
so you can quantify the intensity of the ride and therefore the
training stress of the ride.
In practice, NP and xPower are largely the same, whilst Daniels EqP
place much higher emphasise on upper intensity work. For more info on
place much higher emphasise on upper intensity work. For more info on
xPower see Dr Skiba's paper on BikeScore
<http://www.physfarm.com/bikescore.pdf>
`http://www.physfarm.com/bikescore.pdf'
3.2 What is the difference between CP and FTP?
==============================================
CP is a shorthand for CP60 in GoldenCheetah, and is computed using the
Scherer/Monod protocol using 3 and 20 minutes. Functional Threshold
Power (FTP) is an actual measure of the power an athlete sustains for 60
minutes.
Scherer/Monod protocol using 3 and 20 minutes. Functional Threshold
Power (FTP) is an actual measure of the power an athlete sustains for
60 minutes.
Since it is very difficult for an athlete to maintain the desired
intensity FTP 'reality' tends to result in a number that is much lower
than CP 'theory'. Often users will consider the two as the same.
than CP 'theory'. Often users will consider the two as the same.
In GC we compute TSS and BikeScore using your 'CP' value. If you set it
to your FTP value TSS will be accurate, BikeScore is likely to be lower.
And if you set it to your CP value BikeScore will be accurate, but TSS
will be overstated.
In GC we compute TSS and BikeScore using your 'CP' value. If you set it
to your FTP value TSS will be accurate, BikeScore is likely to be
lower. And if you set it to your CP value BikeScore will be accurate,
but TSS will be overstated.
3.3 Why does my CP chart show higher watts for a longer duration?
=================================================================
A higher power average for a longer time is possible if an effort has
been "book ended". If, for example, you did a massive 30 second effort,
followed by freewheeling for 29:30 then another massive 30 second
effort, then your best average for a continuous 30 minutes would in fact
be lower that your best average for a continuous 30minutes and 30
seconds. (Thanks for Jon Hill from the Golden Cheetah Users mailing
been "book ended". If, for example, you did a massive 30 second
effort, followed by freewheeling for 29:30 then another massive 30
second effort, then your best average for a continuous 30 minutes would
in fact be lower that your best average for a continuous 30minutes and
30 seconds. (Thanks for Jon Hill from the Golden Cheetah Users mailing
list for this example).
3.4 Can I set a different CP/FTP for different reasons e.g. CP/FTP on a trainer?
================================================================================
We allow you to override the CP value for a specific ride by setting the
"CP" field to the value you wish to use for the ride in question. We do
not have a concept of 'separate' Cps for different purposes - you will
need to specify the CP when the data is imported into GC. But this
We allow you to override the CP value for a specific ride by setting
the "CP" field to the value you wish to use for the ride in question.
We do not have a concept of 'separate' Cps for different purposes - you
will need to specify the CP when the data is imported into GC. But this
allows you to make manual adjustments.
We provide this functionality at user request - we do not endorse the
concept of multiple CP values. But we do recognise the ongoing debate
concept of multiple CP values. But we do recognise the ongoing debate
regarding physiological stress from working on a trainer vs on the road.
3.5 How do I seed the CTL for my PMC?
=====================================
You can seed the starting CTL (we call it LTS, for long term stress)
when you define a season. That way it is re-usable in a number of
places. To do this you edit the season (date range) in the Home View
when you define a season. That way it is re-usable in a number of
places. To do this you edit the season (date range) in the Home View
and can set the Starting LTS.
3.6 Why is elevation different in GoldenCheetah to my other training software / website?
========================================================================================
Different programs will use different hysteresis values to smooth the
small changes in altitude. In GC we use a hysteresis value of 3m.
small changes in altitude. In GC we use a hysteresis value of 3m.
If this is of great concern you can adjust the hysteresis value in
preferences under the general tab.
@@ -348,70 +322,70 @@ preferences under the general tab.
3.7 Why is a metric e.g. TSS or average power different in GoldenCheetah to Garmin Connect?
===========================================================================================
The algorithms for calculating TSS, AP etc are static. They are
The algorithms for calculating TSS, AP etc are static. They are
implemented exactly the same way in GoldenCheetah, Garmin Connect,
TrainingPeaks etc. The algorithms are extremely simple and not prone to
TrainingPeaks etc. The algorithms are extremely simple and not prone to
difficulty in implementation.
However, how each application treats pauses and stops or loss of data
accounts for most differences. In GoldenCheetah we always calculate
AP,TSS etc including stop time. Other applications choose to ignore or
accounts for most differences. In GoldenCheetah we always calculate
AP,TSS etc including stop time. Other applications choose to ignore or
smooth segments of short duration.
In addition, if there are anomalies in your data, with large gaps or
even time going backwards, this will drastically affect GoldenCheetah's
calculations.
We NEVER attempt to interpret data anomalies - if the results are not as
you would expect you will need to correct the data. We do not
'silently' fix the data for you. There is no secret sauce in
We NEVER attempt to interpret data anomalies - if the results are not
as you would expect you will need to correct the data. We do not
'silently' fix the data for you. There is no secret sauce in
GoldenCheetah, we are open and transparent with your data.
3.8 How do I set the metrics shown for intervals in the various summaries?
==========================================================================
In the GoldenCheetah preference pane under the Metrics tab you can
choose the metrics that will be shown in the ride summary charts and the
metrics that will be shown in the interval summary in the analysis
choose the metrics that will be shown in the ride summary charts and
the metrics that will be shown in the interval summary in the analysis
sidebar.
3.9 How do I add a metric to the details screen (so I can override it) ?
========================================================================
If the metric you want (e.g. TSS) is not shown then you will need to
add it via the GoldenCheetah preferences pane. On Mac this is from the
menu option GoldenCheetah->Preferences whilst on Windows and Linux it is
under Tools->Options.
If the metric you want (e.g. TSS) is not shown then you will need to
add it via the GoldenCheetah preferences pane. On Mac this is from the
menu option GoldenCheetah->Preferences whilst on Windows and Linux it
is under Tools->Options.
You will need to select 'Data Fields' option from preferences toolbar
and then the 'fields' tab. You will see a list of fields that are
associated with a particular screen tab. If you scroll down you should
and then the 'fields' tab. You will see a list of fields that are
associated with a particular screen tab. If you scroll down you should
find entries for the 'Metrics' screen tab, you can insert a new entry
here with the '+' button. You should make sure the new entry is called
here with the '+' button. You should make sure the new entry is called
exactly the same thing as the metric in question.
For 'TSS' this is relatively straight forward. For others, e.g.
For 'TSS' this is relatively straight forward. For others, e.g.
'Average Heart Rate' you must make sure that the name includes spaces
etc. Once your metric has been added to the configuration you should
etc. Once your metric has been added to the configuration you should
save that and return to the details screen where you can now maintain
it.
If you are creating a manual entry then there is no 'details' tab in the
dialog. Once you have created the entry (and again in this case TSS can
be entered in the dialog) you should go to the details tab to maintain
any other specific fields. The manual entry dialog is designed to be
simple and accept only the most common of entries.
If you are creating a manual entry then there is no 'details' tab in
the dialog. Once you have created the entry (and again in this case TSS
can be entered in the dialog) you should go to the details tab to
maintain any other specific fields. The manual entry dialog is designed
to be simple and accept only the most common of entries.
3.10 Can you calculate gradient, virtual power or other derived series from the ride data?
==========================================================================================
Not in 3.1. We plan to extend this functionality in v3.2.
Not in 3.0. We may introduce derived data series in the future.
3.11 Can I export metrics or access the metric database GC uses?
================================================================
The metrics are stored within a Sqlite 3 Database called 'metricDBv3'
that can be found in the athlete directory. You can use any Sqlite 3
that can be found in the athlete directory. You can use any Sqlite 3
tools to query and work with the db.
Alternatively you can export the db in its entirety using the
@@ -434,19 +408,19 @@ To join two rides together (making one longer ride from two rides) you
can copy rows in the activity editor and paste special in the ride
editor (right click) and then select append mode.
If you wish to merge rides, in v3.1 there is a new Activity->Merge
wizard that will walk you through merging ride files and also provide
the ability to synchronise timestamps.
If you wish to merge rides, that is much harder and would need to be
performed outside of GC or by cutting and pasting columns in the
activity editor.
4.2 How can I find 'spikes' or specific values in activity data?
================================================================
The activity editor has a function to find data on its toolbar. You can
The activity editor has a function to find data on its toolbar. You can
specify a range or upper or lower limit and find values less than,
greater than or between a range of values.
Additionally, the editor will scan the file looking for anomalies -
where the data appears to be out of normal ranges. These are shown with
where the data appears to be out of normal ranges. These are shown with
a wiggly red line in the editor and can also be listed by clicking on
the anomalies icon on the editor toolbar.
@@ -456,24 +430,24 @@ anomalies in the currently selected ride.
4.3 How can I fix 'spikes' or 'anomalies' in activity data?
===========================================================
You can either manually edit the values in the activity editor (there is
full undo and redo in the editor). Or you can use the fix tools that
You can either manually edit the values in the activity editor (there
is full undo and redo in the editor). Or you can use the fix tools that
are listed under the tool menu option (fix power spikes, fix gaps in
recording, fix gps errors, fix torque.
Each of the fix tools opens a dialog that displays texts to explain what
the fix tool does.
Each of the fix tools opens a dialog that displays texts to explain
what the fix tool does.
4.4 How can I add/remove a field to edit on the details screen?
===============================================================
The fields (metadata) that is editable can be configured in the
preferences pane under the data fields tab. Where no screen is
preferences pane under the data fields tab. Where no screen is
specified (its left blank) it will not be made available.
GoldenCheetah ships with a number of fields defined in the config but
with no screen set. If you wish to use them simply set the screen tab
to the tab you would like it to be shown on. To remove a field set the
to the tab you would like it to be shown on. To remove a field set the
field tab to blank.
4.5 What are 'special fields' ?
@@ -485,9 +459,10 @@ purposes.
Some examples include;
Weight - used in W/KG calculations, Sport and Workout code are used when
exporting to other file formats, Identifier is used to assign a UUID to
the activity when it is uploaded to online services and so on.
Weight - used in W/KG calculations, Sport and Workout code are used
when exporting to other file formats, Identifier is used to assign a
UUID to the activity when it is uploaded to online services and so
on.
There is a full list of special fields and their meaning in the Golden
Cheetah user guide appendices.
@@ -495,8 +470,8 @@ Cheetah user guide appendices.
4.6 How do I find/add/sort/delete/edit intervals ?
==================================================
The context menu (on the right hand side of the splitter handle) for the
interval sidebar in Analysis view contains a number of options for
The context menu (on the right hand side of the splitter handle) for
the interval sidebar in Analysis view contains a number of options for
working with intervals.
Additionally, you can click and drag on the performance (aka ride) plot
@@ -511,13 +486,13 @@ Activity->Export allows you to export the activity to csv, fitlog, gc
4.8 Can I use GC to convert data from one format to another on the command line?
================================================================================
No. It is something we may add in v3.2
No. It is something we may add in v3.1
4.9 Can I delete an athlete and all his/her data?
=================================================
No. It must be done manually by removing the athlete directory via the
operating system. Please ensure you do this when GoldenCheetah is not
No. It must be done manually by removing the athlete directory via the
operating system. Please ensure you do this when GoldenCheetah is not
running.

@@ -530,7 +505,7 @@ File: GC3-FAQ.info, Node: UPLOADING AND DOWNLOADING, Next: SEASONS AND EVENTS,
==================================================
The Sport field in TrainingPeaks must have very specific values,
although this is not documented in the XML Schema. We recommend using a
although this is not documented in the XML Schema. We recommend using a
sport of "Bike" if you plan on uploading rides to training peaks.
5.2 Why does download from TrainingPeaks say I need a premium account?
@@ -539,32 +514,43 @@ sport of "Bike" if you plan on uploading rides to training peaks.
Training Peaks only allow paid up members to get access to their data.
If you are using a free service they do not let you retrieve your data.
5.3 What settings do I need to get GoldenCheetah to upload to my Google Calendar?
5.3 Why is data uploaded to Strava all wrong?
=============================================
In general Strava will only use GPS data. If your ride does not contain
GPS data then Strava is not likely to play nice. In addition many of
the other data series will be ignored. This is related to Strava data
processing in V2.0 of their API.
We always upload as TCX since the JSON flavour of their API appears to
have less functionality.
5.4 What settings do I need to get GoldenCheetah to upload to my Google Calendar?
=================================================================================
The upload to Google Calendar uses their CalDAV API, and as such needs
to specify a collection. This means when entering the details in the
to specify a collection. This means when entering the details in the
passwords pane of preferences you should use the following for the
caldav url:
<https://www.google.com/calendar/dav/xxxx@gmail.com/events/>
`https://www.google.com/calendar/dav/xxxx@gmail.com/events/'
Where xxxx is your username. The username will need to be repeated in
Where xxxx is your username. The username will need to be repeated in
the username field and obviously set the password too.
5.4 When setting up my Withings wifi scales where do I get the userid and key ?
5.5 When setting up my Withings wifi scales where do I get the userid and key ?
===============================================================================
You will need to login to your Withings account
(<http://my.withings.com>) and click on the 'share' button at the top of
the dashboard. From there you will get a popup box with lots of
(`http://my.withings.com') and click on the `share' button at the top
of the dashboard. From there you will get a popup box with lots of
options.
If you click on 'share on my website' you will be greeted with a number
of code snippets you can embed in a web page. If you look closely in
the top right hand corner there will be a box containing the user id and
public key. These are the two values you need to enter into the options
dialog.
If you click on `share on my website' you will be greeted with a number
of code snippets you can embed in a web page. If you look closely in
the top right hand corner there will be a box containing the user id
and public key. These are the two values you need to enter into the
options dialog.
You will now be able to retrieve withings data via the tools menu.
@@ -577,31 +563,31 @@ File: GC3-FAQ.info, Node: SEASONS AND EVENTS, Next: CHARTS, Prev: UPLOADING A
6.1 Why are there different types of seasons?
=============================================
This is to help with planning functions. As of v3 there is no real
This is to help with planning functions. As of v3 there is no real
distinction made. Adhoc seasons are expected to be used solely as date
ranges and have no associated plan. Whilst other season types may
contain plans. This is only relevant for planning functions that are
contain plans. This is only relevant for planning functions that are
not available yet.
6.2 What is event used for?
===========================
It is only used to annotate a LTM chart - so you can show an 'event'
that happened at a particular date. There are no rules about what
constitutes and event. It could be a race, a training camp or just a
day that was particularly meaningful e.g. illness, crash.
that happened at a particular date. There are no rules about what
constitutes and event. It could be a race, a training camp or just a
day that was particularly meaningful e.g. illness, crash.
6.3 How do create/edit/delete seasons and events?
=================================================
Seasons and Events are created and edited in the sidebar for the Home
view. Seasons are listed under date ranges, whilst events are listed
under the events sidebar item. In both cases they can be created and
view. Seasons are listed under date ranges, whilst events are listed
under the events sidebar item. In both cases they can be created and
deleted from the sidebar item's drop down menu.
Please note that in v3.1 events can only be created when a user season
is selected, since events are associated with a particular season. This
constraint will be removed in v3.2.
Please note that in v3.0 events can only be created when a user season
is selected, since events are associated with a particular season. This
constraint will be removed in v3.1.

File: GC3-FAQ.info, Node: CHARTS, Next: INDEX, Prev: SEASONS AND EVENTS, Up: Top
@@ -619,70 +605,85 @@ similarly 'This' 'month' and prior '2' is a month 2 months ago, whilst
'This' 'month' prior and 0 is just this month.
7.2 How should I use Aerolab?
7.2 How does the mean max chart calculate CP when showing power?
================================================================
The CP algorithm searches your best power for two durations; for
anaerobic efforts it looks between 15s and 1min, for aerobic it looks
for best efforts between 10mins and an hour.
Once it has found these two best values it will curve fit the two to
enable the 60min value to be extracted. Bear in mind this is a
theoretical number and as described above is applicable to the
BikeScore algorithm. The value for FTP that the TSS algorithm requires
is simply the highest value for 60mins for the time period, assuming
you have performed a 60minute test recently.
7.3 How should I use Aerolab?
=============================
The following is a brief piece of advice from Robert Chung, from a
discussion on the Golden Cheetah Users mailing list:
Ideally, you'll want calm conditions (both in terms of wind and traffic)
but here's a quickie test you can do just to get a handle on what to do.
Try to find a loop without stop signs, or an out-and-back with maybe a
little dip or something in the middle. Make sure you won't get hit by a
car and have good sight lines. I just go around my block a few times.
Do a loop in the drops, then another loop faster, then a loop slower;
then repeat with your hands on the hoods.
Ideally, you'll want calm conditions (both in terms of wind and
traffic) but here's a quickie test you can do just to get a handle
on what to do. Try to find a loop without stop signs, or an
out-and-back with maybe a little dip or something in the middle. Make
sure you won't get hit by a car and have good sight lines. I just go
around my block a few times. Do a loop in the drops, then another
loop faster, then a loop slower; then repeat with your hands on the
hoods.
Weigh yourself and the bike and ballpark the air density.
See whether you can come close to modeling the "true" elevation profile
by sliding the CdA slider around. Even with this informal test, as long
as the wind isn't blowing too hard, you ought to be able to see a
difference between the loops where you were in the drops and the loops
where you on the hoods, and to spot little bumps and dips in the road.
by sliding the CdA slider around. Even with this informal test, as
long as the wind isn't blowing too hard, you ought to be able to
see a difference between the loops where you were in the drops and
the loops where you on the hoods, and to spot little bumps and dips in
the road.
There is also an overview of Virtual Elevation to measure aerodynamics
in this YouTube video from the power seminar at Interbike 2011 given by
Jim Meyer the founder of Quarq:
<http://www.youtube.com/watch?v=b8tJnFE_BFg&feature=youtu.be&t=27m58s>
`http://www.youtube.com/watch?v=b8tJnFE_BFg&feature=youtu.be&t=27m58s'
Finally, Robert Chung's original paper is included in the docs section
of the GoldenCheetah repository, you can it up here (click on 'View Raw'
to download):
of the GoldenCheetah repository, you can it up here (click on 'View
Raw' to download):
<https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/contrib/ChungVE.pdf>
`https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/contrib/ChungVE.pdf'
7.3 My map doesn't show?
7.4 My map doesn't show?
========================
This is most likely because you have a proxy that requires
authentication or session details. We do not have sophisticated support
for internet proxy servers. We will re-use the operating system
authentication or session details. We do not have sophisticated support
for internet proxy servers. We will re-use the operating system
settings where they are configured.
7.4 What is the treemap plot used for?
7.5 What is the treemap plot used for?
======================================
Typically it is used to visualise where you spend your time or where you
get best results. It is not particularly useful if you do not maintain
details for each ride e.g. workout code, sport et al.
Typically it is used to visualise where you spend your time or where
you get best results. It is not particularly useful if you do not
maintain details for each ride e.g. workout code, sport et al.
7.5 Can I change the colors in plot x ?
7.6 Can I change the colors in plot x ?
=======================================
With the exception of the Long Term Metric plots the colours on the
charts are configured in the GoldenCheetah preferences pane. It is
possible to apply a theme or change each individual color.
charts are configured in the GoldenCheetah preferences pane.
We want to use the same colours to plot each data series across the
charts, so you can change them globally.
The only colours you cannot change are the colours assigned to intervals
when plotting them on scatterplot or PfPv. These colours are assigned
according to their sequence.
The only colours you cannot change are the colours assigned to
intervals when plotting them on scatterplot or PfPv. These colours are
assigned according to their sequence.
7.6 How do you zoom in on a chart?
7.7 How do you zoom in on a chart?
==================================
You can zoom in on the distribution, scatterplot and PfPv charts by
@@ -693,17 +694,17 @@ bottom of the chart (if you select the full plot in the chart settings).
There are no other zoom options for the other charts.
7.7 I zoomed in but can't zoom out?
7.8 I zoomed in but can't zoom out?
===================================
Right click will zoom back out to the previous zoom level (in the case
of zooming multiple times). If you select another activity the chart
will return to fully zoomed out.
7.8 GoldenCheetah is saying there is no data for a chart, but I'm sure there is?
7.9 GoldenCheetah is saying there is no data for a chart, but I'm sure there is?
================================================================================
You should check in the editor if the data series is present. if the
You should check in the editor if the data series is present. if the
activity is a manual activity entry it will contain no data.

@@ -716,118 +717,106 @@ Index
* Menu:
* add: MOST COMMON QUESTIONS OF ALL.
(line 22)
(line 20)
* adhoc: SEASONS AND EVENTS. (line 9)
* Aerolab <1>: CHARTS. (line 33)
* Aerolab: MOST COMMON QUESTIONS OF ALL.
(line 75)
* Aerolab <1>: CHARTS. (line 19)
(line 69)
* algorithm: CHARTS. (line 19)
* anomalies: DATA. (line 23)
* anomalies <1>: DATA. (line 38)
* AP: METRICS. (line 80)
* best: MOST COMMON QUESTIONS OF ALL.
(line 62)
(line 61)
* bug: GENERAL. (line 66)
* cervo: MOST COMMON QUESTIONS OF ALL.
(line 136)
* Chung: CHARTS. (line 19)
* Chung: CHARTS. (line 33)
* clone: GENERAL. (line 40)
* colour <1>: CHARTS. (line 84)
* colour: MOST COMMON QUESTIONS OF ALL.
(line 121)
* colour <1>: CHARTS. (line 68)
(line 115)
* contribute: GENERAL. (line 73)
* CP <1>: CHARTS. (line 19)
* CP: METRICS. (line 22)
* CP <1>: METRICS. (line 39)
* CP <2>: METRICS. (line 50)
* CSV: DATA. (line 87)
* CSV: DATA. (line 88)
* CTL: METRICS. (line 63)
* cycle: SEASONS AND EVENTS. (line 9)
* Daniels: METRICS. (line 9)
* donate: GENERAL. (line 85)
* download: GENERAL. (line 31)
* download <1>: UPLOADING AND DOWNLOADING.
(line 16)
* download: GENERAL. (line 31)
* elevation: METRICS. (line 71)
* EqP: METRICS. (line 9)
* event: SEASONS AND EVENTS. (line 18)
* event <1>: SEASONS AND EVENTS. (line 26)
* feature: GENERAL. (line 66)
* FITLOG: DATA. (line 87)
* FITLOG: DATA. (line 88)
* FTP: METRICS. (line 22)
* FTP <1>: METRICS. (line 50)
* Garmin Connect: METRICS. (line 80)
* github: GENERAL. (line 40)
* Google: UPLOADING AND DOWNLOADING.
(line 22)
(line 33)
* install: GENERAL. (line 31)
* join: DATA. (line 9)
* JSON: DATA. (line 87)
* JSON: DATA. (line 88)
* LTS: METRICS. (line 63)
* mail: GENERAL. (line 56)
* map: CHARTS. (line 53)
* map: CHARTS. (line 69)
* merge: DATA. (line 9)
* month: CHARTS. (line 9)
* NP: METRICS. (line 9)
* options: MOST COMMON QUESTIONS OF ALL.
(line 112)
(line 106)
* override: METRICS. (line 110)
* PMC: MOST COMMON QUESTIONS OF ALL.
(line 75)
* PMC <1>: METRICS. (line 63)
* powertap: MOST COMMON QUESTIONS OF ALL.
(line 136)
* PMC: MOST COMMON QUESTIONS OF ALL.
(line 69)
* preferences: MOST COMMON QUESTIONS OF ALL.
(line 112)
(line 106)
* prior: CHARTS. (line 9)
* PWX: DATA. (line 87)
* PWX: DATA. (line 88)
* remove: MOST COMMON QUESTIONS OF ALL.
(line 22)
(line 20)
* report: GENERAL. (line 66)
* season: SEASONS AND EVENTS. (line 9)
* season <1>: SEASONS AND EVENTS. (line 26)
* settings: MOST COMMON QUESTIONS OF ALL.
(line 101)
(line 95)
* source: GENERAL. (line 40)
* spikes: DATA. (line 23)
* spikes <1>: DATA. (line 38)
* split: DATA. (line 9)
* TCX: DATA. (line 87)
* Strava: UPLOADING AND DOWNLOADING.
(line 22)
* TCX: DATA. (line 88)
* trainer: METRICS. (line 50)
* TrainingPeaks: UPLOADING AND DOWNLOADING.
(line 9)
* TrainingPeaks <1>: UPLOADING AND DOWNLOADING.
(line 16)
* treemap: CHARTS. (line 61)
* treemap: CHARTS. (line 77)
* triathlete: GENERAL. (line 47)
* TSS <1>: METRICS. (line 80)
* TSS: MOST COMMON QUESTIONS OF ALL.
(line 9)
* TSS <1>: METRICS. (line 80)
* unzoom: CHARTS. (line 93)
* unzoom: CHARTS. (line 108)
* upload: UPLOADING AND DOWNLOADING.
(line 9)
* usb: MOST COMMON QUESTIONS OF ALL.
(line 136)
* VE: CHARTS. (line 19)
* VE: CHARTS. (line 33)
* weekly summary: MOST COMMON QUESTIONS OF ALL.
(line 87)
(line 81)
* weight: MOST COMMON QUESTIONS OF ALL.
(line 37)
(line 36)
* Withings: UPLOADING AND DOWNLOADING.
(line 35)
(line 46)
* xPower: METRICS. (line 9)
* zoom: CHARTS. (line 82)
* zoom <1>: CHARTS. (line 93)
* zoom: CHARTS. (line 97)

Tag Table:
Node: Top163
Node: MOST COMMON QUESTIONS OF ALL608
Node: GENERAL7263
Node: METRICS10899
Node: DATA17912
Node: UPLOADING AND DOWNLOADING21867
Node: SEASONS AND EVENTS23922
Node: CHARTS25327
Node: INDEX29480
Node: Top164
Node: MOST COMMON QUESTIONS OF ALL609
Node: GENERAL6062
Node: METRICS9684
Node: DATA16676
Node: UPLOADING AND DOWNLOADING20606
Node: SEASONS AND EVENTS23090
Node: CHARTS24487
Node: INDEX29288

End Tag Table

Binary file not shown.

View File

@@ -9,7 +9,7 @@
@paragraphindent 0
@copying
This manual is for Golden Cheetah, version 3.1.
This manual is for Golden Cheetah, version 3.0.
Copyright @copyright{} 2013 Mark Liversedge
@end copying
@@ -35,7 +35,7 @@ Copyright @copyright{} 2013 Mark Liversedge
@node Top,Top,Top,
@top title
This manual is for GoldenCheetah, version 3.1.
This manual is for GoldenCheetah, version 3.0.
@end ifnottex
@menu
@@ -58,24 +58,24 @@ This manual is for GoldenCheetah, version 3.1.
The details chart on the analysis view allows you to override metrics on the metrics tab.
By default the most common metrics are listed, including average HR, distance and so on.
From v3.1 the default setup will also include TSS as a metric you can override here.
From v3.0 the default setup will also include TSS as a metric you can override here.
If the metric is not there you will need to configure GoldenCheetah to allow it to be shown.
This is simple to do and described in 3.9 below. The 3.1 upgrade process should have added it
to the Metric tab if it was not already there.
This is simple to do and described in 3.9 below.
@section How do I add or remove a chart?
@cindex add
@cindex remove
To add a new chart to the view you can select from the hamburger menu on the right hand side of
the chart bar.
To add a new chart to the view you can select from the + menu on the right hand side of
the scope bar (the scope bar is underneath the toolbar and lets you select from Home,
Analysis, Train etc).
Depending upon which view you are on the charts available will differ. For example realtime
plots only appear on the Train view, whilst charts that work with individual rides will only
appear on the analysis view.
To remove a chart, when you mouse over a chart (in tabbed or tiled mode) the word 'More...'
To remove a chart, when you mouse over a chart (in tabbed or tiled mode) a small triangle
will appear in the top left of the chart. This is a menu drop down, if you click on it
you will see a `Close' option. This is the option to remove (close) the chart.
@@ -110,11 +110,7 @@ the LTM plots.
@section How do I plot x sec power best?
@cindex best
In v3.1 it is now possible to plot custom durations for any data series on a metric
trends chart in the Trends view. You will need to add a curve for the data series
and select `Best' instead of `Metric' or `Estimate' on the curve settings.
For v3.0 or earlier it is still not possible to plot custom durations for power bests. We are
As of v3.0 it is still not possible to plot custom durations for power bests. We are
looking to add this in version 3.1, but for now you can only plot 1s, 5s, 10s, 15s, 20s,
30s, 1min, 2min, 5min, 10min, 20min, 30min and 60min bests.
@@ -151,7 +147,7 @@ implement planning functionality in v3.1.
@cindex settings
All chart settings can be found under the drop down menu that appears in the top left hand
corner of a chart when you mouse over it, titled `More...'. They will appear as a popup dialog box.
corner of a chart when you mouse over it. They will appear as a popup dialog box.
Additionally, when you move the cursor towards the title of a chart in a view that is tabbed
(not tiled) then a small selection of the most important settings for the chart will appear
@@ -179,23 +175,7 @@ They are processed in the order they are defined with the first match being retu
care when using values such as 'TT' and 'race' since these can also be part of an English
word (e.g. ATTEMPT contains 'TT' and graceful contains 'race'.
@section GoldenCheetah doesn't find my PowerTap on Ubuntu Linux.
@cindex powertap
@cindex cervo
@cindex usb
If you're using the USB cradle (as opposed to the older, serial one), the FTDI driver sometimes
conflicts with the braille terminal in the default Ubuntu installation. Try unplugging the PT cradle
from the computer and uninstalling brltty: sudo apt-get remove brltty
Then plug the device back in and it should work.
@section GoldenCheetah.dmg installation didn't seem to work.
Are you running OS X Snow Leopard (10.6) or later? You need to be. If you are, and you're still
having this problem, open Terminal (in Applications -> Utilities) and type this at the prompt:
/Applications/GoldenCheetah.app/Contents/MacOS/GoldenCheetah then press <return>
and send an email to the mailing list with whatever it prints out. We'll help you debug it.
@node GENERAL,METRICS,MOST COMMON QUESTIONS OF ALL,Top
@chapter GENERAL
@@ -437,7 +417,7 @@ dialog is designed to be simple and accept only the most common of entries.
@section Can you calculate gradient, virtual power or other derived series from the ride data?
Not in 3.1. We plan to extend this functionality in v3.2.
Not in 3.0. We may introduce derived data series in the future.
@@ -467,8 +447,8 @@ To join two rides together (making one longer ride from two rides) you can copy
in the activity editor and paste special in the ride editor (right click) and then select
append mode.
If you wish to merge rides, in v3.1 there is a new Activity->Merge wizard that will walk
you through merging ride files and also provide the ability to synchronise timestamps.
If you wish to merge rides, that is much harder and would need to be performed outside
of GC or by cutting and pasting columns in the activity editor.
@@ -552,7 +532,7 @@ Training Peaks PWX or Garmin TCX format.
@section Can I use GC to convert data from one format to another on the command line?
No. It is something we may add in v3.2
No. It is something we may add in v3.1
@@ -587,6 +567,18 @@ using a free service they do not let you retrieve your data.
@section Why is data uploaded to Strava all wrong?
@cindex Strava
In general Strava will only use GPS data. If your ride does not contain GPS data then
Strava is not likely to play nice. In addition many of the other data series will be
ignored. This is related to Strava data processing in V2.0 of their API.
We always upload as TCX since the JSON flavour of their API appears to have less
functionality.
@section What settings do I need to get GoldenCheetah to upload to my Google Calendar?
@cindex Google
@@ -647,8 +639,8 @@ Seasons and Events are created and edited in the sidebar for the Home view. Seas
listed under date ranges, whilst events are listed under the events sidebar item. In
both cases they can be created and deleted from the sidebar item's drop down menu.
Please note that in v3.1 events can only be created when a user season is selected, since
events are associated with a particular season. This constraint will be removed in v3.2.
Please note that in v3.0 events can only be created when a user season is selected, since
events are associated with a particular season. This constraint will be removed in v3.1.
@node CHARTS,INDEX,SEASONS AND EVENTS,Top
@chapter CHARTS
@@ -667,6 +659,22 @@ prior '2' is a month 2 months ago, whilst 'This' 'month' and prior '1' is last m
@section How does the mean max chart calculate CP when showing power?
@cindex CP
@cindex algorithm
The CP algorithm searches your best power for two durations; for anaerobic efforts it
looks between 15s and 1min, for aerobic it looks for best efforts between 10mins and
an hour.
Once it has found these two best values it will curve fit the two to enable the
60min value to be extracted. Bear in mind this is a theoretical number and as described
above is applicable to the BikeScore algorithm. The value for FTP that the TSS algorithm
requires is simply the highest value for 60mins for the time period, assuming you have
performed a 60minute test recently.
@section How should I use Aerolab?
@cindex Aerolab
@cindex Chung
@@ -724,8 +732,7 @@ e.g. workout code, sport et al.
@cindex colour
With the exception of the Long Term Metric plots the colours on the charts are
configured in the GoldenCheetah preferences pane. It is possible to apply a theme
or change each individual color.
configured in the GoldenCheetah preferences pane.
We want to use the same colours to plot each data series across the charts, so you
can change them globally.

View File

@@ -1,46 +0,0 @@
We are proud to announce that GoldenCheetah v3.1 was released today.
It can be downloaded from our new website[http://www.goldencheetah.org/index.html#section-download]
We have recorded a video[https://vimeo.com/99817526] to explain the main changes, and the user guide[https://github.com/GoldenCheetah/GoldenCheetah/wiki/Main-Page_Users-Guide] has been overhauled to cover all the main features along with an updated FAQ[https://github.com/GoldenCheetah/GoldenCheetah/wiki/FAQ].
We have also added a section on the science of GoldenCheetah[http://www.goldencheetah.org/index.html#section-science] to help users new to power training and analysis.
MAJOR NEW FEATURES
1. Compare Mode
* Across Summary, Ride, QA, CP, Histogram, Metric charts
* Compare Athletes, Seasons, Rides, Intervals
* Easy and intuitive user interface
2. Additional Power Duration Models
* Multiple PD models now available
* Track changes in model estimates for W', CP, P-Max, FTP over time
* Track changes in model estimates for any duration over time
2. Merge data from multiple rides into a single ride
3. Share Dialog to upload to multiple services in one click
OTHER SELECTED HIGHLIGHTS
* Open Athletes in Tabs
* Redesign Tabbed mode with a ChartBar
* Themes and better support for color customisation
* Improved Interactivity (axes, interval hover)
Device enhancements
* Fixed up Tacx Fortius Support
* Pedal Smoothness / Torque Effectiveness support
Metrics and new science
* Plot best x power
* Plot estimated W', CP, FTP et al
* W'bal implemented with metrics
Charts
* Improved UX for chart configuration and setup
* Export data for MMP curves, trends data
* Over 50 new charting options (heat, stack, labels etc etc)
Work on 3.11 starts today, focusing on indoor training.

View File

@@ -1,270 +0,0 @@
This is GC31-Release.info, produced by makeinfo version 5.2 from
GC31-Release.texinfo.

File: GC31-Release.info, Node: Top, Next: Top, Prev: Top
title
*****
These release notes are for GoldenCheetah, version 3.1.
* Menu:
* WHATS NEW:: What's new in V3.1
* CONTRIBUTORS:: List of Contributors to V3.1

File: GC31-Release.info, Node: WHATS NEW, Next: CONTRIBUTORS, Prev: CONTRIBUTORS, Up: Top
1 Whats New
***********
1.1 Major new features; Compare, Share and Merge
================================================
We have added a new feature to enable comparing rides and intervals
across all the charts where it is sensible to try; performance plot, cp
chart, histogram and QA charts all support compare. Additionally it is
possible to compare trends across different seasons as well as
histograms. And of course, these are also possible across athletes; so
you can compare one athletes season or ride with another athletes season
or ride.
Wherever it is sensible to compare things, we think it is now possible
to compare things.
We have also unified upload to "cloud" across Strava, RideWithGPS and
Cycling Analytics. With a single click you can upload to all services.
We do not currently support Garmin Connect as they have closed their
system and only work with commercial partners - for this reason we
recommend storing data outside for future data security.
Lastly, it is now possible to merge data from different sources into a
single ridefile. This is particularly useful when working with
multipled devices or integrating data from devices like the Moxy SM02
monitor.
1.2 General Enhancements
========================
We have made the following general / UI enhancements:
* Open Athletes in Tabs - it is possible to open up all your athletes
within a single window and switch tabs.
* ChartBar - the chartbar has become a toolbar item and is
scrollable. This dramatically increases the screen estate
available for displaying charts and data but also makes the UI less
'quirky' and align more to typical desktop application styles.
* Themes and better support for color customisation - we now have
much more sophisticated support for color customisation and support
across all the charts. Themes allow you to switch between light on
dark and dark on light setups quickly and easily.
* Improved Interactivity - mouse over interactivity has been extended
over the ride list and most charts for faster exploration of data
and to provide a more fluid and dynamic user experience. This
extendes to isolating curves within a chart by hovering over the
axis labels and automatically selecting intervals as you hover over
their data in the QA and ride charts.
* Autofilter in Trends view - as well as advance data filtering
within chart setup and the toolbar search box we have now added
autofilters in the trends sidebar to make it simple to filter data
based upon metadata e.g. all running files or rides on your TT
bike.
* Specify athlete library location - You can now specify where data
is stored to make it easier to integrate with backup or other
synchronisation tools.
* Improved Dropbox support (CRC) - We will check the data within a
ride has changed (as opposed to its timestamp) before refreshing
metrics. This is to remove unneccessary metric refreshes when
copying data between computers or synchronising using tools like
Dropbox.
* Find intervals via matches, hills etc - The find intervals dialog
will now find hills as well as sustained efforts using W'
consumption (see support for W'bal).
1.3 Enhanced Device Support
===========================
We have fixed or enhanced device support for:
* Fixed up Tacx Fortius Support - Dave Waterworth has updated the
original beta code for Fortius support to now make the Fortius and
fully supported device in train view.
* Joule GPS updates - the latest firmware is now supported and no
longer crashes GC (!).
* FIT ride file updates - better support for custom FIT sections that
are being used by vendors to suport localised data.
* Pedal Smoothness / Torque Effectiveness support - the Rotor and
Vector data series are now extracted and stored in ridefiles and
can be plotted alongside all the other ride data series on
performance, scatter and histogram plots.
* Moxy support - we have added support for the Moxy SM02 monitor and
can be imported and merged with ride data using the new merge
dialog.
1.4 New Metrics Implemented
===========================
We have implemented a lot of new science in 3.1 and along with that
there are a lot of associated metrics:
* Plot bests - It is now possible to plot user-defined durations for
power bests. For example it is now possible to plot 13s power
best, but we have extended this to cover all ride data series, so
you can plot best durations for heartrate, speed, cadence and so on
within a metric trends chart. This feature has been the most
requested feature since LTM was implemeted in 2010, so we've
finally got there.
* Plot Model Estimates - With the new PD models we also derive
estimates for W', CP et al using each of the models. These can
then be plotted; an example 'CP History' plot in the trends view is
provide as an example.
* W'bal implemented with metrics - The W'bal data series is derived
from power data and can be plotted alongside all other ride data.
It has also been implemented within the erg plot to assess ERG
workouts before attempting them.
* TISS implemented - An an Ae TISS have been implemented and can be
plotted as data series within a ride but also as inputs into a PMC
chart. An example 'Stress' chart is provided to plot these in the
Trends and Rides view.
* aPower - We have implemented Altitude Power to adjust recorded
power to take into account the effect of altitude on vo2max and
thus power output. This can be plotted alongside all other ride
data series.
* Polarised Zones - Histogram chart will now plot power histograms in
Polarised Zones as well as the more familar Coggan 7 levels.
* Pacing Index / Fatigue Index - Experimentally added to help review
interval efforts.
* W' work - To compliment W'bal and Work metrics we now isolate and
can track how much W' energy is being expended. This is closely
related to tracking Anaerobic training.
* Average Pedal Smoothness / Torque Efficiency - the Rotor/Vector
metrics can be plotted alongside ride data but also as average
metrics to track across weeks, months and seasons.
1.5 Chart Enhancements
======================
We have made significant changes across all the charts in 3.1. These
have been added to support the new models and science and also to try
and enhance the utility and user experience.
* LTM Chart - It is now possible to select charts via a Chart
selection sidebar thus reducing the number of charts needed to be
pre-configured on the chart bar. We have also tidied up the LTM
settings dialog and improved the UX for setting up charts in the
first place. To support the new compare mode we have also added a
Stack mode and a Data table mode to look at series in isolation or
just review the numbers. It is also now possible to export the
chart data to manipulate or analyse in other tools. Lastly, we
have also added Labels and Quadratic trend lines to create charts
that are more readable without resorting to tooltips and guess
work.
* CP Chart - The critical power chart has seen a lot of new features
added both to support the new PD models but also to provide the
possibility to plot and compare intervals. The key new features
include User selectable CP models and the ability to fine tune the
search intervals used by each of the 4 models. It is also now
possible to plot rates of change for power, heartrate etc and also
to plot heat and heat by age. You can also plot a ride as
percentge of best or as a centile. And as with the LTM charts it
is also possible to export the PD data and model to review and
assess in other tools.
* Ride Chart - It is now possible to plot lots of derived series; NP,
W'bal, xPower, Delta etc and also to plot each series in its own
chart with all series shown as a 'stack'. We have also finally
added the ability to create and edit reference lines for power and
have added an overlay to display interval data as you hover or
select them in the plot.
* Summary Chart - It is mostly unchanged but will now also support
displaying user defined metrics for Athlete Bests for the date
range selected. It will also show model estimates that apply to
the ride or for the date range being summarised.
1.6 Code refactoring and 300 issues fixed
=========================================
Since we release 3.0 in June 2013 we've been busily updating the code to
fix lots and lots of nits and errors, but also slowly adjusting the code
to provide a better platform for new features.
We have deferred almost all features related to indoor training to a
release 3.11 that is planned for the beginning of 2015 with development
starting in August 2014.
However, some of the (boring, tehcnical) foundational things that
changed in 3.1 include:
* QT 5.3 is now supported; so QT video support, QML, Qt Json, faster
webkit and for the future, possible support for IOS and Android
devices.
* QWT 6.1 with multiaxis is now supported; lots of bug fixes and
better rendering on retina and high resolution displays.
* CP chart and AllPlot chart refactored to make it possible to extend
functionality e.g. for new PD models and derived data series.
Some of the functionality that has been fixed include reinstated support
for Strava and Twitter. We also have better native support for
look-and-feel differences across the three platforms we currently
support (Mac, Linux, Windows).
We have also adjusted the startup mechanism to make it possible to
select a different athlete or create a new one if recovering from a
fatal crash.

File: GC31-Release.info, Node: CONTRIBUTORS, Next: WHATS NEW, Prev: WHATS NEW, Up: Top
2 Contributors
**************
2.1 Credits and Contributors
============================
The main contributors continue to be Mark, Damien and Gareth, but a few
new contributors have joined the team in the last year and the future
looks promising. A particular shout out is deserved for Joern
Rischmuller who has updated the GC Wiki to cover all functionality - so
for the first time we have comprehensive user documentation.
The following have all made a contribution to 3.1:
Alejandro Martinez, Bruno Fernandez-Ruiz, Christian Stade-Schuldt,
Damien Grauser, Dave Waterworth, Eric Johnson, Gareth Coco, Ilja Booij,
Jaime Jofre, Joern Rischmuller, Jon Beverley, Jon Escombe, KURASHIKI
Satoru, Mark Liversedge, Rainer Clasen, Ralf Spenneberg, Simon Egli,
Stig B. Dørmænen, Tom Weichmann, Walter Bürki and Alex Delli.

Tag Table:
Node: Top88
Node: WHATS NEW312
Node: CONTRIBUTORS10389

End Tag Table

Binary file not shown.

View File

@@ -1,245 +0,0 @@
\input texinfo @c -*-texinfo-*-
@ifnotinfo
@input palatino
@end ifnotinfo
@c %**start of header
@setfilename Release Notes.texinfo
@settitle Golden Cheetah v3.1 Release Notes
@c %**end of header
@paragraphindent 0
@titlepage
@title Golden Cheetah v3.1 Release Notes
@c @subtitle subtitle-if-any
@c @subtitle second-subtitle
@author Mark Liversedge
@end titlepage
@c So the toc is printed at the start.
@contents
@ifnottex
@node Top,Top,Top,
@top title
These release notes are for GoldenCheetah, version 3.1.
@end ifnottex
@menu
* WHATS NEW:: What's new in V3.1
* CONTRIBUTORS:: List of Contributors to V3.1
@end menu
@node WHATS NEW,CONTRIBUTORS,CONTRIBUTORS,Top
@chapter Whats New
@section Major new features; Compare, Share and Merge
We have added a new feature to enable comparing rides and intervals across all
the charts where it is sensible to try; performance plot, cp chart, histogram
and QA charts all support compare. Additionally it is possible to compare
trends across different seasons as well as histograms. And of course, these are
also possible across athletes; so you can compare one athletes season or ride
with another athletes season or ride.
Wherever it is sensible to compare things, we think it is now possible to compare things.
We have also unified upload to "cloud" across Strava, RideWithGPS and Cycling
Analytics. With a single click you can upload to all services. We do not currently
support Garmin Connect as they have closed their system and only work with commercial
partners - for this reason we recommend storing data outside for future data security.
Lastly, it is now possible to merge data from different sources into a single ridefile.
This is particularly useful when working with multipled devices or integrating data
from devices like the Moxy SM02 monitor.
@section General Enhancements
We have made the following general / UI enhancements:
@itemize @bullet
@item Open Athletes in Tabs - it is possible to open up all your athletes within a
single window and switch tabs.
@item ChartBar - the chartbar has become a toolbar item and is scrollable. This
dramatically increases the screen estate available for displaying charts and data
but also makes the UI less `quirky' and align more to typical desktop application
styles.
@item Themes and better support for color customisation - we now have much more sophisticated
support for color customisation and support across all the charts. Themes allow you
to switch between light on dark and dark on light setups quickly and easily.
@item Improved Interactivity - mouse over interactivity has been extended over the ride
list and most charts for faster exploration of data and to provide a more fluid and
dynamic user experience. This extendes to isolating curves within a chart by hovering
over the axis labels and automatically selecting intervals as you hover over their data
in the QA and ride charts.
@item Autofilter in Trends view - as well as advance data filtering within chart setup and
the toolbar search box we have now added autofilters in the trends sidebar to make it
simple to filter data based upon metadata e.g. all running files or rides on your TT bike.
@item Specify athlete library location - You can now specify where data is stored to make
it easier to integrate with backup or other synchronisation tools.
@item Improved Dropbox support (CRC) - We will check the data within a ride has changed
(as opposed to its timestamp) before refreshing metrics. This is to remove unneccessary
metric refreshes when copying data between computers or synchronising using tools like
Dropbox.
@item Find intervals via matches, hills etc - The find intervals dialog will now find
hills as well as sustained efforts using W' consumption (see support for W'bal).
@end itemize
@section Enhanced Device Support
We have fixed or enhanced device support for:
@itemize @bullet
@item Fixed up Tacx Fortius Support - Dave Waterworth has updated the original beta code
for Fortius support to now make the Fortius and fully supported device in train view.
@item Joule GPS updates - the latest firmware is now supported and no longer crashes GC (!).
@item FIT ride file updates - better support for custom FIT sections that are being used
by vendors to suport localised data.
@item Pedal Smoothness / Torque Effectiveness support - the Rotor and Vector data series
are now extracted and stored in ridefiles and can be plotted alongside all the other ride
data series on performance, scatter and histogram plots.
@item Moxy support - we have added support for the Moxy SM02 monitor and can be imported
and merged with ride data using the new merge dialog.
@end itemize
@section New Metrics Implemented
We have implemented a lot of new science in 3.1 and along with that
there are a lot of associated metrics:
@itemize @bullet
@item Plot bests - It is now possible to plot user-defined durations for power bests.
For example it is now possible to plot 13s power best, but we have extended this to
cover all ride data series, so you can plot best durations for heartrate, speed, cadence
and so on within a metric trends chart. This feature has been the most requested feature
since LTM was implemeted in 2010, so we've finally got there.
@item Plot Model Estimates - With the new PD models we also derive estimates for W', CP et al using
each of the models. These can then be plotted; an example `CP History' plot in the trends view
is provide as an example.
@item W'bal implemented with metrics - The W'bal data series is derived from power data and
can be plotted alongside all other ride data. It has also been implemented within the erg
plot to assess ERG workouts before attempting them.
@item TISS implemented - An an Ae TISS have been implemented and can be plotted as data series
within a ride but also as inputs into a PMC chart. An example `Stress' chart is provided to
plot these in the Trends and Rides view.
@item aPower - We have implemented Altitude Power to adjust recorded power to take into
account the effect of altitude on vo2max and thus power output. This can be plotted alongside
all other ride data series.
@item Polarised Zones - Histogram chart will now plot power histograms in Polarised Zones as well
as the more familar Coggan 7 levels.
@item Pacing Index / Fatigue Index - Experimentally added to help review interval efforts.
@item W' work - To compliment W'bal and Work metrics we now isolate and can track how much
W' energy is being expended. This is closely related to tracking Anaerobic training.
@item Average Pedal Smoothness / Torque Efficiency - the Rotor/Vector metrics can be plotted
alongside ride data but also as average metrics to track across weeks, months and seasons.
@end itemize
@section Chart Enhancements
We have made significant changes across all the charts in 3.1. These have been added
to support the new models and science and also to try and enhance the utility and
user experience.
@itemize @bullet
@item LTM Chart - It is now possible to select charts via a Chart selection sidebar thus
reducing the number of charts needed to be pre-configured on the chart bar. We have also
tidied up the LTM settings dialog and improved the UX for setting up charts in the first place.
To support the new compare mode we have also added a Stack mode and a Data table mode to
look at series in isolation or just review the numbers. It is also now possible to export
the chart data to manipulate or analyse in other tools. Lastly, we have also added Labels
and Quadratic trend lines to create charts that are more readable without resorting to
tooltips and guess work.
@item CP Chart - The critical power chart has seen a lot of new features added both to
support the new PD models but also to provide the possibility to plot and compare intervals.
The key new features include User selectable CP models and the ability to fine tune the
search intervals used by each of the 4 models. It is also now possible to plot rates of change
for power, heartrate etc and also to plot heat and heat by age. You can also plot a ride as
percentge of best or as a centile. And as with the LTM charts it is also possible to export
the PD data and model to review and assess in other tools.
@item Ride Chart - It is now possible to plot lots of derived series; NP, W'bal, xPower, Delta etc
and also to plot each series in its own chart with all series shown as a 'stack'. We have also
finally added the ability to create and edit reference lines for power and have added an overlay
to display interval data as you hover or select them in the plot.
@item Summary Chart - It is mostly unchanged but will now also support displaying user
defined metrics for Athlete Bests for the date range selected. It will also show model
estimates that apply to the ride or for the date range being summarised.
@end itemize
@section Code refactoring and 300 issues fixed
Since we release 3.0 in June 2013 we've been busily updating the
code to fix lots and lots of nits and errors, but also slowly adjusting
the code to provide a better platform for new features.
We have deferred almost all features related to indoor training to a
release 3.11 that is planned for the beginning of 2015 with development
starting in August 2014.
However, some of the (boring, tehcnical) foundational things that changed in 3.1 include:
@itemize @bullet
@item QT 5.3 is now supported; so QT video support, QML, Qt Json, faster
webkit and for the future, possible support for IOS and Android devices.
@item QWT 6.1 with multiaxis is now supported; lots of bug fixes and better
rendering on retina and high resolution displays.
@item CP chart and AllPlot chart refactored to make it possible to extend
functionality e.g. for new PD models and derived data series.
@end itemize
Some of the functionality that has been fixed include reinstated support
for Strava and Twitter. We also have better native support for look-and-feel
differences across the three platforms we currently support (Mac, Linux, Windows).
We have also adjusted the startup mechanism to make it possible to select a
different athlete or create a new one if recovering from a fatal crash.
@node CONTRIBUTORS,WHATS NEW,WHATS NEW,Top
@chapter Contributors
@section Credits and Contributors
The main contributors continue to be Mark, Damien and Gareth, but a few new contributors
have joined the team in the last year and the future looks promising. A particular shout
out is deserved for Joern Rischmuller who has updated the GC Wiki to cover all functionality --
so for the first time we have comprehensive user documentation.
The following have all made a contribution to 3.1:
Alejandro Martinez, Bruno Fernandez-Ruiz, Christian Stade-Schuldt, Damien Grauser, Dave Waterworth, Eric Johnson,
Gareth Coco, Ilja Booij, Jaime Jofre, Joern Rischmuller, Jon Beverley, Jon Escombe, KURASHIKI Satoru, Mark Liversedge,
Rainer Clasen, Ralf Spenneberg, Simon Egli, Stig B. Dørmænen, Tom Weichmann, Walter Bürki and Alex Delli.
@bye

View File

@@ -1,89 +0,0 @@
Some notes on what is new in GC 3.1
-----------------------------------
MAJOR NEW FEATURES
1. Compare Mode
* Across Summary, Ride, QA, CP, Histogram, Metric charts
* Compare Athletes, Seasons, Rides, Intervals
* Easy and intuitive user interface
2. Additional Power Duration Models
* Multiple PD models now available
* Track changes in model estimates for W', CP, P-Max, FTP over time
* Track changes in model estimates for any duration over time
2. Merge Activities
3. Share Dialog
ENHANCEMENTS
1. General
i Open Athletes in Tabs
ii Redesign Tabbed mode with a ChartBar
iii Themes and better support for color customisation
iv Improved Interactivity (axes, interval hover)
v Autofilter in Trends view
vi Specify athlete library location
vii Improved Dropbox support (CRC)
viii Find intervals via matches, hills etc
ix Fix Elevation
2. Device
i Fixed up Tacx Fortius Support
ii Joule GPS updates
iii FIT ride file updates
iv Pedal Smoothness / Torque Effectiveness support
v Moxy support
3. Metrics
i Plot best x power etc, Plot W', CP et al
ii W'bal implemented with metrics
iii TISS implemented
iv aPower
v Polarised Zones
vi Pacing Index / Fatigue Index
vii W' work
viii Average Pedal Smoothness / Torque Efficiency
4. LTM Chart
i Chart selection sidebar
ii LTM settings cleaned up
iii Stack mode
iv Data table mode
v Labels
vi Quadratic trend lines
5. CP Chart
i User selectable CP models
ii Extended CP Model
iii Plot rates of change
iv Plot heat and heat by age
v Plot as percentge of best
vi Plot centiles
v Ranking
vi Plot intervals
vii Export Data
6. Ride Chart
i Plot lots of derived series; NP, W'bal, xPower, Delta etc etc
ii Plot delta series
iii Plot stack series
iv Isolate series hover on axis
v Create/Edit reference lines
7. Summary Chart
i Athlete Bests
ii Model derived estimates (CP, FTP etc)
8. Foundational
i QT 5 support
ii QWT 6.1 support
iii MainWindow/Context/Athlete refactored
iv CP refactored (for models and intervals)
v AllPlot refactored (for compare)
BUG FIXES
i Over 1000 commits since 3.0 including many bug fixes
ii Eradicating assert reduces crashes
iii Crash dialog/restart to menu

View File

@@ -12,7 +12,7 @@ clean:
MANUAL: GC3-Manual.pdf
FAQ: GC3-FAQ.pdf GC3-FAQ.info
RELEASE: GC3-Release.pdf GC3-Release.info GC31-Release.pdf GC31-Release.info
RELEASE: GC3-Release.pdf GC3-Release.info
## The basic commands, good on Linux/Mac
## need mingw on Windows

View File

@@ -8,10 +8,9 @@ OTHER= 3d.png choose-a-cyclist.png cpint.gp cpint.png critical-power-plot.png cr
pm.png power.zones realtime.png ride-plot.png ride-plot2.png ride-summary.png sample.gp \
sample.png weekly-summary.png google-earth.png aerolab.png
BIN= GoldenCheetah_3.0.1_Mac_Universal.dmg \
GoldenCheetah-3.0.1-1.fc18.x86_64.rpm \
GoldenCheetah-3.0.1-1.fc19.x86_64.rpm \
GoldenCheetah_3.0.1_Windows_Installer.exe
BIN= GoldenCheetah_3.0.0_Mac_32bit.dmg \
GoldenCheetah_3.0.0_Mac_64bit.dmg \
GoldenCheetah_3.0.0_Windows_Installer.exe
all: $(HTML)
.PHONY: all clean install
@@ -54,12 +53,6 @@ release-notes.html: release-notes.content genpage.pl
release-notes_2.1.0.html: release-notes_2.1.0.content genpage.pl
./genpage.pl "Release Notes 2.1.0" $< > $@
release-notes_3.0.0.html: release-notes_3.0.0.content genpage.pl
./genpage.pl "Release Notes 3.0.0" $< > $@
release-notes_3.0.1.html: release-notes_3.0.1.content genpage.pl
./genpage.pl "Release Notes 3.0.1" $< > $@
faq.html: faq.content genpage.pl
./genpage.pl "Frequently Asked Questions" $< > $@

View File

@@ -11,8 +11,7 @@ Installing dependencies
</font></big>
<p>GC requires a number of libraries. On Mac OS X, you can get most of these
through <a href="http://www.macports.org/">Mac Ports</a> or
<a href="http://www.brew.sh/">Homebrew</a>. On Linux and other
through <a href="http://www.macports.org/">Mac Ports</a>. On Linux and other
Unixes, you can use whatever package manager your distribution provides. (We
list the package names for MacPorts and Ubuntu below.) On Windows, you'll
probably need to download and install everything by hand. You might also want

View File

@@ -2,13 +2,13 @@
<p>
Golden Cheetah is available in binary form for
Fedora (RPMs), Mac OS X (Universal Intel binary), and Windows.
Linux x86, Mac OS X (universal binary), and Windows.
It is also available as source code.
</p>
<p>
Golden Cheetah downloads data from all versions of the PowerTap
computer including the new Joule GPS. Previously you needed to have the
computer including the new Joule. Previously you needed to have the
FTDI USB Drivers installed if you were using the PowerTap USB cradle
(as opposed to the older, serial cable). This should not be necessary.
If you are having problems then you can manually install the
@@ -16,7 +16,7 @@ If you are having problems then you can manually install the
</p>
<p>
On Windows, Linux and Mac OS X, Golden Cheetah also downloads from the SRM PCV. On Mac
On Linux and Mac OS X, Golden Cheetah also downloads from the SRM PCV. On Mac
OS X, you'll need to install <a href="http://osx-pl2303.sourceforge.net/">the
open source PL2303 driver</a> to download from an SRM. Please see the
<a href="https://github.com/GoldenCheetah/GoldenCheetah/wiki/Installing-the-d2xx-drivers-on-mac-os">WIKI</a> article
@@ -26,28 +26,21 @@ PCV on Mac OS X</a> for further information.
<p>
<font face="arial,helvetica,sanserif">
<big><strong>Download Release 3.0.2</strong></big>
<big><strong>Download Release 3.0</strong></big>
</font>
</p>
<p>This is a bug fix release with a few new features.</p>
<ul>
<li><a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP2/GoldenCheetah_3.0.2_Windows_Installer.exe">Windows 32-bit (runs on 64bit as well)</a>
<li><a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP2/GoldenCheetah_3.0.2_Mac_Universal.dmg">Mac OS X Intel Universal (10.6+)</a><br>
<li>Fedora 18 RPMS - <a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP2/GoldenCheetah-3.0.2-1.fc18.i686.rpm">32bit</a>
/ <a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP2/GoldenCheetah-3.0.2-1.fc18.x86_64.rpm">64 bit</a><br>
<li>Fedora 19 RPMS - <a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP2/GoldenCheetah-3.0.2-1.fc19.i686.rpm">32bit</a>
/ <a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP2/GoldenCheetah-3.0.2-1.fc19.x86_64.rpm">64 bit</a><br>
<li>Fedora 20 RPMS - <a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP2/GoldenCheetah-3.0.2-1.fc20.i686.rpm">32bit</a>
/ <a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP2/GoldenCheetah-3.0.2-1.fc20.x86_64.rpm">64 bit</a><br>
<li><a href="GoldenCheetah_3.0.0_Windows_Installer.exe">Windows 32-bit (runs on 64bit as well)</a>
<li><a href="GoldenCheetah_3.0.0_Mac_32bit.dmg">Mac OS X Intel 32bit (10.6+)</a><br>
<li><a href="GoldenCheetah_3.0.0_Mac_64bit.dmg">Mac OS X Intel 64bit (10.6+)</a><br>
</ul>
</p>
<p>
Installation is simple. Download the file for your operating system.<br>
Installation is simple. Download the file for your operationg system.<br>
On Mac, open the DMG and drag and drop where you would like to install.<br>
For Windows, run the Installer and follow the prompts.<br>
For Fedora, install as root (yum install filename.rpm) or using sudo (sudo yum install filename.rpm).<br>
</p>
<p>
There is a <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-Manual.pdf?raw=true">Manual</a>
@@ -59,7 +52,7 @@ There is the older Version 2.1.0 <a href="/users-guide.html">User's Guide</a> o
and use Golden Cheetah that can assist also.
</p>
<p>
You can also <a href="release-notes.html">view the release notes</a> for 3.0.2
You can also <a href="release-notes.html">view the release notes</a> for 3.0
or <a href="older-releases.html">download older releases</a> of Golden Cheetah.
</p>

View File

@@ -1,12 +1,5 @@
<!-- $Id: faq.content,v 1.4 2006/07/05 16:59:56 srhea Exp $ -->
<h2>Documentation</h2>
<p>
There is a <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-Manual.pdf?raw=true">Manual</a>
and a <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-FAQ.pdf?raw=true">FAQ</a> that
you can use to help you use the program.
</p>
<p>
<b><i>GoldenCheetah doesn't find my PowerTap on Ubuntu Linux.</i></b>
<p>

View File

@@ -13,7 +13,8 @@ GoldenCheetah is a software package that:
<ul>
<li>Downloads ride data directly from the CycleOps PowerTap and the SRM
PowerControl V, VI and VII.</p>
PowerControl V. Support for SRM PowerControl VI and VII is planned for the
future.<p>
<li>Imports ride data downloaded with other programs, including TrainingPeaks
WKO+ and the manufacturers' software for the Ergomo, Garmin, Polar, PowerTap,

View File

@@ -18,69 +18,13 @@ please see <a href="download.html">the download page</a> instead.
<td><i>Description</i></td>
</tr>
<tr>
<td valign="top">3.0.1</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP1/GoldenCheetah_3.0.1_Mac_Universal.dmg">Mac OS X Intel Universal (10.6+)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP1/GoldenCheetah_3.0.1_Windows_Installer.exe">Windows 32-bit</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP1/GoldenCheetah-3.0.1-2.fc18.x86_64.rpm">Fedora 18 RPM (64bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP1/GoldenCheetah-3.0.1-2.fc19.x86_64.rpm">Fedora 19 RPM (64bit)</a>
</td>
<td valign="top">
<a href="release-notes_3.0.1.html">Full Version 3.0.1 change log.</a><br>
</td>
</tr>
<tr>
<td valign="top">3.0.0</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0/GoldenCheetah_3.0.0_Mac_32bit.dmg">Mac OS X Intel (32bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0/GoldenCheetah_3.0.0_Mac_64bit.dmg">Mac OS X Intel (64bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0/GoldenCheetah_3.0.0_Windows_Installer.exe">Windows 32-bit</a>
</td>
<td valign="top">
<p>
New Features and Enhancements
<ul>
<li>See the full log below.</li>
<li>See the <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-Release.pdf?raw=true">Release Notes</a> PDF on GitHub.</li>
<li>A PDF <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-Manual.pdf?raw=true">User's Manual</a></li>
<li>A PDF <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-FAQ.pdf?raw=true">Frequently Asked Questions (FAQ)</a></li>
<li>Welcome Screens to help setup the program.</li>
</ul>
</p>
<p>
Internationalisation
<ul>
<li>German (Tilman Schmiedeberg)</li>
<li>Italian (Marco Piccirilli)</li>
<li>Japanese (Okano Takayoshi)</li>
<li>Spanish (Alejandro Martinez)</li>
</ul>
</p>
<p>
Development Builds
<ul>
<li>Gareth Coco</li>
<li>Jamie Kimberley</li>
</ul>
</p>
<p>
<a href="release-notes_3.0.0.html">Full Version 3.0.0 change log.</a><br>
</p>
</td>
</tr>
<tr>
<td valign="top">2.1.0</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.1/GoldenCheetah_2.1.0_Linux_x86.tgz">Linux (32bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.1/GoldenCheetah_2.1.0_Linux_x86_64.tgz">Linux (64bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.1/GoldenCheetah_2.1.0_Mac_Universal.dmg">Mac OS X Universal</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.1/GoldenCheetah_2.1.0_Windows_Installer.exe">Windows 32-bit</a>
<a href="GoldenCheetah_2.1.0_Linux_x86.gz">Linux x86</a><br>
<a href="GoldenCheetah_2.1.0_Linux_x86_64.gz">Linux x86_64</a><br>
<a href="GoldenCheetah_2.1.0_Mac_Universal.zip">Mac OS X Universal</a><br>
<a href="GoldenCheetah_2.1.0_Windows_Installer.exe">Windows 32-bit</a>
</td>
<td valign="top">
<p>
@@ -130,10 +74,10 @@ Development Builds
<tr>
<td valign="top">2.0.0</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.0/GoldenCheetah_2.0.0_Linux_x86.gz">Linux (32bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.0/GoldenCheetah_2.0.0_Linux_x86_64.gz">Linux (64bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.0/GoldenCheetah_2.0.0_Mac_Universal.dmg">Mac OS X Universal</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.0/GoldenCheetah_2.0.0_Windows_Installer.exe">Windows 32-bit</a>
<a href="GoldenCheetah_2.0.0_Linux_x86.gz">Linux x86</a><br>
<a href="GoldenCheetah_2.0.0_Linux_x86_64.gz">Linux x86_64</a><br>
<a href="GoldenCheetah_2.0.0_Mac_Universal.zip">Mac OS X Universal</a><br>
<a href="GoldenCheetah_2.0.0_Windows_Installer.exe">Windows 32-bit</a>
</td>
<td valign="top">
<p>
@@ -216,10 +160,10 @@ Builds, testing and support
<tr>
<td valign="top">1.3.0</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.3/GoldenCheetah_1.3.0_Linux_x86.gz">Linux (32bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.3/GoldenCheetah_1.3.0_Linux_x86_64.gz">Linux (64bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.3/GoldenCheetah_1.3.0_Mac_Universal.zip">Mac OS X Universal</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.3/GoldenCheetah_1.3.0_Windows_Installer.exe">Windows 32-bit</a>
<a href="GoldenCheetah_1.3.0_Linux_x86.gz">Linux x86</a><br>
<a href="GoldenCheetah_1.3.0_Linux_x86_64.gz">Linux x86_64</a><br>
<a href="GoldenCheetah_1.3.0_Mac_Universal.zip">Mac OS X Universal</a><br>
<a href="GoldenCheetah_1.3.0_Windows_Installer.exe">Windows 32-bit</a>
</td>
<td valign="top">
<p>
@@ -316,10 +260,10 @@ Other new features:
<tr>
<td valign="top">1.2.0</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.2/GoldenCheetah_1.2.0_Linux_x86.tgz">Linux (32bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.2/GoldenCheetah_1.2.0_Linux_x86_64.tgz">Linux (6bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.2/GoldenCheetah_1.2.0_Darwin_Universal.dmg">Mac OS X Universal</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.2/GoldenCheetah_1.2.0_Windows_Installer.exe">Windows 32-bit</a>
<a href="GoldenCheetah_1.2.0_Linux_x86.tgz">Linux x86</a><br>
<a href="GoldenCheetah_1.2.0_Linux_x86_64.tgz">Linux x86_64</a><br>
<a href="GoldenCheetah_1.2.0_Darwin_Universal.dmg">Mac OS X Universal</a><br>
<a href="GoldenCheetah_1.2.0_Windows_Installer.exe">Windows 32-bit</a>
</td>
<td valign="top">
<p>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,99 +0,0 @@
<p>
<font face="arial,helvetica,sanserif">
<big><strong>GoldenCheetah 3.0.1</strong></big>
</font>
</p>
<p>
Full Change Log
</p>
<pre>
$ git checkout release_3.0.0
$ git shortlog v3.0-SP1 ^v3.0
Christian Stade-Schuldt (1):
Updated Tacx Satori Virtual Power values
Damien (16):
CsvRideFile: add temperature and hill slope (%) parsing for ibike csv file
Bin2RideFile: Changes in Summary pages for Data version 5
Bin2RideFile: correct bug for some GPS data
JouleDevice: Remove debug lines
JouleDevice: Remove debug lines
Aerolab: Add a constant altitude option
GoogleMap: Little fix
ShareDialog 2/3 : For version 3.0.1
FitRideFile: Add Calibration Event parsing
Correction for release_3.0.0 branch
AllPlot: plot references lines
OAuthDialog: Remove qDebug()
ShareDialog: Manage null error message
ShareDialog: Add upload to CyclingAnalytics and SelfLoops
FitRideFile: Correction for last Garmin firmware updates In last Garmin firmware there is some (unknow) fields with multi
FitRideFile: - Add Left/Right TorqueEff and Left/Rigth PedalSmooth - Open Truncated file
Dave Waterworth (2):
Fix Tacx Fortius Device Support
More Fortius Fixes
Eric Johnson (1):
Use float division when converting wheel size
G Coco (2):
Reinstate Twitter functionality
Merge StraveDialog and RideWithGPSDialog
Gareth Coco (3):
Website updates for Version 3.0 (cherry picked from commit fb339a527b7937ef8141b90af81cd2fd8017f891)
assert cleanup
Update translation source files
Jaime (1):
Work around to ensure controller key presses aren't missed. Borrowed from Fortius.cpp
Jon Escombe (3):
Detach kernel driver before claiming USB2 ANT+ interface.
Don't reset ANT channel settings on search timeout
Don't reset ANT channel settings on search timeout
Mark Liversedge (18):
Fixup Fit File issue
Fix PWX export SEGV
Deprecate Strava Support
Fix allplot crash on daft power value
Recognise Dave Waterworth
Merge pull request #694 from gcoco/release_3.0.0
Truncate Altitude values
Interval Summary Off By 1 Error
Add /dev/cu.usbserial as a serial device
Merge pull request #713 from gcoco/qwt-fix
V3.0 SP1 RC1 Update
Fix LC_LOCALE on Xcode 5
Fix findBests when no speed/gps
Merge branch 'release_3.0.0' of https://github.com/GoldenCheetah/GoldenCheetah into release_3.0.0
Batch Export remembers last format/dir
Fix 3d grid when users specify background colors
Fix SEGV if metric not available
V3.1 SP1 (3.0.1) released
Rainer Clasen (9):
SrmDevice: fix writing srmio data
inlude srmio version + commit in about dialog
make srmio details in version dialog conditionally
Tcx: fix speed in summary information
fix PWX export: handle end of gaps gracefully.
fix PWX export: always write summarydata
PWX export: keep timestamp + distance precision
PWX: read/write temperature
use pwx for Trainingstagebuch upload
Walter Bürki (1):
adding hr,cad,power,temp of Suunto Ambit gpx files
gcoco (5):
Support Twitter API 1.1
Twitter API change
Kurt Kinetic Road Machine PowerCurve fix
Get rid of qwt compile error about format string.
Add Garmin Forerunner 910XT
</pre>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Some files were not shown because too many files have changed in this diff Show More