ruvnet / ruvnet/RuView

occupancy classification does not change across gross occupancy change (single deployment, needs second-site confirmation)

Open
#1,758 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Rust
Stars
94.4k
Forks
12.5k
Avg merge
21h 27m
Merged PRs (30d)
43

Description

Summary

On one hardware deployment, the top-level occupancy classification never changed value. Across
90 samples spanning deliberately extreme stimulus — including the operator leaving the room
entirely — presence had exactly one distinct value (true), estimated_persons was always
1, and confidence was always 0.4.

Stated limitation up front: this is one room, one server build, one node topology. It has
not been reproduced on a second installation. Filing so it can be checked elsewhere; if other
installs do not show it, something specific to this one is responsible and the issue should be
closed.

Measurements

Three ESP32-S3 nodes on v0.8.4, ~127 frames/s aggregate, with a completed empty-room baseline
active (fresh, bound, 85,731 frames, receipt issued).

Perturbation sequence, 90 samples at 1 Hz:

phase n presence persons confidence variance (median)
sit still 18 18/18 true 1 0.4 427.8
walk through node↔AP line of sight 18 18/18 true 1 0.4 468.3
wave both arms ~50 cm from a node 18 18/18 true 1 0.4 452.7
operator out of the room 18 18/18 true 1 0.4 408.0
return and sit 18 18/18 true 1 0.4 443.9
across all 90 samples:  distinct presence values   = {true}
                        distinct confidence values = [0.4]

Separate empty-vs-occupied A/B (10 samples each) — classification bit-identical. Per-feature
discrimination (AUC; 0.5 = chance):

breathing_band_power  0.38     spectral_power    0.40
dominant_freq_hz      0.53     change_points     0.53
mean_rssi             0.60     motion_band_power 0.60
variance              0.69

The DSP underneath is alive — features vary sample to sample. variance carries weak signal
(AUC 0.69). It does not reach the classification.

breathing_band_power at AUC 0.38 is below chance: it read slightly lower with a person in
the room.

Notes on interpretation

The three constant fields are not three independent results, and should not be read as
three confirmations:

  • confidence is 0.4 + signal_quality * 0.3 + motion_score * 0.3 (main.rs:2670), so 0.4 is
    its floor.
  • estimated_persons is gated behind if classification.presence (main.rs:8090).

So this is one stuck classification echoed through dependent fields.

One inconsistency worth a look independently: the emitted confidence is 0.3999999999999996
while the live signal_quality_score was 0.4928733422189253. By the expression above that
should be at least 0.4 + 0.4929*0.3 = 0.5479, so the emitted value does not appear to come
from that expression.

Environment caveats (disclosed, not dismissed)

  • The three nodes sit within roughly 1 m of one another — poor multistatic geometry.
  • Masonry/stone room with a structural pillar and metal radiators — heavy multipath.

Both would weaken spatial discrimination. Neither explains a constant: node spacing cannot
make presence unable to differ between an occupied and an empty room, and the arms-at-50 cm
phase is about the largest perturbation available in the space.

Done when

Either the classification responds to gross occupancy change on this class of deployment, or
it is established that this configuration is out of scope and the system says so rather than
emitting a confident constant.

Work items

  • Confirm or refute on a second installation — the blocking question.
  • Trace why classification.presence never leaves true when frames continue and the
    environment changes drastically.
  • Check the confidence expression against signal_quality_score (above).
  • Consider whether an undiscriminating classifier should report low confidence rather than
    a constant 0.4.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in main.rs around lines 2670 and 8090, tracing how classification.presence, estimated_persons, and confidence are produced. Check the confidence expression against signal_quality_score, then reproduce the occupancy sequence on a second installation if available. Done means the behavior responds to gross occupancy changes or the configuration is identified as out of scope and reports low confidence rather than a constant.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.