System designTroubleshooting

ROS camera stuck under 1 Hz: set a frame rate the camera can deliver

Why a ROS camera topic publishes under 1 Hz after you set frame_rate, how to read the rate the video mode supports, and the link budgets behind the fix.

LumaSpec Vision10 min read Share on LinkedIn

On this page 10 sections
  1. 01What the symptom is telling you
  2. 02Cause 1: the frame_rate value is outside the current video mode
  3. 03Cause 2: the link cannot carry the frames
  4. 04Worked example: 30 Hz requested from a 12 MP mode
  5. 05Cause 3: exposure and trigger settings swallow frames
  6. 06The fix, in order
  7. 07When the rate parameter is not the problem
  8. 08Prevention checklist
  9. 09Choosing a camera whose full-resolution rate is real
  10. 10Questions

You set frame_rate to 30 in the camera's launch file, and the image topic now delivers a frame every couple of seconds instead of thirty. The cause is rarely ROS, the computer or the driver itself: the number you passed is not a rate the camera can deliver in its current video mode, so the camera refuses the set or throttles the stream, and the debayer nodelet downstream never receives a frame. This page is for anyone wiring a GigE or USB3 area scan camera into a ROS stack. You will rank the three causes that produce an under-1 Hz topic, compute the rate the mode and the link can actually carry, set a legal value, and measure the publish rate before adding processing. The decision in one line: revert the override, read the camera's allowed rate for the current resolution and pixel format, set that value, then measure again.

What the symptom is telling you

Two symptoms, one root. The raw image topic publishes under 1 Hz or not at all, and the color topics are missing entirely. The second follows from the first: the debayer nodelet in image_proc subscribes to the raw stream and publishes image_color and its compressed variants only when raw frames arrive, so an empty raw stream produces no color topics. Diagnose on the raw topic, never on the color stack:

rostopic hz /camera/image_raw

If that reports zero messages or a fraction of a hertz, the camera is not streaming at its mode's rate, and no amount of debayer or compression tuning will fix it. Rank the causes in field order: a frame_rate value outside the current video mode, a link that cannot carry the frames, then exposure and trigger settings that swallow the frames the camera does produce.

Cause 1: the frame_rate value is outside the current video mode

A ROS camera driver does not invent rates; it writes your frame_rate value into the camera, overriding the camera's own default. The achievable rate is a property of the current video mode — resolution, pixel format, binning — not of the driver. Ask a 12 MP 8-bit mode for 30 Hz when its ceiling is 15 Hz, and the camera either refuses the write, leaving the stream stopped so the driver republishes timeouts well under 1 Hz, or it drops into a throttled state that dribbles frames.

The test takes a minute: comment out the frame_rate parameter, relaunch so the driver uses the camera default, and run rostopic hz again. If the topic recovers to a steady native rate, the override was the problem.

The fix is to read the range instead of guessing. The vendor's camera tool lists the frame-rate minimum, maximum and increment for the selected resolution and pixel format; the same limits sit in the camera's GenICam feature list. Set inside them. A value the camera refuses behaves like any other invalid GenICam value: read what the feature list allows before you write.

Even a legal rate fails when the wire cannot move the pixels. Compute the budget before setting anything:

frame size (MB) = width (px) × height (px) × bytes per pixel ÷ 1,000,000 rate ceiling (Hz) = usable payload (MB/s) ÷ frame size (MB)

Payloads after protocol overhead: a GigE link's 1 Gbit/s works out to about 118 MB/s with jumbo frames and about 110 MB/s in typical traffic. A USB3 port signals at 5 Gbit/s, which leaves roughly 400 MB/s of theoretical payload after line encoding; budget 360 MB/s for image data on a clean, dedicated port.

Link Usable payload 12 MB frame (12 MP, 8-bit mono) 3 MB frame (2×2 binned)
GigE 110-118 MB/s 9-10 Hz 37-39 Hz
USB3 360 MB/s budget 30 Hz 120 Hz

When the camera can produce a rate the wire cannot carry, you see dropped frames and a sinking publish rate: the camera produces, the driver times out, the topic slows. Anything sharing the bus divides the budget first — a hub, a busy disk or a second camera takes its share before you compute. The USB hub bandwidth budget walks that arithmetic, and the multi-camera GigE budget covers a shared switch. Two levers shrink the frame itself: cropping the ROI at the camera is the cheapest, and switching a 16-bit format to 8-bit mono halves the bytes per pixel.

Worked example: 30 Hz requested from a 12 MP mode

Take the mode behind half of these tickets: 4000 × 3000 pixels, 8-bit mono format, 30 Hz requested.

  1. Frame size: 4000 × 3000 = 12,000,000 pixels; at one byte per pixel that is 12 MB per frame.
  2. Requested load: 12 MB × 30 Hz = 360 MB/s.
  3. On USB3 this consumes the entire 360 MB/s budget. The combination is legal and some cameras print exactly it, but there is no margin: one hub or one disk write pushes the link over and the publish rate collapses. Set 25 Hz instead — 12 MB × 25 = 300 MB/s, leaving about 60 MB/s of headroom.
  4. On GigE the same request is impossible: 118 MB/s ÷ 12 MB = 9.8 Hz. No parameter changes this; the honest full-resolution rate is 9 fps, and that is the number a 12 MP GigE camera's data sheet prints.
  5. Exposure adds the second ceiling: the period at 30 Hz is 1000 ÷ 30 = 33.3 ms, so the frame must expose and read out inside that. That period is also why the practical exposure maximum sits at roughly 30 ms.

A 12 MP USB3 camera built for exactly that full-budget mode is the LS-CMR-0166: 4000 × 3000 at 30 fps.

Area scan cameras12 MP USB3 area scan camera, IMX226, 1/1.7" rolling shutter, 30 fps, 4000 × 3000 resolution (LS-CMR-0166)LS-CMR-0166
Sensor format
1/1.7"
Interface
USB3
Resolution
12 MP
Shutter
Rolling
$560.00View partBuild a system with it

The LS-CMR-0053 runs the same 12 MP sensor over GigE, and its data sheet prints 9 fps — the number the GigE line of the arithmetic predicts.

Area scan cameras12 MP GigE area scan camera, IMX226, 1/1.7" rolling shutter, 9 fps (LS-CMR-0053)LS-CMR-0053
Sensor format
1/1.7"
Lens mount
C-mount
Interface
GigE
Resolution
12 MP
$560.00View partBuild a system with it

Cause 3: exposure and trigger settings swallow frames

The rate can be legal and the link wide open, and the topic still publishes slowly.

Exposure longer than the period. A camera that needs 40 ms to expose delivers one frame every 40 ms — 25 Hz — no matter what the parameter says. Compare the exposure value against 1000 ÷ frame rate in milliseconds, and shorten one or the other. Pixel format and exposure together define the ceiling a driver can reach; pixel format and exposure limits covers that pairing.

Triggered acquisition. In trigger mode the camera publishes at the trigger arrival rate, and the frame_rate parameter is irrelevant. A trigger firing once per second produces an under-1 Hz topic that looks exactly like a rejected rate set. Check the acquisition mode first — the trigger-mode check is the fast version — and run continuous acquisition for a live viewing loop (continuous acquisition for live loops). A triggered camera that will not reach its rated rate has its own triggered frame rate troubleshooting path, separate from a rejected parameter.

The fix, in order

  1. Revert. Comment out frame_rate, relaunch with the camera default, and confirm the stream with rostopic hz. If nothing streams even at default, power-cycle the camera — a refused value can leave the stream stopped until the camera restarts — and check the driver-firmware compatibility table in the vendor's release notes, because newer driver stacks drop older firmware generations.
  2. Read. Open the vendor camera tool, select the exact resolution and pixel format from your launch file, and write down the frame-rate minimum, maximum and increment for that mode.
  3. Compute. Frame size from width × height × bytes per pixel; link ceiling from the formula above. Target the lower of the two ceilings, minus 10% margin.
  4. Set. frame_rate inside the allowed range, exposure under the period, acquisition mode continuous unless you trigger on purpose.
  5. Measure. rostopic hz on the raw topic should sit within a few percent of the set value.
  6. Then process. Only now start the debayer nodelet, and confirm image_color and its compressed variants appear at the same rate.

When the rate parameter is not the problem

If rostopic hz on the raw topic already matches the value you set, the camera side is finished. Two possibilities remain:

  • The color pipeline is slow. Raw at the requested rate but color at 2 Hz means the debayer and downstream nodes cannot keep up. That is a host throughput problem, and the fix lives there — acquisition faster than processing walks the gap.
  • The parameter never reached the camera. After a ROS version change, launch parameters get renamed and the driver quietly runs its default while your file still looks correct. The renamed launch parameter fix covers that case. The driver console also logs a warning when the camera rejects a value, so read its output once.

Prevention checklist

Before you set frame_rate:

  • Read the allowed range for the exact resolution and pixel format in the vendor tool — the range moves with every mode change, so re-read it after each change.
  • Compute the link budget and target 90% of the link ceiling or less.
  • Check exposure against the period, and set acquisition mode continuous unless you trigger on purpose.
  • Subtract anything sharing the bus: hub, second camera, disk.

After you set it:

  • rostopic hz on the raw topic within a few percent of target — this is the number that counts.
  • Color and compressed topics present, at the same rate, once the debayer nodelet runs.
  • Stable over five minutes: a rate that decays over minutes points to bandwidth creep or thermal throttling, not the parameter.

Choosing a camera whose full-resolution rate is real

Decide from the mode you actually need:

  • 12 MP at 30 Hz, full frame: USB3 run dedicated, or 10GigE or CoaXPress, whose budgets sit an order of magnitude above GigE. GigE cannot carry it — the ceiling is 9-10 Hz.
  • 12 MP at 9-10 Hz: GigE is the honest choice, and the data-sheet rate will match your arithmetic.
  • Around 2 MP at that same rate and above: either link carries it with room to spare; choose on cable length and ecosystem instead.

The area scan cameras category filters by interface, resolution and shutter, and the camera finder applies the same filters when you know the rate you need. The two cameras below are the same 12 MP sensor on the two links, so the pair shows the decision exactly.

Specification LS-CMR-0053 LS-CMR-0166
Resolution 4000 px x 3000 px 4000 × 3000 (12MP)
Pixel size 1.85 μm x 1.85 μm 1.85 μm
Max. frame rate 9 fps 30 fps
Sensor model IMX 226 Sony IMX226
Shutter Rolling Shutter rolling shutter
Data interface GigE USB 3.0
Pixel bit depth 8 / 10 / 12 bits 10-bit
Price $560.00 $560.00

All 2 share: Sensor size 1/1.7". Values as printed in each product's data sheet; open a part for its drawing and full specifications.

Whatever you order, the sequence stays the same: mode first, link arithmetic second, parameter third, measurement last. The systems topic page collects the rest of the stream-setup fixes, and if the rate you need is on no data sheet, size the camera, lens and light together in the camera configurator or ask through the contact page.

Questions

Why is there no image_color/compressed topic at all?

The debayer nodelet subscribes to the raw stream and publishes color topics only when raw frames arrive; image_transport also creates the compressed variants lazily, on the first published frame. No raw frames means no image_color and no compressed topics, even though the nodelet loaded without errors. Restore the raw rate first, and the color topics appear at the same rate with no further configuration.

What frame rate can a 12 MP camera reach over GigE?

Divide the link payload by the frame size: 118 MB/s ÷ 12 MB for an 8-bit full-resolution frame gives about 9.8 Hz, so set 9 Hz or lower, or shrink the frame. Binning 2×2 cuts the frame to 3 MB and lifts the ceiling to about 37-39 Hz. This is why 12 MP GigE cameras print 9 fps-class full-resolution rates.

How long can the exposure be at the rate I asked for?

Use 1000 ÷ frame rate as the exposure limit in milliseconds: at a 30 Hz set the period is 33.3 ms, so keep the exposure at or below roughly 30 ms. Longer exposures make the camera skip frames, so the published rate drops even though the frame_rate parameter is valid and the link has bandwidth to spare.

Does binning or ROI change the rate the camera accepts?

Yes. The allowed range belongs to the current video mode, and binning and ROI both define that mode. A 30 Hz set that the camera refuses at full resolution becomes legal once 2×2 binning quarters the frame to 3 MB, lifting the USB3 ceiling to 120 Hz and the GigE ceiling into the high 30s. Re-read the range after every mode change instead of reusing the previous value.

The raw topic runs at full rate but the color topic is slow — is the camera still at fault?

No. If rostopic hz on the raw topic already matches the requested rate, the camera, the link and the frame_rate parameter are all sound; the bottleneck is debayer and downstream processing. Because the debayer nodelet shares memory with the driver inside the nodelet manager, the usual culprits are the nodes after it — move heavy work out of the callback chain or shrink the images flowing through.