This commit is contained in:
obshenlanzhou
2025-11-17 01:39:39 +00:00
parent b1049146eb
commit 7f4ac6cc82
98 changed files with 1813 additions and 1075 deletions
@@ -1,161 +1,177 @@
# Multi_camera_synced_verification_tool
# Multi-Camera Synchronization Verification Node
> This article will introduce how to verify the synchronization accuracy of multi-camera synchronization.
>
> First, please see how to use [multi_camera_synced](./multi_camera_synced.md).
**File path:** [image_sync_example_node.cpp](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/examples/multi_camera_time_sync/image_sync_example_node.cpp)
You can find example usage code in the [example](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples).
This example node is designed for **synchronized capture and timestamp verification** across **four Orbbec cameras**.
It can be used to validate frame alignment accuracy under the multi-camera **Primary / Secondary Synced** mode.
## Directory Structure
---
## Usage Guide
### **Modify `multi_camera_synced.launch.py` as follows**
- Add `launch_include` to support four cameras.
- Select the appropriate launch file based on your camera model.
For example, use `gemini_330_series.launch.py` for the Gemini 330 series.
- Naming convention:
`camera_name` should follow the format `camera_01`, `camera_02`, `camera_03`, ...
- Set `device_num` to **4**.
- Configure the USB ports using:
`ros2 run orbbec_camera list_devices_node`
to view and bind the correct ports.
- Set synchronization mode to **Primary/Secondary Synced**,
with one camera as **primary** and the others as **secondary_synced**.
- **Startup sequence:**
The **Primary camera should always be launched last** to ensure the synchronization signal is established correctly.
---
### **Modify configuration files**
Edit the following two files under the `config` directory:
- `camera_params.yaml`
- `camera_secondary_params.yaml`
Ensure the following settings are consistent across all cameras:
- Enable both **depth** and **color** streams.
- Use the same **frame rate (fps)** for all cameras.
---
### **Launch and Verification**
- Start the multi-camera synchronization launch file:
`ros2 launch orbbec_camera multi_camera_synced.launch.py`
- In a new terminal, run the synchronization verification node:
`ros2 run orbbec_camera image_sync_example_node`
This node outputs timestamp differences between multiple camera streams for synchronization validation.
---
### **Reference Launch File**
```plaintext
.
├── multicamera_sync/
│ ├── output/
│ ├──20250218102900/
│ ├──DevicesInfo.txt
│ ├──StreamProfileInfo.txt
│ ├── Python/
│ ├──Config.ini
├── gemini_330_series_synced_verify.launch.py
├── multi_camera_synced_verify.launch.py
```
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import IncludeLaunchDescription, GroupAction, TimerAction
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node, LoadComposableNodes
**multicamera_sync**
* `gemini_330_series_synced_verify.launch.py` : Single camera runs launch, which provides the camera running node for multi_camera_synced_verify.launch.py.
* `multi_camera_synced_verify.launch.py` : Multi camer synced + launch of save_rgbir tool.
**output**
def generate_launch_description():
# Include launch files
package_dir = get_package_share_directory("orbbec_camera")
launch_file_dir = os.path.join(package_dir, "launch")
config_file_dir = os.path.join(package_dir, "config")
config_file_path = os.path.join(config_file_dir, "camera_params.yaml")
secondary_config_file_path = os.path.join(config_file_dir, "camera_secondary_params.yaml")
> The `ouput` folder is the folder where the camera pictures are output
launch1_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, "gemini_330_series.launch.py")
),
launch_arguments={
"camera_name": "camera_01",
"usb_port": "2-2.3",
"device_num": "4",
"sync_mode": "primary",
"config_file_path": config_file_path,
"trigger_out_enabled": "true"
}.items(),
)
In the output example provided
launch2_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, "gemini_330_series.launch.py")
),
launch_arguments={
"camera_name": "camera_02",
"usb_port": "2-1",
"device_num": "4",
"sync_mode": "secondary_synced",
"config_file_path": secondary_config_file_path,
"trigger_out_enabled": "false"
}.items(),
)
* `20250218102900` : Represents the camera image information collected at 10:29:00 on February 18, 2025.
* `TotalModeFrames` : Camera image information storage directory.
* `results-2025-02-25_163648` : The result after analyzing and matching the image information of TotalModeFrames.
* `DevicesInfo.txt` : Camera equipment basic information (need to be modified).
* `StreamProfileInfo.txt` : Camera video stream information (no need to modify).
launch3_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, "gemini_330_series.launch.py")
),
launch_arguments={
"camera_name": "camera_03",
"usb_port": "2-3",
"device_num": "4",
"sync_mode": "secondary_synced",
"config_file_path": secondary_config_file_path,
"trigger_out_enabled": "false"
}.items(),
)
**Python**
launch4_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, "gemini_330_series.launch.py")
),
launch_arguments={
"camera_name": "camera_04",
"usb_port": "2-4",
"device_num": "4",
"sync_mode": "secondary_synced",
"config_file_path": secondary_config_file_path,
"trigger_out_enabled": "false"
}.items(),
)
* `Config.ini` : Configuration file for Python analysis script (need to be modified).
## Preparation for operation
**save_rgbir node**
Edit multi_camera_synced_verify.launch.py and fill in the activated camera device,we can find that save_rgbir is started at the end.
> IMPORTANT
>
> If you are using ROS 2 Foxy, you need to launch the save_rgbir node first.
```python
# Launch description
# Launch description
ld = LaunchDescription(
[
shared_orbbec_container,
TimerAction(period=0.0, actions=[GroupAction([launch2_include])]),
TimerAction(period=2.0, actions=[GroupAction([launch1_include])]),
TimerAction(period=2.0, actions=[GroupAction([launch3_include])]),
TimerAction(period=4.0, actions=[GroupAction([launch4_include])]),
TimerAction(period=6.0, actions=[GroupAction([launch1_include])]),
# The primary camera should be launched at last
TimerAction(period=6.0, actions=[GroupAction([save_rgbir])]),
# save_rgbir is synced verification tool
]
)
return ld
```
save_rgbir is a tool for saving images. The configuration file of this tool is in [multi_save_rgbir_params.json](../../config/tools/multisavergbir/multi_save_rgbir_params.json).
```json
{
"save_rgbir_params": {
"time_domain": "global",
"usb_ports": [
"2-1",
"2-3"
],
"camera_name": [
"camera_01",
"camera_02"
]
}
}
```
* `time_domain` : Timestamp Type
* `usb_ports` : "primary", "secondary 1", "secondary 2", "secondary 3", fill in as many usb_ports as there are cameras
* `camera_name` : The name of the camera setting, for example: camera_01
---
**DevicesInfo.txt**
## System Configuration Requirements
Edit DevicesInfo.txt. Only the `primarySerialNumber`, `index` and `serialNumber` parameters need to be changed. Other parameters do not need to be changed.Refer to the example of [20250218102900](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool/multicamera_sync/output/20250218102900).
### **Increase USB Buffer Memory**
* `primarySerialNumber` : The SN serial number of the primary camera
* `index` : Camera index
* `serialNumber` : The SN serial number of the camera
Prevent frame drops caused by concurrent data transmission:
**Config.ini**
`echo 512 | sudo tee /sys/module/usbcore/parameters/usbfs_memory_mb`
Edit Config.ini.Modify `frameRate` and `tspRangeThreshold`.
### **Configure Fast DDS**
## Run this example
**Run launch and save camera pictures**
* First terminal
```bash
ros2 launch orbbec_camera multi_camera_synced_verify.launch.py
```
* Second terminal
```bash
ros2 service call /save_rgbir/start_capture orbbec_camera_msgs/srv/SetInt32 '{data: 100}'
```
When the terminal displays "over", the image is saved.A new multicamera_sync folder will be generated under the workspace.
**Camera pictures naming format**
Take [color_SNCP1E5420006D_Index0_g1739874543227_f0_s1739874543327_e50_d16_.jpg](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool/multicamera_sync/output/20250218102900/TotalModeFrames/SNCP1E5420006D_Index0/color_SNCP1E5420006D_Index0_g1739874543227_f0_s1739874543327_e50_d16_.jpg) as an example
* `color` : This image is a snapshot of the color stream.
* `SNCP1E5420006D` : The camera's SN serial number is CP1E5420006D.
* `Index0` : Camera 0 (usually referred to primary camera).
* `g1739874543227` : “g” represents the global timestamp, which means the global timestamp of this frame is 1739874543227.
* `f0` : The 0th picture of the color stream acquisition of this camera.
* `s1739874543327` : "s" represents the timestamp of the current system, which means the current system timestamp of this frame is 1739874543327.
* `e50` : The exposure of this frame is 50.
* `d16` : The gain of this frame is 16.
**Analyzing camera image data**
You need to copy the modified [Python folder](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multicamera_sync/Python) to the new multi_camera_synced subdirectory, and copy the modified [DevicesInfo.txt ](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool/multicamera_sync/output/20250218102900/DevicesInfo.txt)and [StreamProfileInfo.txt](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multicamera_sync/output/20250218102900/StreamProfileInfo.txt) to the same level directory as the TotalModeFrames folder.
* Finally everything is ready, run the python script
```bash
cd multicamera_sync/Python
python3 SyncFramesMain.py
```
After the operation is successful, you can view the synchronization effect in the `results folder`
## Files that need to be changed
**Analysis tools**
* [multi_save_rgbir_params.json](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/config/tools/multisavergbir/multi_save_rgbir_params.json)
* [DevicesInfo.txt ](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multicamera_sync/output/20250218102900/DevicesInfo.txt)
* [Config.ini](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multicamera_sync/Python/Config.ini)
**Camera Configuration**
[camera_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/config/camera_params.yaml)(Camera startup parameter settings)
[multi_camera_synced_verify.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multi_camera_synced_verify.launch.py)
Optimize ROS2 node communication latency to reduce image transmission delay.
See [this section](../performance/fastdds_tuning.md) for detailed configuration instructions.