Blog / Robotics

What We Learned Building a Self-Improving Museum Guide Robot for WRO 2026

Behind-the-scenes engineering notes from three students building MuseBot AI — the SLAM-and-ROS2 first draft that got cut, the Nano that quietly killed a week, and the two-tier memory system that turned out to be the actual invention.

MuseBot AI is a museum guide robot built by three NebuCoders members for WRO Future Innovators 2026, this year's theme "Robots Meet Culture." It drives a fixed route between exhibit booths, stops automatically at each one, explains the exhibit out loud, and answers visitor questions live — and it gets measurably more informative the longer it runs, because every question it's ever been asked at a given booth gets folded back into how it explains that same exhibit to the next visitor. What follows isn't the polished pitch version of that story. It's what actually happened building it, including the parts that went badly first.

The version that never got built, on purpose

The first real design draft wasn't a line-following robot at all — it was a fully autonomous platform running Ubuntu and ROS2, doing SLAM-based mapping so the robot could navigate freely around a real museum floor, with a camera pipeline to visually recognize which exhibit it was standing in front of and a touchscreen for visitors to pick a language. Every part of that architecture is real and legitimate; it's also, honestly, a six-to-twelve-month professional robotics project, and three students building toward a competition deadline don't have that runway. The actual engineering skill on display wasn't designing that ambitious version. It was recognizing early — before a single motor was wired — that it needed to be cut, and deliberately choosing the boring, reliable mechanism that would actually work in front of judges over the impressive one that might not.

Why a strip of tape beat a camera

The next thing to go was exhibit recognition by camera or QR code, and the reasoning behind cutting it is worth sitting with, because it generalizes past this one robot: a robot moving along a fixed physical track always encounters its booths in the same order, every single run. There is no actual recognition problem to solve there — the order is already known before the robot ever moves. So instead of a vision pipeline, a camera, a recognition model, and everything that could go wrong with any of those live on demo day, the robot uses a perpendicular strip of tape crossing its path to mark a stop, read by sensors it already needed for line-following in the first place. No new hardware, no new failure surface, one less thing that could go wrong at the worst possible moment.

Two boards, split along a fault line that matters

Line-following and stop-tape detection genuinely need millisecond-consistent timing to work reliably — and a Raspberry Pi running full Linux, doing network calls and audio playback at the same time, cannot honestly guarantee that kind of consistency; something is always liable to introduce a few milliseconds of jitter at the worst moment. So the robot's brain is split cleanly in two. An Arduino Uno owns driving and sensor reads in a single tight, predictable loop, with no AI, no network calls, and no audio — nothing that could ever introduce unpredictable timing. A Raspberry Pi 4B owns everything that can tolerate a little jitter without anyone noticing: speech-to-text, the LLM conversation, text-to-speech, and the memory system. The two talk to each other over one USB serial cable and nothing else — no shared state, no shared timing requirements, no way for a slow week on the Pi's side to make the Uno miss a sensor read.

The bug that wasn't a bug

An early Arduino Nano kept failing code uploads, intermittently, for no reason anyone could immediately explain — sometimes it worked, sometimes it silently didn't, with no clear pattern. Real debugging time went into this before anyone correctly diagnosed the actual cause: not the code, not a driver issue, but a fragile Mini-USB connector on the board itself that was making and breaking contact unpredictably. The fix, once diagnosed, was almost anticlimactic — swap to an Uno, identical chip, identical pin map, identical code, just a sturdier full-size USB-B port that doesn't come loose. The lesson that actually mattered wasn't about Arduino boards specifically. It was learning to genuinely suspect the hardware, not just the code, the moment something fails intermittently with no visible pattern — that instinct doesn't come naturally to people who've mostly debugged software, and it costs real time to learn the hard way.

From sensor to spoken sentence: the full conversation pipeline

It's worth walking through what actually happens, in order, from the moment the robot arrives at a booth to the moment it starts driving to the next one, because the individual pieces are each simple and the interesting part is how cleanly they hand off to one another. The Uno detects the stop-tape, halts the motors, and sends a single short message over serial reporting which physical stop this is. The Pi's RFID reader identifies which exhibit is actually sitting at this stop right now — a detail that matters more than it sounds like, covered below. The Pi loads that exhibit's knowledgebase file, builds a prompt combining the exhibit's curated facts with any relevant memory from this visitor's tour so far and from past visitors at this booth, and sends it to the language model. The response comes back as text, gets converted to speech, and plays over a speaker. Then the robot asks if there are any questions, listens with a timeout, and if it hears one, runs that same question-answering loop again before finally sending the Uno a resume signal and moving on.

Every one of those steps is individually unremarkable — speech-to-text, an LLM call, text-to-speech are all things a developer can wire up in an afternoon using off-the-shelf APIs. What took actual engineering time wasn't any single step; it was the handoffs between them staying reliable under real timing pressure, and specifically making sure a slow API response on a bad WiFi connection degrades gracefully — a short apology and a resume signal — rather than leaving the robot stuck at a booth indefinitely with a visitor standing in front of it waiting for a network request that's never coming back.

The part that was actually new

Line-following robots are deliberately boring, well-established technology, and that's fine — being boring was the design goal. What actually separates MuseBot from an audio-guide handset a museum could just rent, or a static QR-code app on a visitor's own phone, is a two-tier memory system layered on top of that boring, reliable base. Every question a visitor asks gets logged, tagged by which exhibit it was asked at and what topic it touches, and then feeds back into the robot's behavior in two distinct ways.

The first is a within-tour digest: if the same visitor already asked something related at an earlier booth this tour, the robot references that briefly instead of re-explaining from scratch, the way an actual human guide would remember what they already told you five minutes ago instead of repeating themselves. The second, and the more interesting one, is a cross-visitor FAQ digest — questions that keep recurring at a specific booth across every tour that's ever run, regardless of who asked them, get proactively folded into that booth's explainer for the next visitor. Ask enough different visitors the same follow-up question at one booth, and eventually that booth just starts covering it upfront, without a single line of code changing and without anyone manually reprogramming anything.

That compounding property — a booth's explanation quietly getting better every time a new visitor asks something at it — is the actual engineering bet the whole project rests on. Not the line sensor. The line sensor was always going to be the boring, solved part.

Letting exhibits move without touching a single line of code

Which physical exhibit sits at which stop is deliberately decoupled from arrival order. An RFID reader mounted on the robot reads a tag stationed at each booth, and a small local web panel maps that tag's ID to a specific exhibit — set up live, not hardcoded anywhere in the firmware. That one decision means a museum, or a competition table under time pressure the night before judging, can rearrange which exhibit sits where without re-flashing anything at all. It sounds like a minor convenience described in a sentence like that. It stops sounding minor the first time you actually have to rebuild a physical course an hour before judging starts and realize you'd otherwise be re-uploading firmware instead of tapping a card against a reader.

The same web panel doubles as the tool for adding an entirely new exhibit — a name and a short summary are enough to generate a starter knowledgebase automatically, which a team member then reviews and edits before it ever gets used live. That review step matters: an automatically-drafted knowledgebase is a starting point, not a finished, trustworthy source of facts a robot should be reciting to a visitor without a human having actually checked it first.

How the team split the work, and where that split came from

With three people and one robot, the natural failure mode is everyone touching everything and nobody owning anything cleanly — so the team split along the same fault line the hardware itself is split on. One person's focus tracked closely with the Arduino side: motor wiring, sensor calibration, the physical chassis. Another's tracked with the Raspberry Pi side: the conversation pipeline, the memory system, the web panel. The third moved across both, plus owned the parts neither side naturally covered — the actual physical course layout, the competition report, and testing the seams where the two halves had to talk to each other over serial, which turned out to be exactly where the trickiest bugs actually lived, since neither the "Arduino person" nor the "Pi person" had full visibility into a bug that only showed up in the handoff between the two.

What we'd actually tell a team starting their own build

  • Cut scope before you're forced to, not after the deadline makes the decision for you — the version you can actually finish and demo reliably beats the more impressive version that might not survive contact with a real judging table.
  • When something fails intermittently with no clear pattern, genuinely suspect the hardware connector before you spend hours re-reading your own code looking for a bug that isn't there.
  • Look hard for the one system-level decision that makes the whole thing more than the sum of its parts — for this project that was a memory loop, not a sensor, and it very easily could have gone unbuilt if the team had stopped at "robot that follows a line and talks."
  • Budget real bench-testing time on the actual competition surface and lighting, not just your workshop table at home — thresholds and gains that work perfectly in a bedroom don't always survive an unfamiliar venue, and finding that out on the day itself is the worst possible time to find it out.
  • Assign ownership along a real technical fault line, not evenly by task count — and specifically assign someone to own the seams between the pieces different people are building, because that's where the bugs that are hardest to attribute to any one person tend to live.

Want to build something like this?

NebuCoders is free to join — no application, no cost.

Read next