Just to be clear: You are recording the image_raw/compressed
topic, and the compression type is set to JPEG, correct? I believe the CPU power required for JPEG compression on the Raspberry Pi is the bottleneck, so it has nothing to do directly with ROS, writing to the SD card, rosbag or the amount of RAM. You could check this by running rostopic hz
on the compressed image topic on the live system. Also running top
or htop
could help - it should show you if the CPU is maxed out.
Unfortunately, saving the uncompressed images is probably also not an option, since the data rate is in the order of 1920×1080×3×30/(1024×1024) = 178 MB/s. If you are going to record very short rosbags only, you can increase the amount of RAM buffer that rosbag uses with the command line option rosbag record --buffsize=SIZE
, where SIZE
is the buffer size in MB (default: 256 MB), but at that data rate, it will only last a minute or so.
I guess recording a 30 Hz image stream in 1080p is just not going to work on a Raspi4.
Edit in response to comment:
Online compression to JPEG for an even bigger image stream (3840x2160@30Hz) will be a challenge on most "embedded" CPUs. You can benchmark your own system by installing sudo apt install libjpeg-turbo-test
and running tjbench
. On my laptop CPU (Intel(R) Core(TM) i9-10885H CPU @ 2.40GHz), I get a compression throughput of 233 Megapixels/sec and decompression throughput of 272 Megapixels/sec. The DJI Manifold 2-C has a Intel Core i7-8550U, which gets a decompression throughput of 176 Megapixels/sec according to this page, so the compression throughput should be about 150 Megapixels/sec (around 3 times faster than the Raspberry Pi 4).
You would need:
- for 640×480@30Hz: 9.2 Megapixels/sec
- for 1920×1080@30Hz: 62.2 Megapixels/sec
- for 3840×2160@30Hz: 248.8 Megapixels/sec
Note that the values from tjbench
are for the libjpeg-turbo
library, but OpenCV (which is used by the ROS image_transport_plugin
for compression) uses the slower libjpeg
library, which can be up to 2-6x slower. It is possible to build OpenCV with libjpeg-turbo
and then rebuild all ROS packages that depend on OpenCV. I have done it, but it's a huge hassle and I wouldn't recommend it if it can be avoided.
The Raspberry Pi's ARMv8 Cortex-A72 has a decompression throughput of 61 Megapixels/sec according to this page, so let's guess the compression throughput should be around 52 Megapixels/sec. What you have actually observed is 1920×1080@11Hz = 22.8 Megapixels/sec. This could be explained by the libjpeg
vs. libjpeg-turbo
issue discussed above, so calculate some large margin of error when speccing your CPU. In other words, I guess that the DJI Manifold 2-C realistically has a compression throughput closer to 60 Megapixels/sec, so it can just barely handle 1920×1080@30Hz and will definitely ... (more)