You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
vital_signs.rs: linear stats on wrapped (atan2) phase values #593
process_frame in vital_signs.rs uses arithmetic mean + arithmetic variance on phase values, but the phases come from q_val.atan2(i_val) (csi.rs:90, main.rs:855) so they're wrapped to (-pi, pi]. When two subcarriers happen to land on opposite sides of the wrap (e.g. 3.14 and -3.14, physically ~0.003 rad apart), the linear formula treats them as ~2*pi apart and you get a variance of ~pi^2 instead of ~1e-6. That value goes straight into the heart-rate FFT buffer.
Repro on a fresh clone:
git clone --depth 1 https://github.com/ruvnet/RuView.git &&cd RuView
sed -n '142,148p' v2/crates/wifi-densepose-sensing-server/src/vital_signs.rs
python3 -c "import mathphases = [math.pi - 0.001, -math.pi + 0.001]m = sum(phases) / 2print('linear: ', sum((p - m) ** 2 for p in phases) / 2)s = sum(math.sin(p) for p in phases); c = sum(math.cos(p) for p in phases)print('circular:', 1 - (s * s + c * c) ** 0.5 / 2)"
You'll see linear: 9.86... vs circular: 5e-07 on the same input.
Probably the cause of the very jumpy vitals reported in #519, and the +/-15 bpm jitter mentioned in #485's description. #485 routes around the buggy detector with an external pipeline but keeps VitalSignDetector as the low-confidence fallback, so the math is still live in that path.
Fix is the standard circular variance (1 - R, mean resultant length). PR coming.
Activity
fix(vital_signs): use circular variance for wrapped phases (#595)
chore(ci): add fix-markers for recent merges (#559, #561, #588, #593, #…
fix(vital_signs): use circular variance for wrapped phases (ruvnet#595)
chore(ci): add fix-markers for recent merges (ruvnet#559, ruvnet#561, r…