> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Run a zero-copy camera with qrb_ros_camera

> The qrb_ros_camera is a ROS package that publishes the images from Qualcomm CSI and GMSL cameras.

The [qrb\_ros\_camera](https://github.com/qualcomm-qrb-ros/qrb_ros_camera) is a ROS package that publishes the images from Qualcomm **CSI** and **GMSL** cameras. It provides the following:

* Support for concurrent multiple streams output.

* Support for composable ROS node.

* Zero-copy transport powered by [QRB ROS Transport](https://github.com/qualcomm-qrb-ros/qrb_ros_transport).

* Support for NV12 only as output format, limited by the Camera Service.

## Pipeline flow for `qrb_ros_camera`

The following figure shows the pipeline flow for `qrb_ros_camera`.

<Frame caption="qrb_ros_camera pipeline.">
  <img src="https://mintcdn.com/qualcomm-prod/EDJV-hu6qJhZi4pm/SDKs/QIR-SDK-Ubuntu/images/image17.svg?fit=max&auto=format&n=EDJV-hu6qJhZi4pm&q=85&s=e9df73382b15053cd7b68bdbf6d81e33" alt="Camera hardware and a camera info YAML file feeding the qrb_ros_camera ROS node through the camera server, which publishes two output topics." width="650" height="258" data-path="SDKs/QIR-SDK-Ubuntu/images/image17.svg" />
</Frame>

The [qrb\_ros\_camera](https://github.com/qualcomm-qrb-ros/qrb_ros_camera/tree/main/qrb_ros_camera) is a ROS 2 package. It creates an image publisher with `qrb_ros_transport` for zero-copy transport. It supports node composition, making it possible to improve performance using ROS intra-process communication.

The [qrb\_camera](https://github.com/qualcomm-qrb-ros/qrb_ros_camera/tree/main/qrb_camera) is a C++ library. It provides APIs to `qrb_ros_camera` for querying images from the lower layer **Camera Service** and CamX libraries.

It includes 2 modules:

* The `camera_manager` module manages the camera stream, which enables the multi-stream support.

* The `camera_client` module calls Camera Service APIs to manage camera streams.

The [qrb\_ros\_transport](https://github.com/qualcomm-qrb-ros/qrb_ros_transport) is a ROS 2 package that supports zero-copy image transport with Linux DMA buffer and implements ROS type adaption. It's compatible with both intraprocessing and interprocessing communication.

The Camera Service is a Qualcomm multimedia framework. It exports APIs for accessing Qualcomm multimedia hardware.

The CamX provides the foundation for image capture, processing, and management on Qualcomm-powered devices.

## `qrb_ros_camera` ROS interfaces and parameters

The `qrb_ros_camera` node exposes ROS interfaces and ROS parameters. Use them to subscribe to the published image topics and to configure the camera streams.

### ROS interfaces

The following table describes the ROS interfaces provided by `qrb_ros_camera`.

| Interface   | Name                              | Type                         | Description                  |
| ----------- | --------------------------------- | ---------------------------- | ---------------------------- |
| `Publisher` | `/cam${camera_id}_${stream_name}` | `sensor_msgs/msg/Image`      | Outputs images.              |
| `Publisher` | `/cam${camera_id}_camera_info`    | `sensor_msgs/msg/CameraInfo` | Provides camera information. |

### ROS parameters

The following table describes the ROS parameters for `qrb_ros_camera`.

| Name                    | Type       | Description                | Default value                    |
| ----------------------- | ---------- | -------------------------- | -------------------------------- |
| `camera_id`             | `int64`    | The camera device ID       | `0`                              |
| `stream_size`           | `uint64`   | Count of camera stream     | `1`                              |
| `stream_name`           | `string[]` | camera stream names        | `["stream1"]`                    |
| `${stream_name}.width`  | `uint32`   | image width                | `1920`                           |
| `${stream_name}.height` | `uint32`   | image height               | `1080`                           |
| `${stream_name}.fps`    | `uint32`   | output image frequency(Hz) | `30`                             |
| `camera_info_path`      | `string`   | Camera metadata file path  | `config/camera_info_imx577.yaml` |

## `qrb_ros_camera` library APIs

The following table describes the `qrb_camera` C++ library functions that `qrb_ros_camera` calls.

| Function                                                                                       | Parameter                                                                                                   | Description                                                     |
| ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `int create_camera(CameraType type, uint32_t camera_id)`                                       | • `type`: camera type<br />• `camera_id`: camera id                                                         | Creates a camera and returns the camera index on success.       |
| `bool set_camera_parameter(int index, CameraConfigure & param)`                                | • `index`: camera index<br />• `param`: camera parameters                                                   | Returns `true` when the camera parameters are set successfully. |
| `bool start_camera(int index)`                                                                 | `index`: camera index                                                                                       | Starts the camera. Returns `true` when started successfully.    |
| `void stop_camera(int index)`                                                                  | `index`: camera index                                                                                       | Stops the camera.                                               |
| `bool register_callback(int index, ImageCallback image_cb, PointCloudCallback point_cloud_cb)` | • `index`: camera index<br />• `Image_cb`: image callback<br />• `Point_cloud_cb`: point cloud msg callback | Registers the callback for image and point cloud messages.      |

## Prerequisites

You have set up the device, installed ROS2 Jazzy and Qualcomm Intelligent Robotics (QIR) SDK on the device according to [Install the QIR SDK](./install-the-qir-sdk).

## Run out-of-the-box `qrb_ros_camera`

<Steps>
  <Step title="Install the qrb_ros_camera packages">
    ```bash Install the packages theme={null}
    sudo apt install ros-jazzy-qrb-ros-camera
    ```
  </Step>

  <Step title="Use the camera node">
    ```bash Launch the camera node theme={null}
    source /opt/ros/jazzy/setup.bash
    ros2 launch qrb_ros_camera qrb_ros_camera_launch.py
    ```
  </Step>

  <Step title="Check ROS topics or view the image with the topic /cam${camera_id}_${stream_name} in RVIZ or RQT">
    ```bash theme={null}
    source /opt/ros/jazzy/setup.bash
    ros2 topic echo /cam0_stream1
    ros2 topic echo /cam0_camera_info
    ```
  </Step>

  <Step title="Enable multiple streams">
    By using the `stream_size` and `stream_name` parameters, you can configure multiple streams for one camera in your launch file, such as `/opt/ros/jazzy/share/qrb_ros_camera/launch/qrb_ros_camera_launch.py`.

    ```python qrb_ros_camera_launch.py theme={null}
    parameters=[{
        'camera_id': 0,
        'stream_size': 2,
        'stream_name': ["stream1", "stream2"],
        'stream1':{
            'width':1920,
            'height':1080,
            'fps':30,
        },
        'stream2':{
            'width':1080,
            'height':720,
            'fps':60,
        },
        'camera_info_path': os.path.join(
            get_package_share_directory('qrb_ros_camera'),
            'config', 'camera_info_imx577.yaml'),
    }]
    ```
  </Step>

  <Step title="Enable the zero-copy transport">
    The `qrb_ros_camera` supports directly sharing image `dmabuf_fd` between nodes, which can avoid image data memory copy with DDS.

    <Note>
      For details about this feature, see [ROS documentation](https://docs.ros.org/en/rolling/Concepts/Intermediate/About-Composition.html).
    </Note>
  </Step>
</Steps>

Following is an example that uses launch (recommended) to compose multiple nodes.

```python theme={null}
def generate_launch_description():
    container = ComposableNodeContainer(
        name='my_container',
        namespace='',
        package='rclcpp_components',
        executable='component_container',
        composable_node_descriptions=[
            ComposableNode(
                package='qrb_ros_camera',
                plugin='qrb_ros::camera::CameraNode',
                name='camera_node',
                parameters=[{
                    # ...
                }]
            ),
            ComposableNode(
                package='qrb_ros_camera',
                plugin='qrb_ros::camera::TestNode',
                name='sub_node',
            )
        ],
        output='screen',
    )
    return launch.LaunchDescription([container])
```

## Build and run `qrb_ros_camera`

<Steps>
  <Step title="Install dependencies">
    ```bash Install the dependencies theme={null}
    sudo apt install ros-jazzy-qrb-ros-transport-image-type \
    ros-dev-tools \
      qcom-camera-server \
      qcom-syslog-plumber-dev \
      libqmmf-dev \
      qcom-camxapi-dev
    ```
  </Step>

  <Step title="Clone the repository to the device">
    ```bash Download the source code theme={null}
    mkdir -p ~/ros2_ws/src
    cd ~/ros2_ws/src
    git clone https://github.com/qualcomm-qrb-ros/qrb_ros_camera.git
    ```
  </Step>

  <Step title="Build and run qrb_ros_camera">
    ```bash Build and launch theme={null}
    cd ~/ros2_ws
    colcon build
    source install/setup.bash
    ros2 launch qrb_ros_camera qrb_ros_camera_launch.py
    ```
  </Step>
</Steps>
