If you are running ROS 2 robots in production — or even just testing in the lab — you eventually hit the same wall: how do I know what my robots are doing when I am not in front of them? A robot sitting in a warehouse, a quadruped in a customer's factory, a drone 50 km away — they all need monitoring. Open a terminal and SSH into each one? Not scalable. Build a custom dashboard? Takes months.
This tutorial walks you through setting up remote monitoring for ROS 2 robots in under 10 minutes using a real, production-ready agent. By the end, you will see battery, CPU, ROS node status, and custom metrics streaming from your robot to a cloud dashboard — from anywhere in the world.
What you will build
By the end of this tutorial:
- ROS 2 robot (or laptop pretending to be one) sends telemetry to a cloud dashboard every 30 seconds
- Battery, CPU, memory, uptime, ROS node status all visible remotely
- Alerts fire when a robot goes offline or battery drops below threshold
- Works from any network — office Wi-Fi, 4G, home internet
- Setup takes 10 minutes, not 10 weeks
What you need
- A robot or computer running ROS 2 Humble, Iron, Jazzy, or Rolling (Ubuntu 22.04+)
- Python 3.10+
- Internet connection (robot-side)
- A free VnRobo account (3 robots free, no credit card)
If you do not have a real robot yet, any Ubuntu laptop works for this tutorial. You will still see real telemetry flowing.
Why not just SSH or custom Flask dashboard?
Before we dive in, a quick reality check on why people reach for a purpose-built platform:
| Approach | Setup time | Scales to 10+ robots? | Alerts included? | Maintenance cost |
|---|---|---|---|---|
| SSH into each robot | 0 min | ❌ | ❌ | High |
| Custom Flask + Grafana | 2-4 weeks | ⚠️ Fragile | DIY | Very high |
| InfluxDB + Telegraf | 1-2 weeks | ✅ | DIY | High |
| Fleet SaaS (VnRobo etc.) | 10 min | ✅ | ✅ | Low |
If you have 1 robot and enjoy Flask: fine, build it yourself. If you have 3+ robots and care about your weekend: use a SaaS.
Step 1: Create a VnRobo account
Head to app.vnrobo.com/sign-up. Sign up with email or Google. No credit card. You will land on the dashboard with 0 robots.
Click "Add Robot" → give it a name (e.g., test-robot-01) → you will get two values:
ORG_ID— your organization IDROBOT_TOKEN— a token for this specific robot
Copy these. We need them in the next step.
Step 2: Install the ROS 2 agent
On your robot (or laptop):
pip install vnrobo-agent
That is literally it — no apt repos, no systemd config yet, no secrets management overhead. Under the hood, this installs a Python package that reads psutil for system metrics and pings your ROS 2 node status.
Requirements check: the agent needs Python 3.10+ and ROS 2 sourced in your shell (source /opt/ros/humble/setup.bash or similar).
Step 3: Initialize the agent
Run once to link this robot to your account:
vnrobo init \
--org YOUR_ORG_ID \
--token YOUR_ROBOT_TOKEN \
--name test-robot-01
This creates a config file at ~/.vnrobo/config.yaml. Do not commit this to git.
Step 4: Start the heartbeat loop
Run the monitoring daemon:
vnrobo run
You should see:
[vnrobo] Connected to cloud
[vnrobo] Sending heartbeat every 30s
[vnrobo] battery=0.87 cpu=12% mem=34% nodes=8
Switch back to the VnRobo dashboard in your browser. Within 30 seconds, your robot shows up with a green dot — ONLINE. Click into it to see live metrics: battery, CPU, memory, ROS node list.
That is the minimum. You now have remote monitoring.
Step 5: Send custom metrics from your ROS 2 code
Default metrics (battery, CPU, memory) are useful, but you probably want to track domain-specific things: current mission, motor temperature, LIDAR health, whatever.
Here is how to push custom metrics from your ROS 2 Python node:
import rclpy
from rclpy.node import Node
from vnrobo import Heartbeat
class MissionNode(Node):
def __init__(self):
super().__init__('mission_node')
self.hb = Heartbeat()
self.timer = self.create_timer(5.0, self.report)
def report(self):
self.hb.send({
"mission_id": 42,
"motor_temp_c": 47.3,
"lidar_fps": 15,
"current_task": "picking",
"battery": 0.72,
})
def main():
rclpy.init()
node = MissionNode()
rclpy.spin(node)
rclpy.shutdown()
if __name__ == "__main__":
main()
Save as mission_node.py, run it alongside vnrobo run. Any key-value pair you send appears in the dashboard automatically — no schema changes, no database migrations.
Step 6: Set up alerts
Alerts are the single highest-value feature of remote monitoring. A robot that went offline 6 hours ago is useless; a robot that went offline 30 seconds ago is a problem you can fix.
In the dashboard, click Alerts → New Alert:
Example: battery low
- Condition:
battery < 0.20 - Notify: email + webhook to Slack
- Cooldown: 5 minutes (don't spam)
Example: robot offline
- Condition: no heartbeat for 2 minutes
- Notify: email + webhook
- Auto-resolves when robot reconnects
Example: motor overheating
- Condition:
motor_temp_c > 80 - Notify: page on-call engineer
Step 7: Run as a systemd service
For production, you want the agent to auto-start on boot and restart if it crashes. Create /etc/systemd/system/vnrobo-agent.service:
[Unit]
Description=VnRobo Agent
After=network-online.target
[Service]
Type=simple
User=robot
Environment="ROS_DOMAIN_ID=0"
ExecStart=/usr/bin/bash -lc 'source /opt/ros/humble/setup.bash && vnrobo run'
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl enable vnrobo-agent
sudo systemctl start vnrobo-agent
sudo systemctl status vnrobo-agent
Now the agent survives reboots, crashes, and network drops.
Step 8: Add more robots
For each new robot:
- Click Add Robot in dashboard → get new token
pip install vnrobo-agenton that machinevnrobo init --org YOUR_ORG_ID --token NEW_TOKEN --name robot-02- Start the systemd service
Free tier handles 3 robots. For more, Pro plan is $29/month for 25 robots.
Common issues and fixes
"Connection refused" on vnrobo run
Check internet access on the robot: curl https://api.vnrobo.com/health. If blocked, your firewall is filtering outbound HTTPS. Whitelist api.vnrobo.com on port 443.
ROS nodes not showing up
Make sure ROS 2 is sourced in the same shell where you run the agent. Check with ros2 node list — if empty, the agent has nothing to report.
Dashboard shows last heartbeat 5 minutes ago, but robot is running
Network issue between robot and cloud. Agent queues heartbeats locally and flushes when connection returns. Wait 2 minutes. If persistent, check journalctl -u vnrobo-agent.
Multiple robots showing up as one
Each robot needs a unique token. Don't reuse tokens across machines.
Beyond basics — what to do next
Once you have basic remote monitoring working:
- Add GPS tracking — push
lat/lonin your heartbeat, the dashboard plots it on a map - Stream rosbag metadata — log trajectories for debugging later
- Integrate with CI/CD — alert when a fleet rollout fails
- Build custom dashboards — use the VnRobo API to pull data into your own tools
How this compares to alternatives
Short version: if you want a drop-in monitoring tool for < 25 robots and care about cost, VnRobo is the fastest path. If you need live video and enterprise compliance, look at Formant or Freedom Robotics instead. If AWS RoboMaker was your old setup, here's the full migration guide.
Conclusion
Remote monitoring for ROS 2 does not need to be a 3-month engineering project. Install the agent, initialize, run. Ten minutes from scratch to a working cloud dashboard. Add custom metrics in a few lines of Python. Alert rules in clicks, not YAML wars.
If this setup works for you, try it free with 3 robots — no credit card. If you hit issues, the VnRobo docs cover edge cases we skipped here (offline detection tuning, proxy configs, multi-org setups).