v1.3.2: Fix HR variation jumping instead of smooth transitions

Remove hard clamp that instantly snapped HR to ±3 of target, causing
jumps when target changed. Now uses rate-limited transitions (1 BPM
per tick at 0.5s intervals) for smooth ramping.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-19 17:28:24 -05:00
parent 0d34cae441
commit 0a48a2928e

View File

@@ -113,14 +113,16 @@ class HRVariationManager:
# Calculate ideal HR # Calculate ideal HR
ideal_hr = state.target + sine_variation + random_walk ideal_hr = state.target + sine_variation + random_walk
# Smooth transition (30% toward ideal each tick) # Smooth transition toward ideal
state.float_hr += (ideal_hr - state.float_hr) * 0.3 # Use rate-limited step when far from target for smooth ramp
distance = abs(ideal_hr - state.float_hr)
# Clamp to ±3 of target if distance > 3:
state.float_hr = max( # Far from target: move max 1 BPM per tick (2 BPM/sec at 0.5s ticks)
state.target - 3, step = 1.0 if ideal_hr > state.float_hr else -1.0
min(state.target + 3, state.float_hr) state.float_hr += step
) else:
# Close to target: use proportional smoothing
state.float_hr += (ideal_hr - state.float_hr) * 0.2
# Round for transmission # Round for transmission
current_hr = round(max(30, min(220, state.float_hr))) current_hr = round(max(30, min(220, state.float_hr)))
@@ -130,7 +132,7 @@ class HRVariationManager:
last_sent = current_hr last_sent = current_hr
await self._send_hr(device_id, current_hr) await self._send_hr(device_id, current_hr)
await asyncio.sleep(1) await asyncio.sleep(0.5)
except asyncio.CancelledError: except asyncio.CancelledError:
pass pass