← Streetlight back to all nodes
← back to robot-framework

πŸ“± phone-head β€” the Pixel taped to Dash's head is a sensor pod

This is the one Jake wanted. A Pixel zip-tied to the robot's head, streaming its rear camera + every browser-reachable sensor over wifi to the Mac, so Claude runs the OODA loop from a first-person view with a real compass. Built same-night from Jake's 6/11 voice memo. Source of truth: phone-head/server.mjs + phone-head/README.md + phone-head/CLAUDE-LOOP.md.

What it does (sensors UP β€” the opposite of the Android remote)

Jake's 6/11 brief: "make an android app that uses all sensors android has … assume I'm gonna tape the phone to the head of the robot and do similar kinds of ooda exploration. phone needs to talk to local computer over wifi, needs to be wireless. claude is in control of ooda."

πŸ“± on πŸ€– headcam Β· IMU Β· compass Β· mic… πŸ’» :8788 uplink/state Β· /frame.jpg 🧠 claudepredict β†’ act β†’ check wifi WS curl ACT: POST :5174/command β†’ robot (with phone) moves β†’ observe again
Why it matters: the first-person camera + an absolute compass give the rig its first ground-truth turn measurement β€” snapshot heading before a turn, again after, instead of photo-guessing the angle from the old top-down webcam.

The phone page (rendered from phone.html β€” not a screen-grab)

No real screenshot exists in the repo. The mockup below is drawn faithfully from phone-head/phone.html β€” the single page the Pixel opens in Chrome. To replace it with a real photo, run the server and grab a frame on the phone (see "How to run it").

STREAMING Β· 8788BATT 78%
phone-head
Rear cam + sensors β†’ Mac over wifi.
Camera (rear, ~1.4 fps)
first-person frame.jpg
Live sensors (5 Hz)
compass213Β° accel xyz0.02 0.01 9.79 gyroβˆ’0.4 0.1 0.0 light142 lux mic rms0.06
START STREAMING

Open https://<mac-ip>:8788/ in Chrome β†’ allow camera+mic+location β†’ tap START. Wake-lock keeps the screen on.

What it is

the buildNot a native app (yet) β€” a single web page served from the Mac over LAN, opened in Chrome on the Pixel. Zero install, zero npm deps, wireless, works tonight. HTTPS is mandatory (Chrome gates camera/mic/motion/geo behind secure contexts); the server auto-generates a self-signed cert into certs/ on first run. The WebSocket server is hand-rolled RFC 6455 inside server.mjs.
sensesRear camera (getUserMedia β†’ canvas β†’ JPEG ~1.4 fps) + 5 Hz packets: accel/gyro (DeviceMotion), absolute compass (DeviceOrientation), magnetometer, ambient light (or camera mean-luma fallback), mic RMS level, geolocation, battery. state.caps reports which sensors actually came alive on this phone.
claude's loopOBSERVE curl /state + /frame.jpg (check stateAgeMs/frameAgeMs < 3000 first) β†’ ORIENT (fuse compass + IMU + frame) β†’ DECIDE one verb + a written prediction β†’ ACT POST :5174/command β†’ check. Full contract: phone-head/CLAUDE-LOOP.md.
HTTP surfaceGET / phone page Β· /watch Mac dashboard Β· /health Β· /state Β· /frame.jpg Β· /history?n=50 (ring buffer, ~2 min @ 5 Hz β€” "did it shake when it hit the wall?") Β· WS /uplink (phone β†’ server).
how to run itnode phone-head/server.mjs on the Mac (prints https://<mac-lan-ip>:8788/) β†’ Pixel on same wifi opens that URL in Chrome β†’ Advanced β†’ Proceed (self-signed) β†’ tape to Dash's head, camera out β†’ START STREAMING. Smoke-tested end-to-end with phone-head/test-uplink.mjs (fake phone over WS).
limitsPixels have no lidar; rear ToF/depth + barometer are NOT browser-reachable. Tab throttles when backgrounded, screen must stay on, mic is RMS level not raw audio. Those are native-path items.

Native-Android upgrade path (when the browser ceiling is hit)

β‘  Termux + termux-api (~1 hr)pkg install termux-api β†’ termux-sensor -a dumps EVERY hardware sensor as JSON (barometer, proximity, step counter, raw uncalibrated IMU). Pipe to curl/websocat. No app build.
β‘‘ eject the Expo app (~1 evening)expo prebuild the existing ../android/ app, add react-native-sensors + react-native-vision-camera. One codebase, both directions (sensors up, commands down).
β‘’ bare Kotlin serviceSensorManager (all ~25 sensor types incl. TYPE_PRESSURE, TYPE_PROXIMITY), Camera2/CameraX with DEPTH16 ToF where hardware exists, AudioRecord raw PCM, runs screen-off, survives Doze. The "phone is permanently the robot's head" build.
Direction note: phone-head is sensors UP (Pixel β†’ Mac β†’ claude). The sibling Android.html ("Dash Remote") is the opposite β€” commands DOWN (phone β†’ laptop β†’ robot). Different jobs, same robot.