System Overview
I built a distributed ROS 2 system for gesture-based robotic control with three main nodes:
-
Raspberry Pi 5: Camera capture and basic processing (Ubuntu 24.04, ROS 2 Jazzy)
-
Development Machine: Computer vision algorithms and parameter tuning
-
MacBook Pro (VM): GUI applications and visualization via Ubuntu 24.04 ARM VM (UTM)
-
Network: WiFi 6
The expected data rate was 30 Hz end-to-end. Actual performance was 1 Hz with frequent topic dropouts and unresponsive GUI tools.
Problem 1: Network Saturation from Raw Image Streams
The Pi 5 camera node published /camera/image_raw and /camera/image_raw/compressed. Local testing confirmed 30 Hz performance. On the dev machine, the raw topic dropped frequently while the compressed topic remained stable.
Root Cause
Bandwidth calculations exposed the bottleneck:
-
Raw (640×480 RGB @ 30 Hz): ≈27 MB/s
-
Compressed (JPEG): ≈3 MB/s
ROS 2 discovery and transport failed to maintain raw topic streaming over WiFi. The system choked on the 27 MB/s stream.
Fix: Compressed-Only Streaming and Local Decompression
Step 1: Disable raw topic in launch file
<remap from="/camera/image_raw" to="/dev/null"/>
Step 2: Decompression node on dev machine
# Subscribes to /camera/image_raw/compressed # Publishes /camera/image_raw
Results
| Configuration | Bandwidth | Frame Rate | Reliability |
|---|---|---|---|
| Raw + Compressed | ~30 MB/s | <1 Hz | Unstable |
| Compressed Only | ~3 MB/s | 30 Hz | Stable |
The decompression node restored full frame rate while maintaining image quality for downstream CV nodes.
Problem 2: GUI Lag from Resource Contention
With image transport fixed, RViz and parameter tuning interfaces remained unusable. RViz ran at 2–3 Hz with second-long UI lag.
Root Cause
The dev machine was overloaded:
-
Computer vision pipelines (CPU)
-
30 Hz image decompression (CPU)
-
RViz rendering (GPU)
-
ROS 2 comms and parameter servers (CPU)
Despite using a powerful workstation, this saturated CPU usage >90%.
Fix: Distribute GUI to a VM
I moved all GUI applications to a VM on my MacBook Pro using UTM with ARM-native Ubuntu 24.04:
-
4 GB RAM
-
4 CPU cores
-
Network bridging enabled
-
Hardware graphics acceleration
Architecture After Split
-
Pi 5: Publishes compressed images only
-
Dev Machine: Decompresses + processes CV pipelines
-
MacBook VM: RViz, parameter sliders, real-time tuning
Results
| Metric | Before | After |
|---|---|---|
| RViz Frame Rate | 2–3 Hz | 30 Hz |
| GUI Response | 1–2 sec | <100 ms |
| CPU Load (Dev Machine) | >90>#/td### | ~60>#/td### |
Distributing GUI apps restored responsiveness and dramatically improved the development experience.
Implementation Summary
Network Optimization
-
Modify camera launch file to disable raw stream.
-
Deploy decompression node on receiving machine.
-
Monitor bandwidth via
iftopornload.
GUI Distribution
-
Create Ubuntu VM with hardware acceleration + bridged networking.
-
Run GUI-only nodes (RViz, rqt, dynamic reconfigure).
-
Keep compute-heavy nodes on dedicated hardware.
Performance Summary
| Resource | Before | After | Improvement |
|---|---|---|---|
| Network Bandwidth | 30 MB/s | 3 MB/s | 10x |
| Frame Rate | <1 Hz | 30 Hz | 30x |
| Dev Machine CPU | >90>#/td### | ~60>#/td### | Reduced contention |
| GUI Responsiveness | 2–3 Hz | 30 Hz | Real-time capable |
Vipin M
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.