此代码库包含xArm模型文件以及相关的控制、规划等示例开发包。开发及测试使用的环境如下
- Ubuntu 20.04 + ROS Foxy
- Ubuntu 20.04 ROS Galactic
- Ubuntu 22.04 + ROS Humble
请根据不同ros2版本切换到对应的代码分支(没有对应的代码分支表示未在该版本测试过)
- 新增xarm_gazebo以支持gazebo,并和moveit关联
- 支持加载其它模型到机械臂末端
- 新增xarm_moveit_servo支持xbox手柄/SpaceMouse/键盘控制
- (2022-09-07) 变更service(set_tgpio_modbus_timeout/getset_tgpio_modbus_data)的参数类型,增加参数支持透传
- (2022-09-07) 变更Topic名字(xarm_states改为robot_states)
- (2022-09-07) 更新子模块xarm-sdk到1.11.0版本
- (2022-09-09) [Beta]支持Ros Humble版本
- (2022-10-10) xarm_api新增一些服务
-
# 如果已经有自己工作区,请跳过这一步骤 $ cd ~ $ mkdir -p dev_ws/src
-
$ cd ~/dev_ws/src # 注意需要--recursive参数,否则不会下载源码包的子模块源码 $ git clone https://github.com/xArm-Developer/xarm_ros2.git --recursive
-
$ cd ~/dev_ws/src/xarm_ros2 $ git pull $ git submodule sync $ git submodule update --init --remote
-
# 记得先source已安装的ros2环境 $ cd ~/dev_ws/src/ $ rosdep update $ rosdep install --from-paths . --ignore-src --rosdistro $ROS_DISTRO -y
-
# 记得先source已安装的ros2环境和moveit2环境 $ cd ~/dev_ws/ # 编译所有包 $ colcon build # 编译单个包 $ colcon build --packages-select xarm_api
注意1: 如果当前局域网有多人使用ros2,为避免相互间发生干扰,请设置一下 ROS_DOMAIN_ID
注意2: 运行xarm_ros2中的程序或启动脚本之前请先source当前工作区环境
$ cd ~/dev_ws/
$ source install/setup.bash
注意3: 以下启动说明以6轴为例,5轴和7轴的用法只需找到对应的启动文件或指定对应的参数
-
此模块包含机械臂的描述文件,通过以下启动脚本可以在rviz中显示对应的机械臂模型
$ cd ~/dev_ws/ # add_gripper为true时会加载xarm夹爪的模型 # add_vacuum_gripper为true时会加载xarm真空吸头的模型 # 注意:只能加载一款末端器件 $ ros2 launch xarm_description xarm6_rviz_display.launch.py [add_gripper:=true] [add_vacuum_gripper:=true]
-
此模块包含整个xarm_ros2所使用到的服务和主题通信格式,使用时请查阅每个文件里的说明. REAEME
-
此模块是作为子模块存在的,子模块仓库为xArm-CPLUS-SDK, 作为控制机械臂的SDK,如需使用请参阅xArm-CPLUS-SDK的文档说明
-
此模块是针对xarm_sdk封装,提供对应的ros service和ros topic,整个xarm_ros2是通过使用此模块的service和topic来和机械臂的通信的 所有service和topic默认都处于xarm/空间下(除非指定了hw_ns参数),即joint_states的完整名字为xarm/joint_states
-
services: 所有提供的service的名字和SDK中的API名字是对应的,但是否创建对应的服务是根据
xarm_api/config/xarm_params.yaml
和xarm_api/config/xarm_user_params.yaml
的services来决定的,只有当services下对应的service的值为true
时才会创建对应的service,如果需要自定义参数,请创建xarm_api/config/xarm_user_params.yaml
文件来修改,格式参照xarm_api/config/xarm_params.yaml
。services: motion_enable: true set_mode: true set_state: true clean_conf: false ...
-
topics:
joint_states: 格式为 sensor_msgs::msg::JointState
robot_states: 格式为 xarm_msgs::msg::RobotMsg
xarm_cgpio_states: 格式为 xarm_msgs::msg::CIOState
uf_ftsensor_raw_states: 格式为 geometry_msgs::msg::WrenchStamped
uf_ftsensor_ext_states: 格式为 geometry_msgs::msg::WrenchStamped
注:: 有些话题需要在launch启动时指定特定的__report_type__才可用,参考这里.
-
启动与测试(xArm):
$ cd ~/dev_ws/ # 启动xarm_driver_node $ ros2 launch xarm_api xarm6_driver.launch.py robot_ip:=192.168.1.117 # 测试service $ ros2 run xarm_api test_xarm_ros_client # 测试topic $ ros2 run xarm_api test_robot_states
-
使用命令行(xArm):
$ cd ~/dev_ws/ # 启动 xarm_driver_node $ ros2 launch xarm_api xarm6_driver.launch.py robot_ip:=192.168.1.117 # 使能所有关节: $ ros2 service call /xarm/motion_enable xarm_msgs/srv/SetInt16ById "{id: 8, data: 1}" # 设置适当的模式 (0) 和状态 (0) $ ros2 service call /xarm/set_mode xarm_msgs/srv/SetInt16 "{data: 0}" $ ros2 service call /xarm/set_state xarm_msgs/srv/SetInt16 "{data: 0}" # 笛卡尔直线运动: (单位: mm, rad) $ ros2 service call /xarm/set_position xarm_msgs/srv/MoveCartesian "{pose: [300, 0, 250, 3.14, 0, 0], speed: 50, acc: 500, mvtime: 0}" # 关节运动 适用xArm6: (单位: rad) $ ros2 service call /xarm/set_servo_angle xarm_msgs/srv/MoveJoint "{angles: [-0.58, 0, 0, 0, 0, 0], speed: 0.35, acc: 10, mvtime: 0}"
-
使用命令行(lite6):
$ cd ~/dev_ws/ # 启动 ufactory_driver_node $ ros2 launch xarm_api lite6_driver.launch.py robot_ip:=192.168.1.161 # 使能所有关节: $ ros2 service call /ufactory/motion_enable xarm_msgs/srv/SetInt16ById "{id: 8, data: 1}" # 设置适当的模式 (0) 和状态 (0) $ ros2 service call /ufactory/set_mode xarm_msgs/srv/SetInt16 "{data: 0}" $ ros2 service call /ufactory/set_state xarm_msgs/srv/SetInt16 "{data: 0}" # 笛卡尔直线运动: (单位: mm, rad) $ ros2 service call /ufactory/set_position xarm_msgs/srv/MoveCartesian "{pose: [250, 0, 250, 3.14, 0, 0], speed: 50, acc: 500, mvtime: 0}" # 关节运动: (单位: rad) $ ros2 service call /ufactory/set_servo_angle xarm_msgs/srv/MoveJoint "{angles: [-0.58, 0, 0, 0, 0, 0], speed: 0.35, acc: 10, mvtime: 0}"
注: 请在使用真机测试之前仔细研究Mode, State和可用运动指令的含义。注意Lite 6与xArm系列提供的服务所在的命名空间不同。
-
-
此模块是ros2_control和机械臂通信的硬件接口模块
$ cd ~/dev_ws/ # 对于xArm系列(xarm6举例):add_gripper为true时会加载xarm夹爪的模型 $ ros2 launch xarm_controller xarm6_control_rviz_display.launch.py robot_ip:=192.168.1.117 [add_gripper:=true] # 对于lite 6: add_gripper为true时会加载Lite夹爪的模型 $ ros2 launch xarm_controller lite6_control_rviz_display.launch.py robot_ip:=192.168.1.161 [add_gripper:=true]
-
此模块提供了通过moveit来控制机械臂的功能
-
【虚拟】启动moveit并在rviz显示, 控制机械臂
$ cd ~/dev_ws/ # 对于xArm系列(xarm6举例):add_gripper为true时会加载xarm夹爪的模型 $ ros2 launch xarm_moveit_config xarm6_moveit_fake.launch.py [add_gripper:=true] # 对于lite 6: add_gripper为true时会加载Lite夹爪的模型 $ ros2 launch xarm_moveit_config lite6_moveit_fake.launch.py [add_gripper:=true]
-
【真机】启动moveit并在rviz显示, 控制机械臂
$ cd ~/dev_ws/ # 对于xArm系列(xarm6举例):add_gripper为true时会加载xarm夹爪的模型 $ ros2 launch xarm_moveit_config xarm6_moveit_realmove.launch.py robot_ip:=192.168.1.117 [add_gripper:=true] # 对于lite 6: add_gripper为true时会加载Lite夹爪的模型 $ ros2 launch xarm_moveit_config lite6_moveit_realmove.launch.py robot_ip:=192.168.1.161 [add_gripper:=true]
-
【Dual虚拟】启动moveit并在rviz显示, 控制两台机械臂
$ cd ~/dev_ws/ # add_gripper为true时会加载xarm夹爪的模型 # add_gripper_1参数可以单独指定左臂是否加载夹爪的模型,默认为add_gripper的值 # add_gripper_2参数可以单独指定右臂是否加载夹爪的模型,默认为add_gripper的值 # dof_1参数可以单独指定左臂轴数,默认为dof的值(这里为6,不同启动脚本不一样) # dof_2参数可以单独指定右臂轴数,默认为dof的值(这里为6,不同启动脚本不一样) # 对于xArm系列(xarm6): $ ros2 launch xarm_moveit_config dual_xarm6_moveit_fake.launch.py [add_gripper:=true] # 对于Lite6: $ ros2 launch xarm_moveit_config dual_lite6_moveit_fake.launch.py [add_gripper:=true]
-
【Dual真机】启动moveit并在rviz显示, 控制两台机械臂
$ cd ~/dev_ws/ # robot_ip_1表示左臂控制的IP地址 # robot_ip_2表示右臂控制的IP地址 # add_gripper为true时会加载xarm夹爪的模型 # add_gripper_1参数可以单独指定左臂是否加载夹爪的模型,默认为add_gripper的值 # add_gripper_2参数可以单独指定右臂是否加载夹爪的模型,默认为add_gripper的值 # dof_1参数可以单独指定左臂轴数,默认为dof的值(这里为6,不同启动脚本不一样) # dof_2参数可以单独指定右臂轴数,默认为dof的值(这里为6,不同启动脚本不一样) # 对于xArm系列(xarm6): $ ros2 launch xarm_moveit_config dual_xarm6_moveit_realmove.launch.py robot_ip_1_1:=192.168.1.117 robot_ip_2:=192.168.1.203 [add_gripper:=true] # 对于Lite6: $ ros2 launch xarm_moveit_config dual_lite6_moveit_realmove.launch.py robot_ip_1_1:=192.168.1.117 robot_ip_2:=192.168.1.203 [add_gripper:=true]
-
-
此模块提供了通过moveit API控制机械臂
$ cd ~/dev_ws/ # 【虚拟xArm】启动xarm_planner_node $ ros2 launch xarm_planner xarm6_planner_fake.launch.py [add_gripper:=true] # 【xArm真机】启动xarm_planner_node $ ros2 launch xarm_planner xarm6_planner_realmove.launch.py robot_ip:=192.168.1.117 [add_gripper:=true] # 【虚拟lite6】启动xarm_planner_node $ ros2 launch xarm_planner lite6_planner_fake.launch.py [add_gripper:=true] # 【lite6真机】启动xarm_planner_node $ ros2 launch xarm_planner lite6_planner_realmove.launch.py robot_ip:=192.168.1.117 [add_gripper:=true] # 运行测试(通过API控制, 根据系列型号指定robot_type为xarm或lite) $ ros2 launch xarm_planner test_xarm_planner_api_joint.launch.py dof:=6 robot_type:=<xarm | lite> $ ros2 launch xarm_planner test_xarm_planner_api_pose.launch.py dof:=6 robot_type:=<xarm | lite>
以下这些测试目前仅适用于xArm:
# 运行测试(通过service控制) $ ros2 launch xarm_planner test_xarm_planner_client_joint.launch.py dof:=6 $ ros2 launch xarm_planner test_xarm_planner_client_pose.launch.py dof:=6 # 运行测试(通过API控制机械爪) $ ros2 launch xarm_planner test_xarm_gripper_planner_api_joint.launch.py dof:=6 # 运行测试(通过service控制机械爪) $ ros2 launch xarm_planner test_xarm_gripper_planner_client_joint.launch.py dof:=6
-
此模块用于在gazobo上对xarm进行仿真。
注意:
(1) 可能需要源码安装gazebo_ros2_control,并source所安装的gazebo_ros2_control环境。
(2) minic_joint_plugin是基于ROS1开发,我们基于此修改并集成了ROS2兼容的插件版本,供xArm Gripper仿真使用。-
单独测试xarm在gazebo上的显示:
$ cd ~/dev_ws/ # 对于xArm系列(xarm6): $ ros2 launch xarm_gazebo xarm6_beside_table_gazebo.launch.py # 对于Lite6: $ ros2 launch xarm_gazebo lite6_beside_table_gazebo.launch.py
-
联合moveit+gazebo进行控制:
$ cd ~/dev_ws/ # 对于xArm系列(xarm6): $ ros2 launch xarm_moveit_config xarm6_moveit_gazebo.launch.py # 对于Lite6: $ ros2 launch xarm_moveit_config lite6_moveit_gazebo.launch.py
-
-
此模块用于通过外部输入来控制机械臂, 基于moveit_servo。
-
通过 XBOX360 手柄控制
- 左摇杆控制TCP的X和Y
- 右摇杆控制TCP的ROLL和PITCH
- [前面]左右两个触发器控制TCP的Z
- [前面]左右两个缓冲器控制TCP的YAW
- 十字键控制关节1和关节2的转动
- 按键X和按键B控制最后一个关节的转动
- 按键Y和按键A控制倒数第二个关节的转动
$ cd ~/dev_ws/ # XBOX Wired -> joystick_type=1 # XBOX Wireless -> joystick_type=2 # 控制虚拟xArm6机械臂 $ ros2 launch xarm_moveit_servo xarm_moveit_servo_fake.launch.py joystick_type:=1 # 或者控制虚拟Lite6: $ ros2 launch xarm_moveit_servo xarm_moveit_servo_fake.launch.py dof:=6 robot_type:=lite joystick_type:=1 # 控制真实xArm5机械臂 $ ros2 launch xarm_moveit_servo xarm_moveit_servo_realmove.launch.py robot_ip:=192.168.1.123 dof:=5 joystick_type:=1 # 或者控制真实Lite6: $ ros2 launch xarm_moveit_servo xarm_moveit_servo_realmove.launch.py robot_ip:=192.168.1.123 dof:=6 robot_type:=lite joystick_type:=1
-
通过六维鼠标 3Dconnexion SpaceMouse Wireless 来控制
- 六维鼠标的六个维度对应控制TCP的X/Y/Z/ROLL/PITCH/YAW
- 左边按键按下时单独控制TCP的XYZ
- 右边按键按下时单独控制TCP的ROLL/PITCH/YAW
$ cd ~/dev_ws/ # 控制虚拟xArm6机械臂 $ ros2 launch xarm_moveit_servo xarm_moveit_servo_fake.launch.py joystick_type:=3 # 或者控制虚拟Lite6: $ ros2 launch xarm_moveit_servo xarm_moveit_servo_fake.launch.py dof:=6 robot_type:=lite joystick_type:=3 # 控制真实xArm5机械臂 $ ros2 launch xarm_moveit_servo xarm_moveit_servo_realmove.launch.py robot_ip:=192.168.1.123 dof:=5 joystick_type:=3 # 或者控制真实Lite6: $ ros2 launch xarm_moveit_servo xarm_moveit_servo_realmove.launch.py robot_ip:=192.168.1.123 dof:=6 robot_type:=lite joystick_type:=3
-
通过 键盘输入 控制
$ cd ~/dev_ws/ # 控制虚拟xArm6机械臂 $ ros2 launch xarm_moveit_servo xarm_moveit_servo_fake.launch.py # 或者控制虚拟Lite6: $ ros2 launch xarm_moveit_servo xarm_moveit_servo_fake.launch.py dof:=6 robot_type:=lite # 控制真实xArm5机械臂 $ ros2 launch xarm_moveit_servo xarm_moveit_servo_realmove.launch.py robot_ip:=192.168.1.123 dof:=5 # 或者控制真实Lite6: $ ros2 launch xarm_moveit_servo xarm_moveit_servo_realmove.launch.py robot_ip:=192.168.1.123 dof:=6 robot_type:=lite # 之后在另一个终端,运行键盘输入响应节点 $ ros2 run xarm_moveit_servo xarm_keyboard_input
-
-
robot_ip 机械臂IP地址,控制真机时需要。
-
report_type, 默认normal。
上报类型,支持normal/rich/dev,
不同上报类型的上报数据和上报频率不一样。 -
dof, 默认为7。 机械臂轴数,如非必须参数一般不需要指定。
对于双臂启动脚本(dual_开头的),可以通过以下参数分别指定:- dof_1
- dof_2
-
velocity_control, 默认为false。
是否使用速度控制。 -
add_gripper, 默认为false。
是否添加UF机械爪xarm_gripper,优先级高于参数add_vacuum_gripper
。 对于双臂启动脚本(dual_开头的),可以通过以下参数分别指定:- add_gripper_1
- add_gripper_2
-
add_vacuum_gripper, 默认为false。
是否添加UF吸泵xarm_vacuum_gripper,设置为true的前提必须要设置参数add_gripper
为false
对于双臂启动脚本(dual_开头的),可以通过以下参数分别指定:- add_vacuum_gripper_1
- add_vacuum_gripper_2
-
add_other_geometry, 默认为false。
是否添加其它几何模型到末端,设置为true的前提:参数add_gripper
和add_vacuum_gripper
必须为false
-
geometry_type, 默认为box, 仅仅在
add_other_geometry=true
时有效。 要添加的几何模型的类型,支持box/cylinder/sphere/mesh。 -
geometry_mass, 单位(kg),默认0.1。
几何模型质量。 -
geometry_height, 单位(米),默认0.1。
几何模型高度,geometry_type为box/cylinder/sphere有效。 -
geometry_radius, 单位(米),默认0.1。
几何模型半径,geometry_type为cylinder/sphere有效。 -
geometry_length, 单位(米),默认0.1。 几何模型长度,geometry_type为box有效。
-
geometry_width, 单位(米),默认0.1。 几何模型宽度,geometry_type为box有效。
-
geometry_mesh_filename, 几何模型的文件名,geometry_type为mesh有效, 该文件需要存放于
xarm_description/meshes/other/
目录下面,这样就不需要在文件名里指定文件目录了。 -
geometry_mesh_origin_xyz, 默认"0 0 0"
-
geometry_mesh_origin_rpy, 默认"0 0 0" 几何模型的基准参考系相对于xArm末端法兰的参考系,geometry_type为
mesh
有效。使用时注意引号: geometry_mesh_origin_xyz:='"0.05 0.0 0.0"'. -
geometry_mesh_tcp_xyz, 默认"0 0 0"
-
geometry_mesh_tcp_rpy, 默认"0 0 0" 几何模型末端(TCP)相对于几何模型基准参考系的偏移,geometry_type为
mesh
有效。使用时注意引号: geometry_mesh_tcp_rpy:='"0.0 0.0 1.5708"'. -
添加自定义末端工具(圆柱体)示例
$ ros2 launch xarm_gazebo xarm6_beside_table_gazebo.launch.py add_other_geometry:=true geometry_type:=cylinder geometry_height:=0.075 geometry_radius:=0.045
对于双臂启动脚本(dual_开头的),可以通过以下参数分别指定:
- add_other_geometry_1
- add_other_geometry_2
- geometry_type_1
- geometry_type_2
- geometry_mass_1
- geometry_mass_2
- geometry_height_1
- geometry_height_2
- geometry_radius_1,
- geometry_radius_2,
- geometry_length_1
- geometry_length_2
- geometry_width_1
- geometry_width_2
- geometry_mesh_filename_1
- geometry_mesh_filename_2
- geometry_mesh_origin_xyz_1
- geometry_mesh_origin_xyz_2
- geometry_mesh_origin_rpy_1
- geometry_mesh_origin_rpy_2
- geometry_mesh_tcp_xyz_1
- geometry_mesh_tcp_xyz_2
- geometry_mesh_tcp_rpy_1
- geometry_mesh_tcp_rpy_2
-