Close

Supercharging ROS 2 Camera Performance on Pi 5: From 1.7 Hz to 30 Hz

A project log for GestureBot - Computer Vision Robot

A mobile robot that responds to human gestures, facial expressions using real-time pose estimation and gesture recognition & intuitive HRI

vipin-mVipin M 08/04/2025 at 05:580 Comments

While developing a ROS 2-based gesture-controlled robot on a Raspberry Pi 5, I encountered a major bottleneck: the camera node was publishing at an unusable 1.7 Hz, making any form of real-time perception infeasible. After a detailed system analysis and targeted optimizations, I achieved a 17x performance increase—reaching a stable 30 Hz with low-latency image delivery.

Hardware & Software Configuration

According to rpicam-hello --list-cameras, the IMX219 supports up to 103.33 fps at 640x480. However, ROS 2 was far from utilizing this potential.

Performance Baseline

This was unacceptable for real-time robotics.

Root Cause Analysis

Kernel Mode Setting (KMS) Configuration

The /boot/firmware/config.txt contained:

disable_fw_kms_setup=1
dtoverlay=vc4-fkms-v3d

disable_fw_kms_setup=1 blocks proper GPU setup. While Raspberry Pi OS prefers full KMS (vc4-kms-v3d), on Ubuntu 24.04 with Pi 5, fake KMS (vc4-fkms-v3d) provides better compatibility. Attempting full KMS caused kernel instability.

Reconfiguration Fix
Changes made:

Ensured:

dtoverlay=vc4-fkms-v3d

Post-reboot, this restored GPU access and stabilized image acquisition.

ROS 2 Camera Node Optimization

Pixel Format

The default node was selecting XRGB8888, which carries a high memory and bandwidth cost. Switching to YUYV reduced transfer size and improved throughput significantly.

Launch Parameters

buffer_queue_size: 2
use_intra_process_comms: true
exposure_time: 33000
frame_rate: 30.0
jpeg_quality: 80

These settings minimized latency, stabilized frame delivery, and aligned image acquisition with the camera's physical capabilities.

System-Level Tuning

CPU Frequency Scaling

To prevent CPU throttling during peak loads, I forced the performance governor:

sudo apt install cpufrequtils
echo "GOVERNOR=performance" | sudo tee /etc/default/cpufrequtils

This kept CPU frequency at maximum for consistent ROS node execution.

Composable Nodes

Switching from separate ROS nodes to a composable container significantly reduced IPC overhead. This helped eliminate minor jitter during image transport and ensured tight timing control.

Performance Results

MetricBeforeAfterImprovement
Raw Image Rate1.7 Hz28 Hz16.5×
Compressed Rate1.8 Hz30 Hz16.7×
Avg. Latency600 ms35 ms17×
CPU GovernorondemandperformanceOptimized


Troubleshooting Notes

Discussions