Skip to content

Repository files navigation

English · 中文

walkpit

A walking companion for Meta Ray-Ban Display, in a fighter-jet cockpit HUD.

A web app rendered on the glasses' right-eye display: steps, distance, pace, heading, and GPS trace, laid out through fighter-HUD visual conventions. The Web Apps API only exposes IMU + GPS — no real 6DoF — so this app squeezes every useful signal out of those two channels and puts it on one frame.

ACTIVE screen during a walk

Composite for illustration — the cyan HUD is rendered into a real outdoor photo. The actual on-glasses view looks similar: a 600 × 600 panel floats in the centre of your field of view while the world stays visible around it.

Try it

Scan this QR with your Meta Ray-Ban Display's camera — the Meta AI app recognizes it as a web-app deep link and opens the app directly:

QR code that opens walkpit on Meta Ray-Ban Display

Or open walk-app-six.vercel.app in any browser — heading tape, step counter, and GPS path can all be simulated through Chrome F12 → Sensors.

The app defaults to English. Tap the small button in the bottom-right of the READY screen to switch to Chinese (the choice persists).

Features

  • 🧭 Compass-style heading tape — driven live by DeviceOrientationEvent.alpha; N / E / S / W scroll under the centre marker as the head turns
  • 👟 Head-mounted IMU step counter — peak detection on devicemotion, default threshold 11.4 m/s², 280 ms debounce
  • 🛰️ GPS distance + pathnavigator.geolocation.watchPosition + Haversine, with noise filtering (accuracy < 30 m, distance > 3 m, dt > 1 s)
  • 🗺️ North-up minimap — last ~500 GPS fixes, auto-fit bbox, amber heading cone
  • 🎯 RECENTER button — zeros displayed angles to the current pose; auto-recenter also fires on the first orientation event after START
  • 💾 Survives mid-walk reload — every state transition writes localStorage, plus a 5-second checkpoint
  • 📐 Self-calibrating stride length — after 50 steps, stepLength is recomputed from GPS distance ÷ step count
  • ⏯️ D-pad first — PAUSE / RESUME / END / NEW WALK all reachable through arrows + OK alone
  • 🌐 English + 中文 — English default, one-tap toggle, persisted

Screenshots

READY ACTIVE
READY screen ACTIVE screen

Design principles

  • Fighter-HUD layout: data in the four corners, centre kept clear, heading tape across the top — minimize what blocks the real world behind the lens
  • Single-hue cyan + amber: the glasses' display has a tight brightness budget; one strong primary, no decorative gradients
  • Zero animation, zero transition: walking + animation = distraction
  • Per-tick zero allocation: 5 Hz data loop + requestAnimationFrame motion loop, so head rotation is tracked smoothly
  • Three-screen state machine: READY / ACTIVE / SUMMARY — no modals, no nested navigation

Tech stack

  • Plain HTML + CSS + vanilla JS — no build step, no framework, zero npm dependencies
  • DeviceMotionEvent / DeviceOrientationEvent for the IMU
  • navigator.geolocation.watchPosition for GPS
  • Canvas 2D for the minimap
  • localStorage for persistence
  • Vercel static deploy

Quick start

1. Run locally

git clone https://github.com/jscmp4/walkpit.git
cd walkpit
node server.js
# → http://localhost:3000

No npm install needed — server.js only uses Node's built-in http module.

2. Desktop debug

Open Chrome F12 → Sensors panel:

  • Custom Orientation — drag the sliders to watch the heading tape react
  • Location — set a position, then nudge lat/lon a few times to draw a path on the minimap

Or open http://localhost:3000/cockpit-dev.html — drag the virtual head in the left panel to simulate orientation, and click MARCH on the right to simulate step IMU pulses without DevTools sensors.

3. Deploy to Vercel

vercel --yes --prod

vercel.json explicitly turns Node runtime off — this is a pure static project, and we don't want Vercel auto-detecting server.js as a serverless function.

4. Install on Meta Ray-Ban Display

  1. Deploy to any HTTPS static host (Vercel / Netlify / Cloudflare Pages all work)
  2. In the Meta AI mobile app, add the web app via link or QR code
  3. Put the glasses on, open it

Project structure

walkpit/
├── index.html            # Three screens: READY / ACTIVE / SUMMARY
├── styles.css            # Cockpit theme (cyan + amber + dim), all --hud-* variables
├── app.js                # State machine, step detector, GPS, HUD renderers, persistence (~750 LOC)
├── server.js             # Local static dev server (Node stdlib only)
├── vercel.json           # Explicitly disables Node auto-detection
├── package.json          # `start` script only, no dependencies
├── .vercelignore         # Keeps dev-only files out of the deploy
├── cockpit-dev.html      # Local debug harness: D-pad + MARCH + Three.js 3D head
├── CHANGELOG.md          # Reverse-chronological changelog
├── DEV_NOTES.md          # Developer cheatsheet (debug flags, sign conventions, file map)
└── docs/
    ├── screenshot-ready.png
    ├── screenshot-active.jpg
    └── _active-shot.html # Screenshot bootstrap (prefills localStorage + fake events)

State machine

        startWalk          pauseWalk
READY ────────────► ACTIVE ─────────► PAUSED
                      ▲                  │
                      └─── resumeWalk ───┘
                      │                  │
                      └── endWalk ──┐  ┌── endWalk
                                    ▼  ▼
                                  SUMMARY ──── newWalk ──→ READY

Every transition syncs to localStorage['current_walk'], plus a 5-second checkpoint. After a mid-walk reload (or a glasses restart), the app restores into ACTIVE or PAUSED automatically.

Data sources

Field Source Stored in
Steps DeviceMotionEvent peak detection (threshold 11.4, debounce 280 ms) session.steps
PDR distance steps × stepLength; after 50 steps GPS auto-calibrates stepLength session.pdrDistance
GPS distance watchPosition + Haversine (acc < 30 m, d > 3 m, dt > 1 s) session.gpsDistance
GPS path watchPosition fixes, capped at 500 points session.gpsPath
Heading DeviceOrientationEvent.alpha hudOrient.alpha (not persisted)
Pose ref First orientation event on ACTIVE / manual RECENTER session.alphaRef (persisted)

Debug flags

Set in DevTools Console on a desktop browser (the glasses don't expose one easily):

localStorage.show_debug = '1'            // show mag / peak / gps_pdr / αR / αA
localStorage.step_threshold = '11.4'     // step-detector sensitivity (default 11.4)
localStorage.lang = 'zh'                 // force Chinese UI
localStorage.removeItem('current_walk')  // wipe the persisted mid-walk session

αR is alpha from the relative deviceorientation event; αA is alpha from deviceorientationabsolute — used to probe whether the glasses expose absolute (magnetometer-referenced) heading. Many browsers only deliver the relative form.

Known limitations

  • Not real 6DoF: the Meta Web Apps API only delivers IMU + GPS — no visual SLAM. This is a pose-aligned instrument panel, not a world-locked AR overlay.
  • alpha is not necessarily true north: in many browsers deviceorientation reports alpha relative to whatever direction the page loaded in. To compensate, the app auto-recenters to the user's current pose when entering ACTIVE. Binding to true north would require deviceorientationabsolute (still being probed on the glasses — see the αA debug row).
  • GPS heading is noisy at low speeds: under ~1.5 m/s, the GPS bearing jitters. IMU heading is preferred while moving slowly.
  • No on-glasses console: changing a debug flag means re-deploy.

License

MIT

About

Walking companion for Meta Ray-Ban Display, fighter-jet cockpit HUD style.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages