er-robot-v0 · field log · 14 jul – 4 aug 2026

Three weeks ago this was a voice pipeline on a bench.
Now it maps, navigates, recovers, refuses — and publishes its own mistakes.

The milestone media: real mission data, the robot's own footage, and the diagrams behind the results. Everything below is measured, not staged.

120/120
mission steps verified by scan-match odometry (no wheel encoders exist)
178 mm
first hardware GOTO arrival error, 2.2 m out (Aug 2)
284 mm
arrival in a room it started with NO map of, 5 m of driving (Aug 4)
12→92%
sim goal-reach after splitting routing (deterministic) from control (learned)
448 mm
where the sentinel stopped for an approaching person, first live trial
0→24
audio clips per mission after today's two-bug fix — the first real sound in the dataset
jul 31 — the bug of the project

The lidar was mirrored, and a second sign error was covering for it

Every consumer assumed the ring counted counter-clockwise; the firmware delivered clockwise. The turn verifier “worked” for weeks because its own sign error cancelled the mirror. Only two instruments cross-checked against each other caught it. After the fix, two independent rotation estimators agreed on hardware to 0.1° — and the robot's odometry became trustworthy enough to verify every single mission step.

Top-down room map: wall points in grey, robot trajectory in orange, start and end marked
This morning's mapping mission, rendered from the raw log. Grey: lidar wall returns from 78 stops. Orange: the driven path (green ring = start, red = end). Every stop's pose was verified by re-aligning consecutive scans — measured motion, not assumed motion.
aug 2–3 — miss, measure, fix, catch

A person crossed the robot's path. The guard missed — so the miss became a fixture

The forward sentinel stopped an approaching person at 448 mm on its first live trial. A crossing person is different geometry — low closing rate, outside the forward watch — and the recorded miss was rebuilt into a 360° transient detector the same afternoon. The repeat test was caught twice (580 and 628 mm); the robot now waits for people instead of mapping them.

Polar plot of two consecutive lidar scans with the person's transient signature circled
The actual recorded signature, from the regression fixture. Two consecutive scans overlaid; the red circle is the narrow sharp range-drop with stable flanks — a person at half a metre — that the detector now fires on. Green arrow = robot's heading.
aug 3–4 — the camera earns a job (and a retraction)

The hunt: stalk, declare, be wrong, rebuild, refuse

Asked to find a yellow package dropped somewhere in the clutter, the robot swept, sighted a dozen-pixel smudge at two metres, and stalked it through eight occlusion losses to under half a metre. Then it declared FOUND — on the wrong object. The close-range confirm had been a leading question, and the model agreed with it. The arbiter is now non-leading (“name what you see”), a sighting is a hypothesis to investigate closely, and the re-run hunt ended “not found” rather than repeat the lie.

The robot's own eye, 3× speed : the closing minute of the first stalk, threading chair legs toward the thing it believed in. It was wrong, and the footage is published anyway — the competence and the mistake are the same drive. (Also on the public model card.)
Robot camera frame with burned-in caption 'approaching' and a yellow detection box on the wrong object
The frame that fooled us — caption and box burned in live. The stream now narrates what the robot thinks it sees (a new /clean endpoint feeds detectors and the dataset, so no machine ever reads its own captions). The boxed yellow sliver is not the package. The operator's overrule became the non-leading arbiter.
A blurry robot camera frame of the office showing the soft lens
Why color is the only signal: the lens itself. Full focus sweep maxes at sharpness 9–16 where decent glass reads 200+ — a hardware verdict, not a software one. Defocus destroys texture and edges but preserves color, so the finder hunts color blobs at range and brings in the vision-language model only when the quarry subtends real pixels (its acuity floor is measured too: a 20-px package gets an honest “no”).
the thesis, sim → hardware

Know which layer owns which job

The simulation series proved a ~4B vision-language model is a superb local controller and a hopeless global router: goal-reach went 12% → 40% (hand it reachable subgoals from a layer that owns the map) → 85% (train it to that interface) → 92% with no prior map at all, built while driving. The hardware platform is that prescription made physical — deterministic layers below, learned controller (still undeployed) above.

flowchart TB
  D["deterministic layers\nown the map, routing, sensing, pose"] --> A["chassis\nself-calibrated actuator model"]
  V["learned controller (sim: 92%)\nNOT deployed to hardware"] -.->|"future"| D
  style V stroke-dasharray: 5 5

Sim media lives on the public card: closed-loop maze runs, including the no-prior-map run where the map draws itself under the robot — ubr-physical-ai/UBR-Nav-E4B (hero GIF and the 92%-row animation, plus every number above with its failure history).

aug 4 — the hunt ends

Found: the yellow mailer, frame-verified

The package hunt that produced the retraction ended the same day, the right way: with every lesson active at once — coverage memory, the calibration-free anomaly eye, the non-leading naming arbiter with a required color word, no-go memory for rejected spots, target commitment — the robot swept, rejected four more candidates by name (including, at one point, its own chassis), crossed the room, and stopped here. The model's close-range verdict: “Yellow rectangular bag.” A human checked the frame. It is the package.

Robot camera frame: a yellow padded mailer on the floor beside a chair base, at touching distance
The moment of the verified FOUND, from the robot's own camera. Yellow padded mailer, on the floor, touching distance — after six hunts whose failures each bought one of the fixes that made the seventh honest.
aug 4 — 51° and back

The tilt climb, halted and self-rescued

Mid-mission the robot climbed an obstacle it couldn't see. The firmware's rollover reflex halted the tracks at 51°; the brain then walked it back down in reverse pulses until the horizon was level, verified it was stable before trusting its own pose again, marked the climb on the map, and replanned around it. Nobody touched it.

The robot's own camera, 2× speed : the horizon keels over on the way up, the tracks halt at 51°, and the reverse-pulse rescue brings the world level again. Cut from the blackbox by the tilt alert's timestamp in the robot's event log.
the rest of the ledger

Also earned these weeks

A 53° tilt climb ended in self-rescue and an operator-designed stabilization doctrine. A sealed-route refusal became an escape through a gap the raw scan could still see. The stair-leg collision (invisible to every sensor) bought a progress watchdog that has since caught an unseen obstacle mid-mission. The wall-follower's stability went from folklore to a derivation to an executable test. Battery envelope: 4.78 W idle, 10.88 W under full LLM load — about 3 h of heavy autonomy per pack. And the dataset finally has ears: two silent bugs (a renumbered ALSA card and arecord rejecting fractional seconds) meant every “audio” campaign to date had recorded zero clips — fixed and field-verified today, 24/24.