chore: Optimal gemini 330 launch file

This commit is contained in:
Joe Dong
2024-07-10 14:46:08 +08:00
parent d4e233b593
commit dfa8066cb6
3 changed files with 130 additions and 56 deletions
+45
View File
@@ -0,0 +1,45 @@
# common params
depth_registration: false
enable_point_cloud: false
enable_colored_point_cloud: false
device_preset: "High Accuracy"
laser_on_off_mode: 1 # 0: off, 1: on-off, 1: off-on
# When 3D reconstruction mode is enabled:
# - The laser will switch to on-off mode
# - IR images without the laser will be used for SLAM localization
# - Depth images with the laser will be used because they provide better depth quality
enable_3d_reconstruction_mode: true
# color params
enable_color: true
color_width: 640
color_height: 480
color_fps: 60
color_format: "YUYV"
enable_color_auto_exposure: false
color_exposure: 50 # 5ms
color_gain: -1 # -1 default
# depth params
depth_width: 640
depth_height: 480
depth_fps: 60
depth_format: "Y16"
# ir exposure
enable_ir_auto_exposure: false
ir_exposure: 5000 # 5ms
ir_gain: 40
#left ir params
left_ir_width: 640
left_ir_height: 480
left_ir_fps: 60
left_ir_format: "Y8"
#right ir params
right_ir_width: 640
right_ir_height: 480
right_ir_fps: 60
right_ir_format: "Y8"
@@ -1,16 +1,48 @@
from launch import LaunchDescription from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument from launch.actions import DeclareLaunchArgument, OpaqueFunction, GroupAction
from launch.substitutions import LaunchConfiguration from launch.substitutions import LaunchConfiguration
from launch_ros.actions import PushRosNamespace from launch_ros.actions import PushRosNamespace, ComposableNodeContainer, Node
from launch.actions import GroupAction
from launch_ros.actions import ComposableNodeContainer
from launch_ros.descriptions import ComposableNode from launch_ros.descriptions import ComposableNode
from launch_ros.actions import Node
import os import os
import yaml
def load_yaml(file_path):
with open(file_path, 'r') as f:
return yaml.safe_load(f)
def merge_params(default_params, yaml_params):
for key, value in yaml_params.items():
if key in default_params:
default_params[key] = value
return default_params
def convert_value(value):
if isinstance(value, str):
try:
return int(value)
except ValueError:
pass
try:
return float(value)
except ValueError:
pass
if value.lower() == 'true':
return True
elif value.lower() == 'false':
return False
return value
def load_parameters(context, args):
default_params = {arg.name: LaunchConfiguration(arg.name).perform(context) for arg in args}
config_file_path = LaunchConfiguration('config_file_path').perform(context)
if config_file_path:
yaml_params = load_yaml(config_file_path)
default_params = merge_params(default_params, yaml_params)
skip_convert = ['config_file_path', 'usb_port', 'serial_number']
return {key: convert_value(value) if key not in skip_convert else value for key, value in default_params.items()}
def generate_launch_description(): def generate_launch_description():
# Declare arguments
args = [ args = [
DeclareLaunchArgument('camera_name', default_value='camera'), DeclareLaunchArgument('camera_name', default_value='camera'),
DeclareLaunchArgument('depth_registration', default_value='true'), DeclareLaunchArgument('depth_registration', default_value='true'),
@@ -117,63 +149,54 @@ def generate_launch_description():
DeclareLaunchArgument('enable_laser', default_value='true'), DeclareLaunchArgument('enable_laser', default_value='true'),
DeclareLaunchArgument('depth_precision', default_value=''), DeclareLaunchArgument('depth_precision', default_value=''),
DeclareLaunchArgument('device_preset', default_value='Default'), DeclareLaunchArgument('device_preset', default_value='Default'),
# Laser on/off alternate mode, 0: off, 1: on-off alternate, 2: off-on alternate.
DeclareLaunchArgument('laser_on_off_mode', default_value='0'), DeclareLaunchArgument('laser_on_off_mode', default_value='0'),
DeclareLaunchArgument('retry_on_usb3_detection_failure', default_value='false'), DeclareLaunchArgument('retry_on_usb3_detection_failure', default_value='false'),
DeclareLaunchArgument('laser_energy_level', default_value='-1'), DeclareLaunchArgument('laser_energy_level', default_value='-1'),
# When 3D reconstruction mode is enabled:
# - The laser will switch to on-off mode
# - IR images without the laser will be used for SLAM localization
# - Depth images with the laser will be used because they provide better depth quality
DeclareLaunchArgument('enable_3d_reconstruction_mode', default_value='false'), DeclareLaunchArgument('enable_3d_reconstruction_mode', default_value='false'),
DeclareLaunchArgument('config_file_path', default_value=''),
] ]
# Node configuration def get_params(context, args):
parameters = [{arg.name: LaunchConfiguration(arg.name)} for arg in args] return [load_parameters(context, args)]
# get ROS_DISTRO
ros_distro = os.environ["ROS_DISTRO"] def create_node_action(context, args):
if ros_distro == "foxy": params = get_params(context, args)
return LaunchDescription( ros_distro = os.environ.get("ROS_DISTRO", "humble")
args if ros_distro == "foxy":
+ [ return [
Node( Node(
package="orbbec_camera", package="orbbec_camera",
executable="orbbec_camera_node", executable="orbbec_camera_node",
name="ob_camera_node", name="ob_camera_node",
namespace=LaunchConfiguration("camera_name"), namespace=LaunchConfiguration("camera_name"),
parameters=parameters, parameters=params,
output="screen", output="screen",
) )
] ]
) else:
# Define the ComposableNode return [
else: GroupAction([
# Define the ComposableNode PushRosNamespace(LaunchConfiguration("camera_name")),
compose_node = ComposableNode( ComposableNodeContainer(
package="orbbec_camera", name="camera_container",
plugin="orbbec_camera::OBCameraNodeDriver", namespace="",
name=LaunchConfiguration("camera_name"), package="rclcpp_components",
namespace="", executable="component_container",
parameters=parameters, composable_node_descriptions=[
) ComposableNode(
# Define the ComposableNodeContainer package="orbbec_camera",
container = ComposableNodeContainer( plugin="orbbec_camera::OBCameraNodeDriver",
name="camera_container", name=LaunchConfiguration("camera_name"),
namespace="", parameters=params,
package="rclcpp_components", ),
executable="component_container", ],
composable_node_descriptions=[ output="screen",
compose_node, )
], ])
output="screen",
)
# Launch description
ld = LaunchDescription(
args
+ [
GroupAction(
[PushRosNamespace(LaunchConfiguration("camera_name")), container]
)
] ]
)
return ld return LaunchDescription(
args + [
OpaqueFunction(function=lambda context: create_node_action(context, args))
]
)
@@ -10,6 +10,8 @@ def generate_launch_description():
# Include launch files # Include launch files
package_dir = get_package_share_directory('orbbec_camera') package_dir = get_package_share_directory('orbbec_camera')
launch_file_dir = os.path.join(package_dir, 'launch') 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')
launch1_include = IncludeLaunchDescription( launch1_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource( PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, 'gemini_330_series.launch.py') os.path.join(launch_file_dir, 'gemini_330_series.launch.py')
@@ -18,7 +20,8 @@ def generate_launch_description():
'camera_name': 'front_camera', 'camera_name': 'front_camera',
'usb_port': '2-1.1', 'usb_port': '2-1.1',
'device_num': '4', 'device_num': '4',
'sync_mode': 'primary' 'sync_mode': 'primary',
'config_file': config_file_path,
}.items() }.items()
) )
@@ -30,7 +33,8 @@ def generate_launch_description():
'camera_name': 'left_camera', 'camera_name': 'left_camera',
'usb_port': '2-1.2.1', 'usb_port': '2-1.2.1',
'device_num': '4', 'device_num': '4',
'sync_mode': 'secondary_synced' 'sync_mode': 'secondary_synced',
'config_file': config_file_path,
}.items() }.items()
) )
launch3_include = IncludeLaunchDescription( launch3_include = IncludeLaunchDescription(
@@ -41,7 +45,8 @@ def generate_launch_description():
'camera_name': 'right_camera', 'camera_name': 'right_camera',
'usb_port': '2-1.2.1', 'usb_port': '2-1.2.1',
'device_num': '4', 'device_num': '4',
'sync_mode': 'secondary_synced' 'sync_mode': 'secondary_synced',
'config_file': config_file_path,
}.items() }.items()
) )
launch4_include = IncludeLaunchDescription( launch4_include = IncludeLaunchDescription(
@@ -52,7 +57,8 @@ def generate_launch_description():
'camera_name': 'right_camera', 'camera_name': 'right_camera',
'usb_port': '2-1.2.1', 'usb_port': '2-1.2.1',
'device_num': '4', 'device_num': '4',
'sync_mode': 'secondary_synced' 'sync_mode': 'secondary_synced',
'config_file': config_file_path,
}.items() }.items()
) )
@@ -63,7 +69,7 @@ def generate_launch_description():
GroupAction([launch2_include]), GroupAction([launch2_include]),
GroupAction([launch3_include]), GroupAction([launch3_include]),
GroupAction([launch4_include]), GroupAction([launch4_include]),
GroupAction([launch1_include]), GroupAction([launch1_include]), # The primary camera should be launched at last
]) ])
return ld return ld