New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dodgy LR balance in one-leg drills #3473
Comments
El vie., 5 jun. 2020 a las 9:04, tkswe88 (<notifications@github.com>)
escribió:
There seem to be some problems in GC when analyzing data from one-leg
drills. To my understanding, a left-leg drill should give an L/R balance
value of 100, whereas a right-leg drill should give an L/R balance of 0.
From Favero Assioma Duo power meter pedals, the L/R balance values seem to
be correctly imported to the tabular Edit view in GC. However, the L/R
balance values are always wrong (at 50%) in the graphical "Ride" view
during right leg drills, as shown here:
[image: LR_balance_old]
<https://user-images.githubusercontent.com/35581455/83773953-74e13980-a685-11ea-99ba-04b6116a8d6e.png>
The test protocol was as follows:
5-6 min left-leg drill
7-8 min right-leg drill
9-10 min left-leg drill
11-12 min right-leg drill
13-14 min left-leg drill
15-16 min right-leg drill
You will notice that the right-leg drills do not show as such, but are
displayed as perfectly balanced efforts. So, right-leg drills are not
properly prepared for plotting in GC.
I had a go at fixing this issue and the following changes, shown below as
output of a diff to the original files (*_bak.cpp), seem to lead to the
correct or at least a better result:
diff src/Charts/AllPlot_bak.cpp src/Charts/AllPlot.cpp
l. 2042
old: if (!objects->balanceArray.empty()) totalBalance +=
(objects->balanceArray[i]>0?objects->balanceArray[i]:50);
new: if (!objects->balanceArray.empty()) totalBalance +=
((objects->balanceArray[i]>=0 &&
objects->balanceArray[i]<=100)?objects->balanceArray[i]:50);
l. 2112
old: totalBalance -= (dp.lrbalance>0?dp.lrbalance:50);
new: totalBalance -= ((dp.lrbalance>=0 &&
dp.lrbalance<=100)?dp.lrbalance:50);
l. 2202
old: if (balance == 0) {
new: if (balance < 0 || balance > 100) {
l. 2313
old: if (dp->lrbalance == RideFile::NA || (dp->lrbalance == 0)) {
new: if (dp->lrbalance == RideFile::NA || (dp->lrbalance < 0) ||
(dp->lrbalance > 100)) {
diff src/Metrics/BasicRideMetrics_bak.cpp src/Metrics/BasicRideMetrics.cpp
l. 2803
old: if (point->lte && point->watts > 0.0f && point->cad &&
point->lrbalance > 0.0f && point->lrbalance < 100.0f) {
new: if (point->lte && point->watts > 0.0f && point->cad &&
point->lrbalance >= 0.0f && point->lrbalance <= 100.0f) {
l. 2857
old: if (point->rte && point->watts > 0.0f && point->cad &&
point->lrbalance > 0.0f && point->lrbalance < 100.0f) {
new: if (point->rte && point->watts > 0.0f && point->cad &&
point->lrbalance >= 0.0f && point->lrbalance <= 100.0f) {
l. 2911
old: if (point->lps && point->watts > 0.0f && point->cad &&
point->lrbalance > 0.0f && point->lrbalance < 100.0f) {
new: if (point->lps && point->watts > 0.0f && point->cad &&
point->lrbalance >= 0.0f && point->lrbalance <= 100.0f) {
l. 2965
old: if (point->rps && point->watts > 0.0f && point->cad &&
point->lrbalance > 0.0f && point->lrbalance < 100.0f) {
new: if (point->rps && point->watts > 0.0f && point->cad &&
point->lrbalance >= 0.0f && point->lrbalance <= 100.0f) {
Uisng these changes, the graphical display looks like this:
[image: LR_balance_new]
<https://user-images.githubusercontent.com/35581455/83773947-73177600-a685-11ea-941a-d2031c675ea7.png>
The modifications in BasicRideMetrics.cpp are related to issues #2955
<#2955> and #3104
<#3104>. To get
correct values for one-leg drills, it seems necessary to include L/R
balance values of 0 and 100. It was great, if @jgpallero
<https://github.com/jgpallero> and @amtriathlon
<https://github.com/amtriathlon> could have a look at this.
I am unsure whether my modifications are a complete or just a partial fix,
and I do not have any insight in how general this problem is. But, I guess
it is a general one.
Thank you for your report. The problem with the Assioma Duo is that not
always the 0 value is assignated as L/R balance when no pedaling. Most of
time this is the behavior, but there are also measures of 0 power with the
value 100 in the L/T balance field, so with the old code (the one I
modified via the #2955
<#2955> and #3104
<#3104> patchs) the L/R
balance was biased towards the left pedal. So the check of point->lrbalance
< 100.0 was necessary in order to suppress these non correct measures.
The problem of adding the >= and <= checks is that some values of 100 will be
added to the mean L/R balance computation, biasing the value. Attached I
send a screenshot of one of my rides. From rows 83 to 89 it can be seen
that for 0 power and 0 cadence no data is stored in the L/R balance field,
which actually means a 0 value. No problem with this behavior. But in rows
80 to 82 we can see a 0 power value and 75 cadence value and different L/R
balance values: 0 for rows 80 and 81, and 100 for row 82. In this case >=
and <= checks for balance could be used as in the same line of code power>0
and cadence >0 are checked also, but see rows 67 to 69. In these cases a 0
power value is stored, but together with cadence>0 (pedaling without
applying force in a descent), and a value of 100 is assigned to L/R balance
field. SO in this last case the use of <= and >= for the lrbalance check
means true, and this fake 100 value of balance will be added to the
lrbalance computation and the mean will be biased. Also see rows 71 to 74.
In these cases the power values are 2, and 4, so they are equivalent to 0,
but again the L/R balance field is set to 100. Using the check
lrbalance<=100 will add these values to the L/R balance average
computation, but they wouldn't taken into account
I don't know if this problems of L/R balance 0 and 100 assignation occur
with other power meters
… —
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3473>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGRHZDT3E3MYBBDGJFYSV3RVCKF7ANCNFSM4NSXHDVA>
.
--
*****************************************
José Luis García Pallero
jgpallero@gmail.com
(o<
/ / \
V_/_
Use Debian GNU/Linux and enjoy!
*****************************************
|
@jgpallero: Many thanks for the comment. Please send the screenshot as well. |
Oh, excuse me. I answered via gmail and I can see the attached files are not present here. Now I attach here the screenshot and also a couple of files containing a ride and a small Matlab/Octave script with different computations of the L/R balance |
@jgpallero, many thanks for your recent post and sorry for being late with my response. I have some general difficulties accepting the idea that the L/R balance value should be 0 if no force is applied. At least from what the Favero Assioma Duos produce, right-leg drills give an L/R balance of 0, whereas left-leg drills give an L/R balance of 100. So, 0 values are meaningful, when power is applied (in right-leg drills), and, in my opinion, 0 values should not have a potential double meaning to indicate periods when no power is applied. Further, all L/R balance values are equally meaningless, when no power is applied. However, to give a "neutral" impression in the plots assigning an L/R balance of 50 may be more appealing to the eye than 0 in this case. To me it seems, the best way of computing averages, would be to check for both power and cadence being larger than 0 and to allow for L/R balance in the interval [0,100], i.e. including end points to allow for one-leg drills. This approach would only leave rows 71 - 74 from your example as problematic, where very low force is applied. One possible way around this would be to check for the force being larger than a small value, say 10 W, rather than 0 W. It might be meaningful to have a user-provided threshold value. Except for the last point, I think I could provide suggestions for changes to the code. However, as said before, I may have missed a few instances in the code, where changes would have to be made. |
Can you attach the file recorded during the test? |
The FIT file format only stores balance for one leg and the value for the other is computed through substraction of 100. This is documented in the file Profile.xslx in the FIT file format documentation (https://www.thisisant.com/resources/fit-sdk/). The FIT file can store the balance for the left leg or for the right, but not for both. GC stores the balance referred to the left leg. So, a 0 value has two possible meanings: no force applied at all of force applied only to the right pedal. This ambiguity can be overcomed, as you suggest, checking for watts>0 and cadence>0, and this is taken into account in
The problem is that although watts>0 and cadence>0 is used, Favero stores randomly values of 100 in lrbalance. I've made some checks using a small threshold as you suggest (you can made tests using the Matlab code I uploaded in my last mail), but the results are not good. The only solution I've found for a correct balance computation is to exclude 0 and 100 values |
To @amtriathlon and @jgpallero, please find attached the fit recorded during the one-leg drills on a home trainer. |
I didn't followed all the discussion, tl:dr, but to adapt the code to the fact "Favero stores randomly values of 100 in lrbalance" doesn't seem a good solution to me. Data processors are the tools to fix anomalies in data. |
Yes, I totally agree |
@jgpallero and @amtriathlon: I also agree that anomalies should be fixed using data processors. However, to me the problem seems more fundamental than taking care of random lrbalance values of 100 from Favero pedals for low values of force. As the code is now, I think, it does not correctly plot right-leg drills in the Ride panel, it does not correctly compute averages of l/r balance, l/r pedal smoothness and l/r torque effectiveness for right-leg or left-leg drills. More importantly, I think this problem will occur for many power meters not just the Assioma Duos. I just do not have other dual-sided PMs to test this with. I realised I forgot to mention the change I made to LeftRightBalance.cpp, which is as follows: diff LeftRightBalance_bak.cpp LeftRightBalance.cpp |
Fixed by b29f72d, the attached example now looks like this: |
Invalid values are now mapped to RideFile::NA on import, 0 and 100 are valid values and should not be excluded. Fixes #3473
@grauser @amtriathlon Many thanks for fixing this issue. Splendid work! |
* master: FixGaps: improve interpolation of left/right balance for smart recording Similar to 2b6473d LRBalance related metrics check for RideFile::NA Invalid values are now mapped to RideFile::NA on import, 0 and 100 are valid values and should not be excluded. Fixes GoldenCheetah#3473 TRAIN - Fix LRBalance from ANT+ channels LRBalance is left side contribution while the ANT+ messages carries right side pedalPower contribution, so it needs to be converted. When not available RideFile::NA is used since 0 means 100% right. Complementes b29f72d, Fixes GoldenCheetah#3017 Estimate CP for Runs - Increase distance precision to 3 digits Distance is in km/mi and 1 digit is not enough to use timed tests to exhaustion, for distance based TTs likely this is not an issue. Fit : improve interpolation of left/right balance for smart recording FIT : add some manufacturers RideFitFile : - Add Right contribution bit in FIT exported - Don't asssume left data if right side not confirmed - Plot 0 left/Balance Daum: Improve support for more cockpits (GoldenCheetah#3775) User PIE and BAR Charts honor x-axis Date and Time settings So labels/categories are displayed in Time/Date format in a similar way to Line and Scatter charts. Add screenshots for the wiki - New Metric Trends Curves [skip ci] Upgraded embedded Python to 3.7.9 for Windows builds [skip travis]
Invalid values are now mapped to RideFile::NA on import, 0 and 100 are valid values and should not be excluded. Fixes GoldenCheetah#3473
Invalid values are now mapped to RideFile::NA on import, 0 and 100 are valid values and should not be excluded. Fixes GoldenCheetah#3473
Invalid values are now mapped to RideFile::NA on import, 0 and 100 are valid values and should not be excluded. Fixes GoldenCheetah#3473
There seem to be some problems in GC when analyzing data from one-leg drills. To my understanding, a left-leg drill should give an L/R balance value of 100, whereas a right-leg drill should give an L/R balance of 0.
From Favero Assioma Duo power meter pedals, the L/R balance values seem to be correctly imported to the tabular Edit view in GC. However, the L/R balance values are always wrong (at 50%) in the graphical "Ride" view during right leg drills, as shown here:
The test protocol was as follows:
5-6 min left-leg drill
7-8 min right-leg drill
9-10 min left-leg drill
11-12 min right-leg drill
13-14 min left-leg drill
15-16 min right-leg drill
You will notice that the right-leg drills do not show as such, but are displayed as perfectly balanced efforts. So, right-leg drills are not properly prepared for plotting in GC.
I had a go at fixing this issue and the following changes, shown below as output of a diff to the original files (*_bak.cpp), seem to lead to the correct or at least a better result:
diff src/Charts/AllPlot_bak.cpp src/Charts/AllPlot.cpp
l. 2042
old: if (!objects->balanceArray.empty()) totalBalance += (objects->balanceArray[i]>0?objects->balanceArray[i]:50);
new: if (!objects->balanceArray.empty()) totalBalance += ((objects->balanceArray[i]>=0 && objects->balanceArray[i]<=100)?objects->balanceArray[i]:50);
l. 2112
old: totalBalance -= (dp.lrbalance>0?dp.lrbalance:50);
new: totalBalance -= ((dp.lrbalance>=0 && dp.lrbalance<=100)?dp.lrbalance:50);
l. 2202
old: if (balance == 0) {
new: if (balance < 0 || balance > 100) {
l. 2313
old: if (dp->lrbalance == RideFile::NA || (dp->lrbalance == 0)) {
new: if (dp->lrbalance == RideFile::NA || (dp->lrbalance < 0) || (dp->lrbalance > 100)) {
diff src/Metrics/BasicRideMetrics_bak.cpp src/Metrics/BasicRideMetrics.cpp
l. 2803
old: if (point->lte && point->watts > 0.0f && point->cad && point->lrbalance > 0.0f && point->lrbalance < 100.0f) {
new: if (point->lte && point->watts > 0.0f && point->cad && point->lrbalance >= 0.0f && point->lrbalance <= 100.0f) {
l. 2857
old: if (point->rte && point->watts > 0.0f && point->cad && point->lrbalance > 0.0f && point->lrbalance < 100.0f) {
new: if (point->rte && point->watts > 0.0f && point->cad && point->lrbalance >= 0.0f && point->lrbalance <= 100.0f) {
l. 2911
old: if (point->lps && point->watts > 0.0f && point->cad && point->lrbalance > 0.0f && point->lrbalance < 100.0f) {
new: if (point->lps && point->watts > 0.0f && point->cad && point->lrbalance >= 0.0f && point->lrbalance <= 100.0f) {
l. 2965
old: if (point->rps && point->watts > 0.0f && point->cad && point->lrbalance > 0.0f && point->lrbalance < 100.0f) {
new: if (point->rps && point->watts > 0.0f && point->cad && point->lrbalance >= 0.0f && point->lrbalance <= 100.0f) {
Uisng these changes, the graphical display looks like this:
The modifications in BasicRideMetrics.cpp are related to issues #2955 and #3104. To get correct values for one-leg drills, it seems necessary to include L/R balance values of 0 and 100. It was great, if @jgpallero and @amtriathlon could have a look at this.
I am unsure whether my modifications are a complete or just a partial fix, and I do not have any insight in how general this problem is. But, I guess it is a general one.
The text was updated successfully, but these errors were encountered: