diff --git a/.gitignore b/.gitignore index 333df5bf..848e7995 100644 --- a/.gitignore +++ b/.gitignore @@ -231,4 +231,5 @@ CATKIN_IGNORE /**/local_config.py -*.graphml \ No newline at end of file +*.graphml +unilabos/device_mesh/view_robot.rviz diff --git a/test/experiments/plr_test_converted.json b/test/experiments/plr_test_converted.json index 9e502e10..d2b3397c 100644 --- a/test/experiments/plr_test_converted.json +++ b/test/experiments/plr_test_converted.json @@ -163,7 +163,7 @@ "type": "plate", "class": "opentrons_96_filtertiprack_1000ul", "position": { - "x": 0, + "x": 265.0, "y": 0, "z": 69 }, @@ -5762,8 +5762,8 @@ "type": "plate", "class": "nest_96_wellplate_2ml_deep", "position": { - "x": 265.0, - "y": 0, + "x": 0, + "y": 90.5, "z": 69 }, "config": { @@ -9623,6 +9623,65 @@ "pending_liquids": [], "liquid_history": [] } + }, + { + "id": "benyao", + "name": "benyao", + "children": [ + ], + "parent": null, + "type": "device", + "class": "moveit.benyao_arm", + "position": { + "x": -500, + "y": 1000, + "z": -100 + }, + "config": { + "moveit_type": "benyao_arm", + "joint_poses": { + "arm": { + "hotel_1": [1.05, 0.568, -1.0821, 0.0, 1.0821], + "home": [0.865, 0.09, 0.8727, 0.0, -0.8727] + } + }, + "rotation": { + "x": 0, + "y": 0, + "z": -1.5708, + "type": "Rotation" + }, + "device_config": { + } + }, + "data": { + } + }, + { + "id": "hotel", + "name": "hotel", + "children": [ + ], + "parent": null, + "type": "device", + "class": "hotel.thermo_orbitor_rs2_hotel", + "position": { + "x": 0, + "y": -700, + "z": -10 + }, + "config": { + "rotation": { + "x": 0, + "y": 0, + "z": 0, + "type": "Rotation" + }, + "device_config": { + } + }, + "data": { + } } ], "links": [] diff --git a/test/experiments/test_moveit.json b/test/experiments/test_moveit.json new file mode 100644 index 00000000..2859dc3a --- /dev/null +++ b/test/experiments/test_moveit.json @@ -0,0 +1,35 @@ +{ + "nodes": [ + + { + "id": "benyao", + "name": "benyao", + "children": [ + ], + "parent": null, + "type": "device", + "class": "moveit.benyao_arm", + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "config": { + "moveit_type": "benyao_arm", + "joint_poses": { + "arm": { + "home": [0.0, 0.2, 0.0, 0.0, 0.0], + "pick": [1.2, 0.0, 0.0, 0.0, 0.0] + } + }, + "device_config": { + } + }, + "data": { + } + } + ], + "links": [ + + ] +} \ No newline at end of file diff --git a/unilabos/device_mesh/devices/benyao_arm/config/initial_positions.yaml b/unilabos/device_mesh/devices/benyao_arm/config/initial_positions.yaml new file mode 100644 index 00000000..94fb9f55 --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/config/initial_positions.yaml @@ -0,0 +1,9 @@ +# Default initial positions for full_dev's ros2_control fake system + +initial_positions: + arm_base_joint: 0 + arm_link_1_joint: 0 + arm_link_2_joint: 0 + arm_link_3_joint: 0 + gripper_base_joint: 0 + gripper_right_joint: 0.03 \ No newline at end of file diff --git a/unilabos/device_mesh/devices/benyao_arm/config/joint_limits.yaml b/unilabos/device_mesh/devices/benyao_arm/config/joint_limits.yaml new file mode 100644 index 00000000..d4dffc37 --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/config/joint_limits.yaml @@ -0,0 +1,40 @@ +# joint_limits.yaml allows the dynamics properties specified in the URDF to be overwritten or augmented as needed + +# For beginners, we downscale velocity and acceleration limits. +# You can always specify higher scaling factors (<= 1.0) in your motion requests. # Increase the values below to 1.0 to always move at maximum speed. +default_velocity_scaling_factor: 0.1 +default_acceleration_scaling_factor: 0.1 + +# Specific joint properties can be changed with the keys [max_position, min_position, max_velocity, max_acceleration] +# Joint limits can be turned off with [has_velocity_limits, has_acceleration_limits] +joint_limits: + arm_base_joint: + has_velocity_limits: true + max_velocity: 0 + has_acceleration_limits: false + max_acceleration: 0 + arm_link_1_joint: + has_velocity_limits: true + max_velocity: 0 + has_acceleration_limits: false + max_acceleration: 0 + arm_link_2_joint: + has_velocity_limits: true + max_velocity: 0 + has_acceleration_limits: false + max_acceleration: 0 + arm_link_3_joint: + has_velocity_limits: true + max_velocity: 0 + has_acceleration_limits: false + max_acceleration: 0 + gripper_base_joint: + has_velocity_limits: true + max_velocity: 0 + has_acceleration_limits: false + max_acceleration: 0 + gripper_right_joint: + has_velocity_limits: true + max_velocity: 0 + has_acceleration_limits: false + max_acceleration: 0 \ No newline at end of file diff --git a/unilabos/device_mesh/devices/benyao_arm/config/kinematics.yaml b/unilabos/device_mesh/devices/benyao_arm/config/kinematics.yaml new file mode 100644 index 00000000..c9a5d608 --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/config/kinematics.yaml @@ -0,0 +1,4 @@ +arm: + kinematics_solver: lma_kinematics_plugin/LMAKinematicsPlugin + kinematics_solver_search_resolution: 0.0050000000000000001 + kinematics_solver_timeout: 0.0050000000000000001 diff --git a/unilabos/device_mesh/devices/benyao_arm/config/macro.ros2_control.xacro b/unilabos/device_mesh/devices/benyao_arm/config/macro.ros2_control.xacro new file mode 100644 index 00000000..70f8634f --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/config/macro.ros2_control.xacro @@ -0,0 +1,56 @@ + + + + + + + + + mock_components/GenericSystem + + + + + ${initial_positions['arm_base_joint']} + + + + + + + ${initial_positions['arm_link_1_joint']} + + + + + + + ${initial_positions['arm_link_2_joint']} + + + + + + + ${initial_positions['arm_link_3_joint']} + + + + + + + ${initial_positions['gripper_base_joint']} + + + + + + + ${initial_positions['gripper_right_joint']} + + + + + + + diff --git a/unilabos/device_mesh/devices/benyao_arm/config/macro.srdf.xacro b/unilabos/device_mesh/devices/benyao_arm/config/macro.srdf.xacro new file mode 100644 index 00000000..aeb56777 --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/config/macro.srdf.xacro @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/unilabos/device_mesh/devices/benyao_arm/config/move_group.json b/unilabos/device_mesh/devices/benyao_arm/config/move_group.json new file mode 100644 index 00000000..5be9ad34 --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/config/move_group.json @@ -0,0 +1,14 @@ +{ + "arm": + { + "joint_names": [ + "arm_base_joint", + "arm_link_1_joint", + "arm_link_2_joint", + "arm_link_3_joint", + "gripper_base_joint" + ], + "base_link_name": "device_link", + "end_effector_name": "gripper_base" + } +} \ No newline at end of file diff --git a/unilabos/device_mesh/devices/benyao_arm/config/moveit_controllers.yaml b/unilabos/device_mesh/devices/benyao_arm/config/moveit_controllers.yaml new file mode 100644 index 00000000..70a1b55d --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/config/moveit_controllers.yaml @@ -0,0 +1,29 @@ +# MoveIt uses this configuration for controller management + +moveit_controller_manager: moveit_simple_controller_manager/MoveItSimpleControllerManager + +moveit_simple_controller_manager: + controller_names: + - arm_controller + - gripper_controller + + arm_controller: + type: FollowJointTrajectory + action_ns: follow_joint_trajectory + default: true + joints: + - arm_base_joint + - arm_link_1_joint + - arm_link_2_joint + - arm_link_3_joint + - gripper_base_joint + action_ns: follow_joint_trajectory + default: true + gripper_controller: + type: FollowJointTrajectory + action_ns: follow_joint_trajectory + default: true + joints: + - gripper_right_joint + action_ns: follow_joint_trajectory + default: true \ No newline at end of file diff --git a/unilabos/device_mesh/devices/benyao_arm/config/moveit_planners.yaml b/unilabos/device_mesh/devices/benyao_arm/config/moveit_planners.yaml new file mode 100644 index 00000000..8560e1cb --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/config/moveit_planners.yaml @@ -0,0 +1,2 @@ +planner_configs: + - ompl_interface/OMPLPlanner \ No newline at end of file diff --git a/unilabos/device_mesh/devices/benyao_arm/config/pilz_cartesian_limits.yaml b/unilabos/device_mesh/devices/benyao_arm/config/pilz_cartesian_limits.yaml new file mode 100644 index 00000000..b2997caf --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/config/pilz_cartesian_limits.yaml @@ -0,0 +1,6 @@ +# Limits for the Pilz planner +cartesian_limits: + max_trans_vel: 1.0 + max_trans_acc: 2.25 + max_trans_dec: -5.0 + max_rot_vel: 1.57 diff --git a/unilabos/device_mesh/devices/benyao_arm/config/ros2_controllers.yaml b/unilabos/device_mesh/devices/benyao_arm/config/ros2_controllers.yaml new file mode 100644 index 00000000..9c68cbf1 --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/config/ros2_controllers.yaml @@ -0,0 +1,39 @@ +# This config file is used by ros2_control +controller_manager: + ros__parameters: + update_rate: 100 # Hz + + arm_controller: + type: joint_trajectory_controller/JointTrajectoryController + + + gripper_controller: + type: joint_trajectory_controller/JointTrajectoryController + + + joint_state_broadcaster: + type: joint_state_broadcaster/JointStateBroadcaster + +arm_controller: + ros__parameters: + joints: + - arm_base_joint + - arm_link_1_joint + - arm_link_2_joint + - arm_link_3_joint + - gripper_base_joint + command_interfaces: + - position + state_interfaces: + - position + - velocity + +gripper_controller: + ros__parameters: + joints: + - gripper_right_joint + command_interfaces: + - position + state_interfaces: + - position + - velocity \ No newline at end of file diff --git a/unilabos/device_mesh/devices/benyao_arm/joint_limit.yaml b/unilabos/device_mesh/devices/benyao_arm/joint_limit.yaml new file mode 100644 index 00000000..b1412620 --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/joint_limit.yaml @@ -0,0 +1,44 @@ +joint_limits: + + arm_base_joint: + effort: 50 + velocity: 1.0 + lower: 0 + upper: 1.5 + + arm_link_1_joint: + effort: 50 + velocity: 1.0 + lower: 0 + upper: 0.6 + + arm_link_2_joint: + effort: 50 + velocity: 1.0 + lower: !degrees -95 + upper: !degrees 95 + + arm_link_3_joint: + effort: 50 + velocity: 1.0 + lower: !degrees -195 + upper: !degrees 195 + + gripper_base_joint: + effort: 50 + velocity: 1.0 + lower: !degrees -95 + upper: !degrees 95 + + + gripper_right_joint: + effort: 50 + velocity: 1.0 + lower: 0 + upper: 0.03 + + gripper_left_joint: + effort: 50 + velocity: 1.0 + lower: 0 + upper: 0.03 diff --git a/unilabos/device_mesh/devices/benyao_arm/macro_device.xacro b/unilabos/device_mesh/devices/benyao_arm/macro_device.xacro new file mode 100644 index 00000000..137c916d --- /dev/null +++ b/unilabos/device_mesh/devices/benyao_arm/macro_device.xacro @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/arm_base.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_base.STL new file mode 100644 index 00000000..804e1c69 Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_base.STL differ diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_1.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_1.STL new file mode 100644 index 00000000..dd1d7c14 Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_1.STL differ diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_2.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_2.STL new file mode 100644 index 00000000..6042fa0f Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_2.STL differ diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_3.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_3.STL new file mode 100644 index 00000000..e8510fbc Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_3.STL differ diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/arm_slideway.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_slideway.STL new file mode 100644 index 00000000..65737ab5 Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_slideway.STL differ diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_base.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_base.STL new file mode 100644 index 00000000..5de88d0c Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_base.STL differ diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_left.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_left.STL new file mode 100644 index 00000000..0a5fd526 Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_left.STL differ diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_right.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_right.STL new file mode 100644 index 00000000..0c5ac69f Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_right.STL differ diff --git a/unilabos/device_mesh/devices/opentrons_liquid_handler/macro_device.xacro b/unilabos/device_mesh/devices/opentrons_liquid_handler/macro_device.xacro index 4e660557..f76f654f 100644 --- a/unilabos/device_mesh/devices/opentrons_liquid_handler/macro_device.xacro +++ b/unilabos/device_mesh/devices/opentrons_liquid_handler/macro_device.xacro @@ -3,11 +3,10 @@ - + params="parent_link:='' station_name:='' device_name:='' x:=0 y:=0 z:=0 rx:=0 ry:=0 r:=0 mesh_path:=''"> - + diff --git a/unilabos/device_mesh/devices/slide_w140/macro_device.xacro b/unilabos/device_mesh/devices/slide_w140/macro_device.xacro index 7e43242e..d6d93f96 100644 --- a/unilabos/device_mesh/devices/slide_w140/macro_device.xacro +++ b/unilabos/device_mesh/devices/slide_w140/macro_device.xacro @@ -8,11 +8,11 @@ For more information, please see http://wiki.ros.org/sw_urdf_exporter --> - + - + diff --git a/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/hotel.png b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/hotel.png new file mode 100644 index 00000000..daecc639 Binary files /dev/null and b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/hotel.png differ diff --git a/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/macro_device.xacro b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/macro_device.xacro new file mode 100644 index 00000000..52c9536e --- /dev/null +++ b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/macro_device.xacro @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.glb b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.glb new file mode 100644 index 00000000..724b85f7 Binary files /dev/null and b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.glb differ diff --git a/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.stl b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.stl new file mode 100644 index 00000000..59cb9084 Binary files /dev/null and b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.stl differ diff --git a/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meta.json b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meta.json new file mode 100644 index 00000000..b8f35cb5 --- /dev/null +++ b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meta.json @@ -0,0 +1,10 @@ +{ + "fileName": "thermo_orbitor_rs2_hotel", + "related": [ + "thermo_skyline_stacker", + "thermo_cytomat2c_stacker_15", + "thermo_fisher_cytomat_stacker_16", + "thermo_cytomat2c_stacker_21", + "thermo_orbitor_rs2_hotel" + ] +} diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/full_dev.urdf.xacro b/unilabos/device_mesh/devices/toyo_xyz/config/full_dev.urdf.xacro new file mode 100644 index 00000000..29bd48de --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/config/full_dev.urdf.xacro @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/initial_positions.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/initial_positions.yaml new file mode 100644 index 00000000..d44ccee9 --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/config/initial_positions.yaml @@ -0,0 +1,6 @@ +# Default initial positions for full_dev's ros2_control fake system + +initial_positions: + slider1_joint: 0 + slider2_joint: 0 + slider3_joint: 0 \ No newline at end of file diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/joint_limits.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/joint_limits.yaml new file mode 100644 index 00000000..251b26c1 --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/config/joint_limits.yaml @@ -0,0 +1,25 @@ +# joint_limits.yaml allows the dynamics properties specified in the URDF to be overwritten or augmented as needed + +# For beginners, we downscale velocity and acceleration limits. +# You can always specify higher scaling factors (<= 1.0) in your motion requests. # Increase the values below to 1.0 to always move at maximum speed. +default_velocity_scaling_factor: 0.1 +default_acceleration_scaling_factor: 0.1 + +# Specific joint properties can be changed with the keys [max_position, min_position, max_velocity, max_acceleration] +# Joint limits can be turned off with [has_velocity_limits, has_acceleration_limits] +joint_limits: + slider1_joint: + has_velocity_limits: false + max_velocity: 0 + has_acceleration_limits: false + max_acceleration: 0 + slider2_joint: + has_velocity_limits: false + max_velocity: 0 + has_acceleration_limits: false + max_acceleration: 0 + slider3_joint: + has_velocity_limits: false + max_velocity: 0 + has_acceleration_limits: false + max_acceleration: 0 \ No newline at end of file diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/kinematics.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/kinematics.yaml new file mode 100644 index 00000000..d11fa7bf --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/config/kinematics.yaml @@ -0,0 +1,4 @@ +toyo_xyz: + kinematics_solver: lma_kinematics_plugin/LMAKinematicsPlugin + kinematics_solver_search_resolution: 0.0050000000000000001 + kinematics_solver_timeout: 0.0050000000000000001 \ No newline at end of file diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/macro.ros2_control.xacro b/unilabos/device_mesh/devices/toyo_xyz/config/macro.ros2_control.xacro new file mode 100644 index 00000000..5bc3404d --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/config/macro.ros2_control.xacro @@ -0,0 +1,35 @@ + + + + + + + + + mock_components/GenericSystem + + + + + ${initial_positions['slider1_joint']} + + + + + + + ${initial_positions['slider2_joint']} + + + + + + + ${initial_positions['slider3_joint']} + + + + + + + diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/macro.srdf.xacro b/unilabos/device_mesh/devices/toyo_xyz/config/macro.srdf.xacro new file mode 100644 index 00000000..753382fe --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/config/macro.srdf.xacro @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/move_group.json b/unilabos/device_mesh/devices/toyo_xyz/config/move_group.json new file mode 100644 index 00000000..d9006744 --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/config/move_group.json @@ -0,0 +1,12 @@ +{ + "toyo_xyz": + { + "joint_names": [ + "slider1_joint", + "slider2_joint", + "slider3_joint" + ], + "base_link_name": "device_link", + "end_effector_name": "slider3_link" + } +} \ No newline at end of file diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/moveit_controllers.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/moveit_controllers.yaml new file mode 100644 index 00000000..0fcac512 --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/config/moveit_controllers.yaml @@ -0,0 +1,16 @@ +# MoveIt uses this configuration for controller management + +moveit_controller_manager: moveit_simple_controller_manager/MoveItSimpleControllerManager + +moveit_simple_controller_manager: + controller_names: + - toyo_xyz_controller + + toyo_xyz_controller: + type: FollowJointTrajectory + action_ns: follow_joint_trajectory + default: true + joints: + - slider1_joint + - slider2_joint + - slider3_joint \ No newline at end of file diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/pilz_cartesian_limits.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/pilz_cartesian_limits.yaml new file mode 100644 index 00000000..b2997caf --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/config/pilz_cartesian_limits.yaml @@ -0,0 +1,6 @@ +# Limits for the Pilz planner +cartesian_limits: + max_trans_vel: 1.0 + max_trans_acc: 2.25 + max_trans_dec: -5.0 + max_rot_vel: 1.57 diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/ros2_controllers.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/ros2_controllers.yaml new file mode 100644 index 00000000..1d1a552e --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/config/ros2_controllers.yaml @@ -0,0 +1,34 @@ +# This config file is used by ros2_control +controller_manager: + + ros__parameters: + update_rate: 100 # Hz + + joint_state_broadcaster: + type: joint_state_broadcaster/JointStateBroadcaster + # action_ns: $(var device_id) + toyo_xyz_controller: + type: joint_trajectory_controller/JointTrajectoryController + +# joint_state_broadcaster: +# ros__parameters: {} + +toyo_xyz_controller: + ros__parameters: + joints: + - slider1_joint + - slider2_joint + - slider3_joint + command_interfaces: + - position + state_interfaces: + - position + - velocity + allow_partial_joints_goal: false + open_loop_control: true + allow_integration_in_goal_trajectories: true + action_monitor_rate: 20.0 + # goal_time: 0.0 + # constraints: + # stopped_velocity_tolerance: 0.01 + # goal_time: 0.0 \ No newline at end of file diff --git a/unilabos/device_mesh/devices/toyo_xyz/joint_config.json b/unilabos/device_mesh/devices/toyo_xyz/joint_config.json new file mode 100644 index 00000000..26bda262 --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/joint_config.json @@ -0,0 +1,14 @@ +{ + "slider1_joint": { + "child":"slider1_link", + "axis" : "x" + }, + "slider2_joint": { + "child":"slider2_link", + "axis" : "x" + }, + "slider3_joint": { + "child":"slider3_link", + "axis" : "x" + } +} \ No newline at end of file diff --git a/unilabos/device_mesh/devices/toyo_xyz/macro_device.xacro b/unilabos/device_mesh/devices/toyo_xyz/macro_device.xacro new file mode 100644 index 00000000..5694c353 --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/macro_device.xacro @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.STL new file mode 100755 index 00000000..ded0641d Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.fbx new file mode 100644 index 00000000..a278cc67 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.STL new file mode 100755 index 00000000..d1dba510 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.fbx new file mode 100644 index 00000000..8c28d394 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.STL new file mode 100755 index 00000000..24205e50 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.fbx new file mode 100644 index 00000000..5a243395 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.STL new file mode 100755 index 00000000..fcbfdce5 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.fbx new file mode 100644 index 00000000..8bd35dbf Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.STL new file mode 100755 index 00000000..1b72d5db Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.fbx new file mode 100644 index 00000000..01079615 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.STL new file mode 100755 index 00000000..ce0dd9f1 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.fbx new file mode 100644 index 00000000..f0e55b56 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.STL new file mode 100755 index 00000000..6f5e5044 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.fbx new file mode 100644 index 00000000..4ba363c7 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.STL new file mode 100755 index 00000000..7a064ccf Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.fbx new file mode 100644 index 00000000..ea46d658 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.STL new file mode 100755 index 00000000..9eb85cdc Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.fbx new file mode 100644 index 00000000..5375fcec Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.STL new file mode 100755 index 00000000..3ffad0f2 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.fbx new file mode 100644 index 00000000..f94c5a6d Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.STL new file mode 100755 index 00000000..1afcdd2c Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.fbx new file mode 100644 index 00000000..a812b4c5 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.STL new file mode 100755 index 00000000..9ef91e28 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.fbx new file mode 100644 index 00000000..e2a7c861 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.STL new file mode 100755 index 00000000..abd8c568 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.fbx new file mode 100644 index 00000000..a46df101 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.STL new file mode 100755 index 00000000..a0bfb168 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.STL differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.fbx new file mode 100644 index 00000000..6cec9641 Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.fbx differ diff --git a/unilabos/device_mesh/devices/toyo_xyz/param_config.json b/unilabos/device_mesh/devices/toyo_xyz/param_config.json new file mode 100644 index 00000000..457332b6 --- /dev/null +++ b/unilabos/device_mesh/devices/toyo_xyz/param_config.json @@ -0,0 +1,20 @@ +{ + "private_param": + { + "min_d1": 0.01 , + "max_d1": 0.01 , + "slider_d1": 0.135, + "min_d2": 0.01 , + "max_d2": 0.01 , + "slider_d2": 0.116, + "min_d3": 0.01 , + "max_d3": 0.01 , + "slider_d3": 0.09 + }, + "public_param": + { + "length1" :0.5, + "length2" :0.2, + "length3" :0.2 + } +} \ No newline at end of file diff --git a/unilabos/device_mesh/resource_visalization.py b/unilabos/device_mesh/resource_visalization.py index b840789f..dab18f18 100644 --- a/unilabos/device_mesh/resource_visalization.py +++ b/unilabos/device_mesh/resource_visalization.py @@ -1,13 +1,38 @@ +import json import os from pathlib import Path +import re + +import yaml from launch import LaunchService from launch import LaunchDescription from launch_ros.actions import Node as nd import xacro from lxml import etree - +from launch_param_builder import load_yaml +from launch_ros.parameter_descriptions import ParameterFile from unilabos.registry.registry import lab_registry +from ament_index_python.packages import get_package_share_directory +def get_pattern_matches(folder, pattern): + """Given all the files in the folder, find those that match the pattern. + + If there are groups defined, the groups are returned. Otherwise the path to the matches are returned. + """ + matches = [] + if not folder.exists(): + return matches + for child in folder.iterdir(): + if not child.is_file(): + continue + m = pattern.search(child.name) + if m: + groups = m.groups() + if groups: + matches.append(groups[0]) + else: + matches.append(child) + return matches class ResourceVisualization: def __init__(self, device: dict, resource: dict, enable_rviz: bool = True): @@ -31,9 +56,8 @@ class ResourceVisualization: self.enable_rviz = enable_rviz registry = lab_registry - self.srdf_str = ''' - - + self.srdf_str = ''' + ''' @@ -43,23 +67,46 @@ class ResourceVisualization: ''' self.root = etree.fromstring(self.robot_state_str) + self.root_srdf = etree.fromstring(self.srdf_str) xacro_uri = self.root.nsmap["xacro"] + self.moveit_nodes = {} + self.moveit_nodes_kinematics = {} + self.moveit_controllers_yaml = { + "moveit_controller_manager": "moveit_simple_controller_manager/MoveItSimpleControllerManager", + "moveit_simple_controller_manager": { + "controller_names": [] + } + } + self.ros2_controllers_yaml = { + "controller_manager": { + "ros__parameters": { + "update_rate": 100, + "joint_state_broadcaster": { + "type": "joint_state_broadcaster/JointStateBroadcaster", + } + } + } + } + # 遍历设备节点 for node in device.values(): - if node['type'] == 'device' and node['class'] != '': - device_class = node['class'] - # 检查设备类型是否在注册表中 - if device_class not in registry.device_type_registry.keys(): - raise ValueError(f"设备类型 {device_class} 未在注册表中注册") - elif node['type'] in self.resource_type: - # print(registry.resource_type_registry) - resource_class = node['class'] - if resource_class not in registry.resource_type_registry.keys(): - raise ValueError(f"资源类型 {resource_class} 未在注册表中注册") - elif "model" in registry.resource_type_registry[resource_class].keys(): - model_config = registry.resource_type_registry[resource_class]['model'] + if node['type'] in self.resource_type or (node['type'] == 'device' and node['class'] != ''): + model_config = {} + if node['type'] in self.resource_type: + resource_class = node['class'] + if resource_class not in registry.resource_type_registry.keys(): + raise ValueError(f"资源类型 {resource_class} 未在注册表中注册") + elif "model" in registry.resource_type_registry[resource_class].keys(): + model_config = registry.resource_type_registry[resource_class]['model'] + elif node['type'] == 'device' and node['class'] != '': + device_class = node['class'] + if device_class not in registry.device_type_registry.keys(): + raise ValueError(f"设备类型 {device_class} 未在注册表中注册") + elif "model" in registry.device_type_registry[device_class].keys(): + model_config = registry.device_type_registry[device_class]['model'] + if model_config: if model_config['type'] == 'resource': self.resource_model[node['id']] = { 'mesh': f"{str(self.mesh_path)}/resources/{model_config['mesh']}", @@ -71,18 +118,40 @@ class ResourceVisualization: 'mesh_tf': model_config['children_mesh_tf'] } elif model_config['type'] == 'device': + new_include = etree.SubElement(self.root, f"{{{xacro_uri}}}include") new_include.set("filename", f"{str(self.mesh_path)}/devices/{model_config['mesh']}/macro_device.xacro") new_dev = etree.SubElement(self.root, f"{{{xacro_uri}}}{model_config['mesh']}") new_dev.set("parent_link", "world") new_dev.set("mesh_path", str(self.mesh_path)) new_dev.set("device_name", node["id"]+"_") - new_dev.set("station_name", node["parent"]+'_') + if node["parent"] is not None: + new_dev.set("station_name", node["parent"]+'_') new_dev.set("x",str(float(node["position"]["x"])/1000)) new_dev.set("y",str(float(node["position"]["y"])/1000)) new_dev.set("z",str(float(node["position"]["z"])/1000)) if "rotation" in node["config"]: - new_dev.set("r",str(float(node["config"]["rotation"]["z"])/1000)) + new_dev.set("rx",str(float(node["config"]["rotation"]["x"]))) + new_dev.set("ry",str(float(node["config"]["rotation"]["y"]))) + new_dev.set("r",str(float(node["config"]["rotation"]["z"]))) + if "device_config" in node["config"]: + for key, value in node["config"]["device_config"].items(): + new_dev.set(key, str(float(value))) + + # 添加ros2_controller + if node['class'].startswith('moveit.'): + new_include_controller = etree.SubElement(self.root, f"{{{xacro_uri}}}include") + new_include_controller.set("filename", f"{str(self.mesh_path)}/devices/{model_config['mesh']}/config/macro.ros2_control.xacro") + new_controller = etree.SubElement(self.root, f"{{{xacro_uri}}}{model_config['mesh']}_ros2_control") + new_controller.set("device_name", node["id"]+"_") + new_controller.set("mesh_path", str(self.mesh_path)) + + # 添加moveit的srdf + new_include_srdf = etree.SubElement(self.root_srdf, f"{{{xacro_uri}}}include") + new_include_srdf.set("filename", f"{str(self.mesh_path)}/devices/{model_config['mesh']}/config/macro.srdf.xacro") + new_srdf = etree.SubElement(self.root_srdf, f"{{{xacro_uri}}}{model_config['mesh']}_srdf") + new_srdf.set("device_name", node["id"]+"_") + self.moveit_nodes[node["id"]] = model_config['mesh'] else: print("错误的注册表类型!") re = etree.tostring(self.root, encoding="unicode") @@ -90,8 +159,37 @@ class ResourceVisualization: xacro.process_doc(doc) self.urdf_str = doc.toxml() + re_srdf = etree.tostring(self.root_srdf, encoding="unicode") + doc_srdf = xacro.parse(re_srdf) + xacro.process_doc(doc_srdf) + self.urdf_str_srdf = doc_srdf.toxml() + if self.moveit_nodes: + self.moveit_init() - def create_launch_description(self, urdf_str: str) -> LaunchDescription: + def moveit_init(self): + + for name, config in self.moveit_nodes.items(): + controller_dict = yaml.safe_load(open(f"{str(self.mesh_path)}/devices/{config}/config/ros2_controllers.yaml", "r")) + moveit_dict = yaml.safe_load(open(f"{str(self.mesh_path)}/devices/{config}/config/moveit_controllers.yaml", "r")) + kinematics_dict = yaml.safe_load(open(f"{str(self.mesh_path)}/devices/{config}/config/kinematics.yaml", "r")) + + for key_kinematics, value_kinematics in kinematics_dict.items(): + self.moveit_nodes_kinematics[f'{name}_{key_kinematics}'] = value_kinematics + + for key, value in controller_dict['controller_manager']['ros__parameters'].items(): + if key == 'update_rate' or key == 'joint_state_broadcaster': + continue + self.ros2_controllers_yaml['controller_manager']['ros__parameters'][f"{name}_{key}"] = value + controller_dict[key]['ros__parameters']['joints'] = [f"{name}_{joint}" for joint in controller_dict[key]['ros__parameters']['joints']] + self.ros2_controllers_yaml[f"{name}_{key}"] = controller_dict[key] + + for controller_name in moveit_dict['moveit_simple_controller_manager']['controller_names']: + self.moveit_controllers_yaml['moveit_simple_controller_manager']['controller_names'].append(f"{name}_{controller_name}") + moveit_dict['moveit_simple_controller_manager'][controller_name]['joints'] = [f"{name}_{joint}" for joint in moveit_dict['moveit_simple_controller_manager'][controller_name]['joints']] + self.moveit_controllers_yaml['moveit_simple_controller_manager'][f"{name}_{controller_name}"] = moveit_dict['moveit_simple_controller_manager'][controller_name] + + + def create_launch_description(self) -> LaunchDescription: """ 创建launch描述,包含robot_state_publisher和move_group节点 @@ -101,10 +199,93 @@ class ResourceVisualization: Returns: LaunchDescription: launch描述对象 """ + moveit_configs_utils_path = Path(get_package_share_directory("moveit_configs_utils")) + default_folder = moveit_configs_utils_path / "default_configs" + planning_pattern = re.compile("^(.*)_planning.yaml$") + pipelines = [] - + for pipeline in get_pattern_matches(default_folder, planning_pattern): + if pipeline not in pipelines: + pipelines.append(pipeline) + + if "ompl" in pipelines: + default_planning_pipeline = "ompl" + else: + default_planning_pipeline = pipelines[0] + + planning_pipelines = { + "planning_pipelines": pipelines, + "default_planning_pipeline": default_planning_pipeline, + } + + for pipeline in pipelines: + planning_pipelines[pipeline] = load_yaml( + default_folder / f"{pipeline}_planning.yaml" + ) + + if "ompl" in planning_pipelines: + ompl_config = planning_pipelines["ompl"] + if "planner_configs" not in ompl_config: + ompl_config.update(load_yaml(default_folder / "ompl_defaults.yaml")) + + yaml.safe_dump(self.ros2_controllers_yaml, open(f"{str(self.mesh_path)}/ros2_controllers.yaml", "w")) + + robot_description_planning = { + "default_velocity_scaling_factor": 0.1, + "default_acceleration_scaling_factor": 0.1, + "cartesian_limits": { + "max_trans_vel": 1.0, + "max_trans_acc": 2.25, + "max_trans_dec": -5.0, + "max_rot_vel": 1.57 + } + } # 解析URDF文件 - robot_description = urdf_str + robot_description = self.urdf_str + urdf_str_srdf = self.urdf_str_srdf + + kinematics_dict = self.moveit_nodes_kinematics + + if self.moveit_nodes: + controllers = [] + ros2_controllers = ParameterFile(f"{str(self.mesh_path)}/ros2_controllers.yaml", allow_substs=True) + + controllers.append( + nd( + package="controller_manager", + executable="ros2_control_node", + output='screen', + parameters=[ + {"robot_description": robot_description}, + ros2_controllers, + ] + ) + ) + for controller in self.moveit_controllers_yaml['moveit_simple_controller_manager']['controller_names']: + controllers.append( + nd( + package="controller_manager", + executable="spawner", + arguments=[f"{controller}", "--controller-manager", f"controller_manager"], + output="screen", + ) + ) + controllers.append( + nd( + package="controller_manager", + executable="spawner", + arguments=["joint_state_broadcaster", "--controller-manager", f"controller_manager"], + output="screen", + ) + ) + for i in controllers: + self.launch_description.add_action(i) + else: + ros2_controllers = None + + + + # 创建robot_state_publisher节点 robot_state_publisher = nd( @@ -115,23 +296,21 @@ class ResourceVisualization: parameters=[{ 'robot_description': robot_description, 'use_sim_time': False - }] + }, + # kinematics_dict + ] ) - # joint_state_publisher_node = nd( - # package='joint_state_publisher_gui', # 或 joint_state_publisher - # executable='joint_state_publisher_gui', - # name='joint_state_publisher', - # output='screen' - # ) # 创建move_group节点 move_group = nd( package='moveit_ros_move_group', executable='move_group', output='screen', parameters=[{ + 'allow_trajectory_execution': True, 'robot_description': robot_description, - 'robot_description_semantic': self.srdf_str, + 'robot_description_semantic': urdf_str_srdf, + 'robot_description_kinematics': kinematics_dict, 'capabilities': '', 'disable_capabilities': '', 'monitor_dynamics': False, @@ -141,7 +320,13 @@ class ResourceVisualization: 'publish_geometry_updates': True, 'publish_state_updates': True, 'publish_transforms_updates': True, - }] + # 'robot_description_planning': robot_description_planning, + }, + self.moveit_controllers_yaml, + # ompl_planning_pipeline_config, + robot_description_planning, + planning_pipelines, + ] ) # 将节点添加到launch描述中 @@ -156,7 +341,14 @@ class ResourceVisualization: executable='rviz2', name='rviz2', arguments=['-d', f"{str(self.mesh_path)}/view_robot.rviz"], - output='screen' + output='screen', + parameters=[ + {'robot_description_kinematics': kinematics_dict, + }, + robot_description_planning, + planning_pipelines, + + ] ) self.launch_description.add_action(rviz_node) @@ -169,6 +361,11 @@ class ResourceVisualization: Args: urdf_str: URDF文件路径 """ - launch_description = self.create_launch_description(self.urdf_str) + launch_description = self.create_launch_description() + # print('--------------------------------') + # print(self.moveit_controllers_yaml) + # print('--------------------------------') + # print(self.urdf_str) + # print('--------------------------------') self.launch_service.include_launch_description(launch_description) self.launch_service.run() \ No newline at end of file diff --git a/unilabos/device_mesh/ros2_controllers.yaml b/unilabos/device_mesh/ros2_controllers.yaml new file mode 100644 index 00000000..e54c64c3 --- /dev/null +++ b/unilabos/device_mesh/ros2_controllers.yaml @@ -0,0 +1,31 @@ +benyao_arm_controller: + ros__parameters: + command_interfaces: + - position + joints: + - benyao_arm_base_joint + - benyao_arm_link_1_joint + - benyao_arm_link_2_joint + - benyao_arm_link_3_joint + - benyao_gripper_base_joint + state_interfaces: + - position + - velocity +benyao_gripper_controller: + ros__parameters: + command_interfaces: + - position + joints: + - benyao_gripper_right_joint + state_interfaces: + - position + - velocity +controller_manager: + ros__parameters: + benyao_arm_controller: + type: joint_trajectory_controller/JointTrajectoryController + benyao_gripper_controller: + type: joint_trajectory_controller/JointTrajectoryController + joint_state_broadcaster: + type: joint_state_broadcaster/JointStateBroadcaster + update_rate: 100 diff --git a/unilabos/device_mesh/view_robot.rviz b/unilabos/device_mesh/view_robot.rviz index 07bf15df..f042cc27 100644 --- a/unilabos/device_mesh/view_robot.rviz +++ b/unilabos/device_mesh/view_robot.rviz @@ -1,23 +1,18 @@ Panels: - Class: rviz_common/Displays - Help Height: 138 + Help Height: 0 Name: Displays Property Tree Widget: Expanded: - - /Global Options1 - - /TF1 + - /TF1/Frames1 - /TF1/Tree1 - - /RobotModel1 - - /PlanningScene1 - /PlanningScene1/Scene Geometry1 - - /RobotState1 - - /RobotState1/Links1 - /MotionPlanning1 - /MotionPlanning1/Scene Geometry1 - /MotionPlanning1/Scene Robot1 - /MotionPlanning1/Planning Request1 - Splitter Ratio: 0.5 - Tree Height: 345 + Splitter Ratio: 0.4940796494483948 + Tree Height: 602 - Class: rviz_common/Selection Name: Selection - Class: rviz_common/Tool Properties @@ -61,7 +56,7 @@ Visualization Manager: Name: TF Show Arrows: true Show Axes: true - Show Names: false + Show Names: true Tree: {} Update Interval: 0 @@ -203,6 +198,63 @@ Visualization Manager: Show Axes: false Show Trail: false Value: true + benyao_arm_base: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_arm_link_1: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_arm_link_2: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_arm_link_3: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_arm_slideway: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_device_link: + Alpha: 1 + Show Axes: false + Show Trail: false + benyao_gripper_base: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_gripper_left: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_gripper_right: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + hotel_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + hotel_device_link: + Alpha: 1 + Show Axes: false + Show Trail: false + hotel_socketTypeGenericSbsFootprint: + Alpha: 1 + Show Axes: false + Show Trail: false world: Alpha: 1 Show Axes: false @@ -230,7 +282,7 @@ Visualization Manager: Goal State Color: 250; 128; 0 Interactive Marker Size: 0 Joint Violation Color: 255; 0; 255 - Planning Group: "" + Planning Group: benyao_arm Query Goal State: false Query Start State: false Show Workspace: false @@ -290,6 +342,63 @@ Visualization Manager: Show Axes: false Show Trail: false Value: true + benyao_arm_base: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_arm_link_1: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_arm_link_2: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_arm_link_3: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_arm_slideway: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_device_link: + Alpha: 1 + Show Axes: false + Show Trail: false + benyao_gripper_base: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_gripper_left: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + benyao_gripper_right: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + hotel_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + hotel_device_link: + Alpha: 1 + Show Axes: false + Show Trail: false + hotel_socketTypeGenericSbsFootprint: + Alpha: 1 + Show Axes: false + Show Trail: false world: Alpha: 1 Show Axes: false @@ -345,43 +454,43 @@ Visualization Manager: Views: Current: Class: rviz_default_plugins/Orbit - Distance: 1.595012903213501 + Distance: 2.622864246368408 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 Swap Stereo Eyes: false Value: false Focal Point: - X: 0.29730814695358276 - Y: 0.21228469908237457 - Z: 0.20008830726146698 + X: -0.2880733013153076 + Y: -0.16004444658756256 + Z: -0.16730672121047974 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.38979560136795044 + Pitch: 0.634795606136322 Target Frame: Value: Orbit (rviz) - Yaw: 0.05074193701148033 + Yaw: 5.590744495391846 Saved: ~ Window Geometry: Displays: - collapsed: false - Height: 2160 - Hide Left Dock: false + collapsed: true + Height: 1897 + Hide Left Dock: true Hide Right Dock: true MotionPlanning: - collapsed: false + collapsed: true MotionPlanning - Trajectory Slider: collapsed: false - QMainWindow State: 000000ff00000000fd0000000400000000000003a3000005dcfc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b000000b000fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073000000006e000002510000018200fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb000000280020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000000000000000fb00000044004d006f00740069006f006e0050006c0061006e006e0069006e00670020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000007a00fffffffb0000001c004d006f00740069006f006e0050006c0061006e006e0069006e006700000002cb0000037f000002b800ffffff000000010000010f00000387fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003b000003870000013200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d00650100000000000004500000000000000000000010000000087000000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730000000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd0000000400000000000003a300000714fc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b000000b000fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c0061007900730000000027000002c80000018200fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb000000280020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000000000000000fb00000044004d006f00740069006f006e0050006c0061006e006e0069006e00670020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000002600000026fb0000001c004d006f00740069006f006e0050006c0061006e006e0069006e006700000002fb00000440000002b800ffffff000000010000010f00000387fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003b000003870000013200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d0065010000000000000450000000000000000000000ddb0000071400000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730000000000ffffffff0000000000000000 Selection: collapsed: false Tool Properties: collapsed: false Views: collapsed: true - Width: 4096 - X: 0 - Y: 0 + Width: 3547 + X: -857 + Y: 149 diff --git a/unilabos/devices/resource_container/__init__.py b/unilabos/devices/resource_container/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/unilabos/devices/resource_container/container.py b/unilabos/devices/resource_container/container.py new file mode 100644 index 00000000..38b9a806 --- /dev/null +++ b/unilabos/devices/resource_container/container.py @@ -0,0 +1,9 @@ + +class HotelContainer: + def __init__(self, rotation: dict, device_config: dict): + self.rotation = rotation + self.device_config = device_config + self.status = 'idle' + + def get_rotation(self): + return self.rotation diff --git a/unilabos/devices/ros_dev/moveit_interface.py b/unilabos/devices/ros_dev/moveit_interface.py new file mode 100644 index 00000000..4f9daad0 --- /dev/null +++ b/unilabos/devices/ros_dev/moveit_interface.py @@ -0,0 +1,435 @@ +from pathlib import Path +from threading import Thread +import time + +import rclpy +import rclpy.duration +import rclpy.time +from unilabos_msgs.action import SendCmd +from rclpy.action import ActionServer, ActionClient +from rclpy.action.server import ServerGoalHandle +from rclpy.callback_groups import ReentrantCallbackGroup +from moveit_msgs.msg import JointConstraint, Constraints +from copy import deepcopy + +from pymoveit2 import MoveIt2, GripperInterface + +import numpy as np +from unilabos.ros.nodes.base_device_node import BaseROS2DeviceNode + +# from tf_transformations import quaternion_from_euler +from tf2_ros import Buffer, TransformListener +import json + + +class MoveitInterface(BaseROS2DeviceNode): + def __init__(self, device_id, moveit_type, joint_poses, resource_tracker, rotation = None, device_config = None): + super().__init__( + driver_instance=self, + device_id=device_id, + status_types={}, + action_value_mappings={}, + hardware_interface={}, + print_publish=False, + resource_tracker=resource_tracker, + ) + self.callback_group = ReentrantCallbackGroup() + data_config = json.load(open(f"{Path(__file__).parent.parent.parent.absolute()}/device_mesh/devices/{moveit_type}/config/move_group.json", encoding="utf-8")) + + self.tf_buffer = Buffer() + self.tf_listener = TransformListener(self.tf_buffer, self) + + self.arm_move_flag = False + + self.move_option = ['pick', 'place', 'side_pick', 'side_place'] + self.joint_poses = joint_poses + self.cartesian_flag = False + + self.mesh_group = ['reactor','sample','beaker'] + + self.moveit2 = {} + + + self.resource_action = None + self.resource_client = None + self.resource_action_ok = False + + + + for move_group, config in data_config.items(): + + base_link_name = f"{device_id}_{config['base_link_name']}" + end_effector_name = f"{device_id}_{config['end_effector_name']}" + joint_names = [f"{device_id}_{name}" for name in config['joint_names']] + + self.moveit2[f"{move_group}"] = MoveIt2( + node=self, + joint_names=joint_names, + base_link_name=base_link_name, + end_effector_name=end_effector_name, + group_name=f"{device_id}_{move_group}", + callback_group=self.callback_group, + use_move_group_action= True, + ignore_new_calls_while_executing = True + ) + self.moveit2[f"{move_group}"].allowed_planning_time = 3.0 + + + self.moveit_pose_server = ActionServer( + self, + SendCmd, + f'set_position', + execute_callback=self.callback, + callback_group=self.callback_group, + result_timeout=5000 + ) + + self.moveit_pick_server = ActionServer( + self, + SendCmd, + f'pick_and_place', + execute_callback=self.pick_and_place_callback, + callback_group=self.callback_group, + result_timeout=5000 + ) + + + self.moveit_joint_server = ActionServer( + self, + SendCmd, + f'set_status', + execute_callback=self.set_status_callback, + callback_group=self.callback_group, + result_timeout=5000 + ) + + self.create_timer(1, self.wait_for_resource_action,callback_group=ReentrantCallbackGroup()) + + + def wait_for_resource_action(self): + if not self.resource_action_ok: + + while self.resource_action is None: + self.resource_action = self.check_tf_update_actions() + time.sleep(1) + self.resource_client = ActionClient(self, SendCmd, self.resource_action) + self.resource_action_ok = True + while not self.resource_client.wait_for_server(timeout_sec=5.0): + self.get_logger().info('等待 TfUpdate 服务器...') + + + def check_tf_update_actions(self): + topics = self.get_topic_names_and_types() + + + for topic_item in topics: + + topic_name, topic_types = topic_item + + if 'action_msgs/msg/GoalStatusArray' in topic_types: + # 删除 /_action/status 部分 + + base_name = topic_name.replace('/_action/status', '') + # 检查最后一个部分是否为 tf_update + parts = base_name.split('/') + if parts and parts[-1] == 'tf_update': + return base_name + + return None + + def callback(self,goal_handle: ServerGoalHandle): + + """使用moveit 移动到指定点 + Args: + command: A JSON-formatted string that includes quaternion, speed, position + + position (list) : 点的位置 [x,y,z] + quaternion (list) : 点的姿态(四元数) [x,y,z,w] + move_group (string) : The move group moveit will plan + speed (float) : The speed of the movement, speed > 0 + retry (int) : Retry times when moveit plan fails + + Returns: + None + """ + + result = SendCmd.Result() + + try: + cmd_str = str(goal_handle.request.command).replace('\'','\"') + cmd_dict = json.loads(cmd_str) + + self.moveit_task(**cmd_dict) + goal_handle.succeed() + result.success=True + + except Exception as e: + print(e) + goal_handle.abort() + result.success=False + + return result + + def moveit_task(self,move_group,position,quaternion,speed=1,retry=10,cartesian=False, target_link = None ,offsets =[0,0,0]): + + speed_ = float(max(0.1, min(speed, 1))) + + self.moveit2[move_group].max_velocity = speed_ + self.moveit2[move_group].max_acceleration = speed_ + + re_ = False + + pose_result =[x + y for x, y in zip(position, offsets)] + # print(pose_result) + + while retry > -1 and not re_ : + + self.moveit2[move_group].move_to_pose( + target_link=target_link, + position=pose_result, + quat_xyzw=quaternion, + cartesian=cartesian, + # cartesian_fraction_threshold=0.0, + cartesian_max_step=0.01, + weight_position=1.0 + ) + re_ = self.moveit2[move_group].wait_until_executed() + retry += -1 + + return re_ + + def moveit_joint_task(self, move_group, joint_positions, joint_names = None,speed=1,retry=10): + + re_ = False + + joint_positions_ = [float(x) for x in joint_positions] + + speed_ = float(max(0.1, min(speed, 1))) + + self.moveit2[move_group].max_velocity = speed_ + self.moveit2[move_group].max_acceleration = speed_ + + while retry > -1 and not re_ : + + self.moveit2[move_group].move_to_configuration(joint_positions=joint_positions_,joint_names=joint_names) + re_ = self.moveit2[move_group].wait_until_executed() + + retry += -1 + print(self.moveit2[move_group].compute_fk(joint_positions)) + return re_ + + + def resource_manager(self,resource, parent_link): + goal_msg = SendCmd.Goal() + str_dict = {} + str_dict[resource] = parent_link + + goal_msg.command = json.dumps(str_dict) + self.resource_client.send_goal(goal_msg) + + return True + + + + def pick_and_place_callback(self,goal_handle: ServerGoalHandle): + + """ + Using MoveIt to make the robotic arm pick or place materials to a target point. + + Args: + command: A JSON-formatted string that includes option, target, speed, lift_height, mt_height + + *option (string) : Action type: pick/place/side_pick/side_place + *move_group (string): The move group moveit will plan + *status(string) : Target pose + resource(string) : The target resource + x_distance (float) : The distance to the target in x direction(meters) + y_distance (float) : The distance to the target in y direction(meters) + lift_height (float) : The height at which the material should be lifted(meters) + retry (float) : Retry times when moveit plan fails + speed (float) : The speed of the movement, speed > 0 + Returns: + None + """ + result = SendCmd.Result() + + try: + cmd_str = str(goal_handle.request.command).replace('\'','\"') + cmd_dict = json.loads(cmd_str) + + if cmd_dict["option"] in self.move_option: + option_index = self.move_option.index(cmd_dict["option"]) + place_flag = option_index % 2 + + config = {} + function_list = [] + + status = cmd_dict["status"] + joint_positions_ = self.joint_poses[cmd_dict["move_group"]][status] + + config.update({k: cmd_dict[k] for k in ["speed", "retry", 'move_group'] if k in cmd_dict}) + + + # 夹取 + if not place_flag: + if 'target' in cmd_dict.keys(): + function_list.append(lambda: self.resource_manager(cmd_dict["resource"], cmd_dict["target"])) + else: + function_list.append(lambda: self.resource_manager(cmd_dict["resource"], self.moveit2[cmd_dict["move_group"]].end_effector_name)) + else: + function_list.append(lambda: self.resource_manager(cmd_dict["resource"], 'world')) + + constraints = [] + if "constraints" in cmd_dict.keys(): + + for i in range(len(cmd_dict["constraints"])): + v = float(cmd_dict["constraints"][i]) + if v > 0: + constraints.append(JointConstraint( + joint_name=self.moveit2[cmd_dict["move_group"]].joint_names[i], + position=joint_positions_[i], + tolerance_above=v, + tolerance_below=v, + weight=1.0 + )) + + + if "lift_height" in cmd_dict.keys(): + + retval = self.moveit2[cmd_dict["move_group"]].compute_fk(joint_positions_) + pose = [retval.pose.position.x, retval.pose.position.y, retval.pose.position.z] + quaternion = [retval.pose.orientation.x, retval.pose.orientation.y, retval.pose.orientation.z, retval.pose.orientation.w] + + function_list = [lambda: self.moveit_task(position=[retval.pose.position.x, retval.pose.position.y, retval.pose.position.z], quaternion=quaternion,**config, cartesian=self.cartesian_flag)] + function_list + + pose[2] += float(cmd_dict["lift_height"]) + function_list.append(lambda: self.moveit_task(position=pose, quaternion=quaternion,**config, cartesian=self.cartesian_flag)) + end_pose = pose + + + if "x_distance" in cmd_dict.keys() or "y_distance" in cmd_dict.keys(): + if "x_distance" in cmd_dict.keys(): + deep_pose = deepcopy(pose) + deep_pose[0] += float(cmd_dict["x_distance"]) + elif "y_distance" in cmd_dict.keys(): + deep_pose = deepcopy(pose) + deep_pose[1] += float(cmd_dict["y_distance"]) + + function_list = [lambda: self.moveit_task(position=pose, quaternion=quaternion,**config, cartesian=self.cartesian_flag)] + function_list + function_list.append(lambda: self.moveit_task(position=deep_pose, quaternion=quaternion,**config, cartesian=self.cartesian_flag)) + end_pose = deep_pose + + retval_ik = self.moveit2[cmd_dict["move_group"]].compute_ik( + position=end_pose, + quat_xyzw=quaternion, + constraints=Constraints(joint_constraints=constraints)) + + + position_ = [retval_ik.position[retval_ik.name.index(i)] for i in self.moveit2[cmd_dict["move_group"]].joint_names] + + function_list = [lambda: self.moveit_joint_task( + joint_positions=position_, + joint_names=self.moveit2[cmd_dict["move_group"]].joint_names, + **config, + )] + function_list + else: + + function_list = [lambda: self.moveit_joint_task(**config,joint_positions=joint_positions_)] + function_list + + for i in range(len(function_list)): + if i == 0: + self.cartesian_flag = False + else: + self.cartesian_flag = True + + re = function_list[i]() + + if not re: + + print(i,re) + goal_handle.abort() + result.success=False + + return result + + goal_handle.succeed() + result.success=True + + except Exception as e: + print(e) + goal_handle.abort() + self.cartesian_flag = False + result.success=False + + return result + + def set_status_callback(self,goal_handle: ServerGoalHandle): + + """ + Goto home position + + Args: + command: A JSON-formatted string that includes speed + *status (string) : The joint status moveit will plan + *move_group (string): The move group moveit will plan + separate (list) : The joint index to be separated + lift_height (float) : The height at which the material should be lifted(meters) + x_distance (float) : The distance to the target in x direction(meters) + y_distance (float) : The distance to the target in y direction(meters) + speed (float) : The speed of the movement, speed > 0 + retry (float) : Retry times when moveit plan fails + + Returns: + None + """ + + result = SendCmd.Result() + + try: + cmd_str = str(goal_handle.request.command).replace('\'','\"') + cmd_dict = json.loads(cmd_str) + + config = {} + config["move_group"] = cmd_dict["move_group"] + if "speed" in cmd_dict.keys(): + config["speed"] = cmd_dict["speed"] + if "retry" in cmd_dict.keys(): + config["retry"] = cmd_dict["retry"] + + + + if "separate" in cmd_dict.keys(): + separate = cmd_dict["separate"] + else: + separate = None + + status = cmd_dict["status"] + joint_positions_ = self.joint_poses[cmd_dict["move_group"]][status] + + if separate is not None : + + separate_j = [joint_positions_[i] for i in separate] + separate_n = [self.joint_names[i] for i in separate] + + re = self.moveit_joint_task(**config, joint_positions=separate_j,joint_names=separate_n) + if not re: + goal_handle.abort() + result.success=False + return result + + re = self.moveit_joint_task(**config,joint_positions=joint_positions_) + + if not re: + goal_handle.abort() + result.success=False + return result + + goal_handle.succeed() + result.success=True + + except Exception as e: + print(e) + goal_handle.abort() + result.success=False + + return result \ No newline at end of file diff --git a/unilabos/registry/devices/hotel.yaml b/unilabos/registry/devices/hotel.yaml new file mode 100644 index 00000000..0f925118 --- /dev/null +++ b/unilabos/registry/devices/hotel.yaml @@ -0,0 +1,9 @@ +hotel.thermo_orbitor_rs2_hotel: + description: Thermo Orbitor RS2 Hotel + class: + module: unilabos.devices.resource_container.container:HotelContainer + type: python + model: + type: device + mesh: thermo_orbitor_rs2_hotel + diff --git a/unilabos/registry/devices/moveit_config.yaml b/unilabos/registry/devices/moveit_config.yaml new file mode 100644 index 00000000..c30ffba8 --- /dev/null +++ b/unilabos/registry/devices/moveit_config.yaml @@ -0,0 +1,17 @@ +moveit.toyo_xyz: + description: Toyo XYZ + class: + module: unilabos.devices.ros_dev.moveit_interface:MoveitInterface + type: ros2 + model: + type: device + mesh: toyo_xyz + +moveit.benyao_arm: + description: Benyao Arm + class: + module: unilabos.devices.ros_dev.moveit_interface:MoveitInterface + type: ros2 + model: + type: device + mesh: benyao_arm \ No newline at end of file diff --git a/unilabos/ros/nodes/presets/resource_mesh_manager.py b/unilabos/ros/nodes/presets/resource_mesh_manager.py index afa90568..d49f733d 100644 --- a/unilabos/ros/nodes/presets/resource_mesh_manager.py +++ b/unilabos/ros/nodes/presets/resource_mesh_manager.py @@ -124,6 +124,8 @@ class ResourceMeshManager(BaseROS2DeviceNode): """检查move_group节点是否已初始化完成""" # 获取当前可用的节点列表 + if len(self.resource_tf_dict) == 0: + return tf_ready = self.tf_buffer.can_transform("world", next(iter(self.resource_tf_dict.keys())), rclpy.time.Time(),rclpy.duration.Duration(seconds=2)) # if tf_ready: @@ -397,7 +399,8 @@ class ResourceMeshManager(BaseROS2DeviceNode): transform = self.tf_buffer.lookup_transform( parent_id, resource_id, - rclpy.time.Time(seconds=0) + self.get_clock().now(), + timeout=rclpy.duration.Duration(seconds=10) ) # 提取转换中的位置和旋转信息