|
| 1 | +#!/usr/bin/env python3 |
| 2 | +# Software License Agreement (BSD License) |
| 3 | +# |
| 4 | +# Copyright (c) 2021, UFACTORY, Inc. |
| 5 | +# All rights reserved. |
| 6 | +# |
| 7 | + |
| 8 | + |
| 9 | +import os |
| 10 | +import json |
| 11 | +from ament_index_python import get_package_share_directory |
| 12 | +from launch.frontend import expose |
| 13 | +from launch.launch_description_sources import load_python_launch_file_as_module |
| 14 | +from launch import LaunchDescription |
| 15 | +from launch.actions import OpaqueFunction |
| 16 | +from launch.substitutions import LaunchConfiguration, PathJoinSubstitution |
| 17 | +from launch_ros.actions import Node |
| 18 | +from launch_ros.substitutions import FindPackageShare |
| 19 | + |
| 20 | + |
| 21 | +def launch_setup(context, *args, **kwargs): |
| 22 | + prefix_1 = LaunchConfiguration('prefix_1', default='L_') |
| 23 | + prefix_2 = LaunchConfiguration('prefix_2', default='R_') |
| 24 | + dof = LaunchConfiguration('dof', default=7) |
| 25 | + dof_1 = LaunchConfiguration('dof_1', default=dof) |
| 26 | + dof_2 = LaunchConfiguration('dof_2', default=dof) |
| 27 | + robot_type = LaunchConfiguration('robot_type', default='xarm') |
| 28 | + robot_type_1 = LaunchConfiguration('robot_type_1', default=robot_type) |
| 29 | + robot_type_2 = LaunchConfiguration('robot_type_2', default=robot_type) |
| 30 | + add_gripper = LaunchConfiguration('add_gripper', default=False) |
| 31 | + add_gripper_1 = LaunchConfiguration('add_gripper_1', default=add_gripper) |
| 32 | + add_gripper_2 = LaunchConfiguration('add_gripper_2', default=add_gripper) |
| 33 | + add_vacuum_gripper = LaunchConfiguration('add_vacuum_gripper', default=False) |
| 34 | + add_vacuum_gripper_1 = LaunchConfiguration('add_vacuum_gripper_1', default=add_vacuum_gripper) |
| 35 | + add_vacuum_gripper_2 = LaunchConfiguration('add_vacuum_gripper_2', default=add_vacuum_gripper) |
| 36 | + hw_ns = LaunchConfiguration('hw_ns', default='xarm') |
| 37 | + limited = LaunchConfiguration('limited', default=True) |
| 38 | + effort_control = LaunchConfiguration('effort_control', default=False) |
| 39 | + velocity_control = LaunchConfiguration('velocity_control', default=False) |
| 40 | + ros2_control_plugin = LaunchConfiguration('ros2_control_plugin', default='uf_robot_hardware/UFRobotFakeSystemHardware') |
| 41 | + node_executable = LaunchConfiguration('node_executable', default='xarm_planner_node') |
| 42 | + node_name = LaunchConfiguration('node_name', default=node_executable) |
| 43 | + node_parameters = LaunchConfiguration('node_parameters', default={}) |
| 44 | + use_gripper_node = LaunchConfiguration('use_gripper_node', default=add_gripper) |
| 45 | + |
| 46 | + add_realsense_d435i = LaunchConfiguration('add_realsense_d435i', default=False) |
| 47 | + add_realsense_d435i_1 = LaunchConfiguration('add_realsense_d435i_1', default=add_realsense_d435i) |
| 48 | + add_realsense_d435i_2 = LaunchConfiguration('add_realsense_d435i_2', default=add_realsense_d435i) |
| 49 | + |
| 50 | + add_d435i_links = LaunchConfiguration('add_d435i_links', default=True) |
| 51 | + add_d435i_links_1 = LaunchConfiguration('add_d435i_links_1', default=add_d435i_links) |
| 52 | + add_d435i_links_2 = LaunchConfiguration('add_d435i_links_2', default=add_d435i_links) |
| 53 | + |
| 54 | + model1300 = LaunchConfiguration('model1300', default=False) |
| 55 | + model1300_1 = LaunchConfiguration('model1300_1', default=model1300) |
| 56 | + model1300_2 = LaunchConfiguration('model1300_2', default=model1300) |
| 57 | + |
| 58 | + robot_sn = LaunchConfiguration('robot_sn', default='') |
| 59 | + robot_sn_1 = LaunchConfiguration('robot_sn_1', default=robot_sn) |
| 60 | + robot_sn_2 = LaunchConfiguration('robot_sn_2', default=robot_sn) |
| 61 | + |
| 62 | + add_other_geometry = LaunchConfiguration('add_other_geometry', default=False) |
| 63 | + add_other_geometry_1 = LaunchConfiguration('add_other_geometry_1', default=add_other_geometry) |
| 64 | + add_other_geometry_2 = LaunchConfiguration('add_other_geometry_2', default=add_other_geometry) |
| 65 | + |
| 66 | + geometry_type = LaunchConfiguration('geometry_type', default='box') |
| 67 | + geometry_type_1 = LaunchConfiguration('geometry_type_1', default=geometry_type) |
| 68 | + geometry_type_2 = LaunchConfiguration('geometry_type_2', default=geometry_type) |
| 69 | + |
| 70 | + geometry_mass = LaunchConfiguration('geometry_mass', default=0.1) |
| 71 | + geometry_mass_1 = LaunchConfiguration('geometry_mass_1', default=geometry_mass) |
| 72 | + geometry_mass_2 = LaunchConfiguration('geometry_mass_2', default=geometry_mass) |
| 73 | + |
| 74 | + geometry_height = LaunchConfiguration('geometry_height', default=0.1) |
| 75 | + geometry_height_1 = LaunchConfiguration('geometry_height_1', default=geometry_height) |
| 76 | + geometry_height_2 = LaunchConfiguration('geometry_height_2', default=geometry_height) |
| 77 | + |
| 78 | + geometry_radius = LaunchConfiguration('geometry_radius', default=0.1) |
| 79 | + geometry_radius_1 = LaunchConfiguration('geometry_radius_1', default=geometry_radius) |
| 80 | + geometry_radius_2 = LaunchConfiguration('geometry_radius_2', default=geometry_radius) |
| 81 | + |
| 82 | + geometry_length = LaunchConfiguration('geometry_length', default=0.1) |
| 83 | + geometry_length_1 = LaunchConfiguration('geometry_length_1', default=geometry_length) |
| 84 | + geometry_length_2 = LaunchConfiguration('geometry_length_2', default=geometry_length) |
| 85 | + |
| 86 | + geometry_width = LaunchConfiguration('geometry_width', default=0.1) |
| 87 | + geometry_width_1 = LaunchConfiguration('geometry_width_1', default=geometry_width) |
| 88 | + geometry_width_2 = LaunchConfiguration('geometry_width_2', default=geometry_width) |
| 89 | + |
| 90 | + geometry_mesh_filename = LaunchConfiguration('geometry_mesh_filename', default='') |
| 91 | + geometry_mesh_filename_1 = LaunchConfiguration('geometry_mesh_filename_1', default=geometry_mesh_filename) |
| 92 | + geometry_mesh_filename_2 = LaunchConfiguration('geometry_mesh_filename_2', default=geometry_mesh_filename) |
| 93 | + |
| 94 | + geometry_mesh_origin_xyz = LaunchConfiguration('geometry_mesh_origin_xyz', default='"0 0 0"') |
| 95 | + geometry_mesh_origin_xyz_1 = LaunchConfiguration('geometry_mesh_origin_xyz_1', default=geometry_mesh_origin_xyz) |
| 96 | + geometry_mesh_origin_xyz_2 = LaunchConfiguration('geometry_mesh_origin_xyz_2', default=geometry_mesh_origin_xyz) |
| 97 | + |
| 98 | + geometry_mesh_origin_rpy = LaunchConfiguration('geometry_mesh_origin_rpy', default='"0 0 0"') |
| 99 | + geometry_mesh_origin_rpy_1 = LaunchConfiguration('geometry_mesh_origin_rpy_1', default=geometry_mesh_origin_rpy) |
| 100 | + geometry_mesh_origin_rpy_2 = LaunchConfiguration('geometry_mesh_origin_rpy_2', default=geometry_mesh_origin_rpy) |
| 101 | + |
| 102 | + geometry_mesh_tcp_xyz = LaunchConfiguration('geometry_mesh_tcp_xyz', default='"0 0 0"') |
| 103 | + geometry_mesh_tcp_xyz_1 = LaunchConfiguration('geometry_mesh_tcp_xyz_1', default=geometry_mesh_tcp_xyz) |
| 104 | + geometry_mesh_tcp_xyz_2 = LaunchConfiguration('geometry_mesh_tcp_xyz_2', default=geometry_mesh_tcp_xyz) |
| 105 | + |
| 106 | + geometry_mesh_tcp_rpy = LaunchConfiguration('geometry_mesh_tcp_rpy', default='"0 0 0"') |
| 107 | + geometry_mesh_tcp_rpy_1 = LaunchConfiguration('geometry_mesh_tcp_rpy_1', default=geometry_mesh_tcp_rpy) |
| 108 | + geometry_mesh_tcp_rpy_2 = LaunchConfiguration('geometry_mesh_tcp_rpy_2', default=geometry_mesh_tcp_rpy) |
| 109 | + |
| 110 | + kinematics_suffix = LaunchConfiguration('kinematics_suffix', default='') |
| 111 | + kinematics_suffix_1 = LaunchConfiguration('kinematics_suffix_1', default=kinematics_suffix) |
| 112 | + kinematics_suffix_2 = LaunchConfiguration('kinematics_suffix_2', default=kinematics_suffix) |
| 113 | + |
| 114 | + moveit_config_package_name = 'xarm_moveit_config' |
| 115 | + xarm_type = '{}{}'.format(robot_type.perform(context), '' if robot_type.perform(context) == 'uf850' else dof.perform(context)) |
| 116 | + |
| 117 | + # robot_description_parameters |
| 118 | + # xarm_moveit_config/launch/lib/robot_moveit_config_lib.py |
| 119 | + mod = load_python_launch_file_as_module(os.path.join(get_package_share_directory(moveit_config_package_name), 'launch', 'lib', 'robot_moveit_config_lib.py')) |
| 120 | + get_xarm_robot_description_parameters = getattr(mod, 'get_xarm_robot_description_parameters') |
| 121 | + robot_description_parameters = get_xarm_robot_description_parameters( |
| 122 | + xacro_urdf_file=PathJoinSubstitution([FindPackageShare('xarm_description'), 'urdf', 'dual_xarm_device.urdf.xacro']), |
| 123 | + xacro_srdf_file=PathJoinSubstitution([FindPackageShare(moveit_config_package_name), 'srdf', 'dual_xarm.srdf.xacro']), |
| 124 | + urdf_arguments={ |
| 125 | + 'prefix_1': prefix_1, |
| 126 | + 'prefix_2': prefix_2, |
| 127 | + 'dof_1': dof_1, |
| 128 | + 'dof_2': dof_2, |
| 129 | + 'robot_type_1': robot_type_1, |
| 130 | + 'robot_type_2': robot_type_2, |
| 131 | + 'add_gripper_1': add_gripper_1, |
| 132 | + 'add_gripper_2': add_gripper_2, |
| 133 | + 'add_vacuum_gripper_1': add_vacuum_gripper_1, |
| 134 | + 'add_vacuum_gripper_2': add_vacuum_gripper_2, |
| 135 | + 'hw_ns': hw_ns.perform(context).strip('/'), |
| 136 | + 'limited': limited, |
| 137 | + 'effort_control': effort_control, |
| 138 | + 'velocity_control': velocity_control, |
| 139 | + 'ros2_control_plugin': ros2_control_plugin, |
| 140 | + 'add_realsense_d435i_1': add_realsense_d435i_1, |
| 141 | + 'add_realsense_d435i_2': add_realsense_d435i_2, |
| 142 | + 'add_d435i_links_1': add_d435i_links_1, |
| 143 | + 'add_d435i_links_2': add_d435i_links_2, |
| 144 | + 'model1300_1': model1300_1, |
| 145 | + 'model1300_2': model1300_2, |
| 146 | + 'robot_sn_1': robot_sn_1, |
| 147 | + 'robot_sn_2': robot_sn_2, |
| 148 | + 'add_other_geometry_1': add_other_geometry_1, |
| 149 | + 'add_other_geometry_2': add_other_geometry_2, |
| 150 | + 'geometry_type_1': geometry_type_1, |
| 151 | + 'geometry_type_2': geometry_type_2, |
| 152 | + 'geometry_mass_1': geometry_mass_1, |
| 153 | + 'geometry_mass_2': geometry_mass_2, |
| 154 | + 'geometry_height_1': geometry_height_1, |
| 155 | + 'geometry_height_2': geometry_height_2, |
| 156 | + 'geometry_radius_1': geometry_radius_1, |
| 157 | + 'geometry_radius_2': geometry_radius_2, |
| 158 | + 'geometry_length_1': geometry_length_1, |
| 159 | + 'geometry_length_2': geometry_length_2, |
| 160 | + 'geometry_width_1': geometry_width_1, |
| 161 | + 'geometry_width_2': geometry_width_2, |
| 162 | + 'geometry_mesh_filename_1': geometry_mesh_filename_1, |
| 163 | + 'geometry_mesh_filename_2': geometry_mesh_filename_2, |
| 164 | + 'geometry_mesh_origin_xyz_1': geometry_mesh_origin_xyz_1, |
| 165 | + 'geometry_mesh_origin_xyz_2': geometry_mesh_origin_xyz_2, |
| 166 | + 'geometry_mesh_origin_rpy_1': geometry_mesh_origin_rpy_1, |
| 167 | + 'geometry_mesh_origin_rpy_2': geometry_mesh_origin_rpy_2, |
| 168 | + 'geometry_mesh_tcp_xyz_1': geometry_mesh_tcp_xyz_1, |
| 169 | + 'geometry_mesh_tcp_xyz_2': geometry_mesh_tcp_xyz_2, |
| 170 | + 'geometry_mesh_tcp_rpy_1': geometry_mesh_tcp_rpy_1, |
| 171 | + 'geometry_mesh_tcp_rpy_2': geometry_mesh_tcp_rpy_2, |
| 172 | + 'kinematics_suffix_1': kinematics_suffix_1, |
| 173 | + 'kinematics_suffix_2': kinematics_suffix_2, |
| 174 | + }, |
| 175 | + srdf_arguments={ |
| 176 | + 'prefix_1': prefix_1, |
| 177 | + 'prefix_2': prefix_2, |
| 178 | + 'dof_1': dof_1, |
| 179 | + 'dof_2': dof_2, |
| 180 | + 'robot_type_1': robot_type_1, |
| 181 | + 'robot_type_2': robot_type_2, |
| 182 | + 'add_gripper_1': add_gripper_1, |
| 183 | + 'add_gripper_2': add_gripper_2, |
| 184 | + 'add_vacuum_gripper_1': add_vacuum_gripper_1, |
| 185 | + 'add_vacuum_gripper_2': add_vacuum_gripper_2, |
| 186 | + 'add_other_geometry_1': add_other_geometry_1, |
| 187 | + 'add_other_geometry_2': add_other_geometry_2, |
| 188 | + }, |
| 189 | + arguments={ |
| 190 | + 'context': context, |
| 191 | + 'xarm_type': xarm_type |
| 192 | + } |
| 193 | + ) |
| 194 | + |
| 195 | + load_yaml = getattr(mod, 'load_yaml') |
| 196 | + |
| 197 | + kinematics_yaml_1 = load_yaml(moveit_config_package_name, 'config', xarm_type, 'kinematics.yaml') |
| 198 | + joint_limits_yaml_1 = load_yaml(moveit_config_package_name, 'config', xarm_type, 'joint_limits.yaml') |
| 199 | + |
| 200 | + xarm_type = '{}{}'.format(robot_type_2.perform(context), '' if robot_type_2.perform(context) == 'uf850' else dof_2.perform(context)) |
| 201 | + kinematics_yaml_2 = load_yaml(moveit_config_package_name, 'config', xarm_type, 'kinematics.yaml') |
| 202 | + joint_limits_yaml_2 = load_yaml(moveit_config_package_name, 'config', xarm_type, 'joint_limits.yaml') |
| 203 | + |
| 204 | + if add_gripper_1.perform(context) in ('True', 'true'): |
| 205 | + gripper_joint_limits_yaml_1 = load_yaml(moveit_config_package_name, 'config', '{}_gripper'.format(robot_type_1.perform(context)), 'joint_limits.yaml') |
| 206 | + if joint_limits_yaml_1 and gripper_joint_limits_yaml_1: |
| 207 | + joint_limits_yaml_1['joint_limits'].update(gripper_joint_limits_yaml_1['joint_limits']) |
| 208 | + if add_gripper_2.perform(context) in ('True', 'true'): |
| 209 | + gripper_joint_limits_yaml_2 = load_yaml(moveit_config_package_name, 'config', '{}_gripper'.format(robot_type_2.perform(context)), 'joint_limits.yaml') |
| 210 | + if joint_limits_yaml_2 and gripper_joint_limits_yaml_2: |
| 211 | + joint_limits_yaml_2['joint_limits'].update(gripper_joint_limits_yaml_2['joint_limits']) |
| 212 | + |
| 213 | + |
| 214 | + add_prefix_to_moveit_params = getattr(mod, 'add_prefix_to_moveit_params') |
| 215 | + add_prefix_to_moveit_params(kinematics_yaml=kinematics_yaml_1, joint_limits_yaml=joint_limits_yaml_1, prefix=prefix_1.perform(context)) |
| 216 | + add_prefix_to_moveit_params(kinematics_yaml=kinematics_yaml_2, joint_limits_yaml=joint_limits_yaml_2, prefix=prefix_2.perform(context)) |
| 217 | + kinematics_yaml = {} |
| 218 | + kinematics_yaml.update(kinematics_yaml_1) |
| 219 | + kinematics_yaml.update(kinematics_yaml_2) |
| 220 | + joint_limits_yaml = {'joint_limits': {}} |
| 221 | + joint_limits_yaml.update(joint_limits_yaml_1['joint_limits']) |
| 222 | + joint_limits_yaml.update(joint_limits_yaml_2['joint_limits']) |
| 223 | + robot_description_parameters['robot_description_kinematics'] = kinematics_yaml |
| 224 | + robot_description_parameters['robot_description_planning'] = joint_limits_yaml |
| 225 | + |
| 226 | + try: |
| 227 | + xarm_planner_parameters = json.loads(node_parameters.perform(context)) |
| 228 | + except: |
| 229 | + xarm_planner_parameters = {} |
| 230 | + |
| 231 | + xarm_planner_node = Node( |
| 232 | + name=node_name, |
| 233 | + package='xarm_planner', |
| 234 | + executable=node_executable, |
| 235 | + output='screen', |
| 236 | + parameters=[ |
| 237 | + robot_description_parameters, |
| 238 | + { |
| 239 | + 'robot_type_1': robot_type_1, |
| 240 | + 'robot_type_2': robot_type_2, |
| 241 | + 'dof_1': dof_1, |
| 242 | + 'dof_2': dof_2, |
| 243 | + 'prefix_1': prefix_1, |
| 244 | + 'prefix_2': prefix_2, |
| 245 | + }, |
| 246 | + xarm_planner_parameters, |
| 247 | + ], |
| 248 | + ) |
| 249 | + |
| 250 | + nodes = [ |
| 251 | + xarm_planner_node |
| 252 | + ] |
| 253 | + if add_gripper.perform(context) in ('True', 'true') and use_gripper_node.perform(context) in ('True', 'true'): |
| 254 | + xarm_gripper_planner_node = Node( |
| 255 | + name=node_name, |
| 256 | + package='xarm_planner', |
| 257 | + executable='xarm_gripper_planner_node', |
| 258 | + output='screen', |
| 259 | + parameters=[ |
| 260 | + robot_description_parameters, |
| 261 | + {'PLANNING_GROUP': 'xarm_gripper'}, |
| 262 | + ], |
| 263 | + ) |
| 264 | + nodes.append(xarm_gripper_planner_node) |
| 265 | + return nodes |
| 266 | + |
| 267 | + |
| 268 | +def generate_launch_description(): |
| 269 | + return LaunchDescription([ |
| 270 | + OpaqueFunction(function=launch_setup) |
| 271 | + ]) |
0 commit comments