目录
一、基础语法
1. urdf文件组成
2. robot根标签
3. link 和 joint标签
4. sensor标签
二、 实验:使用launch文件启动rviz查看机器人模型
1. 编写机器人模型的urdf文件。
2. 编写launch文件。
3. 运行launch,查看效果。
URDF(Unified Robot Description Format)是一种基于XML的格式,用于描述机器人模型的结构、关节、连杆和传感器信息,并可以与Gazebo、RViz等仿真环境结合使用。
一、基础语法
1. urdf文件组成
URDF 主要由以下几个核心元素(标签)组成:
(1)一级标签(根标签)
<robot> <!--根标签-->
(2)二级标签
根标签是
robot
,而二级标签通常是在robot
标签内定义的具体组件和元素。以下是一些常见的二级标签:<link> <!-- 定义一个刚体部分 --> <joint> <!-- 定义两个链接之间的连接及其运动方式 --> <sensor> <!-- 定义传感器 --> <transmission> <!-- 定义传动方式,主要用于控制器与电机连接 --> <material> <!-- 定义材质属性 --> <geometry> <!-- 定义几何形状,用于可视化 --> <visual> <!-- 定义视觉表示,用于渲染和模拟 --> <collision> <!-- 定义碰撞体积,用于物理引擎 --> <inertial> <!-- 定义惯性矩阵,用于物理仿真 --> <frame> <!-- 定义坐标系 -->
(3)三级标签
在 URDF 中,三级标签通常是用于具体配置和描述某个二级标签的更多详细信息。以下是一些常见的三级标签,它们一般位于二级标签内部。
<geometry> <!-- 用于定义物体的几何形状 --> <box> <!-- 定义立方体的几何形状 --> <cylinder> <!-- 定义圆柱体的几何形状 --> <sphere> <!-- 定义球形几何形状 --> <mesh> <!-- 定义网格形状 --> </geometry> <visual> <!-- 定义可视化表示 --> <material> <!-- 定义可视化的材质 --> <ambient> <!-- 环境光 --> <diffuse> <!-- 漫反射光 --> <specular> <!-- 高光反射 --> </material> </visual> <collision> <!-- 定义碰撞体积 --> <geometry> <!-- 定义碰撞体积的几何形状 --> <box> <!-- 立方体 --> <cylinder><!-- 圆柱体 --> <sphere> <!-- 球体 --> </geometry> </collision> <inertial> <!-- 定义惯性属性 --> <mass> <!-- 质量 --> <inertia> <!-- 惯性矩阵 --> </inertial> <origin> <!-- 定义元素在坐标系中的位置和姿态 --> <xyz> <!-- 定义位置 --> <rpy> <!-- 定义旋转角度 --> </origin> <transmission> <!-- 定义传动系统 --> <actuator> <!-- 定义执行器 --> <hardwareInterface> <!-- 定义硬件接口 --> </actuator> </transmission>
2. robot根标签
URDF 中为了保证 XML 语法的完整性,使用
<robot>
标签作为根标签,所有的<link>
和<joint>
以及其他标签都必须包含在<robot>
标签内。在该标签内,可以通过name
属性设置机器人模型的名称。所有其他标签(如<link>
、<joint>
、<material>
、<transmission>
等)都是<robot>
的子级标签。<?xml version="1.0"?> <robot name="simple_robot"> <!-- 名称自定 --> <!-- 这里是机器人模型的内容 --> </robot>
3. link 和 joint标签
简述:在机器人模型中,link1
和 link2
分别代表类似于人的大臂和小臂的刚体部分,而 joint
则类似于肘关节,负责连接这两个部件并允许它们相对运动(例如,肘部的弯曲)。
(1)<link>
link
代表机器人中的一个刚性部件,例如机械臂的一个关节、轮式机器人的车轮等。link
主要包含以下元素:
<inertial>
:描述link
的惯性,包括质量、质心和惯性矩阵。<visual>
:定义link
的外观(几何形状、颜色、材质)。<collision>
:定义物理仿真中link
的碰撞形状(通常比visual
简化)。<?xml version="1.0"?> <robot name="simple_robot"> <!-- 定义一个 link --> <link name="simple_link"> <!-- 定义惯性属性 --> <inertial> <mass value="1.0"/> <!-- 质量 --> <origin xyz="0 0 0"/> <!-- 相对坐标 --> <inertia ixx="0.1" iyy="0.1" izz="0.1" ixy="0" ixz="0" iyz="0"/> <!-- 惯性矩阵 --> </inertial> <!-- 定义可视化属性 --> <visual> <geometry> <box size="1 1 1"/> <!-- 立方体形状,尺寸为 1x1x1 --> </geometry> <material name="green"/> <!-- 绿色 --> </visual> <!-- 定义碰撞属性 --> <collision> <geometry> <box size="1 1 1"/> <!-- 碰撞盒子,尺寸为 1x1x1 --> </geometry> </collision> </link> </robot>
(2)<joint>
joint
用于连接两个link
,并定义它们的相对运动方式,例如固定连接、旋转或滑动等。joint
主要包含以下元素:
<parent>
:定义joint
连接的父link
。<child>
:定义joint
连接的子link
。<type>
:定义joint
的类型(fixed
、revolute
、prismatic
、continuous
等)。
<origin>
:定义joint
相对于parent
的初始位置。<axis>
(可选):如果是revolute
或prismatic
关节,则定义运动轴。<limit>
(可选):定义joint
的运动范围、速度和力矩限制。<?xml version="1.0"?> <robot name="simple_robot"> <!-- 第一个 link --> <link name="link1"> <visual> <geometry> <box size="1 1 1"/> </geometry> </visual> </link> <!-- 第二个 link --> <link name="link2"> <visual> <geometry> <box size="1 1 1"/> </geometry> </visual> </link> <!-- 定义关节,连接 link1 和 link2 --> <joint name="simple_joint" type="revolute"> <parent link="link1"/> <child link="link2"/> <axis xyz="0 1 0"/> <!-- 旋转轴:绕 y 轴旋转 --> <limit lower="-1.57" upper="1.57" effort="10" velocity="1"/> <!-- 旋转范围限制 --> </joint> </robot>
4. sensor标签
<sensor>
标签在 URDF 中用于定义机器人上的传感器,例如激光雷达、相机、IMU(惯性测量单元)等。传感器用于模拟机器人感知环境的能力,在 Gazebo 等仿真环境中非常常见。传感器类型如下所示:<sensor type="camera"/> <!-- 相机传感器 --> <sensor type="ray"/> <!-- 激光雷达传感器 --> <sensor type="proximity"/> <!-- 接近传感器 --> <sensor type="imu"/> <!-- 惯性测量单元传感器 --> <sensor type="force_torque"/> <!-- 力与扭矩传感器 --> <sensor type="gps"/> <!-- 全球定位系统传感器 --> <sensor type="contact"/> <!-- 接触传感器 --> <sensor type="barometer"/> <!-- 气压计传感器 --> <sensor type="ultrasonic"/> <!-- 超声波传感器 --> <sensor type="range"/> <!-- 距离传感器 -->
不同类型的传感器(如相机、IMU、激光雷达等)会有不同的子标签和配置项,具体内容会根据传感器的类型而变化。这里将不太过多介绍标签,详细查看其他博客,这里主要是为了让读者了解其结构框架。激光雷达传感器如下所示:
<robot name="example_robot"> <!-- 定义一个 Link --> <link name="base_link"> <visual> <geometry> <box size="1 1 1"/> </geometry> </visual> </link> <!-- 定义一个传感器 (激光雷达) --> <sensor name="laser_sensor" type="ray"> <origin xyz="0 0 1" rpy="0 0 0"/> <!-- 定义传感器相对于 link 的位置和姿态 --> <ray> <scan> <horizontal> <samples value="720"/> <!-- 扫描样本数量 --> <resolution value="1"/> <!-- 扫描分辨率 --> <min_angle value="-1.5708"/> <!-- 最小扫描角度 (单位: 弧度) --> <max_angle value="1.5708"/> <!-- 最大扫描角度 (单位: 弧度) --> </horizontal> </scan> <range> <min value="0.1"/> <!-- 最小测距距离 --> <max value="10.0"/> <!-- 最大测距距离 --> <resolution value="0.01"/> <!-- 测距分辨率 --> </range> </ray> </sensor> </robot>
<sensor>
标签
这是根标签,定义了一个传感器的相关信息。
name
:传感器的名称(在本例中为laser_sensor
)。type
:传感器的类型(在本例中为ray
,表示激光雷达)。
<origin>
标签
这个标签定义了传感器相对于父link
的位置和姿态。
xyz="0 0 1"
:表示传感器在父link
坐标系中的位置。x
、y
和z
表示位置的偏移量。rpy="0 0 0"
:表示传感器的旋转姿态,rpy
表示滚转(roll)、俯仰(pitch)、偏航(yaw)的角度,这里都是 0,表示没有旋转。
<ray>
标签
这个标签用于定义激光传感器的具体扫描行为。
<scan>
标签:定义扫描的相关参数。
<horizontal>
标签:定义水平扫描的参数。
<range>
标签:定义传感器的测距范围。
二、 实验:使用launch文件启动rviz查看机器人模型
注意:什么类型的文件就要放在功能包的什么目录下,没有则手动创建该目录。
1. 编写机器人模型的urdf文件。
my_car.urdf
<?xml version="1.0"?>
<robot name="mybot"> <!-- 定义机器人名称为mybot -->
<link name="base_footprint"/> <!-- 基础脚印链接,用于表示机器人基座的参考框架 -->
<joint name="base_joint" type="fixed"> <!-- 固定关节,连接base_footprint和base_link -->
<parent link="base_footprint"/> <!-- 父链接,表示基座 -->
<child link="base_link"/> <!-- 子链接,表示机器人主体 -->
<origin rpy="0 0 0" xyz="0 0 0"/> <!-- 定义关节的相对位置与姿态 -->
</joint>
<link name="base_link"> <!-- 机器人主体链接 -->
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/> <!-- 质量中心的位置与姿态 -->
<mass value="0.1"/> <!-- 质量 -->
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.001" /> <!-- 惯性矩阵 -->
</inertial>
<visual>
<geometry>
<box size="0.25 0.16 0.05"/> <!-- 机器人主体的可视化几何形状,长宽高 -->
</geometry>
<origin rpy="0 0 0" xyz="0 0 0"/> <!-- 可视化位置与姿态 -->
<material name="blue">
<color rgba="0 0 0.8 1"/> <!-- 可视化颜色,蓝色 -->
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/> <!-- 碰撞模型的相对位置与姿态 -->
<geometry>
<box size="0.25 0.16 0.05"/> <!-- 碰撞模型的几何形状 -->
</geometry>
</collision>
</link>
<link name="right_wheel_link"> <!-- 右轮链接 -->
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/> <!-- 右轮的质量中心位置与姿态 -->
<mass value="0.1"/> <!-- 右轮质量 -->
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001" /> <!-- 右轮惯性矩阵 -->
</inertial>
<visual>
<geometry>
<cylinder length="0.02" radius="0.025"/> <!-- 右轮的可视化几何形状,圆柱 -->
</geometry>
<material name="black">
<color rgba="0 0 0 1"/> <!-- 右轮的颜色,黑色 -->
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/> <!-- 碰撞模型的位置与姿态 -->
<geometry>
<cylinder length="0.02" radius="0.025"/> <!-- 碰撞模型为圆柱 -->
</geometry>
</collision>
</link>
<joint name="right_wheel_joint" type="continuous"> <!-- 右轮关节,连续旋转 -->
<axis xyz="0 0 -1"/> <!-- 旋转轴,垂直于地面 -->
<parent link="base_link"/> <!-- 父链接为机器人主体 -->
<child link="right_wheel_link"/> <!-- 子链接为右轮 -->
<origin rpy="1.5707 0 0" xyz=" 0.1 -0.09 -0.03"/> <!-- 关节相对于父链接的相对位置与姿态 -->
</joint>
<link name="left_wheel_link"> <!-- 左轮链接 -->
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/> <!-- 左轮质量中心的位置与姿态 -->
<mass value="0.1"/> <!-- 左轮质量 -->
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001" /> <!-- 左轮惯性矩阵 -->
</inertial>
<visual>
<geometry>
<cylinder length="0.02" radius="0.025"/> <!-- 左轮可视化几何形状,圆柱 -->
</geometry>
<material name="black">
<color rgba="0 0 0 1"/> <!-- 左轮颜色,黑色 -->
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/> <!-- 左轮碰撞模型的位置与姿态 -->
<geometry>
<cylinder length="0.02" radius="0.025"/> <!-- 碰撞模型为圆柱 -->
</geometry>
</collision>
</link>
<joint name="left_wheel_joint" type="continuous"> <!-- 左轮关节,连续旋转 -->
<axis xyz="0 0 -1"/> <!-- 旋转轴,垂直于地面 -->
<parent link="base_link"/> <!-- 父链接为机器人主体 -->
<child link="left_wheel_link"/> <!-- 子链接为左轮 -->
<origin rpy="1.5707 0 0" xyz="0.1 0.09 -0.03"/> <!-- 关节相对于父链接的相对位置与姿态 -->
</joint>
<link name="ball_wheel_link"> <!-- 小球轮链接 -->
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/> <!-- 小球轮的质量中心位置与姿态 -->
<mass value="0.1"/> <!-- 小球轮质量 -->
<inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0" /> <!-- 小球轮惯性矩阵,设为零 -->
</inertial>
<visual>
<geometry>
<sphere radius="0.025"/> <!-- 小球轮的可视化几何形状,球形 -->
</geometry>
<material name="black">
<color rgba="0 0 0 1"/> <!-- 小球轮颜色,黑色 -->
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/> <!-- 小球轮的碰撞模型的位置与姿态 -->
<geometry>
<sphere radius="0.025"/> <!-- 碰撞模型为球形 -->
</geometry>
</collision>
</link>
<joint name="ball_wheel_joint" type="fixed"> <!-- 小球轮的固定关节 -->
<axis xyz="0 0 1"/> <!-- 旋转轴,沿Z轴 -->
<parent link="base_link"/> <!-- 父链接为机器人主体 -->
<child link="ball_wheel_link"/> <!-- 子链接为小球轮 -->
<origin rpy="0 0 0" xyz="-0.10 0 -0.03"/> <!-- 关节相对于父链接的相对位置与姿态 -->
</joint>
</robot>
2. 编写launch文件。
mycar_rviz.launch
<launch>
<!-- 传入参数,决定是否启用图形界面 -->
<arg name="gui" default="true" />
<!-- 加载 URDF 机器人模型 -->
<param name="robot_description" command="$(find xacro)/xacro $(find my_package)/urdf/my_car.urdf"/>
<!-- 机器人状态发布器 -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher">
<param name="use_sim_time" value="false"/>
</node>
<!-- 关节状态发布器(如果机器人有 Revolute/Prismatic 关节) -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
<param name="use_gui" value="false"/> <!-- 这里设置为 false,避免重复图形化界面 -->
</node>
<!-- 关节状态发布器图形界面(可选,基于 "gui" 参数) -->
<node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" if="$(arg gui)" />
<!-- 启动 RViz -->
<node name="rviz" pkg="rviz" type="rviz" required="true">
<param name="config" value="$(find my_package)/rviz/robot.rviz"/>
</node>
</launch>
3. 运行launch,查看效果。
运行完后,界面中没有机器人模型,我们需要先添加模型。
注意:如果没有下面base_link的选项,则关闭重新启动一下launch文件。