mirror of
https://github.com/introlab/rtabmap_ros.git
synced 2026-10-04 08:47:45 +08:00
* rtabmap_sync tests and doc * Added some diagrams * cleanup some diagrams * fixing running tests in parallels
91 lines
5.0 KiB
Markdown
91 lines
5.0 KiB
Markdown
# rgb_sync
|
|
|
|
Groups a camera's color image and calibration into a single [`rtabmap_msgs/msg/RGBDImage`](https://docs.ros.org/en/jazzy/p/rtabmap_msgs/msg/RGBDImage.html), with no depth.
|
|
|
|
The monocular counterpart of [rgbd_sync](rgbd_sync.md). It exists for pipelines that have no depth to offer: a single camera doing appearance-based loop closure detection and relocalization against a map built earlier, where images are used to recognize places rather than to reconstruct them.
|
|
|
|
Without depth, RTAB-Map cannot build a metric map from these frames alone. It can still detect that a place has been seen before, which is enough for relocalization in an existing map and for adding loop closure constraints to a graph whose geometry comes from odometry or a lidar.
|
|
|
|
The camera cannot supply a pose here — visual odometry needs depth or a stereo baseline — so the pose has to come from somewhere else:
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
CAM["camera driver"]
|
|
SYNC["rgb_sync"]
|
|
ODOM["odometry source<br>wheel, lidar or external"]
|
|
MAP["rtabmap"]
|
|
CAM -->|rgb/image| SYNC
|
|
CAM -->|rgb/camera_info| SYNC
|
|
SYNC -->|rgbd_image| MAP
|
|
ODOM -->|odometry| MAP
|
|
```
|
|
|
|
## Usage
|
|
|
|
```bash
|
|
ros2 run rtabmap_sync rgb_sync --ros-args \
|
|
-r rgb/image:=/camera/image_raw \
|
|
-r rgb/camera_info:=/camera/camera_info
|
|
```
|
|
|
|
```python
|
|
ComposableNode(
|
|
package='rtabmap_sync',
|
|
plugin='rtabmap_sync::RGBSync',
|
|
name='rgb_sync',
|
|
remappings=[('rgb/image', '/camera/image_raw'),
|
|
('rgb/camera_info', '/camera/camera_info')])
|
|
```
|
|
|
|
## Subscribed Topics
|
|
|
|
| Topic | Type | Description |
|
|
|---|---|---|
|
|
| `rgb/image` | [`sensor_msgs/msg/Image`](https://docs.ros.org/en/jazzy/p/sensor_msgs/msg/Image.html) | Color image. Goes through `image_transport`. |
|
|
| `rgb/camera_info` | [`sensor_msgs/msg/CameraInfo`](https://docs.ros.org/en/jazzy/p/sensor_msgs/msg/CameraInfo.html) | Calibration of the camera. |
|
|
|
|
## Published Topics
|
|
|
|
| Topic | Type | Description |
|
|
|---|---|---|
|
|
| `rgbd_image` | [`rtabmap_msgs/msg/RGBDImage`](https://docs.ros.org/en/jazzy/p/rtabmap_msgs/msg/RGBDImage.html) | The image and its calibration. The depth slot is left empty unless `fill_empty_depth`. Published only when someone is subscribed. |
|
|
| `rgbd_image/compressed` | [`rtabmap_msgs/msg/RGBDImage`](https://docs.ros.org/en/jazzy/p/rtabmap_msgs/msg/RGBDImage.html) | The same frame with the image as JPEG. Published only when someone is subscribed. |
|
|
|
|
The output's `header.frame_id` comes from the camera_info; its `header.stamp` is the image's.
|
|
|
|
## Parameters
|
|
|
|
| Parameter | Type | Default | Description |
|
|
|---|---|---|---|
|
|
| `approx_sync` | `bool` | `false` | Match the image and its calibration by nearest stamp. Defaults to **exact**; see [Synchronization](#synchronization). |
|
|
| `approx_sync_max_interval` | `double` | `0.0` | Reject pairs spanning more than this many seconds. `0` disables. |
|
|
| `topic_queue_size` | `int` | `10` | Queue depth of each input subscription. |
|
|
| `sync_queue_size` | `int` | `10` | Queue depth of the synchronizer. |
|
|
| `queue_size` | `int` | — | **Deprecated**, renamed to `sync_queue_size`. |
|
|
| `qos` | `int` | `0` | Reliability of the subscription and the publishers: `0` system default, `1` reliable, `2` best effort. |
|
|
| `qos_camera_info` | `int` | value of `qos` | Reliability of the `rgb/camera_info` subscription alone. |
|
|
| `fill_empty_depth` | `bool` | `false` | Add an all-zero depth image the size of the color one. See below. |
|
|
| `compressed_rate` | `double` | `0.0` | Maximum rate, in Hz, of `rgbd_image/compressed`. `0` means every frame. |
|
|
| `image_transport` | `string` | `"raw"` | Transport for `rgb/image`, e.g. `compressed`. |
|
|
|
|
## fill_empty_depth
|
|
|
|
By default the output carries no depth image and no depth calibration, which is how a consumer tells "this camera has no depth" from "this frame's depth happens to be all zeros".
|
|
|
|
Some consumers refuse a message without one. `fill_empty_depth` gives them a depth image of the right size and encoding (`16UC1`) filled with zeros, registered to the color camera and sharing its calibration. Zero in a depth image means *no reading*, so the frame still carries no geometry — the flag changes the shape of the message, not its content. Leave it off unless something downstream requires it.
|
|
|
|
## Synchronization
|
|
|
|
`approx_sync` defaults to **false** here. A driver built on `image_transport`'s camera publisher sends the image and its `camera_info` as a pair carrying the same stamp, so there is nothing to approximate: the exact policy is cheaper and cannot mismatch.
|
|
|
|
Set `approx_sync:=true` when the two do not share a stamp — a `camera_info` republished on its own timer, or read from a YAML file and stamped with the current time. That is the case to watch for if the node is silent: the calibration values are constant and look fine, but their stamps never match an image.
|
|
|
|
```bash
|
|
ros2 topic echo --once /camera/image_raw --field header.stamp
|
|
ros2 topic echo --once /camera/camera_info --field header.stamp
|
|
```
|
|
|
|
## Diagnostics
|
|
|
|
The node publishes to `/diagnostics` — input rate, output rate, and a warning in the log every 5 seconds while nothing is arriving.
|