Skip to content

unnc-aim/Camera2Topic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

camera2topic

ROS2 (C++) package that discovers every connected USB webcam and Intel RealSense camera and forwards their data as ROS2 topics:

  • USB cameras → RGB image stream (sensor_msgs/Image).
  • RealSense cameras → RGB image, depth (aligned to color), colored point cloud, and camera intrinsics (sensor_msgs/CameraInfo, read from hardware by the official driver).
  • All forwarded topic names are written to a text file for downstream consumers to read.

Designed for Ubuntu / ROS2 (Humble or Jazzy). Discovery happens at launch time, so re-run the launch after plugging/unplugging cameras.

Architecture

Source Driver Topics
USB (UVC) webcam built-in usb_camera_node (OpenCV/V4L2) image only — no intrinsics (by design)
RealSense official realsense2_camera image + depth + pointcloud + intrinsics
built-in topic_recorder_node writes the topic list to a file

Why this split: RealSense ships factory-calibrated intrinsics that the official package exposes automatically; generic USB webcams have none, and intrinsics were intentionally left out for USB (see Future work to add YAML-based intrinsics later).

Topic naming

<serial> is the RealSense's full serial number (sanitized to alnum/underscore), so each camera gets a unique namespace and unique TF frames — multiple RealSense units coexist without topic or TF conflicts.

Camera Prefix Example topics
USB i /usb_cam_<i>/ image_raw (sensor_msgs/Image)
RealSense <serial> /cam_<serial>/ color/image_raw, color/camera_info (intrinsics), aligned_depth_to_color/image_raw (16-bit depth), depth/camera_info, depth/color/points

Exact path depth (/cam_<serial>/color/... vs /cam_<serial>/cam_<serial>/color/...) depends on the realsense-ros version; both start with /cam_ and are recorded. Run ros2 topic list to confirm exact names on your system.

Output file

By default, ~/Desktop/camera2topic_topics.txt, one topic per line:

/usb_cam_0/image_raw [sensor_msgs/msg/Image]
/cameras/cam_831612060238/color/image_raw [sensor_msgs/msg/Image]
...

Override with the output_file launch argument.

Prerequisites (on the target Linux device)

# ROS2 (Humble or Jazzy) already installed + sourced.
sudo apt update
sudo apt install -y ros-<distro>-cv-bridge ros-<distro>-image-transport \
                    ros-<distro>-realsense2-camera ros-<distro>-realsense2-camera-msgs \
                    libopencv-dev v4l-utils

# RealSense udev rules (so /dev/video nodes get correct attributes):
# https://github.com/IntelRealSense/librealsense/blob/master/doc/distribution_linux.md

Build

cd ~/colcon_ws/src
git clone <this-repo-url> camera2topic
cd ~/colcon_ws
rosdep install -i --from-path src -y
colcon build --packages-select camera2topic
source install/setup.bash

Run

# Forward ALL connected USB + RealSense cameras and write the topic file:
ros2 launch camera2topic all_cameras.launch.py

# Common overrides:
ros2 launch camera2topic all_cameras.launch.py output_file:=/tmp/topics.txt
ros2 launch camera2topic all_cameras.launch.py color_profile:=1920,1080,30 depth_profile:=1280,720,30
ros2 launch camera2topic all_cameras.launch.py enable_pointcloud:=false
ros2 launch camera2topic all_cameras.launch.py usb_width:=1280 usb_height:=720 usb_fps:=30
ros2 launch camera2topic all_cameras.launch.py usb_only:=true        # skip RealSense
ros2 launch camera2topic all_cameras.launch.py realsense_only:=true  # skip USB
ros2 launch camera2topic all_cameras.launch.py refresh_period:=5.0   # refresh file every 5s (hot-plug)

# Subsets for debugging:
ros2 launch camera2topic usb_cameras.launch.py
ros2 launch camera2topic realsense_cameras.launch.py

Verify

cat ~/Desktop/camera2topic_topics.txt                                       # the recorded topic list
ros2 topic list                                                        # cross-check
ros2 run rqt_image_view rqt_image_view                                 # view USB + RealSense color
ros2 topic list | grep cam_                                            # find the exact RealSense topic paths first
ros2 topic echo /cameras/cam_<serial>/color/camera_info --once    # RealSense intrinsics (K matrix)
ros2 topic echo /cameras/cam_<serial>/aligned_depth_to_color/image_raw --once  # depth (Z16)
ros2 topic hz /usb_cam_0/image_raw                                     # frame rate

How device discovery works

  • USB: enumerates /dev/video*, reads udev attributes with udevadm info and /sys/class/video4linux/.../name. RealSense nodes are excluded by ID_VENDOR_ID == 8086 (Intel) and a case-insensitive realsense name match. Metadata-only nodes are dropped via ID_V4L_CAPABILITIES (falling back to v4l2-ctl --list-formats-ext). Stable /dev/v4l/by-id/* paths are preferred.
  • RealSense: parses serial numbers from rs-enumerate-devices --compact, falling back to pyrealsense2. Each camera is launched with its own serial_no + camera_namespace so multiple RealSense units coexist.

Both helpers degrade gracefully: missing tools → empty list → that source is simply skipped, launch still succeeds.

Notes / gotchas

  • USB cameras publish no camera_info by design. RealSense intrinsics come from the official package (read from the camera's EEPROM).
  • Hot-plugging: re-run the launch, or set refresh_period so the topic file updates (USB/RealSense node sets themselves are fixed at launch time).
  • Don't rely on stable /dev/videoN numbers — they shift on replug; the discovery code re-scans every launch and prefers by-id paths for USB.
  • RealSense serial_no is passed with inner quotes (a quirk of realsense-ros); this is handled in launch/common.py.

Future work (not included)

  • YAML-based intrinsics for USB cameras (load a calibration per device).
  • image_transport compressed streams.
  • Lifecycle / composable-node packaging.

About

An ROS2 package that converts usb camera/realsense to topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors