Releases: yrkan/7climb
7Climb v3.0.2
Critical fix
Sensor emission batching to 1Hz — All 8 sensor callbacks (power, HR, cadence, speed, altitude, grade, distance, GPS) previously called emitState() independently, creating ~8 emissions/second. Since each emission carried a fresh timestamp, StateFlow never deduplicated — all downstream engines fired on every callback.
This caused:
- ~8x overcounting of energy (kJ), Normalized Power, TSS, and match burn durations — MetricsEngine and MatchBurnEngine assumed 1 call = 1 second
- ~8x CPU overhead — PacingCalculator ran 20 Newton iterations with trig per call, all 6 engines processed redundantly
Now a single 1Hz timer emits state, and a sensorUpdatedSinceLastEmit guard prevents stale emissions during ride pause (which would inflate kJ/NP/TSS with phantom power data).
Performance improvements
-
TacticalAnalyzer caching —
getPrimaryInsight()was called 14×/sec (once per data field per second), each time rebuilding all insights with list allocations and sorting. Now cached with 1% progress threshold — recomputes only when the rider moves meaningfully along the climb. -
MetricsEngine running NP sum — Replaced
npWindow.sum()(O(30) per tick) with a running sum variable (O(1)). -
PacingCalculator physics cache —
calculateTargetPower()runsspeedFromPower()(Newton iterations with atan/sin/cos/exp) every tick. Now cached when grade (±0.1%), altitude (±5m), FTP, mode, and athlete profile haven't changed. On a steady 7% climb, physics runs once on entry instead of 3600×/hour. -
PowerZonesGlance composable reduction — Zone bar segments reduced from 20 to 10 in
ZonesLarge,ZoneBar, andProgressBar. 140 → 70 Box composables in the largest layout. Visual difference negligible at Karoo display sizes. -
ClimbDetector ArrayDeque — Replaced
mutableListOfwithArrayDequefor O(1)removeFirst()instead of O(n)removeAt(0). ReplacedtakeLast(N).average()(temporary list allocation) with index-based iteration. -
PhysicsUtils solver — Newton iterations reduced from 20 to 10, convergence tolerance from 0.1W to 1.0W. 1W precision is more than sufficient for pacing advice.
Minor improvements
- Cached
activeClimb.valueread in extension's main data flow (1 StateFlow read instead of 2 per tick) - Removed unnecessary
@Serializableannotations from 7 transient model classes (LiveClimbState, WPrimeState, ClimbStats, RideMetrics, PacingTarget, MatchBurnState/Match, NextClimbInfo) — none are ever serialized - Defensive
emitJob?.cancel()at start ofstartStreaming()prevents duplicate timers on Karoo reconnect edge case
Behavioral note
MatchBurnEngine's belowCpCounter >= 5 threshold now means 5 real seconds below CP (previously ~0.6s at 8Hz). This is an improvement: brief power dips during intervals no longer prematurely end a match, matching industry-standard match burn detection behavior.
7Climb v3.0.1
Bug Fixes
- Match Burn: Fixed match duration dropping 5-second grace period — live and saved durations now consistent
- Match Burn: Recovery timer now uses ride elapsed time instead of wall clock — no longer inflates during pauses
- Pacing Strategy: Fixed negative-split overloading exhausted riders — when W' < 60%, second half target no longer exceeds base power
- Pacing Calculator: Added @volatile to profile and mode fields to prevent stale reads across threads
- Power Zones: Fixed potential ArrayIndexOutOfBounds crash with zone bounds check
- Next Climb: Distance and ETA can no longer go negative from GPS jumps
- Metrics Engine: Removed dead variable in NP circular buffer
7Climb v3.0.0
Pro Features, Physics-Based Pacing & 16 Languages
New Data Fields (10 → 14)
- Ride Metrics — NP, IF, TSS, Variability Index, kJ, elapsed time
- Power Zones — live Coggan zone tracking with time-in-zone distribution (7 zones)
- Match Burn — above-CP match detection, kJ burned, peak power, recovery timer
- Next Climb Countdown — distance, ETA, name, category, elevation for upcoming climbs on route
Physics-Based Pacing
- Pacing now uses full physics model (CdA, Crr, mass, altitude-adjusted air density)
- CdA/Crr/bike weight settings now directly affect pacing targets (previously cosmetic)
- Smooth gradient response replaces old stepped lookup table
- Mode-specific speed targets: Steady (92% FTP speed), Race (100%), Survival (80%)
Whole-Climb Pacing Strategy
- Negative-split approach with 4 phases: SAVE → BUILD → PUSH → SPRINT
- Split bias adapts to W' balance — conserves energy when W' is low
- Strategy phase + split targets shown in Large and Medium Wide pacing layouts
Fatigue/Durability Model
- Configurable FTP decay after threshold hours (default: −3%/hr after 2h)
- Fatigue-adjusted FTP feeds into pacing targets automatically
- New Durability section in Pacing settings with toggle, decay rate, threshold
FIT Recording
- 3 new developer fields: Normalized Power, TSS, Match Count
Localization
- 16 languages: Russian, Ukrainian, Polish, German, French, Spanish, Italian, Portuguese, Dutch, Danish, Swedish, Japanese, Korean, Chinese, Arabic, Hebrew
7Climb v2.1.1
Engine Reliability Fixes & Pacing Overhaul
Critical Fixes
- Crash recovery: W' balance now persists to SharedPreferences — survives app crashes and restarts
- PR history preserved: removed destructive database migration that silently wiped climb history on schema changes
- Pacing rewrite: replaced flawed speed-based model with FTP-based pacing (gradient + altitude correction)
- Climb ID stability: GPS-based climb IDs (
geo_lat_lon) for reliable cross-ride PR matching - Memory safety: Flow collector jobs are now tracked and properly cancelled on disconnect
High Priority
- Fixed
distanceClimbedKmshowing total length instead of distance actually climbed on route climbs - W' engine no longer freezes on duplicate-timestamp sensor events (min 0.1s dt clamp)
- W' critical alert fires once on threshold crossing instead of spamming every second
- W/kg calculation validates weight > 0 before division
- Tactical analyzer searches only upcoming segments for attack points
Improvements
- W' balance clamped when W'max changes mid-ride; TTE/TTF capped at 1 hour
- Climb detector resets count between rides, tracks max grade per-climb accurately
- Altitude-aware pacing: VO2max correction above 1500m (−6.5% per 1000m)
- Auto-generated climb names ("Cat 2 3.5km") instead of blank labels
7Climb v2.1.0
Hub-and-Spoke Settings, Configurable Detection & Alerts
Settings Navigation
- New hub-and-spoke architecture — main menu with live config summaries
- Dedicated sub-screens: Athlete, Bike, Detection, Pacing, Alerts, About
- Back navigation with arrow header on each sub-screen
- About screen: version, GitHub, Privacy Policy, Contact
Climb Detection
- Sensitivity presets: Sensitive, Balanced, Conservative
- Fine-tune: min grade, min elevation, confirm/end distance
- Auto-detects custom configuration when params diverge from preset
Pacing
- Configurable tolerance: Tight (±5W), Normal (±10W), Relaxed (±20W)
Alerts
- Individual toggles for W' Critical, Steep Ahead, Summit, Climb Started
- Configurable W' alert threshold (default 20%)
- PR alerts now show improvement delta
Glance
- Climb Overview shows live grade/power/W' when no climb is active
- Refined layouts across all 10 data fields
7Climb v2.0.1
SettingsScreen UI overhaul for Karoo 3
- BikeType selector — split into 2 rows (Race/Aero/TT + Endurance/Custom) for larger touch targets
- Surface selector — split into 2 rows (Smooth/Road/Rough + Cobbles/Gravel)
- Increased spacing & padding across all interactive elements (section headers, hints, toggles, cooldown buttons, position selector)
- Expandable arrow — larger and more visible (14sp)
- Full label — "Endur." → "Endurance"
7Climb v2.0.0
Climb Stats, Bike Setup & Validation Overhaul
What's New
Climb Stats Data Field
New dedicated data field for comprehensive climb metrics:
- VAM — real-time vertical ascent meters per hour (rolling 60s window)
- W/kg — instant power-to-weight ratio with intensity color coding
- HR / Cadence — heart rate and cadence tracking during climbs
- Energy (kJ) — total energy expenditure on the current climb
- Elapsed Time — climb duration
- Avg/Max Power, Avg W/kg — summary statistics per climb
- 6 responsive layouts from compact single-metric to full dashboard
Bike Setup
- Bike type presets: Race (7.5 kg), Aero (8.0 kg), TT (9.0 kg), Endurance (9.5 kg), Custom
- Custom bike weight input with per-gram precision
- Physics calculations now use your actual bike weight instead of a hardcoded 8 kg
Critical Power (CP)
- Manual CP override in Advanced settings
- Auto-calculation from FTP × 0.95 when left at 0
- Proper CP/FTP separation for W' balance accuracy
Expanded Presets
- Riding positions: added Aero Drops (CdA 0.270) and TT (CdA 0.220)
- Road surfaces: added Cobbles (Crr 0.010) and Gravel (Crr 0.012)
- Position and surface selectors now show hint text explaining their effect
Improved Glance Displays
- ETA (large): replaced speed with live VAM and color-coded intensity
- Grade (large): shows HR (bpm) and cadence (rpm) instead of power/speed
- Pacing (large): added live W/kg metric with zone coloring
- Next Segment: final segment now shows "LAST SEGMENT" with grade, length, and elevation instead of an empty state
Validation & Architecture
- Single validation layer: removed duplicate range checks from UI — PreferencesRepository is now the single source of truth
- Tightened physics ranges: CdA 0.15–0.60 (was 0.1–1.0), Crr 0.002–0.015 (was 0.001–0.02)
- FTP upper limit raised from 500W to 600W
- Input fields now handle copy-pasted whitespace correctly
- AthleteProfile uses actual bike weight for total mass calculation
- W' engine uses effective CP (manual override or auto-calculated)
- All hardcoded UI strings extracted to strings.xml
Full Changelog: v1.0.1...v2.0.0
7Climb v1.0.1
Remove unused vibration support (Karoo has no vibration motor), clean up alerts.
7Climb v1.0.0
7Climb v1.0.0 — Initial Release
Real-time climb intelligence for Hammerhead Karoo.
Features
- W' Balance — Skiba differential model with 6 status levels, depletion gauge, time-to-empty/full
- Pacing Engine — Physics-based target power (gravity + aero + rolling resistance + altitude-adjusted air density)
- Climb Detection — Automatic climb detection from gradient when no route is loaded
- PR Tracking — GPS-matched climb history with live time delta comparison
- Tactical Insights — Steep sections ahead, recovery zones, attack points, final kick analysis
- Alerts — W' critical, steep ahead, summit approaching, new PR — with sound and vibration
- FIT Recording — Custom developer fields: W' balance, pacing status, target power, PR delta
Data Fields
9 specialized data fields, each with 6 layout sizes:
Grade, W' Balance, Pacing Target, Climb Overview, Summit ETA, Climb Progress, Climb Profile, Next Segment, Compact Climb
Install
adb install 7climb.apk
Open 7Climb on Karoo → configure FTP and weight → add data fields to your ride profile.
Requirements
- Hammerhead Karoo 2 or Karoo 3
- Power meter
- FTP and weight configured in app settings