Closed mattipee closed 4 years ago
The easiest would be to have a minimum time for calibratioN.
(I am.not near the code now) OR is the maximum time too short?
The calibration stops when the reported resistance is stable OR when a "maximum time" is reached. Try to increment that time, please
One is supposed to ride for 10 minutes or something, before calibration, to bring up to temp. As Fortius has a motor, running the motor for longer will warm the tyre up more. Running faster will obviously warm faster.
Aside: I think the check for stability is prone to false-positives - looks like a couple of comments around ResistanceArray suggest an average but the code only uses min/max. The cause for false positives is that CurrentResistance values are noisy and without a wide enough threshold, one might never detect stability. But too wide, and it thinks its settled too soon. So I've tried reduced the min/max difference threshold from 30 to 15, to try to force an even "steadier state", but it takes a while. Mathematically, checking for settling of a moving average (trend) would reduce the effect of the noise.
Yes, having a long-duration calibration routine will increase temperature further, and by improving the ability to detect settling will allow that routine to run for "long enough". But from cold, I know it's not going to settle for a good time, so a separate warm-up phase at higher wheel speed is simply more convenient.
I guess the first issue is perhaps improving calibration, and separating out warm up rather than just calibrating for longer is simply a time-optimisation.
I'm "splitting hairs", I know. Just looking to maximise accuracy for accuracy's sake.
Blue and Yellow are against the left-hand Y axis, and represent the CurrentResistance*-1, and numpy.average(ResistanceArray), respectively.
Red and Green are against the right-hand Y axis, and represent the different between min/max of ResistanceArray and a new AvgResistanceArray respectively.
AvgResistanceArray is again a 20-entry array, and which receives a new value numpy.average(ResistanceArray) at each step. A simple "cascade" for the running average. ResistanceArray takes 20 cycles to eliminate 0-entries, AvgResistanceArray takes a further 20 cycles to eliminate the effect of 0 values in the average values, specifically for numpy.min(AvgResistanceArray) to rise, about 10 seconds (40 cycles @4Hz)
You can see how noise Blue and Red are... and how, at X-axis position 120 (30 seconds * 4 samples in), would result in calibration value being set at approx 1070, given the difference between min and max is <30.
I chose for the threshold for the difference between min/max of the AvgResistanceArray arbitrarily to be 5 (something small), which results in a calibration value of approximately 1000. However, you can see the yellow line has not yet settled, suggesting threshold 2 might be better.
So relying on a wide-difference 30 based on the min/max of ResistanceArray results in a rather early "settling". But averaging to reduce noise and tightening the threshold difference between min/max of the secondary AvgResistanceArray, a more accurate calibration value can be obtained.
Taking a difference of min/max approximates a time-based derivative, ie gradient, of the resistance. Doing so based on a moving average reduces noise, and allows a tighter difference threshold. The longer it runs and the smaller the threshold, the closer to steady state is achieved... part of that long run is never intended to achieve steady state and is in fact, in practice, a warm-up phase.
Looks good. Note that the wheelspeed of 20km/hr is an arbitrary choice; perhaps a higher wheelspeed would be advantageous...
https://github.com/WouterJD/FortiusANT/blob/master/pythoncode/usbTrainer.py#L1402
Will look into it asap. Thanks!
20kmh is what TTS4 uses for calibration iirc. So perhaps keep it at that (for calibration). Otherwise you'd end up with a larger value.
(I have often wondered whether 20 matters... or if it is just a "typical average" for users... ie whether in fact you'd want a calibration "curve", from which to draw values for different current wheel speeds, but I don't know the answer...)
Ah, did not know anymore where the 20kmh came from.
Implemented as requested
There is no WarmUp() routine as the issue-title states. Let's keep the issue open for some time and see whether current implementation is enough
It takes longer now, but is arguable more accurate using the running averages. It taking longer means a better warm up.
It will depend whether there's any push back from users on calibration taking longer. A quick minute blast at 40kmh would indeed help, but there's the safety aspect also... that's at least double the power spinning the wheel. In hindsight, I'd be hesitant to increase. I'm satisfied with the improved calibration, thanks for the merge!
I also wonder, on a related note, what the old TTS4 red/green indicated range was for calibration in terms of the calibration value, ie to inform the user to adjust pressure on the wheel.
As an aside: my 56/16 gearing with cadence 60-90 gives wheel speed of approx 16.5 - 24.5. So I'm happy with 20. :)
Edit: I've changed the title to exclude warmup, but worth investigating the "ideal range" for calibration values, to possibly feedback to adjust wheel pressure.
FYI: Both my T1292 Tacx headunit, the Tacx Andorid app and the Zwift desktop asks for:
The TacX mobile app even gave adjustment instruction:
Thanks, @orrmany .
The Fortius having a motor means it can do its own warmup, saving me five minutes of work. 😂
I've never done a spindown test yet, but I'm aware of it.
I note that the Fortius will give different calibration results depending on whether I am sitting on the bike or not. I can't just run calibration unattended then ride, I have to ensure calibration finishes with me on the bike.
can't just run calibration unattended then ride, I have to ensure calibration finishes with me on the bike.
Yes, your weight affects the pressure, hence the friction between the tyre and the roller.
Implemented in 3.6
Running at 40kmh for a few minutes, before running Calibration yields (for me) a more reliable calibration first time.
I've found myself a few times, during calibration, alternating sitting or standing on the ground, or occasionally tickling the pedal, and reducing the threshold of 30 to 15, to prevent calibration from settling too quickly.
However, a quick WarmUp() would probably do the trick. I changed code manually to do this just now, and it was certainly less-faff.
My garage is cold, and is where I'll be riding through winter.
Wonder is this is useful enough to others to consider implementing?