Skip to content

CLIMBER as canonical climb source + GPS route matching#8

Open
lgangitano wants to merge 2 commits into
yrkan:mainfrom
lgangitano:feature/climber-gps
Open

CLIMBER as canonical climb source + GPS route matching#8
lgangitano wants to merge 2 commits into
yrkan:mainfrom
lgangitano:feature/climber-gps

Conversation

@lgangitano
Copy link
Copy Markdown

Summary

Adapts 7climb to Karoo's native CLIMBER (karoo-ext 1.1.8) and makes it the authoritative climb source, with GPS-based identification of which route climb the rider is on.

Built on #6 (the 1.1.7 → 1.1.8 SDK bump) — please merge that first; until then this PR's diff also contains the bump commit.

Climb data & detection

  • Subscribe to DataType.Type.CLIMB; CLIMBER is the sole climb detector (the route/GPS path no longer activates a climb on its own).
  • Total ascent = ELEVATION_TO_TOP + ELEVATION_FROM_BOTTOM. (CLIMB_ELEVATION turned out to be the rider's current altitude ASL, not the climb total.)
  • Route climbs: latch the full climb list from the first populated NavigationState emit and keep it — Karoo progressively prunes the climb you're on and re-bases the remaining climbs' startDistance to your position as you ride.
  • Skip the stale carry-over tick at a climb switch (Karoo flips climbNumber before refreshing the distance/elevation fields), so each climb is processed with its own data.

GPS route matching

  • Decode the precision-5 routePolyline into points carrying cumulative (haversine) distance-along-route; map the live LOCATION fix to a route distance — independent of ride/recording distance, which desyncs on a mid-ride route add or a partial join.
  • Max-snap gate (50 m): a far continuity candidate triggers a global re-acquire; beyond the route entirely is treated as off-route (hold last). Reads LOC_LATITUDE / LOC_LONGITUDE.

Alerts

  • Climb-started announces remaining-to-top (distanceToTop / elevationToTop) to match CLIMBER, fires once per climb session (id keyed on the session start, with a continuation guard for same-climb stream blips), and shows distance to 2 decimals.

Testing

  • On-device via karoo-ride-replay: correct elevation, GPS-anchored matching, off-route → rejoin re-acquire, and one alert per climb (route and freestyle).
  • JVM unit tests for the polyline / route-geometry math and climb detection.

Scope

  • No changes to pacing strategy, FIT recording, Room schema, or the data-field roster — internal data plumbing + alert content only.

Brings in upstream PR hammerheadnav/karoo-ext#72 (January 2026):

- Exports the CLIMB DataType (TYPE_CLIMB_ID) with fields
  DISTANCE_FROM_BOTTOM, DISTANCE_TO_TOP, ELEVATION_FROM_BOTTOM,
  ELEVATION_TO_TOP, CLIMB_ELEVATION — driven by Karoo's native
  Climber detection on routes and freestyle rides.
- Exports CLIMB_NUMBER, SEGMENT_ELEVATION_REMAINING, DESCENT_REMAINING.
- Fixes the ELEVATION_REMAINING field-name mismatch reported in
  upstream issue #71 (was emitting FIELD_ASCENT_REMAINING_ID under
  FIELD_ELEVATION_REMAINING_ID's umbrella since 1.1.7).

KOS requirement moves from 1.594.2280+ to 1.613.2351+ accordingly;
listed in the PR body for users running older KOS releases.

No behavioral change in this PR — only the dependency version. Follow-up
PRs will subscribe to the newly-exported CLIMB stream and adapt
ClimbDataService accordingly.
Adapts 7climb to Karoo's native Climber (karoo-ext 1.1.8) and makes it the
authoritative climb source, with GPS-based route-climb identification.

Climb data & detection:
- Subscribe to DataType.Type.CLIMB; CLIMBER is the sole climb detector (the
  route/GPS path no longer activates a climb on its own).
- Total ascent = ELEVATION_TO_TOP + ELEVATION_FROM_BOTTOM (CLIMB_ELEVATION is the
  rider's current altitude ASL, not the climb total).
- Route climbs: latch the full climb list from the first populated NavigationState
  emit; ignore Karoo's progressive pruning/re-basing of the same route.
- Skip the stale carry-over tick at a climb switch (climbNum flips before the
  geometry refreshes), so each climb is processed with its own data.

GPS route matching (ElevationPolylineDecoder):
- Decode the precision-5 routePolyline into RoutePoint (lat/lng + cumulative
  haversine distance); map a live GPS fix to distance-along-route, independent of
  ride/recording distance (which desyncs on mid-ride route add / partial join).
- Max-snap gate (50 m): far windowed candidate → global re-acquire; beyond the
  route entirely → off-route (hold last). Read LOCATION via LOC_LATITUDE/LONGITUDE.

Alerts:
- Climb-started announces remaining-to-top (distanceToTop/elevationToTop), matching
  CLIMBER; fires once per climb session (id keyed on session start, with a
  continuation guard for same-climb stream blips). Distance shown to 2 decimals.

Tests: JVM unit tests for the polyline/route-geometry math and climb detection.
Excludes pacing-strategy changes and the local-only dev variant.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant