很多人一听ROS2就头大,觉得门槛太高。其实入门的第一座山没那么难爬:用URDF写一个文件,就能给机器人搭出3D模型,再在RViz里直接拖关节让它动起来,还不用真买硬件。今天把这套流程从零走一遍,照着做十几分钟就能看到自己的机器人模型站起来。
先说清楚URDF是啥
URDF(Unified Robot Description Format)就是一个描述机器人长什么样的XML文件。它只有两个核心概念:link和joint。link是机器人的一个刚体部件,比如底盘、车轴、机械臂的一节;joint是连接两个link的关节,决定了它们之间怎么相对运动。机器人就是一棵由link和joint组成的树。
这个文件不是给人看的摆设。ROS2里有一个叫robot_state_publisher的节点,会读你的URDF,自动把每个link之间的坐标系关系(tf2变换)发出来。RViz拿到这些数据,才能把你写的模型渲染成看到的3D图形。
从一个link开始
先建个工作空间,我们做一个最简的小车模型。URLD里写一个base_link作为底盘,它里面要包一个visual(视觉显示),visual里放一个geometry描述形状——长方体就用box、圆柱用cylinder、球用sphere,再指定尺寸和颜色material。这部分就是搭积木的积木块。
先把最简单的一个文件跑起来验证一下。启动方式很固定:运行display.launch.py,它会加载模型、启动节点、打开RViz。RViz里左侧Displays面板把Fixed Frame设成base_link,点Add,在By display type里加一个RobotModel,Description Topic选/robot_description,一个长方体底盘就出现在网格上了。网格中心就是fixed frame所在的位置。
加关节把模型拼起来
只有一个link太单调,来给小车装两个轮子。先定义left_wheel_link和right_wheel_link两个link,几何形状用圆柱。问题来了,轮子该放在哪、怎么连到底盘上?这就是joint干的活。用joint把child link连到parent link上,origin里写child相对parent的xyz偏移和rpy旋转。比如左右轮就差在y坐标一正一负,圆柱默认是横着的轮轴,需要加一个rpy旋转把轮子竖起来。
轮子这种要一直转的,joint类型用continuous(连续旋转关节);机械臂那种只在一段角度内转的,用revolute并设limits限位;底座这种固定的用fixed。关节类型和轴方向axis写对了,模型才能正确动。
在RViz里让它跑起来
模型拼好,用display启动带joint_state_publisher_gui(滑块发布关节状态的节点)的launch文件。RViz里点开Joint State Publisher那个滑块,拖动轮子或机械臂的关节,模型就会在3D视图里跟着转起来。想看到坐标系,再Add一个TF显示,所有关节轴和坐标系就都标出来了。
这一步很关键:RViz只是比照着当前关节角度把模型画出来,没有重力也没有物理,模型看起来有点飘是正常的。等你要做真正仿真、让机械臂在重力下不掉下去,才需要进Gazebo,那里才处理质量、惯量、碰撞这些。
新手最容易翻车的几个点
第一,joint的origin是相对parent link算的,写错坐标系整个模型就散架。第二,轮子方向不对多半是轴方向或rpy没搞对。第三,如果用了mesh网格文件,路径要写package://包名/相对路径,路径坏了模型会静默加载失败,一点提示没有,先检查这个。第四,新建的launch文件要把urdf和launch目录在CMakeLists里装进share目录,不然ros2 launch找不到。第五,不同ROS2版本(Humble/Iron/Jazzy)接口有差异,教程文件尽量选匹配自己版本的那一版。
说句实在话
URDF入门最爽的一点是零硬件成本,一台电脑就能把自己的机器人想法先在屏幕上跑起来验证结构。别一上来就啃整本文档,先写一个link看到小方块,再拼轮子让它转,一点点来。模型能在RViz里动起来的那一刻,你就已经把ROS2最核心的那套逻辑跑通了一半。

RViz没重力那个提醒很真实,我第一次看模型飘着以为写错了,查半天。原来是RDviz本来就不带物理。