vdg · 8 August 2026

The robot drives back to things it remembers.

Last month our ground robot learned to find things it had never seen. This week it learned to remember them — and to use the memory.

The loop, end to end. Every time a mission stops to judge an object — is this the bin I’m looking for? — the robot now writes down two things: what its vision model called the object, in its own words, and where the object stood, ranged by sonar. No labels, no annotation pass. Eighteen hours of ordinary missions produced a map of 60 named places: a drone near the centre, three exercise machines, a fire extinguisher, two pianos, a whiteboard with diagrams, a wooden ladder.

Then we tested the part that matters. We picked the robot up mid-day and set it down somewhere else, facing a direction of our choosing. It turned a slow circle, named what it saw, and matched those names against its own map. Names are ambiguous — “office chair” matches four chairs — but wrong matches cannot agree about geometry, so they are simply outvoted: 15 landmark votes fixed its position and heading.

Then one command: go back to the drone. The phrase matched the remembered place “Drone, near the center.”, the target came out of its self-computed pose, and it drove 2.7 m, stopping within 350 mm of its own computed goal — and turned to face it. We phrase that carefully: we did not tape-measure the final distance to the physical drone. The number we can defend is the number we publish.

To be precise about what this is: the navigation here is the deployed brain composing skills it already had — language-matched memory, self-computed pose, clamped drive commands. It is not the simulation-trained navigation planner from our Codefest note; that adapter remains undeployed.

Six missions to find one drone. The drone took six attempts, and we are keeping all six on the record, because each failure paid for something permanent.

Mission one climbed a floor obstacle and beached itself at 78.8° — the first real firing of the rollover reflex, which cut the tracks exactly as specified and left the robot waiting safely for a human hand. Mission two reached the drone and refused it: at point-blank range a 12 cm-high camera sees only the camera gimbal, and the judge correctly ruled “camera equipment” is not an aircraft. Mission three refused it again as a “blue and white robot” — a fair description of a blue-armed quadcopter, and we only know it was the drone because every judgement keeps its frame on disk. Missions four and five lost elections to bigger furniture, which produced a new behaviour: after any rejection, the robot takes one more look before leaving, in case the real target was standing next to the impostor. It had been — twice.

What finally worked was not a smarter model. It was a better sentence. We added the drone’s field appearance to the mission description itself — “up close it can look like a small blue-armed robot or a blue camera-and-sensor assembly on thin legs” — benched it against every recorded confusable (6/6), and launched. First look, two minutes, parked at 825 mm.

Three prompt rewrites had failed to fix by cleverness what one honest description fixed by information. We expect to reuse that lesson more than any code we wrote this week.

Measured, not guessed. Three number stories from the same 48 hours, in the spirit of checking our own first answers.

The context window was pure cost. We had raised the language model’s context to 8192 tokens on the theory that more is better. Measuring every request the robot actually makes gave a ceiling of 688 tokens — an image is a fixed 256 — against a window that was causing 14 GPU out-of-memory crashes a day on the 8 GB Jetson and doubling vision-call latency. We tested 8192, 4096 and 2048 live on the robot the same evening. 4096 is the sweet spot. Crashes since: zero.

The search was slow for boring reasons. A per-mission time ledger showed 84% of search time going to lidar scans, turns, and fixed sleep statements waiting for the camera’s auto-exposure. The sleeps became adaptive (1.13 s → 0.12 s per stop), the drive speed came off a conservative default, and a coverage bug fell out of the same investigation: the explorer’s spacing rule was mathematically unsatisfiable, so the robot had been sweeping beautifully while never actually travelling. Honest search span went from 0.4 m to 14.2 m.

Prompts now ship with numbers or not at all. Every perception question the robot asks — is the target visible, what is this object, could these two reports be the same thing — now has a regression suite grown from real field frames and real mistakes. The arbitration judge went 10/18 → 16/18 on frozen field cases, then was validated over 100 recorded arbitrations: the only eight places it disagrees with history are the eight mistakes history is documented to have made. One candidate “improvement” collapsed a prompt to answering no to everything — caught in 40 seconds on the bench, where the same class of edit used to cost a field day.

Also in the window. The robot learned to peek: when a target disappears behind an obstacle, it finds the occluder’s edge on the lidar ring and arcs sideways for a second viewpoint — proven live against a 47 cm pillar. Counting missions now verify each find from two displaced viewpoints before it enters the tally; five phantoms were killed by geometry in a single evening, including a punching bag that one ambiguous glance had counted as a bin. And every mission — hunts, counts, drives, relocalizations — now writes its milestones into the robot’s black-box event log, aligned with the ring footage, so what happened while I was away? has an answer that survives the robot losing its link.

The theme of the week, if it has one: the robot’s memory is no longer something we maintain. It is something the work leaves behind.

If you’re building autonomy for the places the network can’t reach, talk to us.