fix(ui): trail sampling, avg speed, RTC elapsed, segment-aware map

Test feedback revealed four issues:

1. Sampling too sparse — defaults were 60 s interval + 25 m min-delta,
   so a walking pace dropped ~80% of samples. New defaults: 30 s + 5 m.
   Interval options expanded to { 30, 10, 20, 60, 300, 900 } s and
   min-delta to { 5, 10, 25, 100 } m so the user can dial it further
   from Settings (phase 5).

2. "Speed" was current-from-last-pair, misleading next to a Time field
   that grows monotonically. Switch to avgSpeedKmh = total / elapsed,
   labeled "Avg speed".

3. Time advanced only when a new sample landed (it used
   last().ts - first().ts). Now elapsedSeconds takes an optional
   now_ts and uses it whenever the trail is active, so the Time field
   in Summary ticks every render cycle. Sub-1h shown as m:ss for
   visible seconds.

4. Stop → start drew a straight line across the dead time. TrailPoint
   gains a flags byte; addPoint flags the first point and the first
   point after a re-arm as SEG_START. The map renderer skips the line
   from the predecessor for SEG_START points (still draws the start
   pixel). totalDistanceMeters also skips segment boundaries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-25 10:10:03 +02:00
co-authored by Claude Sonnet 4.6
parent 9d038730df
commit 7f0985c63f
2 changed files with 61 additions and 29 deletions
+17 -5
View File
@@ -81,13 +81,17 @@ private:
break;
}
case 3: {
uint32_t es = _store->elapsedSeconds();
snprintf(buf, n, "Time: %lu:%02lu",
(unsigned long)(es / 3600), (unsigned long)((es % 3600) / 60));
uint32_t es = _store->elapsedSeconds((uint32_t)rtc_clock.getCurrentTime());
// Below 1 h show m:ss so the seconds counter updates visibly each refresh.
if (es < 3600) snprintf(buf, n, "Time: %lu:%02lu",
(unsigned long)(es / 60), (unsigned long)(es % 60));
else snprintf(buf, n, "Time: %lu:%02lu",
(unsigned long)(es / 3600), (unsigned long)((es % 3600) / 60));
break;
}
case 4:
snprintf(buf, n, "Speed: %u km/h", (unsigned)_store->currentSpeedKmh());
snprintf(buf, n, "Avg speed: %u km/h",
(unsigned)_store->avgSpeedKmh((uint32_t)rtc_clock.getCurrentTime()));
break;
default:
buf[0] = '\0';
@@ -181,12 +185,20 @@ private:
py = off_y + (int)dy;
};
// Draw connected segments. A point flagged SEG_START starts a new segment;
// its predecessor is not joined to it. Single-point segments still get a
// visible pixel.
int x0, y0;
project(_store->at(0), x0, y0);
display.fillRect(x0, y0, 1, 1);
for (int i = 1; i < _store->count(); i++) {
int x1, y1;
project(_store->at(i), x1, y1);
drawLine(display, x0, y0, x1, y1);
if (_store->at(i).flags & TRAIL_FLAG_SEG_START) {
display.fillRect(x1, y1, 1, 1); // mark the segment's first point
} else {
drawLine(display, x0, y0, x1, y1);
}
x0 = x1;
y0 = y1;
}