From 61ee663864286aa79844df6f0bb42d46132dac17 Mon Sep 17 00:00:00 2001 From: ob-yalian Date: Tue, 11 Aug 2026 16:44:22 +0800 Subject: [PATCH] feat: enhance GMSL camera support and configuration options --- orbbec_camera/examples/README.MD | 4 +--- .../gmsl_camera/multi_gmsl_camera.launch.py | 24 +++++++++++++++---- .../multi_gmsl_camera_synced.launch.py | 24 +++++++++++++++---- .../include/orbbec_camera/constants.h | 5 ++++ orbbec_camera/launch/gemini345_lg.launch.py | 2 ++ .../launch/gemini_301_series.launch.py | 2 ++ orbbec_camera/src/ob_camera_node_driver.cpp | 2 +- 7 files changed, 49 insertions(+), 14 deletions(-) diff --git a/orbbec_camera/examples/README.MD b/orbbec_camera/examples/README.MD index 7755bddf..51cd7ffd 100644 --- a/orbbec_camera/examples/README.MD +++ b/orbbec_camera/examples/README.MD @@ -7,8 +7,6 @@ These simple examples demonstrate how to easily use the camera with OrbbecSDK_RO | Name | Description | Experience Level | Document | | :---------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------- | | [Net_camera](./net_camera) | How to use Net camera in OrbbecSDK_ROS2(Only Femto Mega nad Gemini 335Le) | ⭐️ | [Net_camera](https://orbbec.github.io/OrbbecSDK_ROS2/source/5_advanced_guide/configuration/net_camera.html) | -| [Gmsl_camera](./gmsl_camera) | How to use GMSL camera.(Only Gemini 335Lg) | ⭐️ | [Gmsl_camera](https://orbbec.github.io/OrbbecSDK_ROS2/source/5_advanced_guide/multi_camera/gmsl_camera.html) | +| [Gmsl_camera](./gmsl_camera) | How to use GMSL cameras (Gemini 335Lg, 338Lg, 345Lg, and 305g). | ⭐️ | [Gmsl_camera](https://orbbec.github.io/OrbbecSDK_ROS2/source/5_advanced_guide/multi_camera/gmsl_camera.html) | | [Benchmark](./benchmark) | The goal of this tool is to benchmark the performance of various OrbbecSDK_ROS2 camera configurations. | ⭐️⭐️ | [Benchmark](https://orbbec.github.io/OrbbecSDK_ROS2/source/5_advanced_guide/performance/benchmark.html) | | [Multi_camera_synced_verification_tool](./multi_camera_synced_verification_tool) | How to verify the synchronization accuracy of multi-camera synchronization. | ⭐️⭐️⭐️ | [Multi_camera_synced_verification_tool](https://orbbec.github.io/OrbbecSDK_ROS2/source/5_advanced_guide/multi_camera/multi_camera_synced_verification_tool.html) | - - diff --git a/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera.launch.py b/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera.launch.py index 139b08b9..03c64764 100644 --- a/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera.launch.py +++ b/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera.launch.py @@ -11,6 +11,19 @@ from launch.substitutions import TextSubstitution from launch_ros.descriptions import ComposableNode +GMSL_CAMERA_LAUNCH_DIRS = { + "gemini_330_gmsl.launch.py": ("examples", "gmsl_camera"), # Gemini 335Lg / 338Lg + "gemini_301_series.launch.py": ("launch",), # Gemini 305G / 309G + "gemini345_lg.launch.py": ("launch",), # Gemini 345Lg +} + + +def get_camera_launch_file(package_dir, launch_file_name): + return os.path.join( + package_dir, *GMSL_CAMERA_LAUNCH_DIRS[launch_file_name], launch_file_name + ) + + def load_yaml(file_path): with open(file_path, "r") as f: return yaml.safe_load(f) @@ -43,9 +56,6 @@ def convert_value(value): def generate_launch_description(): # Include launch files package_dir = get_package_share_directory("orbbec_camera") - launch_file_dir = os.path.join( - package_dir, "examples/gmsl_camera" #or launch - ) config_file_dir = os.path.join(package_dir, "config") secondary_config_file_path = os.path.join(config_file_dir, "camera_secondary_params.yaml") @@ -67,8 +77,10 @@ def generate_launch_description(): attach_to_shared_component_container_arg = TextSubstitution(text="true") launch1_include = IncludeLaunchDescription( + # Supported launch files: gemini_330_gmsl.launch.py, gemini_301_series.launch.py, + # and gemini345_lg.launch.py. PythonLaunchDescriptionSource( - os.path.join(launch_file_dir, "gemini_330_gmsl.launch.py") #or gemini345_lg.launch.py + get_camera_launch_file(package_dir, "gemini_330_gmsl.launch.py") ), launch_arguments={ "camera_name": "camera_01", @@ -82,8 +94,10 @@ def generate_launch_description(): ) launch2_include = IncludeLaunchDescription( + # Supported launch files: gemini_330_gmsl.launch.py, gemini_301_series.launch.py, + # and gemini345_lg.launch.py. PythonLaunchDescriptionSource( - os.path.join(launch_file_dir, "gemini_330_gmsl.launch.py")#or gemini345_lg.launch.py + get_camera_launch_file(package_dir, "gemini_330_gmsl.launch.py") ), launch_arguments={ "camera_name": "camera_02", diff --git a/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera_synced.launch.py b/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera_synced.launch.py index 5b172c43..3a1ca52a 100644 --- a/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera_synced.launch.py +++ b/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera_synced.launch.py @@ -11,6 +11,19 @@ from launch.substitutions import TextSubstitution from launch_ros.descriptions import ComposableNode +GMSL_CAMERA_LAUNCH_DIRS = { + "gemini_330_gmsl.launch.py": ("examples", "gmsl_camera"), # Gemini 335Lg / 338Lg + "gemini_301_series.launch.py": ("launch",), # Gemini 305G / 309G + "gemini345_lg.launch.py": ("launch",), # Gemini 345Lg +} + + +def get_camera_launch_file(package_dir, launch_file_name): + return os.path.join( + package_dir, *GMSL_CAMERA_LAUNCH_DIRS[launch_file_name], launch_file_name + ) + + def load_yaml(file_path): with open(file_path, "r") as f: return yaml.safe_load(f) @@ -43,9 +56,6 @@ def convert_value(value): def generate_launch_description(): # Include launch files package_dir = get_package_share_directory("orbbec_camera") - launch_file_dir = os.path.join( - package_dir, "examples/gmsl_camera" - ) config_file_dir = os.path.join(package_dir, "config") secondary_config_file_path = os.path.join(config_file_dir, "camera_secondary_params.yaml") @@ -67,8 +77,10 @@ def generate_launch_description(): attach_to_shared_component_container_arg = TextSubstitution(text="true") launch1_include = IncludeLaunchDescription( + # Supported launch files: gemini_330_gmsl.launch.py, gemini_301_series.launch.py, + # and gemini345_lg.launch.py. PythonLaunchDescriptionSource( - os.path.join(launch_file_dir, "gemini_330_gmsl.launch.py") + get_camera_launch_file(package_dir, "gemini_330_gmsl.launch.py") ), launch_arguments={ "camera_name": "camera_01", @@ -84,8 +96,10 @@ def generate_launch_description(): ) launch2_include = IncludeLaunchDescription( + # Supported launch files: gemini_330_gmsl.launch.py, gemini_301_series.launch.py, + # and gemini345_lg.launch.py. PythonLaunchDescriptionSource( - os.path.join(launch_file_dir, "gemini_330_gmsl.launch.py") + get_camera_launch_file(package_dir, "gemini_330_gmsl.launch.py") ), launch_arguments={ "camera_name": "camera_02", diff --git a/orbbec_camera/include/orbbec_camera/constants.h b/orbbec_camera/include/orbbec_camera/constants.h index 947a5df6..d52c1faf 100644 --- a/orbbec_camera/include/orbbec_camera/constants.h +++ b/orbbec_camera/include/orbbec_camera/constants.h @@ -154,4 +154,9 @@ inline bool isGemini305SeriesPID(uint32_t pid) { pid == GEMINI_309G_PID; } +inline bool isGmslCameraPID(uint32_t pid) { + return pid == GEMINI_335LG_PID || pid == GEMINI_338LG_PID || pid == GEMINI_345LG_PID || + pid == GEMINI_305G_PID || pid == GEMINI_309G_PID; +} + } // namespace orbbec_camera diff --git a/orbbec_camera/launch/gemini345_lg.launch.py b/orbbec_camera/launch/gemini345_lg.launch.py index 05fac10a..87e46fdd 100644 --- a/orbbec_camera/launch/gemini345_lg.launch.py +++ b/orbbec_camera/launch/gemini345_lg.launch.py @@ -222,6 +222,8 @@ def generate_launch_description(): DeclareLaunchArgument('config_file_path', default_value=''), DeclareLaunchArgument('enable_heartbeat', default_value='false'), DeclareLaunchArgument('enable_firmware_log', default_value='false'), + DeclareLaunchArgument('gmsl_trigger_fps', default_value='3000'), + DeclareLaunchArgument('enable_gmsl_trigger', default_value='false'), #color image transport plugins DeclareLaunchArgument('color.image_raw.enable_pub_plugins',default_value='["image_transport/compressed", "image_transport/raw", "image_transport/theora"]'), diff --git a/orbbec_camera/launch/gemini_301_series.launch.py b/orbbec_camera/launch/gemini_301_series.launch.py index 1c48e5a7..4339900b 100644 --- a/orbbec_camera/launch/gemini_301_series.launch.py +++ b/orbbec_camera/launch/gemini_301_series.launch.py @@ -274,6 +274,8 @@ def generate_launch_description(): DeclareLaunchArgument('config_file_path', default_value=''), DeclareLaunchArgument('enable_heartbeat', default_value='false'), DeclareLaunchArgument('enable_firmware_log', default_value='false'), + DeclareLaunchArgument('gmsl_trigger_fps', default_value='3000'), + DeclareLaunchArgument('enable_gmsl_trigger', default_value='false'), DeclareLaunchArgument('disparity_range_mode', default_value='-1'), DeclareLaunchArgument('disparity_search_offset', default_value='-1'), DeclareLaunchArgument('disparity_offset_config', default_value='false'), diff --git a/orbbec_camera/src/ob_camera_node_driver.cpp b/orbbec_camera/src/ob_camera_node_driver.cpp index f1674598..9afb2aec 100644 --- a/orbbec_camera/src/ob_camera_node_driver.cpp +++ b/orbbec_camera/src/ob_camera_node_driver.cpp @@ -1589,7 +1589,7 @@ void OBCameraNodeDriver::startDevice(const std::shared_ptr &list } auto pid = device->getDeviceInfo()->getPid(); - if (GEMINI_335LG_PID == pid || GEMINI_338LG_PID == pid) { + if (isGmslCameraPID(pid)) { ob_camera_node_->startGmslTrigger(); } // if (isGemini305SeriesPID(pid)) {