The rover has a head now. It also has eyes that move, blink, and look at things. People react to it differently the moment it's bolted on, which is the entire point.
This post is partly a build log and partly an argument for doing things the harder way when the harder way is the right way.
The Head
It started as an off-the-shelf 3D model of a familiar little robot head, the kind anyone who's seen the film will recognise instantly. The original model was designed to be printed as a display piece. Lovely on a shelf. Useless for what I needed.
So I modified it. Split the shell into sections that come apart cleanly, hollowed out the internals to make room for two small screens behind the eye sockets, and carved out a cavity for an ESP32 to live inside the skull. The split lines are hidden along natural seams in the model so the assembled head still reads as one object. Print, assemble, disassemble, repeat, that part took more iterations than I'd like to admit. PLA doesn't forgive a sloppy tolerance.
The eyes are two small round displays running animation frames off the ESP32. Blink. Look left. Look right. Narrow when angry. Widen when surprised. None of this is groundbreaking, people have been doing animated robot eyes for years, but there's a specific moment the first time you mount it on something that moves and the whole thing stops being a collection of parts and starts being a character. Kids will talk to it. Adults will talk to it and then apologise for talking to it.
The base of the head is modelled to fit the Picatinny rail on top of the rover's camera mount. That detail wasn't an afterthought, it's the whole reason the head is removable in the first place. Slide it on, lock it down, plug in the USB, and it's mounted. Pop the lock, unplug, lift it off, and the rover goes back to being a rover. Picatinny is a standard, which means anything else I print to fit that rail will mount the same way. The head is just the first thing.
Why the Head Has Its Own Brain
Here's the bit worth dwelling on, because it's the decision I keep getting asked about.
The Raspberry Pi on the rover has spare GPIO. It has spare CPU. It could absolutely drive the two eye displays directly. Wiring it that way would mean one fewer microcontroller, one fewer thing to flash firmware to. On paper it's the obvious choice.
I didn't do it. The head has its own ESP32, talking to the rest of the system over the network when it needs to.
A quick clarification before anyone writes in: the head does take its power from the Pi, over USB. That's deliberate. Power is a utility, the rover's already carrying a battery, and running a second one just for the head would be daft. What I wanted to decouple is the logic, not the electricity. The Pi provides 5V. The ESP32 decides what to do with it. Those are two different conversations and they don't need to be tangled up.
The reason for the separate brain is modularity, and modularity is one of those words that gets thrown around until it stops meaning anything, so let me be specific about what I mean by it here.
The head is one of many strange things I want to do.
That sentence is the whole design philosophy. The head exists today. Tomorrow it might be a different head. Next month it might be a head on a different robot entirely. Or it might be a head mounted on the wall of the workshop, watching people walk past, with no rover underneath at all. Or the rover might be running a different payload, a gripper arm, a camera mast, a tray for delivering snacks across a room. (Not ruling that one out.)
If the head's logic were wired into the Pi, every one of those futures would require a rebuild. The head would be a feature of this rover, not a thing in its own right. Coupling the brain to the Pi makes a stronger system today and a weaker system in six months.
By giving the head its own brain and a standard USB power input, it becomes a self-contained unit that speaks a simple protocol and runs off any 5V source. Anything that can send it a message can drive it. Anything that can provide power can run it. The rover currently does both. Tomorrow something else might. The head doesn't care.
This is the same principle that makes the rover itself work the way it does. The ESP32 handles motors. The Pi handles thinking. The Steam Deck handles control. Each layer does its job and talks to the next over a documented interface. You can swap any layer out without rebuilding the others. That's what modularity is for. Not elegance. Not theoretical purity. The freedom to change your mind without starting over.
The Cost
I'm not going to pretend this is free. A second microcontroller is a second thing that can fail, a second thing to flash, a second set of bugs to chase when something doesn't behave. There is genuinely more to go wrong.
The trade is that when something does go wrong, it goes wrong in one place. The head misbehaving is a head problem. The rover misbehaving is a rover problem. Debugging a tangled monolithic system where everything shares the same brain is its own special kind of pain, and I've done enough of it to want to avoid more.
What's Next
The head is mounted, eyes are animating, and the whole assembly drives around on the rover looking, and I mean this sincerely, quite startling the first time you see it move under its own power. There's still a list. Synchronise the eye animations with the TTS audio so it actually looks like it's saying what it's saying. Add an idle behaviour so it glances around when nothing's happening. Maybe a sleep mode for when it's been still too long.
And then, eventually, the next strange thing. I haven't decided what yet. That's sort of the point.
