sivertschou / dundring

dundring.com is a free and open source in-browser training application created to control and track your training with a smart bike trainer⚡️
https://dundring.com
Apache License 2.0
62 stars 8 forks source link

Fix watt-to-ftp-calculation rounding issues #414

Open morteako opened 1 month ago

morteako commented 1 month ago

When inputing watts in the editor, the resulting watts in the workout can differ by 1, because of flooring/rounding issues. This is fixed by rounding the wattFromFtpPct-calculation instead of flooring

Example FTP: 280, input 279 ftpPct = Math.floor(1000 * (279 / 280)) / 10; ftPct = 99.6

result in editor: 279, 99.6%

when we then calculate in the workout: Math.floor((ftpPct * ftp) / 100) = Math.floor((27888 / 100) = 278;

Based on my tests, changing the floor in the wattFromFtpPct to round, should fix this. Since

Gif of error in action : 279 => 278

2024-10-22 20 51 32

Testing

Testing code old version

let failures = [];
for (let ftp = 1; ftp <= 500; ftp += 1) {
  for (let watt = 0; watt <= 1000; watt += 1) {
    const ftpPct = Math.floor(1000 * (watt / ftp)) / 10;
    const wattFromFtpPct = Math.floor((ftpPct * ftp) / 100);
    if (wattFromFtpPct !== watt) {
      failures.push({
        watt,
        exactWattFromFtpPct: (ftpPct * ftp) / 100,
        ftpPct,
        ftp,
      });
    }
  }
}
console.log(failures);

=> Lots of issues

image

Testing code for new version

let failures = [];
for (let ftp = 1; ftp <= 500; ftp += 1) {
  for (let watt = 0; watt <= 1000; watt += 1) {
    const ftpPct = Math.floor(1000 * (watt / ftp)) / 10;
    const wattFromFtpPct = Math.round((ftpPct * ftp) / 100);
    if (wattFromFtpPct !== watt) {
      failures.push({
        watt,
        exactWattFromFtpPct: (ftpPct * ftp) / 100,
        ftpPct,
        ftp,
      });
    }
  }
}
console.log(failures);
image

=> All watts are correct