第1章:机械臂URDF模型构建

大家好,我是你们的老朋友。今天咱们来聊聊URDF——这个在机器人世界里绕不开的话题。

说实话,我刚开始接触URDF时,也觉得它就是个“高级XML”。但后来在项目里吃过亏,才明白这东西写得好不好,直接决定了你后面所有工作的效率。嗯,咱们今天就从最基础的东西讲起。

1.1 URDF语法详解

URDF全称是Unified Robot Description Format,统一机器人描述格式。说白了,就是用一种标准化的方式,告诉计算机你的机器人长什么样、关节怎么动。

我个人习惯把URDF文件想象成一张“机器人骨架图”。它只关心两件事:连杆和关节。

1.1.1 基本结构

一个完整的URDF文件,大概长这样:

<robot name="my_robot">
    <link name="base_link">
        <visual>
            <geometry>
                <box size="0.2 0.2 0.1"/>
            </geometry>
        </visual>
    </link>
    
    <joint name="joint1" type="revolute">
        <parent link="base_link"/>
        <child link="link1"/>
        <origin xyz="0 0 0.1" rpy="0 0 0"/>
        <axis xyz="0 0 1"/>
    </joint>
</robot>

你看,结构其实很清晰。一个<robot>标签包住所有内容,里面是<link>和<joint>交替出现。

小技巧:我建议你给每个link和joint起名时,用下划线命名法。比如shoulder_link、elbow_joint。这样后面调试时,一眼就能看出谁是谁。

1.1.2 关键标签说明

标签 作用 常用属性
<link> 定义连杆 visual(视觉)、collision(碰撞)、inertial(惯性)
<joint> 定义关节 type(类型)、origin(原点)、axis(旋转轴)
<geometry> 几何形状 box、cylinder、sphere、mesh
<origin> 位置和姿态 xyz(平移)、rpy(旋转)

这里我要特别提一下rpy。它代表绕固定轴的旋转顺序:先绕X轴(roll),再绕Y轴(pitch),最后绕Z轴(yaw)。我在项目中遇到过好几次,因为搞混了旋转顺序,导致机械臂在仿真里“扭成了麻花”。

1.2 连杆与关节定义

咱们把机器人拆开来看。一个机械臂,本质上就是一堆连杆通过关节串起来。

1.2.1 连杆(Link)

每个连杆有三个核心部分:

  • visual:视觉显示用的,就是你在Rviz里看到的样子
  • collision:碰撞检测用的,一般比visual简单一些,节省计算
  • inertial:惯性参数,包括质量、惯性矩阵。这个在动力学仿真里特别重要
注意:我曾经偷懒没写collision,结果在MoveIt里做运动规划时,机械臂直接“穿模”了。嗯,该写的还是得写。

1.2.2 关节(Joint)

关节类型有六种,但咱们做机械臂最常用的是这两种:

  • revolute:旋转关节,像人的肘关节,只能转一个角度范围
  • continuous:连续旋转关节,像车轮,可以一直转
  • prismatic:滑动关节,像抽屉,直线移动
  • fixed:固定关节,两个连杆焊死了

关节定义里,<parent>和<child>指明了父子关系。这个顺序不能搞反,否则整个运动学树就乱了。

1.3 从零搭建一个简单机械臂URDF

光说不练假把式。咱们现在动手,搭一个两自由度的简单机械臂。

先画个草图:

base_link J1 link1 J2 link2 末端 两自由度机械臂结构图

好,现在咱们把这个结构写成URDF:

<robot name="simple_arm">
    <!-- 底座 -->
    <link name="base_link">
        <visual>
            <geometry>
                <box size="0.1 0.1 0.05"/>
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0"/>
        </visual>
    </link>
    
    <!-- 关节1:绕Z轴旋转 -->
    <joint name="joint1" type="revolute">
        <parent link="base_link"/>
        <child link="link1"/>
        <origin xyz="0 0 0.05" rpy="0 0 0"/>
        <axis xyz="0 0 1"/>
        <limit lower="-3.14" upper="3.14" effort="10" velocity="1"/>
    </joint>
    
    <!-- 连杆1 -->
    <link name="link1">
        <visual>
            <geometry>
                <cylinder radius="0.02" length="0.2"/>
            </geometry>
            <origin xyz="0 0 0.1" rpy="0 0 0"/>
        </visual>
    </link>
    
    <!-- 关节2:绕Y轴旋转 -->
    <joint name="joint2" type="revolute">
        <parent link="link1"/>
        <child link="link2"/>
        <origin xyz="0 0 0.2" rpy="0 0 0"/>
        <axis xyz="0 1 0"/>
        <limit lower="-1.57" upper="1.57" effort="5" velocity="1"/>
    </joint>
    
    <!-- 连杆2 -->
    <link name="link2">
        <visual>
            <geometry>
                <box size="0.15 0.02 0.02"/>
            </geometry>
            <origin xyz="0.075 0 0" rpy="0 0 0"/>
        </visual>
    </link>
</robot>
关键点:注意<origin>的写法。每个关节的origin,是相对于父连杆的坐标系。你想想看,如果这里写错了,整个机械臂的位姿就全乱了。

1.4 使用SolidWorks导出URDF

手工写URDF,对于简单模型还行。但真实机械臂有几十个零件,手写会疯掉的。这时候就需要工具了。

SolidWorks有个官方插件叫sw2urdf,可以一键导出。我当年第一次用的时候,觉得这简直是神器。

1.4.1 准备工作

在SolidWorks里,你需要做几件事:

  1. 把每个连杆建成单独的零件文件
  2. 用装配体把零件组装起来
  3. 给每个关节定义配合关系(同轴、重合等)
  4. 安装sw2urdf插件
经验之谈:我建议你在SolidWorks里就把坐标系定好。每个连杆的坐标系原点,最好放在关节轴线上。这样导出的URDF几乎不用修改。

1.4.2 导出步骤

插件装好后,在SolidWorks里点“工具”→“Export as URDF”。会弹出一个配置界面:

  • 选择基准坐标系(一般选装配体的原点)
  • 设置每个关节的类型和限位
  • 指定每个连杆的参考坐标系
  • 点击导出,生成URDF和mesh文件

导出的文件结构是这样的:

my_robot/
├── urdf/
│   └── my_robot.urdf
├── meshes/
│   ├── base_link.STL
│   ├── link1.STL
│   └── link2.STL
├── launch/
│   └── display.launch
└── config/
    └── joint_limits.yaml
注意:导出的URDF里,<mesh>标签引用的路径是相对路径。如果你移动了文件夹位置,记得更新路径。我吃过这个亏,在同事电脑上跑不起来,排查了半天才发现是路径问题。

1.4.3 导出后的检查

导出完成后,别急着用。先做三件事:

  1. 用check_urdf命令检查语法
  2. 用urdf_to_graphiz生成结构图,看看父子关系对不对
  3. 在Rviz里加载,手动拖动关节,看看运动学是否正确

嗯,这三步走完,基本就稳了。

小结

URDF是机器人描述的基础。它不复杂,但细节很多。我个人觉得,最核心的就是搞清楚坐标系和父子关系。这两个搞明白了,后面MoveIt的配置就顺风顺水。

今天的内容就到这里。记住,写URDF就像搭积木,一块一块来,别着急。

可可精品资料库