From 5ca4160a7e1edca6ada8470bf78965e83c4a12ea Mon Sep 17 00:00:00 2001 From: DeeJanuz <45082401+DeeJanuz@users.noreply.github.com> Date: Wed, 30 Sep 2026 15:07:58 -0600 Subject: [PATCH] Hands: fixes from the second headset test (pinches) - The palm-down filter is off by default: the user's deliberate pinches, hand raised, read 0.90-0.99, like typing. - Typing is told apart by the keyboard instead: the input relay sends the pointer helper "typing" on key presses, and it takes no pinch within POINTER_PINCH_TYPING (1 s) of one. - Grips are still held to hands raised (POINTER_GRIP_BELOW, 0.35 m below the eyes); pinches aren't, since the user's own sat 0.35-0.45 m below, elbow resting. - A grip doesn't begin with the thumb on the index tip: that's a pinch with the other fingers curled, which was taken for a grip. - A pinch's point is the index and middle knuckles: the tips' midpoint moved 1-2 cm as the pinch opened, dragging every release off its press. - ft-hands --gesture-log prints what the detectors measure, 10 times a second. Pinches still aren't reliable enough to use; hand tracking is parked for now in favour of the controllers. Co-Authored-By: Claude Opus 5.5 --- hands/include/fh_gestures.h | 7 ++++--- hands/track/main.cpp | 14 ++++++++++++-- hands/track/pinch.cpp | 23 +++++++++++++++-------- hands/track/pinch.h | 9 ++++++++- input/input-relay.py | 6 ++++++ pointer/helper/ft-pointer.cpp | 33 +++++++++++++++++++++++---------- session/frametop.conf.example | 3 ++- 7 files changed, 70 insertions(+), 25 deletions(-) diff --git a/hands/include/fh_gestures.h b/hands/include/fh_gestures.h index 5a843fa..445e1ce 100644 --- a/hands/include/fh_gestures.h +++ b/hands/include/fh_gestures.h @@ -10,7 +10,8 @@ * One slot per side and gesture: pinch[0] and grip[0] are the left hand, [1] the right. * A gesture follows the hand it began on until it ends. * Pinch: begins when the thumb and index tips close within begin_m and ends when they - * open past end_m (the gap between keeps it from flickering). point is between the tips. + * open past end_m (the gap between keeps it from flickering). point is the index and middle + * knuckles, which don't move as the fingers open and close (the tips' midpoint did). * Grip: a closed hand. It begins when all four fingers are curled in (each fingertip * nearer the wrist than grip_begin times its knuckle is) and ends when they open past * grip_end on average. distance is that average (about 2 open, under 1.2 closed), strength @@ -55,8 +56,8 @@ typedef struct { float distance; /* pinch: thumb tip to index tip, m, at this user's */ /* hand size. grip: the fingers' mean curl (above) */ float strength; /* 0 open .. 1 closed */ - float point[3]; /* pinch: between the thumb and index tips; grip: */ - /* the palm's centre */ + float point[3]; /* pinch: the index and middle knuckles; grip: the */ + /* palm's centre */ float begin_point[3]; /* point when the current or last one began */ } fh_pinch_t; /* 64 bytes */ diff --git a/hands/track/main.cpp b/hands/track/main.cpp index 40aedf0..af8a029 100644 --- a/hands/track/main.cpp +++ b/hands/track/main.cpp @@ -177,6 +177,7 @@ int main(int argc, char **argv) { double keep_presence = 0.5; // landmark presence a tracked view needs to stay PinchParams pinch_params; GripParams grip_params; + bool gesture_log = false; // what the pinch and grip detectors measure, 10 times a second double record_for = 120; for (int i = 1; i < argc; ++i) { const std::string a = argv[i]; @@ -194,6 +195,7 @@ int main(int argc, char **argv) { else if (a == "--pinch-palm-down" && more) pinch_params.palm_down_max = std::atof(argv[++i]); else if (a == "--grip-begin" && more) grip_params.begin = std::atof(argv[++i]); else if (a == "--grip-end" && more) grip_params.end = std::atof(argv[++i]); + else if (a == "--gesture-log") gesture_log = true; else if (a == "--swap-sides") swap_sides = true; else if (a == "--record-only") track = publish = false; else if (a == "--ring" && more) ring_path = argv[++i]; @@ -220,7 +222,7 @@ int main(int argc, char **argv) { " [--cams auto|mono|color|all] (auto) [--bright all|color] (all) [--bright-on L] (40) [--bright-off L] (25)\n" " [--color-left color_video0|color_video3] [--color-crop subtract|none]\n" " [--pinch-begin M] (0.020) [--pinch-end M] (0.035) [--pinch-triangulated] [--pinch-palm-down MAX] (0.6)\n" - " [--grip-begin R] (1.2) [--grip-end R] (1.45)\n" + " [--grip-begin R] (1.2) [--grip-end R] (1.45) [--gesture-log]\n" " [--contrast MODE|PALM/HAND] (clahe[:CLIP], none, stretch; default clahe:2/none)\n" "Recording saves every frame set for S seconds (120) to DIR/sets.bin, for ft-handreplay; SIGUSR1\n" "starts one in ~/.local/share/frametop/hands/rec-