← Streetlight back to all nodes
node · 2026-05-13 project

robot-framework · letters on butcher paper

Working node: where the project IS right now. The public trailer lives at robot-draws. The long historical page is archived in versions/.

Why it exists (Jake, 6/10 memo): "make the loop big enough that you can see it" — an OODA loop blown up in space + time, like the walk-around computers in 80s documentaries. Future knobs: tighter/looser loop · more per action · most efficient observe.

Also from the 6/10 12:28 memo: "the robot can make a documenting page for itself" · battery life is a lesson to measure, not a blocker · "the real constraint is… the marker is always making a mark" (→ pen-lift).

Lived verdict (6/10 4:13 PM memo, from the cabin): "I'm doing the thing that's been on the [docket] for like 10 years… Doing the robot thing. And it's working." · "It's working."

📷 /snapshotwebcam JPEG 👁 vision modelpicks ONE verb POST /commandfwd / turn / stop 🤖 ink look again — every move costs one photo, not video

Phase: ① CALIBRATE (butcher paper is a NEW surface — whiteboard constants don't transfer)



go-time protocolJake places the laptop and walks away. Agent runs letters/04-session-protocol.md end-to-end: connect → baseline snapshot → start recorder → probe moves → log. Jake sees the green camera light as the heartbeat.
known-good stroketurn_right 360 → clean ~25cm circle (whiteboard truth; re-verify on paper).
known trapPartial turns (90°/180°) are open-loop timed and drift. NOT a left/right bug — that one is fixed. Precision unlock: wire move(0x23) into /command.
vision modelSetup driven by Fable (this). Loop runs google/gemini-2.5-flash via OpenRouter (key: ~/Documents/pi-mono/.env). Cheap swap candidates: gemini-2.5-flash-lite, claude-haiku-4-5.
New-surface hazards: off-paper is now bare wood floor (marker ink on wood!). Blue-tape edges may snag the caster. Paper corridor is WIDE and SHORT in frame — vertical headroom is small. Books prop the laptop at frame-bottom: keep Dash away from the bottom edge.
The old left/right turn bug is FIXED. Original harness hard-coded positive degrees both ways; current dash_ble.py:214-232 takes signed degrees, server.py negates for turn_left. Solving it on camera = blog beat (see robot-draws).

NEW (6/11): phone-head — the Pixel taped to Dash's head is a sensor pod

📱 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
whatJake's 6/11 memo built same night: node phone-head/server.mjs on the Mac, Pixel opens the printed https URL in Chrome, taps START. Zero install, zero npm deps — web build now, native app is the documented upgrade (phone-head/README.md).
sensesRear camera ~1.4 fps + 5 Hz packets: accel/gyro, absolute compass (first ground-truth turn measurement!), magnetometer, light, mic level, geo, battery. No lidar on Pixels; ToF/barometer need the native path.
claude's loopObserve curl /state + /frame.jpg → predict → one verb to :5174/command → check. Contract: phone-head/CLAUDE-LOOP.md. Smoke-tested end-to-end with a fake-phone WS client.

Roadmap

① calibrate✅ FIRST RUN DONE 2026-06-10: the O is on paper (closed 26cm circle ×2, deg/s=43 holds). Stroke vocabulary verified — see letters/01-stroke-vocabulary.md. Next unlock: wire move(0x23).
② letters← NOW (gated): O + C achievable open-loop; everything else needs closed-loop move(0x23) wired into /command.
③ THE FONTAC (2026-06-10): all 26+ letters → photos → SVG → installable .ttf "Dash Sans". Enablers: head-servo pen-lift (letters/05-pen-lift.md) + move(0x23). See letters/06-font-pipeline.md.
④ simulator✅ CALIBRATED 2026-06-11: letter-sim.html v2 (real-run defaults) + headless sim-runs/run-sim.mjs — 50 seeded runs, 8/9 channels faithful (fidelity section below). Web deploy still open.
⑤ idea (6/10 memo)Post-calibration deterministic executor: lines → deterministic program, no LLM per stroke — "more happens in the action" — with a preview step (draw → see picture → execute). Seeds in robot-framework.md.

📸 Highlights — the knockdown reel

Real footage from the repo. The headline event: 2026-06-10 late night, "knock the blue tape off the shoebox" — Dash drove THROUGH the box at speed 400, 3 strokes, zero turns, box shoved off the paper's edge. Now on its own page (per Jake's 6/13 ask).

Open Highlights.html — the ram timelapse video, the knockdown frame-by-frame (①–⑤), rounds 3–6, and the fun drawing images. All real committed media.

One open ask: Jake wanted "a quick video of us really knocking down the robot" — that exact clip does NOT exist in the repo (the knockdown was captured as stills; the only ram-at-speed video is the head-pen timelapse). Tracked as a PROPOSAL on Highlights.html, blocked on Jake's footage. No media fabricated.

📱 The Android app — Dash Remote

Yes, it got made. It's "Dash Remote", an Expo / React-Native phone remote that drives Dash via the laptop control server at :5174 over LAN. Source: android/App.tsx + android/README.md. Per Jake's 6/13 ask, it now lives on its own page.

Open Android.html — the two screens (faithful render from App.tsx, no real screenshot exists yet), full API contract, how to run it, and v1 limits.

what it isThin phone-side remote. The phone never BLE-talks to Dash directly — Dash allows one BLE peer at a time, and that's the laptop. The app drives over HTTP. Expo managed workflow (ships in hours; bare-native is one expo prebuild away).
two screensServer picker (URL + Connect, AsyncStorage) → Control screen (drive pad, head-tilt cross, Say, status pill + battery, Pair/Drop Dash; polls /health every 2s).
full detailAndroid.html. Sibling: phone-head/ is the opposite direction (sensors UP, not commands DOWN).

📱 phone-head — the Pixel taped to Dash's head

This is the one Jake wanted. A Pixel zip-tied to Dash's head streams its rear camera + every browser-reachable sensor over wifi to the Mac, so Claude runs OODA from a first-person view with a real compass. Built same-night from the 6/11 memo. Now on its own page (per Jake's "make html and make it appear in header like this one").

Open PhoneHead.html — the sensor-pod page: the wifi uplink diagram, the phone-page render, the full sensor table + HTTP surface, how to run it, and the native-Android upgrade path. All real, built from phone-head/.

directionsensors UP (Pixel → Mac → claude). The opposite of Android.html "Dash Remote," which is commands DOWN (phone → laptop → robot). Different jobs, same robot.
the buildZero-install web page served from the Mac (node phone-head/server.mjs:8788), Pixel opens it in Chrome, taps START. Camera ~1.4 fps + 5 Hz packets: accel/gyro, absolute compass, mic, light, geo, battery.
full detailPhoneHead.html. Loop contract: phone-head/CLAUDE-LOOP.md.
▤ html in this noderobot-framework.html (this page) · ooda-speed.html (loop-speed investigation, absorbed 2026-06-11) · letter-sim.html (calibrated simulator v2)
new (6/13): Highlights.html (real knockdown footage + the open knockdown-video proposal) · Android.html (Dash Remote — render from App.tsx) · PhoneHead.html (the phone-as-sensor-pod, sensors up) — all split out to their own pages.