Inspiration

After a building collapses, the odds of getting someone out alive drop fast: about 74% in the first 24 hours, 22% by hour 72, and 6% by day five. Rescuers risk their lives every minute they spend searching inside, and the robots that could go in for them usually need a network connection that died with the building. We built Rove to go in first, work with zero connectivity, and come back with a real lead on where someone is trapped!

What it does

A responder presses one button and Rove goes in. It switches to blackout mode, stops waiting on any connection, and makes its decisions on board. Two ultrasonic sensors keep it off the walls while a YOLO model running on the Pi scans the camera feed for people. Once it spots someone, it drives over, beeps twice, and speaks to them. On the dashboard, ElevenLabs gives that line a real human voice, so the responder hears exactly what Rove is saying to the survivor as it happens. Then Rove retraces its own recorded path back to the entrance, with no map needed.

Back in range, Rove hands what it collected to Gemini, which transcribes the audio, looks at the snapshot, and writes a draft triage report. If there's no internet, an Ollama model on the responder's laptop takes over, and if that fails too, a fixed template still gets the report out. You run the whole mission from one dashboard at claudesplan.tech that shows the live camera, controls, the robot's senses, and a gallery of survivor photos that open into their transcripts and reports. It works the same on a laptop or a phone.

How we built it

Rove runs on a 2 GB Raspberry Pi 4 with a Camera Module 3, two HC-SR04 ultrasonic sensors angled 30° off center, a DHT11 temperature and humidity sensor, a sound sensor, a buzzer, and an L298N driving the DC motors. The Pi runs a Python FastAPI server, and YOLOv8n runs through ONNX and OpenCV's DNN module right on the board.

We set one hard rule on day one: generative AI never drives. A deterministic state machine issues every motor command from local sensor data:

$$ a(t) = \begin{cases} \pi\big(s(t)\big) & d_{\min}(t) > d_{\text{safe}} \[4pt] \text{STOP} & d_{\min}(t) \le d_{\text{safe}} \end{cases} $$

Here $d_{\min}(t) = \min_i d_i(t)$ is the closest ultrasonic reading, $\pi$ is our fixed rule-based policy, and $s(t)$ is the current sensor and vision state. No model output appears anywhere in that rule. AI handles detection and reporting, where a wrong answer costs you a bad report instead of a crash.

For the cloud side, we spun up an Ubuntu server on Vultr running FastAPI behind Caddy with automatic HTTPS. The Pi dials out to it over a secure websocket and pushes its state and camera frames, and the server tunnels dashboard commands back down to the robot. A stop command makes the full round trip in about 305 ms. The server logs telemetry, events, and survivors, and we built an ingest service that writes survivor records, sightings, and telemetry to MongoDB Atlas with unique event IDs, so a retry after a dropped connection never creates duplicates. The ElevenLabs voice runs on the same server, and it only speaks lines the robot actually said, caching each one so a viewer can't burn through credits.

We wrote the code to run three ways: a simulated room with no hardware at all, a laptop mode that swaps the webcam and dashboard sliders in for the sensors, and the real robot on the Pi. You can watch the simulator live at auto.claudesplan.tech. That let us keep shipping software while the hardware sat on the bench.

We used off-the-shelf parts, and the sensors cost under $50 total. For the price of one purpose-built search robot, you could send a whole team of Roves into a building, each covering its own section, and losing one wouldn't end the mission.

Challenges we ran into

Our hardest problems were physical! One sonar read a rock-steady 4 cm for hours, and we swapped wiring before we realized it was pointed at the floor. We added a guard that throws out any echo under 6 cm, so a knocked sensor now reads as dead and Rove drives on the other one instead of freezing in front of a fake wall. One side of the drivetrain spun backward until we added motor inversion. Our phone hotspot kept knocking the Pi offline, and we traced it to NetworkManager giving up after four reconnect attempts, so we set it to retry forever. With no working fan, the Pi hit 84°C, so we capped the clock at 1.2 GHz and cut the camera to 8 fps and detection to 1.5 fps until it held a steady 66°C.

The physical speaker on the robot still isn't making sound. It needs cleaner splices and an amp, and we never wired in a mic for live answers, so we've designed the full survivor conversation but haven't proven it on the hardware yet.

What we learned

We learned to plan for failure before adding features. A robot built for dead zones has to make its important calls on board, and a reporting pipeline needs a fallback for its fallback. Rove shows that a cheap rover can get into a disconnected space and come back with something real, and we know it needs a lot more testing before anyone should call it rescue gear.

What's next

First we'll get the onboard speaker working with an amp and add a mic. After that, we'll calibrate the drivetrain on real floors and run repeated missions on test courses built by real responders to measure an actual success rate.

Then we want to build fleets! Each Rove would pick up a role as the mission unfolds. Scouts explore, relays carry findings home for units still out of range, and a coordinator splits the building into zones and merges everyone's maps in MongoDB. When two Roves pass within short-range radio of each other, they'd swap what they've found, so a unit near the exit can carry survivor locations out while the deeper unit keeps searching. If the coordinator gets stuck, another Rove takes its place. We haven't built any of this yet, and it's the next problem we want to tackle once a single Rove is solid.

Built With

  • claude
  • cursor
  • dc-motors
  • dht
  • edge-ai
  • elevenlabs
  • grok
  • l298n
  • mongodb
  • ollama
  • raspberry-pi
  • ultrasonic-sensor
  • yolo
Share this project:

Updates

Submission history