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
-
Board: Raspberry Pi 5 (8GB)
-
OS: Ubuntu 24.04 LTS (64-bit)
-
Camera: Arducam-compatible IMX219 (8MP)
-
Middleware: ROS 2 Jazzy
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
-
/camera/image_raw: ~1.7 Hz -
/camera/image_raw/compressed: ~1.8 Hz -
Latency: 470–740 ms per frame
-
Frame interval: Highly inconsistent
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:
-
Removed
disable_fw_kms_setup=1
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
| Metric | Before | After | Improvement |
|---|---|---|---|
| Raw Image Rate | 1.7 Hz | 28 Hz | 16.5× |
| Compressed Rate | 1.8 Hz | 30 Hz | 16.7× |
| Avg. Latency | 600 ms | 35 ms | 17× |
| CPU Governor | ondemand | performance | Optimized |
Troubleshooting Notes
-
Camera not detected: Validate
/boot/firmware/config.txt, ensure FFC cable integrity, and checkdmesgfor I2C errors. -
Low frame rates: Confirm pixel format and node parameters match camera capabilities.
-
Node crashes: Ensure ROS launch parameters are aligned with supported formats and bandwidth.
Vipin M
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.