在ur12e上玩一玩ROS2 + Moveit2
一. 安装
1. 环境:ubuntu24,RTX5070Ti,UR12e机械臂,Realsense D435i or D555 or D405双目
2. 安装ROS2
参考这里:https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html,跟着只是一步一步cv指令就好。
另外,不想每次都source的话,安装后要补上:
sudo vim ~/.bashrc
source /opt/ros/jazzy/setup.bash
source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash # colcon自动补全
3. 安装Moveit2
参考这里:https://moveit.ai/install-moveit2/binary/,安装前先:
sudo apt install ros-$ROS_DISTRO-rmw-cyclonedds-cpp
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
sudo vim ~/.bashrc
RMW_IMPLEMENTATION=rmw_cyclonedds_cpp # 最后写入这个,把DDS换成cyclone DDS
然后按照官网去安装就好
4. 安装vscode和terminator
vscode:安装【CMake】和【Robot Developer Extensions for ROS 2】插件
terminator:sudo apt install terminator(一个可以分屏的终端)
二. 配置机械臂
5. Create a URDF for a 6-axis Robotic Arm
URDF:统一机器人描述格式
cd ~/Project/
mkdir ros2_ws
cd ros2_ws
mkdir src
colcon build # build完之后除了src外多了:build、log、install文件夹
cd install
source setup.bash # source一下使得工作区可以运行
vim ~/.bashrc
source ~/Project/ros2_ws/install/setup.bash # 每次打开bash都跑起这个工作区
# 重启终端
cd ~/Project/ros2_ws/src
ros2 pkg create my_robot_description
# 这时src文件夹下会多了:my_robot_description文件夹
cd my_robot_description
# 这是会发现有CMakeLists.txt、include、package.xml、src,删掉include和src文件夹
rm -rf include/ src/
# urdf就是描述文件了,launch启动文件用来可视化这个urdf,rviz用来放rviz的配置
mkdir urdf launch rviz
# 然后我们就可以在vscode里面以src作为项目根目录打开了~
# 然后编辑CMakeLists.txt文件,删掉BUILDING_TESTING的IF语句,加入:
install(
DIRECTORY launch rviz urdf
DESTINATION share/${PROJECT_NAME}
)
# 修改完之后切回终端
cd ~/Project/ros2_ws
colcon build --packages-select my_robot_description
6. Create and Setup the URDF
URDF:Unified Robot Description Format 统一机器人描述格式
link可以理解为一个刚体,他可以是机械臂的手臂,也可以是基座等一切刚体。
【 文档地址:https://wiki.ros.org/urdf/XML/link 】
在vscode中在urdf文件夹里面新建一个文件arm.urdf,输入以下内容:
<?xml version="1.0"?>
<robot name="my_robot">
<!--材质灰-->
<material name="grey">
<color rgba="0.5 0.5 0.5 1.0" />
</material>
<!--材质红-->
<material name="blue">
<color rgba="0 0 0.5 1.0" />
</material>
<!--基座-->
<link name="base_link">
<visual>
<geometry>
<box size="0.4 0.4 0.1" />
</geometry>
<!--原点向量-->
<origin xyz="0 0 0.05" rpy="0 0 0" />
<!--通过name引用了上面的材质-->
<material name="grey" />
</visual>
</link>
<link name="shoulder_link">
<visual>
<geometry>
<cylinder length="0.5" radius="0.1" />
</geometry>
<origin xyz="0 0 0.25" rpy="0 0 0" />
<material name="blue" />
</visual>
</link>
<joint name="joint1" type="revolute">
<parent link="base_link" />
<child link="shoulder_link" />
<origin xyz="0 0 0.1" rpy="0 0 0" />
<!--绕z旋转-->
<axis xyz="0 0 1" />
<!-- effort:作用在这个关节上的力,单位N,大于这个力运动就会被阻断, velocity:转速,秒/弧度, lower/upper:最小/大转角-->
<limit effort="1000.0" velocity="1.0" lower="-3.14" upper="3.14" />
</joint>
</robot>
打开终端,导航到urdf文件夹里面,输入:
sudo apt install ros-jazzy-urdf-tutorial
source ~/.bashrc
# 注意路径只能是绝对路径
ros2 launch urdf_tutorial display.launch.py model:=/home/gssl/Project/ros2_ws/src/my_robot_description/urdf/arm.urdf
这样我们就可以在一个可视化的窗口里面看到刚才新建的小小的机械臂了~
n个link,就要有n-1个joint,如果没有joint的话会报错
在跑这RVIz的时候输入:
ros2 run tf2_tools view_frames
就会生成机械臂树
PS:引入UR12e的URDF文件(后面讲讲怎么从UR官网弄这份urdf出来)
找你的UR机械臂的提供商拿到URDF文件,然后:
sudo apt update
sudo apt install ros-jazzy-ur-description
然后把这份URDF拷到这个目录里面打开就可以了
7. Improve the URDF with Xacro
好处:material和geo分离;共性抽离;可以为机器人的不同部件模块化配置;
把之前的arm.urdf拆成3份文件:my_robot.urdf.xacro、arm.xacro、common_properties.xacro
common_properties.xacro:
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">
<!--材质灰-->
<material name="grey">
<color rgba="0.5 0.5 0.5 1.0" />
</material>
<!--材质红-->
<material name="blue">
<color rgba="0 0 0.5 1.0" />
</material>
</robot>
arm.xacro:
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">
<!--基座-->
<link name="base_link">
<visual>
<geometry>
<box size="0.4 0.4 0.1" />
</geometry>
<!--原点向量-->
<origin xyz="0 0 0.05" rpy="0 0 0" />
<!--通过name引用了上面的材质-->
<material name="grey" />
</visual>
</link>
<link name="shoulder_link">
<visual>
<geometry>
<cylinder length="0.5" radius="0.1" />
</geometry>
<origin xyz="0 0 0.25" rpy="0 0 0" />
<material name="blue" />
</visual>
</link>
<joint name="joint1" type="revolute">
<parent link="base_link" />
<child link="shoulder_link" />
<origin xyz="0 0 0.1" rpy="0 0 0" />
<!--绕z旋转-->
<axis xyz="0 0 1" />
<!-- effort: 作用在这个关节上的力,单位N,大于这个力运动就会被阻断, velocity: 转速,秒/弧度, lower/upper: 最小/大转角-->
<limit effort="1000.0" velocity="1.0" lower="-3.14" upper="3.14" />
</joint>
</robot>
my_robot.urdf.xacro:
<?xml version="1.0"?>
<robot name="my_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:include filename="common_properties.xacro" />
<xacro:include filename="arm.xacro" />
</robot>
然后终端运行:
ros2 launch urdf_tutorial display.launch.py model:=/home/gssl/Project/ros2_ws/src/my_robot_description/urdf/my_robot.urdf.xacro
8. Create a Launch File to Display the Robot
查看当前ROS2节点的状态
ros2 node list
rqt_graph
Launch File有xml和python两种写法,这里先用xml入门~
在launch文件夹新建文件:display.launch.xml
display.launch.xml:
<launch>
<let name="urdf_path" value="$(find-pkg-share my_robot_description)/urdf/my_robot.urdf.xacro"/>
<let name="rviz_config_path" value="$(find-pkg-share my_robot_description)/rviz/urdf_config.rviz"/>
<node pkg="robot_state_publisher" exec="robot_state_publisher">
<param name="robot_description" value="$(command 'xacro $(var urdf_path)')" />
</node>
<!--调节关节的GUI-->
<node pkg="joint_state_publisher_gui" exec="joint_state_publisher_gui" />
<node pkg="rviz2" exec="rviz2" output="screen" args="-d $(var rviz_config_path)" />
</launch>
然后在Bash输入,后面的都按照这个跑:
cd ~/Project/ros2_ws
colcon build
source install/setup.bash
ros2 launch my_robot_description display.launch.xml
这时候会啥也没有,在fix_frame选base_link;左下角Add,弹窗选择RobotModel;Description Topic选/robot_description;左下角Add,添加TF
然后save as,保存rviz文件到src的rviz文件夹下,命名为:urdf_config.rviz
后面再打开就不用配置了;
三. Set Up Your Robot for MoveIt
9. Add Collision Tags (配置刚体)
arm.xacro,加入碰撞体标签【collision】,描述碰撞体的几个形状:
<?xml version="1.0"?>
<!--xmlns:xacro这个一定要加-->
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">
<!--基座-->
<link name="base_link">
<visual>
<geometry>
<box size="0.4 0.4 0.1" />
</geometry>
<!--原点向量-->
<origin xyz="0 0 0.05" rpy="0 0 0" />
<!--通过name引用了上面的材质-->
<material name="grey" />
</visual>
<collision>
<geometry>
<box size="0.4 0.4 0.1" />
</geometry>
<!--原点向量-->
<origin xyz="0 0 0.05" rpy="0 0 0" />
</collision>
</link>
<link name="shoulder_link">
<visual>
<geometry>
<cylinder length="0.5" radius="0.1" />
</geometry>
<origin xyz="0 0 0.25" rpy="0 0 0" />
<material name="blue" />
</visual>
</link>
<joint name="joint1" type="revolute">
<parent link="base_link" />
<child link="shoulder_link" />
<origin xyz="0 0 0.1" rpy="0 0 0" />
<!--绕z旋转-->
<axis xyz="0 0 1" />
<!--effort:作用在这个关节上的力,单位N,大于这个力运动就会被阻断, velocity:转速,秒/弧度, lower/upper:最小/大转角-->
<limit effort="1000.0" velocity="1.0" lower="-3.14" upper="3.14" />
</joint>
</robot>
跑起之后在RobotModel里面把Visual Enable的勾去掉,把Collision的勾打上,然后你就会发现基座的碰撞体就显示出来了
碰撞体的几何结构尽量要比Visual的简单,大概归纳成一个box或者其他简单几何体就好
10. 加入UR12e机械臂
之前提到的ur12e.urdf是找机械臂那边的人拿到的,但是我们不是每个人都可以买得起那么十几万的设备,所以我们可以到这里弄一个出来:
ur_description:https://github.com/UniversalRobots/Universal_Robots_ROS2_Description/tree/rolling/urdf
一个有背景墙的启动项目github地址:https://github.com/UniversalRobots/Universal_Robots_ROS2_Tutorials/tree/main
官方文档:https://docs.universal-robots.com/Universal_Robots_ROS2_Documentation/doc/ur_tutorials/tutorial_index.html
由于我实在没有耐心自己弄一个6轴机械臂,而且后面也需要引入官方的URDF,那倒不如早点引入好了
# 反正就是在项目下面新建ur_tutorials文件夹,在ur_tutorials里面再新建src文件夹
mkdir -p ~/Project/ur_tutorials/src
# 定位到~/Project/ur_tutorials,克隆仓库
git clone https://github.com/UniversalRobots/Universal_Robots_ROS2_Tutorials.git src/ur_tutorials
# 这个可以不运行也没所谓
rosdep update && rosdep install --ignore-src --from-paths src -y
# 然后是build、source、launch三步曲
colcon build
source install/setup.bash
ros2 launch my_robot_cell_control start_robot.launch.py use_mock_hardware:=true
恭喜你,执行完上面的内容就表示已经跑起这个demo了,demo里面的具体内容详细可以看官方文档,其实有了上面的基础,应该直接看代码也能明白~
然后就是要把官方的东西搬到自己的项目里面了~
# 把~/Project/ur_tutorials/src/ur_tutorials/my_robot_cell/my_robot_cell_description文件夹复制到~/Project/ros2_ws/src下,跟我们那个my_robot_description同一个层级
# 然后经典三部曲,ur_type设置成ur12e
cd ~/Project/ros2_ws
colcon build
source install/setup.bash
ros2 launch my_robot_cell_description view_robot.launch.py ur_type:="ur12e"
可以看到引用了ur_description这个包,所有ros的包可以在【/opt/ros/jazzy/share】这里找到,而ur12e的配置放在/opt/ros/jazzy/share/ur_description/config/ur12e里面
而这个包在第6步,通过【sudo apt install ros-jazzy-ur-description】安装了
因为这个是包含了所有版本机械臂的,通过ur_type来控制,我们如果想导出指定机械臂型号的xacro文件可以这样:
xacro /home/gssl/Project/ur_tutorials/src/ur_tutorials/my_robot_cell/my_robot_cell_description/urdf/my_robot_cell.urdf.xacro -o /home/gssl/Project/ros2_ws/src/my_ur12e_robot.xacro ur_type:=ur12e
然后在2025-9-25的这个moveit版本有问题,ros-jazzy-rviz-common模块需要退一下版本,要不moveit助手导入ur模型的时候会闪退,bug描述在这里:
https://github.com/moveit/moveit2/issues/3546#issuecomment-3252683608
wget http://snapshots.ros.org/jazzy/2025-05-23/ubuntu/pool/main/r/ros-jazzy-rviz-common/ros-jazzy-rviz-common_14.1.11-1noble.20250520.201719_amd64.deb
sudo chmod 777 ros-jazzy-rviz-common_14.1.11-1noble.20250520.201719_amd64.deb
sudo dpkg -i ros-jazzy-rviz-common_14.1.11-1noble.20250520.201719_amd64.deb
后面的步骤我们就用 UR_Tutorials 这个库里面的 my_robot_cell_description 包来跑了,之前自己手搓的玩具可以放一放了~
11. Run the moveit setup Assistant(Moveit的配置助手)
把my_robot_cell_description,复制去那个手搓玩具的平级,终端跑:
ros2 launch moveit_setup_assistant setup_assistant.launch.py
* 【create new moveit configuration package】>>【Browse】>>【~/Project/ros2_ws/src/my_robot_cell_description/urdf/my_robot_cell.urdf.xacro】
>> optional xacro arguments填入:ur_type:=ur12e >> 右下角【load files】(因为我们用的是ur12e的机械臂,所以要配置一下生成的参数)
* 左侧【Self-Collision】tab >> 【Generate Collision Matrix】
* 左侧【Virtual Joints】tab >> 【Add Virtual Joints】>> parent填world,child填base_link,type填fixed(把base固定到world)
* 左侧【Planning Groups】>> 【Add Group】>> 填入Group Name,Kinematic Solver 选择 KDL >> 【Add Joints】>> 选择所有ur12e
* 左侧 【Robot Poses】:添加机械臂姿态的,可以为一些固定点位摆好pose
* 左侧【End Effectors】:添加末端工具
* 左侧【Passive Joints】:设置Joints为被动模式
* 左侧【ros2_control URDF Model】:Commonet Interfaces 控制接口、State Interfaces 状态接口,选好之后点击【Add Interfaces】把这些加入到udrf的关节描述里面
* 左侧【ROS 2 Controllers】:点击【Auto...Group】自动加载,这里是控制硬件的
* 左侧【Moveit Controllers】:点击【Auto...Group】自动加载,这里是控制Moveit的
* 左侧【Perception】:感知模块,可以加深度图或点云
* 左侧【Launch Files】:自动生成启动文件
* 左侧【Author information】:作者信息
* 左侧【Configuration Files】:生成配置文件,设置好保存路径,我们保存到src下面就好,点击【Generate Package】
这样我们就会在指定的目录下有一个moveit的配置文件夹了,再次打开配置助手,我们可以在编辑那里选择这个文件夹并编辑
12. Moveit Config Files Overview
config文件:
initial_positions.yaml:记录了在fake system的关节初始位置
joint_limits.yaml:记录了关节限制,default_velocity_scaling_factor=0.1 表示相当于10%的速度这个速度是弧度/时间,default_acceleration_scaling_factor表示加速度,max_velocity要设置成浮点
kinematics.yaml:运动学求解器,配置这个求解器的参数。我们用到KDL插件,那就是配置这个参数,一般不用配置~
moveit_controllers.yaml:Moveit Controller控制器的管理工具
moveit.rviz:显示demo的rviz配置
my_robot_cell.ros2_control.xacro:加入了ROS2控制的URDF文件,对应配置助手的【ros2_control URDF Model】,提供了硬件的控制和反馈接口
* my_robot_cell.srdf:里面定义了相当于【Self-Collision】、【Virtual Joints】、【Planning Groups】、【Robot Poses】的内容
my_robot_cell.urdf.xacro:演示demo真正引用的urdf文件
pilz_cartesian_limits.yaml:这个不用改
ros2_controllers.yaml:这个是ros2_controllers的配置文件, 有个 update_rate 的字段,表示机械臂的刷新率是100次/秒,ur机械臂可以做到500
launch文件:就是各种不同的启动项目
四. 控制机械臂
13. 一图说明moveit、ros_controller、机械臂/simulator之间的关系

14. 在rviz上控制ur12e
好了,终于到这步了,由于我用的是ur12e+ros2 humble,所以就针对ur12e来,之前的内容算是基础,就算跑不起来问题也不大,UR官方提供了比较完善的ROS2+moveit的支持,我们照着做就行了。
这里首先不得不说,Gemini是真的nb,我就是他扶着把这步走完的
首先下载UR的官方驱动包,里面包含了driver和moveit config,github地址:
https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver
然后执行:
sudo apt-get install ros-humble-ur
然后是mon住两份文档:
driver的文档:https://docs.universal-robots.com/Universal_Robots_ROS2_Documentation/doc/ur_robot_driver/ur_robot_driver/doc/usage/startup.html
moveit config的文档:https://docs.universal-robots.com/Universal_Robots_ROS2_Documentation/doc/ur_robot_driver/ur_moveit_config/doc/index.html
主要用来查那两条启动指令和启动参数。
好了,let go:
1)先在github那里选好ros版本对应的分支,下载包。然后把包里面【/ur_robot_driver/resources】下的【externalcontrol-x.x.x.urcap】拷到U盘。
2)运行两次【conda deactivate】退出conda环境,然后在包的根目录下执行【colcon build】,然后【source install/setup.bash】。(有条件的话可以把source写入.bashrc)
3)U盘插入到示教器,然后:
-
点击右上角 汉堡菜单 (≡) -> 设置 (Settings)。
-
选择 系统 (System) -> URCaps。
-
点击底部的 加号 (+),选择 U 盘里的文件并打开。
-
重启机械臂(必须重启才会生效)。
-
进入 安装设置 (Installation) -> URCap -> 外部控制 (External Control)。
-
Host IP:填写你 电脑的 IP(
192.168.xx.xx)。 -
Custom port:保持 50002。
-
新建一个程序,在左侧 URCaps 栏里点击 External Control。
-
你会看到程序树里多了一个节点。现在点击示教器底部的 Play,它就不会立刻停止了。
4)把示教器上面的程序停止了,然后打开终端,定位到驱动包的根目录,输入【 ros2 launch ur_robot_driver ur_control.launch.py ur_type:=ur12e robot_ip:=[机械臂ip] launch_rviz:=false 】
5)打开一个新的终端,定位到驱动包的根目录,输入【 ros2 launch ur_moveit_config ur_moveit.launch.py ur_type:=ur12e launch_rviz:=true】,这时会开启一个仿真的界面
6)打开一个新的终端,输入【ros2 control set_controller_state scaled_joint_trajectory_controller active】激活控制器
7)终端点击三角形运行之前的程序,在仿真界面拖动机械臂末端,点击plan,看路径没有问题之后,点击execute,看到现实的机械臂能动即可
15. python控制机械臂运动
rclpy github:https://github.com/ros2/rclpy/tree/jazzy
根据上述文档从源码安装rclpy
然后安装moveit_py,文档在这里:https://moveit.picknik.ai/main/doc/api/python_api/api.html
sudo apt install ros-jazzy-moveit-py
PS:
1)clone下来之后记得切去jazzy分支~
2)如果用pycharm开发的话,先把rclpy的source install/setup.bash放到~/.bashrc里面,然后:
# 找到snap的启动文件
sudo find /var/lib/snapd/desktop/applications/ -name "*pycharm*"
# 修改启动文件
sudo vim xxxx/pycharm-community_pycharm-community.desktop
# 找到Exec这行,里面有一个环境变量,我顺手也写到~/.bashrc里面了,然后改成这样:
Exec=bash -i -c "/snap/bin/pycharm-community %f"
# 这样做的话重启之后又变回去了,因此需要改这里
sudo vim ~/.local/share/applications/pycharm-community_pycharm-community.desktop
sudo chmod 777 ~/.local/share/applications/pycharm-community_pycharm-community.desktop

浙公网安备 33010602011771号