Demo · live · read-only
A virtual rover, driven by n8n
A self-contained showcase for the ROS 2 node package: a simulated rover that offers real ROS 2 topics, services and actions, eleven n8n workflows that drive it, and a read-only live view on the public web. Everything the workflows do shows up on screen.
-
The live view
Watch the robot. Read-only at the protocol level — x11vnc runs with -viewonly, so the server never applies pointer or keyboard events no matter what a client sends.
-
The n8n editor
Every workflow that drives the rover, on the canvas that runs them. Viewing is behind the n8n owner login.
-
Send the rover somewhere
A public form with a dropdown of places on the map — lake, tree, house, mountain, dock. Works from a phone.
-
Camera snapshot
A webhook that captures the robot camera topic and returns it as a JPEG.
-
The operator manual
Written from the live ROS graph on request, not from a file. Whatever the robot exposes right now is what it documents.
-
The source
The n8n node package, the demo compose stack, the rover node and all eleven workflows.
How it fits together
The robot is turtlesim wrapped in a rover-shaped interface: a battery that drains while driving, a dock that recharges it, an e-stop, and a map with landmarks drawn on it so a demo can talk about places rather than coordinates. n8n reaches it over a rosbridge WebSocket on the internal Docker network.
Two things are worth pointing at. The custom message types are discovered at runtime —
rover_interfaces is a real ROS 2 interface package with nested messages, and nothing
about them is hardcoded in n8n. And every interface documents itself: each one publishes a
latched <name>/desc topic saying what it is for, which is how an agent
that has never seen this robot can still work out what to call.
Three choices keep it safe to leave on the internet: rosbridge is bound to localhost and never exposed, the live view is read-only at the protocol level rather than by convention, and the workflows that only observe use a credential that is refused at the node level if it tries to publish or call a service.
┌─ n8n editor (owner login)
Internet ─ Caddy ─┤
(TLS) └─ live view (read-only, public)
internal network
n8n ──ws──▶ ros2 container
├─ rosbridge + rosapi (not exposed)
├─ turtlesim on Xvfb
├─ x11vnc -viewonly ─▶ noVNC
├─ rover_node.py
└─ camera_node.py What the robot exposes
Actions
-
/rover/navigate_toDrives to one point. Feedback carries distance remaining; cancellable. -
/rover/patrolVisits named waypoints in order, feedback per waypoint, optional looping.
Services
-
/rover/set_ledSets the status LED, which is also the trail colour. -
/rover/dockDrives home and starts charging. Preempts a running mission. -
/rover/emergency_stopEngages or releases the e-stop. -
/rover/reset_demoFull reset: battery, e-stop, trail, back to the centre.
Topics
-
/rover/statusRover state at 2 Hz. Embeds the battery and the current waypoint. -
/rover/batteryCharge and charging state at 1 Hz. -
/rover/eventsOne JSON message per event — this is what the watchdog triggers on. -
/rover/camera/compressedThe screen, published as a camera topic at 2 Hz.
Embedded live view, the status readout, the workflow gallery and the agent chat land here as the demo hosts come online. Until then the cards above open each one directly.