mirror of
https://github.com/orbbec/OrbbecSDK_ROS2.git
synced 2026-09-12 19:20:20 +08:00
185 lines
7.7 KiB
Python
185 lines
7.7 KiB
Python
import os
|
|
import yaml
|
|
import logging
|
|
from launch import LaunchDescription
|
|
from launch.actions import DeclareLaunchArgument, OpaqueFunction
|
|
from launch.substitutions import LaunchConfiguration
|
|
from launch_ros.actions import Node
|
|
from launch_ros.descriptions import ComposableNode
|
|
from launch.conditions import UnlessCondition
|
|
from launch_ros.actions import LoadComposableNodes
|
|
from ament_index_python.packages import get_package_share_directory
|
|
import sys
|
|
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
|
from utils_yaml import *
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
default_package_name = 'orbbec_camera'
|
|
default_camera_model = 'gemini330_series'
|
|
default_common_yaml = 'common.yaml'
|
|
default_component_container_name = 'orbbec_container'
|
|
|
|
def generate_launch_arguments():
|
|
launch_arguments = [
|
|
#general config
|
|
DeclareLaunchArgument('camera_model', default_value=default_camera_model),
|
|
DeclareLaunchArgument('config_file_path', default_value=''),
|
|
#multi-device sync param
|
|
DeclareLaunchArgument('camera_name', default_value='camera'),
|
|
DeclareLaunchArgument('usb_port', default_value=''),
|
|
DeclareLaunchArgument('device_num', default_value='1'),
|
|
DeclareLaunchArgument('sync_mode', default_value='standalone'),
|
|
DeclareLaunchArgument('trigger_out_enabled', default_value='true'),
|
|
#instra-process demo set
|
|
DeclareLaunchArgument('use_intra_process_comms', default_value='false'),
|
|
DeclareLaunchArgument('attach_component_container_enable', default_value='false'),
|
|
DeclareLaunchArgument('attach_component_container_name', default_value=default_component_container_name),
|
|
]
|
|
return launch_arguments
|
|
|
|
|
|
def load_common_yaml_params():
|
|
common_yaml_path = os.path.join(
|
|
get_package_share_directory(default_package_name), 'config', default_common_yaml
|
|
)
|
|
common_yaml_path = get_absolute_path(common_yaml_path, package_name=default_package_name)
|
|
logger.info(f"load convert Absolute path: {common_yaml_path}")
|
|
return load_and_parse_yaml(common_yaml_path)
|
|
|
|
|
|
def load_config_yaml_params(config_file_path, camera_model):
|
|
config_yaml_path = config_file_path or os.path.join(
|
|
get_package_share_directory(default_package_name), 'config', f"{camera_model}.yaml"
|
|
)
|
|
config_yaml_path = get_absolute_path(config_yaml_path, package_name=default_package_name)
|
|
print(f"load convert Absolute config_yaml_path: {config_yaml_path}")
|
|
return load_and_parse_yaml(config_yaml_path)
|
|
|
|
|
|
def load_parameters(context, args):
|
|
camera_model = LaunchConfiguration("camera_model").perform(context)
|
|
config_file_path = LaunchConfiguration("config_file_path").perform(context)
|
|
usb_port = LaunchConfiguration("usb_port").perform(context)
|
|
print(f"camera_model: {camera_model}", f"config_file_path: {config_file_path}", f"usb_port: {usb_port}")
|
|
|
|
try:
|
|
#1.load ymal params
|
|
yaml_common_params = load_common_yaml_params()
|
|
yaml_params = load_config_yaml_params(config_file_path,camera_model)
|
|
#print_params(yaml_common_params)
|
|
#print_params(yaml_params)
|
|
yaml_params = update_params(yaml_common_params,yaml_params)
|
|
#print_params(yaml_params)
|
|
|
|
#2.load args params
|
|
args_params = {arg.name: LaunchConfiguration(arg.name).perform(context) for arg in args}
|
|
#print_params(args_params)
|
|
|
|
#3.meger params args
|
|
if usb_port is None or usb_port == "": #meger yaml->args params
|
|
print("usb_port param null")
|
|
default_params = update_params(args_params, yaml_params)
|
|
else:
|
|
print("usb_port param not null value:", usb_port) #meger args->yaml params
|
|
default_params = update_params(yaml_params, args_params)
|
|
#print_params(default_params)
|
|
|
|
#4.load cmd params & meger params cmd->yaml
|
|
cmd_params = dict([a for a in [a.split(':=') for a in sys.argv] if len(a) == 2])
|
|
default_params = update_params(default_params,cmd_params)
|
|
#print_params(args_params)
|
|
|
|
except (FileNotFoundError, yaml.YAMLError) as e:
|
|
logger.error(f"Error loading YAML file: {e}")
|
|
return {}
|
|
|
|
#5.Skip conversion for specific parameters
|
|
SKIP_CONVERT = {'config_file_path', 'usb_port', 'serial_number', 'attach_component_container_name'}
|
|
return {
|
|
key: (value if key in SKIP_CONVERT else convert_value(value))
|
|
for key, value in default_params.items()
|
|
}
|
|
|
|
|
|
def find_camera_name(params):
|
|
return find_param(params, 'camera_name', 'camera')
|
|
|
|
def find_use_intra_process_comms(params):
|
|
return find_param(params, 'use_intra_process_comms', False)
|
|
|
|
|
|
def generate_launch_description():
|
|
args = generate_launch_arguments()
|
|
def get_params(context, args):
|
|
return [load_parameters(context, args)]
|
|
|
|
def create_composable_node(camera_name, params, use_intra_process):
|
|
common_arguments = [{'use_intra_process_comms': use_intra_process}]
|
|
composable_node = ComposableNode(
|
|
namespace=camera_name,
|
|
name=camera_name,
|
|
package=default_package_name,
|
|
plugin='orbbec_camera::OBCameraNodeDriver',
|
|
parameters=params,
|
|
#extra_arguments=[{'use_intra_process_comms': LaunchConfiguration("use_intra_process_comms")}],
|
|
extra_arguments=common_arguments,
|
|
)
|
|
return composable_node
|
|
|
|
|
|
def create_orbbec_container(attach_component_container_name, attach_component_container_enable):
|
|
orbbec_container = Node(
|
|
name=attach_component_container_name,
|
|
package='rclcpp_components',
|
|
executable='component_container_mt',
|
|
output='screen',
|
|
condition=UnlessCondition(attach_component_container_enable)
|
|
)
|
|
return orbbec_container
|
|
|
|
|
|
def create_node_action(context, args):
|
|
params = get_params(context, args)
|
|
camera_name = find_camera_name(params)
|
|
|
|
use_intra_process = find_use_intra_process_comms(params)
|
|
#use_intra_process = LaunchConfiguration("use_intra_process_comms", default=False).perform(context)
|
|
print(f"camera_name: {camera_name}", f"use_intra_process: {use_intra_process}")
|
|
|
|
attach_enable_condition = LaunchConfiguration("attach_component_container_enable", default=False).perform(context)
|
|
attach_component_container_name = LaunchConfiguration("attach_component_container_name", default='orbbec_container').perform(context)
|
|
print(f"attach_enable_condition: {attach_enable_condition}", f"attach_component_container_name: {attach_component_container_name}")
|
|
|
|
ros_distro = os.environ.get("ROS_DISTRO", "humble")
|
|
if ros_distro == "foxy":
|
|
return [
|
|
Node(
|
|
package=default_package_name,
|
|
executable="orbbec_camera_node",
|
|
name="ob_camera_node",
|
|
namespace=camera_name,
|
|
parameters=params,
|
|
output="screen",
|
|
#condition=UnlessCondition(attach_enable_condition)
|
|
#prefix=['xterm -e gdb -ex run --args'],
|
|
),
|
|
]
|
|
else:
|
|
composable_node = create_composable_node(camera_name, params, use_intra_process)
|
|
orbbec_container= create_orbbec_container(attach_component_container_name, attach_enable_condition)
|
|
return [
|
|
orbbec_container,
|
|
LoadComposableNodes(
|
|
target_container=attach_component_container_name,
|
|
composable_node_descriptions=[composable_node]
|
|
),
|
|
]
|
|
|
|
return LaunchDescription(
|
|
args + [
|
|
OpaqueFunction(function=lambda context: create_node_action(context, args))
|
|
]
|
|
) |