|
| 1 | +# Multi-Camera Synchronization Node |
| 2 | + |
| 3 | +A ROS2 node that uses message filters to time-synchronize N camera image messages, supporting both compressed and raw images. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- **Flexible camera count**: Supports 2-6 cameras simultaneously |
| 8 | +- **Image format support**: Works with both `sensor_msgs/Image` (raw) and `sensor_msgs/CompressedImage` |
| 9 | +- **Configurable synchronization**: Adjustable time tolerance and queue sizes |
| 10 | +- **Real-time monitoring**: Synchronization statistics and rate monitoring |
| 11 | +- **Easy integration**: Standard ROS2 node with parameter-based configuration |
| 12 | + |
| 13 | +## Parameters |
| 14 | + |
| 15 | +| Parameter | Type | Default | Description | |
| 16 | +|-----------|------|---------|-------------| |
| 17 | +| `camera_topics` | string[] | `[]` | List of camera image topics to synchronize | |
| 18 | +| `camera_names` | string[] | `[]` | Names for cameras (auto-generated if empty) | |
| 19 | +| `use_compressed` | bool | `false` | Use compressed images instead of raw | |
| 20 | +| `sync_tolerance_ms` | double | `50.0` | Max time difference for sync (milliseconds) | |
| 21 | +| `queue_size` | int | `10` | Message filter queue size | |
| 22 | +| `publish_sync_info` | bool | `true` | Publish synchronization statistics | |
| 23 | + |
| 24 | +## Usage |
| 25 | + |
| 26 | +### Basic 2-camera setup (raw images): |
| 27 | + |
| 28 | +```bash |
| 29 | +ros2 run camera_sync multi_camera_sync_node --ros-args \ |
| 30 | + -p camera_topics:="['/camera1/image_raw', '/camera2/image_raw']" \ |
| 31 | + -p camera_names:="['left_camera', 'right_camera']" |
| 32 | +``` |
| 33 | + |
| 34 | +### 4-camera setup (compressed images): |
| 35 | + |
| 36 | +```bash |
| 37 | +ros2 run camera_sync multi_camera_sync_node --ros-args \ |
| 38 | + -p camera_topics:="['/front/image_raw/compressed', '/rear/image_raw/compressed', '/left/image_raw/compressed', '/right/image_raw/compressed']" \ |
| 39 | + -p camera_names:="['front', 'rear', 'left', 'right']" \ |
| 40 | + -p use_compressed:=true \ |
| 41 | + -p sync_tolerance_ms:=30.0 |
| 42 | +``` |
| 43 | + |
| 44 | +### Using launch files: |
| 45 | + |
| 46 | +```bash |
| 47 | +# Basic launch with configurable parameters |
| 48 | +ros2 launch camera_sync multi_camera_sync.launch.py \ |
| 49 | + camera_topics:="['/cam1/image_raw', '/cam2/image_raw', '/cam3/image_raw']" \ |
| 50 | + use_compressed:=false \ |
| 51 | + sync_tolerance_ms:=25.0 |
| 52 | + |
| 53 | +``` |
| 54 | + |
| 55 | +## How It Works |
| 56 | + |
| 57 | +The node uses ROS2 message filters with approximate time synchronization policy to match images from multiple cameras based on their timestamps. Key components: |
| 58 | + |
| 59 | +1. **Message Subscribers**: Creates subscribers for each camera topic |
| 60 | +2. **Synchronizer**: Uses `message_filters::sync_policies::ApproximateTime` to match messages |
| 61 | +3. **Callback & Publishing**: Creates MultiImage msgs with timestamp to batch the camera images together |
| 62 | +4. **Statistics**: Tracks synchronization rate and timing spread |
| 63 | + |
| 64 | +### Synchronization Logic |
| 65 | + |
| 66 | +- Messages are considered synchronized if their timestamps are within `sync_tolerance_ms` |
| 67 | +- The synchronizer maintains a queue of recent messages from each camera |
| 68 | +- When a valid sync set is found, all cameras' images are processed together |
| 69 | +- Unmatched messages are eventually dropped when they exceed the age penalty |
| 70 | + |
| 71 | + |
| 72 | +## Monitoring |
| 73 | + |
| 74 | +The node provides several ways to monitor synchronization performance: |
| 75 | + |
| 76 | +1. **Console logs**: Periodic sync rate and timing statistics |
| 77 | +2. **ROS2 parameters**: Runtime inspection of configuration |
| 78 | +3. **Debug output**: Detailed timestamp information (when debug logging enabled) |
| 79 | + |
| 80 | +Example log output: |
| 81 | +``` |
| 82 | +[INFO] [multi_camera_sync]: Sync #500: compressed images from 4 cameras, spread: 12.3 ms, rate: 29.8 Hz |
| 83 | +``` |
| 84 | + |
| 85 | +## Dependencies |
| 86 | + |
| 87 | +- `rclcpp` - ROS2 C++ client library |
| 88 | +- `sensor_msgs` - Standard sensor message types |
| 89 | +- `message_filters` - Time synchronization utilities |
| 90 | +- `cv_bridge` - OpenCV integration (for future extensions) |
| 91 | +- `image_transport` - Efficient image transmission |
| 92 | + |
| 93 | +## Limitations |
| 94 | + |
| 95 | +- Maximum 6 cameras supported (can be extended by adding more sync policies) |
| 96 | +- Uses approximate time synchronization (not exact) |
| 97 | +- All cameras must use the same image message type (raw or compressed) |
| 98 | +- Requires reasonably synchronized system clocks across camera sources |
0 commit comments