mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-06 03:00:06 +02:00
Map the Frame controllers' buttons; make gaze clicks correctable
The Frame controllers aren't input devices on the host, so the pointer helper reads them with SteamVR input (vrbuttons.h, actions/), one action set per button, and sends presses to the relay, which does the mapped action like for a mouse button. Only mapped buttons are taken, at an overlay-global priority (SteamVR's experimental "Enable global input from overlays"), and only outside games unless In games is on. Frametop Input Settings gets a Controllers page to map them. Gaze mode: a left press while the gaze has the pointer isn't sent at once. The pointer stops, you drag it onto what you meant with the button held, and the release clicks there; a press held still for POINTER_GAZE_HOLD (0.5 s) becomes a real press, for drags. The dot shows only while the mouse moves it (POINTER_GAZE_SHOW), while a press is held, and as a pulse per click. Outside games the pointer stays on while gaze mode is on. ft-gazed takes a third of each lesson's offset instead of all of it: in the first live test one 6 degree lesson moved everything and put the next target 7 degrees off. Frametop Input Settings gets a Gaze page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3070fd5776
commit
0d50efec45
13 files changed
+1426
-54
No files matched your search
+17
-5
@@ -69,6 +69,18 @@ LESSON_MAX = 8.0 # degrees past the correction
|
||||
RETRY = 3.0 # seconds before starting ft-gaze again
|
||||
|
||||
|
||||
class PointerLessons(LiveCorrection):
|
||||
"""LiveCorrection, with the offset held back: one lesson moves the whole correction by a
|
||||
third of what it measured, not all of it (two alike, half; three, three fifths). In the
|
||||
probe, clicks came thick and fast on a stale calibration, where the error was mostly one
|
||||
offset. Here lessons are few and the calibration is often fresh: in the first live test a
|
||||
6 degree lesson shifted everything 6 degrees, and the next target, 10 degrees away and
|
||||
1.4 off before, was 7.1 off (3.6 with this). Near the lesson, the kernel still takes up
|
||||
most of it (5.1 of the 6 degrees)."""
|
||||
|
||||
RIDGE = [2.0] + LiveCorrection.RIDGE[1:]
|
||||
|
||||
|
||||
def log(msg):
|
||||
print(f"ft-gazed: {msg}", file=sys.stderr, flush=True)
|
||||
|
||||
@@ -80,7 +92,7 @@ class Service:
|
||||
self.base = Correction()
|
||||
self.mode = DEFAULT_MODEL
|
||||
self.cal_mtime = None
|
||||
self.live = LiveCorrection()
|
||||
self.live = PointerLessons()
|
||||
self.dirty = False
|
||||
self.load_calibration()
|
||||
self.load_lessons()
|
||||
@@ -91,7 +103,7 @@ class Service:
|
||||
self.fix = Fixation(radius=1.0)
|
||||
self.opens = (deque(maxlen=90), deque(maxlen=90)) # left, right
|
||||
self.vergence = deque(maxlen=90)
|
||||
self.counts = {"samples": 0, "sent": 0, "blinks": 0, "one_eye": 0, "dropped": 0, "lessons": 0, "refused": 0}
|
||||
self.counts = {"samples": 0, "sent": 0, "blinks": 0, "one_eye": 0, "dropped": 0, "lessons_taken": 0, "refused": 0}
|
||||
self.last_sample = 0.0
|
||||
self.last = None
|
||||
|
||||
@@ -124,7 +136,7 @@ class Service:
|
||||
try:
|
||||
d = json.loads(LESSONS.read_text())
|
||||
if d.get("source") == self.source:
|
||||
self.live.samples = d.get("samples", [])[-LiveCorrection.KEEP:]
|
||||
self.live.samples = d.get("samples", [])[-PointerLessons.KEEP:]
|
||||
except (OSError, ValueError):
|
||||
pass
|
||||
log(f"{len(self.live.samples)} lessons")
|
||||
@@ -152,7 +164,7 @@ class Service:
|
||||
else:
|
||||
self.live.add({"time": rec["time"], "hy": rhy, "hp": rhp, "dy": dy, "dp": dp, "wy": 1.0, "wp": 1.0,
|
||||
"how": "pointer"}, self.base, self.mode)
|
||||
self.counts["lessons"] += 1
|
||||
self.counts["lessons_taken"] += 1
|
||||
self.dirty = True
|
||||
try:
|
||||
with open(LESSON_LOG, "a") as f:
|
||||
@@ -293,7 +305,7 @@ class Service:
|
||||
elif words[:1] == ["status"]:
|
||||
reply = json.dumps(self.status())
|
||||
elif words[:1] == ["forget"]:
|
||||
self.live = LiveCorrection()
|
||||
self.live = PointerLessons()
|
||||
self.live.wear_time = self.steam.worn()
|
||||
self.save_lessons()
|
||||
reply = "ok"
|
||||
|
||||
Reference in new issue
Block a user