You launched the simulation, opened RViz2, added an Image display, and the camera topic is not there. The guide showed /camera, ros2 topic list prints nothing like it, and every other node in the stack looks healthy. This is the most common camera snag in ROS 2 integration, and it is almost never a broken sensor. This troubleshooting guide is for engineers wiring cameras, simulated or real, into a ROS 2 system. Working through it takes minutes: you will enumerate the live topic graph, read what a node really publishes, separate a naming problem from a dead stream, and fix a display that stays grey.
Why is the camera topic missing in ROS 2?
The topic is almost never missing: the node is publishing, but under names the documentation never mentioned, and one command — ros2 topic list -t, run while the stack is up — settles the question in under a minute.
Documentation trails code. A guide written against one release shows /camera, while the package you installed a year later publishes namespaced names such as /camera_front/color/image_raw. The first response to a missing-topic report is therefore to read the graph, not the guide: whatever the docs claim, your subscribers, displays and tests must attach to the names the launched nodes actually advertise.
How do I list every topic a camera node actually publishes?
Run ros2 topic list -t while the stack is up to print every live topic with its message type, then ros2 node info on the camera node to see its publishers, subscribers and services, including topics the plain list hides.
If you do not know the node's name yet, ros2 node list comes first. With names in hand:
$ ros2 topic list -t
/camera_front/color/camera_info [sensor_msgs/msg/CameraInfo]
/camera_front/color/image_raw [sensor_msgs/msg/Image]
/camera_front/depth/camera_info [sensor_msgs/msg/CameraInfo]
/camera_front/depth/image_raw [sensor_msgs/msg/Image]
/camera_front/depth/points [sensor_msgs/msg/PointCloud2]
/tf [tf2_msgs/msg/TFMessage]
The names come from a typical two-camera robot stack; read your own output the same way. ros2 topic info /camera_front/color/image_raw then prints the type, the publisher count and the subscriber count in one line, and a publisher count of 1 tells you a live node owns the topic.
Why does the simulator publish no camera topics at all?
Check the simulator's own transport before ROS: gz topic -l | grep camera lists the Gazebo-side camera streams, and an empty result means the spawned robot model carries no camera sensor, so there is nothing for a bridge to forward.
Two causes cover nearly every case. First, launch arguments: many simulation stacks take an argument that selects the sensor configuration, and the default spawns the base model without cameras. Relaunching with the full sensor configuration — ros2 launch my_robot_sim robot_sim.launch.py configuration:=full, with your stack's own file and argument names — adds the camera model, and the topics appear.
Second, the bridge: the Gazebo-ROS bridge maps Gazebo Transport names to ROS names, and the two sides need not match. List both with gz topic -l and ros2 topic list, and compare them pair by pair. Simulators fail in their own dialects; the same checklist applies after other engine setups, and the walkthrough of resolving missing topics after a ROS 2 Humble simulator setup covers a common one step by step.
Why does RViz2 show nothing even with the right topic?
If the topic appears in ros2 topic list and frames flow, but the RViz2 Image display stays grey, the usual cause is QoS: image publishers commonly use Best Effort reliability, and a display left on Reliable never receives a frame.
In the display's settings, set the Reliability Policy to Best Effort and pick the topic again; PointCloud2 displays on depth topics need the same treatment. If the driver also publishes a CompressedImage sibling, the Image display can subscribe to that directly. For a second opinion outside RViz2, ros2 run rqt_image_view rqt_image_view lists every image topic in one window. The neighbouring fault — display set, topic right, still grey — is the subject of RViz2 image topic published but not displaying: fix the QoS mismatch.
How do I tell a naming problem from a dead stream?
A topic in the list with a live publisher but zero messages is a stream problem, not a name problem: ros2 topic hz /camera_front/depth/image_raw held for about ten seconds prints the frame rate, and 0.0 Hz means the sensor or bridge is producing nothing.
Probe in order. ros2 topic echo --once on the topic either prints one message or times out; ros2 topic hz gives the rate; ros2 topic bw gives bytes per second. echo with --field encoding prints just the pixel encoding, and camera_info carries the width and height, which is all the arithmetic needs:
A 640 × 480 depth image in 16UC1 encoding carries 2 bytes per pixel, so one frame is 640 × 480 × 2 = 614,400 bytes, about 0.61 MB. At 30 fps the stream must move 0.61 MB × 30 = 18.4 MB/s. If ros2 topic bw reads near 18 MB/s, frames are whole; near 9 MB/s suggests half the frames or half the resolution; a few kB/s means effectively no data.
Four symptoms, four decisions:
- No camera topic under any name: the sensor never entered the launched configuration; fix the launch arguments.
- Topic present, 0.0 Hz: a stream fault at the sensor, driver or bridge; check stream-enable settings first, as in ROS infrared topics no messages: check stream enable settings.
- Topic present with a counted rate: it was a name problem; repoint your code.
- Frames counted but the display is grey: QoS, as above.
How do namespaces and remaps change the topic name?
A camera node's topic names are set by its remap rules and namespace at launch, so the same driver publishes /camera/image_raw on the bench and /robot2/front_camera/image_raw on the robot with no change to its source.
Launch files pass a namespace and a remappings list, which is why a checkout on a multi-robot system shows names the single-robot documentation never mentions. Two habits prevent the surprise: give every camera wrapper its own namespace, as planned in ROS multi camera topic names: give each wrapper a namespace, and when a consumer expects depth under a fixed name, remap at launch, as worked through in Remap depth camera topics for a ROS people detection node.
Every image topic also travels with a camera_info sibling. If the image appears but camera_info does not, the calibration file is missing or misnamed, which camera_info not published: fix the calibration file path and name repairs; ROS 2 camera calibration: validate and publish camera_info keeps it correct afterwards.
When should I move the diagnosis to a real camera?
Switch to hardware once the topic graph makes sense, because the same three commands work unchanged against a physical camera's driver node: list, node info and hz. What changes is the driver layer underneath, not the diagnosis.
Machine-vision cameras stream over GigE Vision or USB3 Vision, and in ROS 2 a driver node wraps that transport and publishes sensor_msgs/msg/Image plus camera_info, so the graph tools read a factory camera exactly like the simulator. Two hardware-only faults join the list: a USB camera that probes but stays silent usually has its controls aimed at the wrong device node — v4l2-ctl list-ctrls returns nothing: controls live on the right node is that exact fault — and depth frames that vanish on the machine, not in the graph, are traced end to end in Depth stream missing on Linux: find where frames stop.
For a bench rig that mirrors production, pick a color and a mono model from the area scan cameras:
- Sensor format
- 1/1.7"
- Lens mount
- C-mount
- Sensor format
- 1/1.7"
- Lens mount
- C-mount
- Sensor format
- 1"
- Lens mount
- C-mount
Point-cloud and depth topics come from 3D hardware; the 3D depth cameras category holds the laser profilers, stereo sensors and ToF cameras, and a ToF sensing camera is the simplest of that class to start with:
- Type
- Depth / ToF camera
Whatever the sensor, the three graph commands read it the same way. A 12 MP, 9 fps GigE stream is ample for graph checks and slow pipelines; step up resolution only when the production pipeline itself needs the pixels. The camera finder filters by interface, resolution and shutter when the bench needs something else.
The configurator matches a camera, lens, light, light controller and cables to each other, step by step, and lists only parts that fit what you already picked.
How do I stop tutorial names from breaking the next project?
Treat the live graph as the interface: after the first launch of any new stack, capture ros2 topic list -t into the project notes and write every subscriber, display and test against those captured names, never against the documentation's.
Make the capture a habit, not a memory:
- Paste the ros2 topic list -t output into the project README, dated and next to the stack version it belongs to.
- Diff the capture after every stack upgrade; a new namespace shows up as a rename.
- Check the contract before writing a subscriber: ros2 interface show sensor_msgs/msg/Image lists the exact fields your code will read.
- Keep one namespace per camera so two drivers never fight for the same names.
Decided per symptom, the whole fault is four lines: no topic at all means the launch arguments; 0.0 Hz means the stream; a counted rate means it was the name; a grey display means QoS. Three commands — ros2 topic list -t, ros2 node info, ros2 topic hz — decide among the four in about two minutes. The neighbouring graph faults, from QoS mismatches to compression routing, are collected on the systems topic page.
Questions
What is the difference between ros2 topic list and ros2 node info?
ros2 topic list prints every topic on the graph at once, fast but anonymous; ros2 node info shows one node's publishers, subscribers and services grouped under it, which is how you attribute a topic to the node that owns it. Use the list to discover names, node info to trace ownership, and ros2 topic info on a single name for its type and publisher count.
Why does the camera render in rqt_image_view but not in my subscriber?
The viewer and your code rarely share the same QoS profile. Image publishers commonly declare Best Effort; a subscription that requests Reliable is incompatible and receives nothing, while the viewer set to Best Effort works. Create the subscription with sensor-data QoS, Best Effort reliability and volatile durability, and the frames arrive. The graph commands prove the publisher was alive the whole time.
How many topics does a stereo depth camera normally publish?
Commonly six to eight: an image for each sensor, a depth image, one camera_info per image topic and often a point cloud, all under the node's namespace. The exact set depends on the driver, so count them with ros2 topic list -t on your own stack rather than assuming the tutorial's list. Depth and camera_info names must pair up correctly for depth color alignment to work.
Can I rename a camera topic without editing the driver?
Yes, with a remap rule at launch: a remapping argument reroutes the node's published name to the one your system expects, with no source change. Remaps apply when the node starts, so restart it after editing, and confirm with ros2 node info that the new name is live. Keep one namespace per camera when two drivers would otherwise collide.



