fix(train): the wheel is learnt from rides GPS covered, whatever its size (ADR 0030, D56)

The measure was held to GPS making 90 % of the wheel's way at the
circumference taken, 2105 mm to start: a real wheel under some 1.9 m fell
short of it on every ride and was never learnt. A ride now measures where
precise fixes followed it for 95 % of its moving time, its quotient between
1 and 3 m as one typed may be.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-30 16:01:40 +01:00
commit 9b9b8d08ca
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -122,14 +122,21 @@ void main() {
});
group("the wheel's distance (D49)", () {
/// A ride of [seconds] with GPS [gpsMetres] a second and the wheel
/// turning twice a second, its 2.1 m round.
Recording ride({required int seconds, required num gpsMetres}) => Recording(
/// A ride of [seconds] with GPS [gpsMetres] a second, no fix between
/// the seconds [lostFrom] and [lostTo], and the wheel turning twice a
/// second, taken for 2.1 m round.
Recording ride({
required int seconds,
required num gpsMetres,
int? lostFrom,
int? lostTo,
}) => Recording(
activity: Activity.cycling,
startedAt: start,
fixes: [
for (var s = 0; s <= seconds; s += 10)
north(s, (s * gpsMetres).round()),
if (lostFrom == null || s <= lostFrom || s >= lostTo!)
north(s, (s * gpsMetres).round()),
],
wheel: [
for (var s = 0; s <= seconds; s++) Reading(time: at(s), value: s * 2),
@ -162,15 +169,39 @@ void main() {
() {
expect(measuredWheelMm(ride(seconds: 200, gpsMetres: 4.2)), isNull);
expect(measuredWheelMm(ride(seconds: 600, gpsMetres: 8)), isNull);
expect(measuredWheelMm(ride(seconds: 1200, gpsMetres: 1.6)), isNull);
},
);
test("one whose GPS fell short of the wheel's way (a tunnel) measures "
'none: its quotient would read as a smaller wheel', () {
// 3.6 m a second by GPS, 4.2 by the wheel: 86 %, a 1.8 m wheel.
final tunnel = ride(seconds: 1500, gpsMetres: 3.6);
expect(rodeByWheel(tunnel), isTrue);
test('a smaller wheel than the one taken is measured all the same: '
"GPS's track is held to time, not to the wheel taken", () {
// 3 m a second by GPS, two turns: a 20" wheel's 1.5 m.
final small = ride(seconds: 900, gpsMetres: 3);
expect(measuredWheelMm(small), closeTo(1500, 5));
// A child's 16" wheel, 1.25 m.
expect(
measuredWheelMm(ride(seconds: 900, gpsMetres: 2.5)),
closeTo(1250, 5),
);
});
test('one whose GPS was lost for a while (a tunnel) measures none: the '
'straight line across would read as another wheel', () {
final tunnel = ride(
seconds: 1500,
gpsMetres: 4.2,
lostFrom: 600,
lostTo: 720,
);
expect(measuredWheelMm(tunnel), isNull);
// A fix lost now and then, as on any ride, still measures.
final patchy = ride(
seconds: 1500,
gpsMetres: 4.2,
lostFrom: 600,
lostTo: 620,
);
expect(measuredWheelMm(patchy), closeTo(2100, 5));
});
});