> ## 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.

# QRB ROS Transport

`qrb_ros_transport` is a zero‑copy ROS 2 transport for Qualcomm robotics platforms. It's implemented on top of [REP 2007](https://ros.org/reps/rep-2007.html) (Type Adaptation), which lets a ROS node declare that a custom message type is interchangeable with a standard one — so the middleware can hand off the DMA‑buf file descriptor that the camera ISP wrote instead of serializing and copying the pixel payload.

```mermaid theme={null}
flowchart LR
    subgraph stock["Stock image_transport"]
        A1[Camera Node<br/>CPU] -->|serialize| B1[memcpy<br/>CPU]
        B1 -->|copy bytes| C1[Consumer Node<br/>CPU/GPU/NPU]
    end
    subgraph qrb["qrb_ros_transport"]
        A2[Camera ISP] -->|DMA-buf fd| B2[Consumer Node<br/>GPU/NPU/EVA]
    end
```

In the stock path every subscriber receives its own copy of the frame, and every copy is a CPU memcpy. In the QRB path the producer and all consumers share the same DMA buffer — the fd is what travels through the ROS graph, not the pixels.

## Supported adapted types

| QRB adapted type                                                                                                                                                                                            | Stock ROS interface                                                                                                       |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| [`qrb_ros::transport::type::Image`](https://github.com/qualcomm-qrb-ros/qrb_ros_transport/blob/main/qrb_ros_transport_image_type/include/qrb_ros_transport_image_type/image.hpp)                            | [`sensor_msgs::msg::Image`](https://github.com/ros2/common_interfaces/blob/rolling/sensor_msgs/msg/Image.msg)             |
| [`qrb_ros::transport::type::PointCloud2`](https://github.com/qualcomm-qrb-ros/qrb_ros_transport/blob/main/qrb_ros_transport_point_cloud2_type/include/qrb_ros_transport_point_cloud2_type/point_cloud2.hpp) | [`sensor_msgs::msg::PointCloud2`](https://github.com/ros2/common_interfaces/blob/rolling/sensor_msgs/msg/PointCloud2.msg) |

<Note>
  An [`Imu` adapted type](https://github.com/qualcomm-qrb-ros/qrb_ros_transport/blob/main/qrb_ros_transport_imu_type/include/qrb_ros_transport_imu_type/imu.hpp) also exists upstream, but producing data through it requires `qrb_sensor_client` + the specific ICM-42688 IMU on the RB3 Gen2 kit. If you have that exact hardware, see [`qrb_ros_imu`](https://github.com/qualcomm-qrb-ros/qrb_ros_imu). For typical use cases the bandwidth case lives in `Image` and `PointCloud2` — IMU payloads are tiny enough that zero-copy adds little.
</Note>

## Supported targets

| Hardware                         |
| -------------------------------- |
| Qualcomm Dragonwing™ IQ‑9075 EVK |

<Note>
  IQ‑8275 EVK is not currently listed by the upstream `qrb_ros_transport` README. Check the [upstream repo](https://github.com/qualcomm-qrb-ros/qrb_ros_transport) for the latest supported targets before building.
</Note>

## Vs. stock `image_transport`

Stock `image_transport` / `sensor_msgs::Image` always serializes the payload into the ROS message and copies it into each subscriber's buffer. That's fine for small topics and CPU-resident data, but it's wasted work when the producer is a hardware block that wrote the frame into DMA memory (the camera ISP is the common case) and the consumer is another hardware block (GPU for color conversion, NPU for inference, EVA for computer-vision ops). `qrb_ros_transport` exists specifically for that hardware‑to‑hardware case — the pixels stay in DMA memory, and only the fd moves.

If both ends of your topic are CPU code, stock `image_transport` is fine and simpler. The zero‑copy win scales with (payload size × number of subscribers × number of node boundaries crossed).

## Installation

<Info>
  These steps require **Qualcomm Ubuntu** and **ROS 2 Jazzy**. Start from [Install Ubuntu on Qualcomm IoT Platforms](https://ubuntu.com/download/qualcomm-iot) and [Install ROS Jazzy](https://docs.ros.org/en/jazzy/index.html) if you haven't already. For Qualcomm Linux, use the [QIRP SDK](https://docs.qualcomm.com/bundle/publicresource/topics/80-70018-265/introduction_1.html?vproduct=1601111740013072\&version=1.4\&facet=Qualcomm%20Intelligent%20Robotics%20Product%20\(QIRP\)%20SDK) instead.
</Info>

<Steps>
  <Step title="Add the Qualcomm IoT PPAs">
    ```bash theme={null}
    sudo add-apt-repository ppa:ubuntu-qcom-iot/qcom-ppa
    sudo add-apt-repository ppa:ubuntu-qcom-iot/qirp
    sudo apt update
    ```
  </Step>

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

## Usage

Add the adapted type as a dependency and write against it the same way you'd write against any typed ROS message — the middleware handles the rest.

<CodeGroup>
  ```xml package.xml theme={null}
  <depend>qrb_ros_transport_image_type</depend>
  ```

  ```cmake CMakeLists.txt theme={null}
  find_package(ament_cmake_auto REQUIRED)
  ament_auto_find_build_dependencies()
  ```

  ```cpp publisher.cpp theme={null}
  #include "qrb_ros_transport_image_type/image.hpp"

  // Create message
  auto msg = std::make_unique<qrb_ros::transport::type::Image>();
  msg->header   = std_msgs::msg::Header();
  msg->width    = width;
  msg->height   = height;
  msg->encoding = "nv12";

  // Allocate dmabuf for message
  auto dmabuf = lib_mem_dmabuf::DmaBuffer::alloc(size, "/dev/dma_heap/system");
  // ... populate dmabuf ...
  msg->dmabuf = dmabuf;

  // Publish — no memcpy: subscribers receive the fd, not the payload
  pub->publish(std::move(msg));
  ```
</CodeGroup>

<AccordionGroup>
  <Accordion title="Build from source" icon="hammer">
    Install the development dependencies:

    ```bash theme={null}
    sudo add-apt-repository ppa:ubuntu-qcom-iot/qcom-noble-ppa
    sudo add-apt-repository ppa:ubuntu-qcom-iot/qirp
    sudo apt update

    sudo apt install ros-dev-tools \
      ros-jazzy-lib-mem-dmabuf \
      ros-jazzy-qrb-sensor-client \
      ros-jazzy-pcl-conversions
    ```

    Clone and build with `colcon`:

    ```bash theme={null}
    source /opt/ros/jazzy/setup.bash
    git clone https://github.com/qualcomm-qrb-ros/qrb_ros_transport.git
    colcon build
    ```
  </Accordion>
</AccordionGroup>

<AccordionGroup>
  <Accordion title="How it's built" icon="layer-group">
    `qrb_ros_transport` sits on top of two upstream packages in the same org:

    ```mermaid theme={null}
    flowchart TB
        L["<b>lib_mem_dmabuf</b><br/>userspace DMA-buf helper<br/>(alloc, mmap, fd passing)"]
        D["<b>dmabuf_transport</b><br/>portable REP 2007 adapted types<br/>(Image, PointCloud2)"]
        Q["<b>qrb_ros_transport</b><br/>Qualcomm-optimized<br/>(Image, PointCloud2, Imu adapter)"]
        L --> D
        D --> Q
        classDef portable fill:#F4EFFA,stroke:#31017D,color:#31017D,stroke-width:1.5px;
        classDef silicon fill:#31017D,stroke:#31017D,color:#fff,stroke-width:1.5px;
        class L,D portable;
        class Q silicon;
    ```

    You don't interact with either directly when using `qrb_ros_transport` — they're pulled in transitively. The pointers are here for readers who want the full stack or who need to port code to non-Qualcomm Linux SoCs with DMA-heap support:

    * [`dmabuf_transport`](https://github.com/qualcomm-qrb-ros/dmabuf_transport) — portable REP 2007 adapted types for `Image` and `PointCloud2`. Works on any Linux 5.12+ SoC with a DMA heap.
    * [`lib_mem_dmabuf`](https://github.com/qualcomm-qrb-ros/lib_mem_dmabuf) — the userspace C++ DMA-buf allocation library. Use directly only if you're doing non-ROS interop (GStreamer, V4L2, custom drivers, OpenGL ES).
  </Accordion>
</AccordionGroup>

## Related

* Sample pipelines that use `qrb_ros_transport` as the camera path: [QRB ROS Samples](./qrb-ros-samples).
* Upstream source and latest docs: [`qualcomm-qrb-ros/qrb_ros_transport`](https://github.com/qualcomm-qrb-ros/qrb_ros_transport).
