Files
rtabmap_ros/rtabmap_util/doc/rgbd_relay.md
T
matlabbe cf7d7ab958 Supporting image compression formats passthrough (#1461)
* Supporting ros depth compression formats passthrough

* Added image_compression_format (support jpg,png). Use Compression.h constants.

* Bridging gap with #1457

* CoreWrapper: decode_images_on_demand

* rgbd_sync->rgbd_split encoding/decoding test with image_transport validation. rgbd_split color passthrough

* more tests

* fixing ci on kilted+

* fixing test

* fixing lyrical tests

* fixing rolling ci

* Improved test coverage

* fixing some tf waitForTransform deadlocks when sim time is used in tests

* CI: build rtabmap_slam on rolling

rtabmap_slam builds without nav2_msgs, which is not on resolute yet: skip its
key instead of leaving the package out. Only rtabmap_costmap_plugins (and the
rtabmap_ros metapackage pulling it in) still need nav2.
2026-10-10 16:05:08 -07:00

6.0 KiB

rgbd_relay

Republishes an rtabmap_msgs/msg/RGBDImage, optionally compressing or decompressing it on the way through.

An RGBDImage can carry its images raw or compressed. This node converts between the two so that the expensive form crosses the network only where it has to: compress before a wifi link, decompress on the other side.

With both compress and uncompress left false the message is forwarded untouched, which makes the node a plain relay — useful to give a topic a second name, or to bridge two incompatible QoS profiles with qos_sub and qos_pub. See Bridging QoS profiles.

Contents

Usage

Compress before sending over a slow link:

ros2 run rtabmap_util rgbd_relay --ros-args \
  -r rgbd_image:=/camera/rgbd_image \
  -p compress:=true
ComposableNode(
    package='rtabmap_util',
    plugin='rtabmap_util::RGBDRelay',
    name='rgbd_relay',
    parameters=[{'compress': True}],
    remappings=[('rgbd_image', '/camera/rgbd_image')])

A relay at each end of the link, so only the compressed form crosses it. Once it is raw again it feeds the SLAM node directly, and rgbd_split unpacks it into the plain Image topics RViz can display:

flowchart LR
    subgraph ROBOT["robot"]
        CAM["camera driver"]
        SYNC["rgbd_sync"]
        RELAY1["rgbd_relay<br>compress: true"]
    end
    subgraph REMOTE["remote computer"]
        RELAY2["rgbd_relay<br>uncompress: true"]
        RAW(["rgbd_image_relay"])
        MAP["rtabmap"]
        SPLIT["rgbd_split"]
        RVIZ["RViz"]
    end
    CAM -->|"rgb, depth,<br>camera_info"| SYNC
    SYNC -->|rgbd_image| RELAY1
    RELAY1 -->|compressed| RELAY2
    RELAY2 --> RAW
    RAW --> MAP
    RAW --> SPLIT
    SPLIT -->|rgb, depth| RVIZ

Subscribed Topics

Topic Type Description
rgbd_image rtabmap_msgs/msg/RGBDImage Queue depth queue_sub, 5 by default.

Published Topics

Topic Type Description
rgbd_image_relay rtabmap_msgs/msg/RGBDImage Queue depth queue_pub, 1 by default. Published only when someone is subscribed.

Parameters

Parameter Type Default Description
compress bool false Fill the compressed fields of the output. Color becomes JPEG; depth becomes PNG, or JPEG when the message carries a stereo pair rather than depth (see image_compression_format and depth_compression_format). Fields already compressed on input are passed through as-is.
image_compression_format string ".jpg" With compress, format of the color image, and of the right image of a stereo pair: ".jpg" (lossy, smaller) or ".png" (lossless, larger). An invalid value falls back to ".jpg" with an error.
uncompress bool false Fill the raw fields of the output by decoding the compressed ones. Fields already raw on input are passed through as-is. Depth compressed by rtabmap or by compressed_depth_image_transport is accepted.
depth_compression_format string ".png" With compress, format of the compressed depth, see rgbd_sync's parameter of the same name: ".png" or ".rvl" (32FC1 converted to millimeters), optionally followed by ":<maxDepth>[:<quantization>]" (32FC1 as inverse depth), optionally prefixed by "legacy:" (rtabmap's own format, 32FC1 lossless without depth parameters), or "legacy" ("legacy:.png").
qos int 0 Reliability of both sides: 0 system default, 1 reliable, 2 best effort.
qos_sub int value of qos Reliability of the rgbd_image subscription alone.
qos_pub int value of qos Reliability of the rgbd_image_relay publisher alone.
queue_sub int 5 Queue depth of the rgbd_image subscription. Must be at least 1.
queue_pub int 1 Queue depth of the rgbd_image_relay publisher. Must be at least 1.

Bridging QoS profiles

A subscriber that asks for reliable will not connect to a publisher offering best effort — the request cannot be satisfied, so the two silently never match. A best-effort subscriber, on the other hand, connects to either.

That is a real problem when a camera driver publishes best effort and the consumer insists on reliable. Set the two sides of the relay separately and it forwards across the gap:

ros2 run rtabmap_util rgbd_relay --ros-args \
  -r rgbd_image:=/camera/rgbd_image \
  -p qos_sub:=2 \
  -p qos_pub:=1
flowchart LR
    CAM["camera driver<br>publishes best effort"]
    SYNC["rgbd_sync"]
    RELAY["rgbd_relay<br>qos_sub: 2, qos_pub: 1"]
    MAP["rtabmap<br>needs reliable"]
    CAM -->|"rgb, depth,<br>camera_info"| SYNC
    SYNC -->|rgbd_image| RELAY
    RELAY -->|rgbd_image_relay| MAP

Both parameters default to qos, so setting qos alone configures both sides at once.

Reliability is all that is bridged — durability is left at the default, so a transient-local publisher is not converted. The queue depths are separate too, through queue_sub and queue_pub.

Notes

Setting neither compress nor uncompress forwards the message unchanged and skips all image handling — the cheapest path by a wide margin.

Setting both is allowed and produces a message carrying each image twice, raw and compressed. That is rarely what you want.

Depth is compressed as PNG by default (see depth_compression_format), in compressed_depth_image_transport's format, color and stereo right images as JPEG by default (see image_compression_format), in compressed_image_transport's format.