feat(deck-pose): gesture recognition and Unix socket publisher (phase 2) #907
Closed
lytedev
wants to merge 3 commits from
deck-pose-events into deck-pose
pull from: deck-pose-events
merge into: lytedev:deck-pose
lytedev:main
lytedev:propose/module-directory-scanner
lytedev:propose/special-args-cleanup
lytedev:propose/limine-fallback
lytedev:propose/household-kiosk
lytedev:propose/xwayland-ei-display-from-client
lytedev:propose/steamdeck-mouse-steps-aside-for-games
lytedev:propose/assistant-watch
lytedev:propose/lpcamm-watch
lytedev:propose/agents-where-information-lives
lytedev:propose/tuwunel-1.9.2
lytedev:propose/pin-flake-registry
lytedev:propose/headscale-0-29-3
lytedev:propose/canary-freshness-per-repo
lytedev:propose/boot-guard-efivars-fix
lytedev:propose/deck-dock-panel-under-niri
lytedev:propose/admindevice-ssh-anything
lytedev:propose/kdeconnect-announce
lytedev:steamdeck-mgba
lytedev:propose/doorbell-no-internet
lytedev:propose/ha-list-tasks
lytedev:propose/ha-music-not-found
lytedev:propose/bc250-40cu-measured
lytedev:propose/multiboot-foxtrot-dragon
lytedev:propose/pitft-stmpe-drive
lytedev:propose/foxtrot-multiboot-prep
lytedev:propose/pitft-no-smartd
lytedev:propose/kexec-luks-reboot
lytedev:propose/foxtrot-multiboot
lytedev:propose/model-eval
lytedev:propose/foxtrot-vm-seats
lytedev:iamb-sender
lytedev:propose/calendar-alarms
lytedev:pinephone-niri
lytedev:push-tsntxvxynzps
lytedev:propose/spoof-reject-cleanups
lytedev:propose/finance-pipeline
lytedev:steamframe-plan
lytedev:pinephone-buildable
lytedev:deck-pose-wip
lytedev:aerc-open-html
lytedev:local-auth-unification
lytedev:iamb-dotfiles
lytedev:esphome-music-panel
lytedev:wifi-system-profile
lytedev:gauge-history
lytedev:validate-gate-fix2
lytedev:validate-slot-no-hugepages
lytedev:pinephone-reenable
lytedev:cyberdeck-research
lytedev:git-anon-ratelimit
lytedev:headscale-basedomain
lytedev:ssd-fast-tier
lytedev:hold-impermanence-flip
lytedev:gate-dummy-eval
lytedev:zen-browser
lytedev:initrd-remote-unlock
lytedev:beefcake-rpool-backup
lytedev:sec-sso-plan
lytedev:sec-mail
lytedev:flab-lid-wake
lytedev:hearth-k8s
lytedev:zulip
lytedev:router-guest-vlan
lytedev:headscale-extra-records
lytedev:beefcake-advertise-lan
lytedev:push-qrvuuqmxtznv
lytedev:voxtype-per-host-model
lytedev:cleanup
lytedev:push-kanidm-opt-in
lytedev:push-voxtype-flake-fix
lytedev:push-uvqqknxvqlvy
lytedev:push-qrqsxkmlrevert
lytedev:fix-kanidm-uid-attr-map
lytedev:nix-on-droid
lytedev:self-hosted-dns
lytedev:fix-runner-tmpfs-revert
lytedev:beefcake-email
lytedev:beefcake-immich
lytedev:firefox-nightly-devedition
lytedev:fix-bun-baseline
lytedev:flab-stuff
lytedev:printer-sftp
lytedev:dragon-vr-monado
lytedev:clever-vr-game-clamshell-mode-detection
lytedev:wireguard-mesh
lytedev:rescue-beefcake-unpushed-nix
No reviewers
Labels
No labels
bug
enhancement
question
scary
upstream
Milestone
Clear milestone
No items
No milestone
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
lytedev/nix!907
Loading…
Reference in a new issue
No description provided.
Delete branch "deck-pose-events"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 2 of deck-pose: the event/gesture layer and the publishing API.
Stacked on #906 — base is
deck-pose, notmain, because this builds directly on the phase-1 daemon and the events.rs seam it defined. Review/merge #906 first.Nothing is deployed and nothing is enabled. Publishing is off unless explicitly asked for.
Recognisers (
recognise.rs)jump,squat,punch,swipe,dwell, plusplayer_joined/player_left. Three properties matter more than the individual thresholds:Velocities are per-second from frame timestamps, not per-frame deltas, so no threshold silently changes meaning when the frame rate does.
Swipecarries a unit direction vector, speed, and the wrist position at recognition time — a slice game has to hit-test the path, and by the time the event arrives the hand has moved on.One deliberate deviation from the spec, flagged
Dwellcarries a position rather than theregion: u32the phase-1 sketch imagined. Regions are a game's notion of its own UI; the daemon cannot know them without being configured with each game's layout, so hit-testing belongs on the game's side of the socket. Say the word if you want the region form back and I'll add a configurable region table.Publisher (
publish.rs)Newline-delimited JSON over a Unix socket. Connect, read lines, parse each as one object — no handshake, no framing beyond the newline, so anything that can read lines can be a client.
The rule the module is built around: a slow or dead client must never slow the daemon down. The publish path does no I/O. It serialises once, fans the same
Arc<str>to each client's writer thread through a bounded queue withtry_send, and moves on. A full queue drops and counts the message; a client behind for a sustained run is disconnected rather than accumulating a backlog of stale poses it could not use anyway — the same newest-wins reasoning as the capture stage.Both requested streams are there: a continuous per-frame pose message (all 17 keypoints per player, not just wrists — a few KB at six players, and a new game then needs no daemon change to use hip position) and discrete event messages. Events are stamped with their frame's capture instant, so events and poses share one clock and can be correlated.
Publishing is opt-in. A pose stream is a camera feed by another name and should not appear on a socket because someone ran the binary.
--socket,[publish] socket, orlyte.deck-pose.socketin the NixOS module.Measured on dragon, live camera + live client
PUBfield in the readoutdwellevent fired from a hand held still:{"t":"event","seq":280,"ts_ms":8740.1,"player":1,"kind":"dwell","hand":"right","x":0.52,"y":0.79,"held_ms":715.2}Checks
nix build .#deck-posesucceedscargo fmt,nix fmtcleanUntested
socathas read it; the slice game is the real test.dwellfired correctly on real motion; jump/squat/punch/swipe have unit tests over synthetic bodies but nobody has stood in front of the camera and tried to trigger them deliberately. Expect tuning.Superseded by #915, which consolidates the whole markerless-pose-input program into a single WIP branch against
main. Every commit from this PR is preserved there — nothing was squashed, so the root-cause writeups in the commit messages are intact. Closing here; review happens on #915.Pull request closed