ROS2机器人仿真:urdf模型、gaezbo仿真
机器URDF模型
URDF 的全称是 Unified Robot Description Format(统一机器人描述格式)。它是 ROS / ROS2 系统里专门用来描述机器人结构和属性的一种 XML 格式文件。简单来说,URDF 就是“机器人说明书”,告诉 ROS:这个机器人长什么样、由哪些零件组成、它们之间怎么连接。
URDF核心作用是建模机器人、仿真可视化、运动学与动力学计算。一个带轮式的机器人URDF示例:
<robot name="simple_bot">
<!-- 车体 -->
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.3 0.1"/>
</geometry>
</visual>
</link>
<!-- 左轮 -->
<link name="left_wheel"/>
<joint name="left_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="left_wheel"/>
<origin xyz="0.2 0.15 0"/>
<axis xyz="0 1 0"/>
</joint>
<!-- 右轮 -->
<link name="right_wheel"/>
<joint name="right_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="right_wheel"/>
<origin xyz="0.2 -0.15 0"/>
<axis xyz="0 1 0"/>
</joint>
</robot>
创建一个URDF
(1)创建一个包
ros2 pkg create --build-type ament_python learn_urdf --dependencies rclpy robot_state_publisher joint_state_publisher_gui rviz2
(2)新建urdf和launch目录
主要用于存放URDF和launch文件。
cd learn_urdf
mkdir urdf launch
(3)编写urdf文件
进入urdf目录,创建simple_bot.urdf模型文件。
<?xml version="1.0"?>
<robot name="simple_bot">
<!-- 车体 -->
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.3 0.1"/> <!-- 长0.5m 宽0.3m 高0.1m -->
</geometry>
<material name="gray">
<color rgba="0.7 0.7 0.7 1.0"/>
</material>
</visual>
</link>
<!-- 左轮 -->
<link name="left_wheel">
<visual>
<geometry>
<cylinder radius="0.05" length="0.02"/> <!-- 半径0.05m 厚度0.02m -->
</geometry>
<!-- 旋转90度,让圆柱变成“轮子”横放 -->
<origin xyz="0 0 0" rpy="1.5708 0 0"/>
<material name="black">
<color rgba="0 0 0 1.0"/>
</material>
</visual>
</link>
<joint name="left_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="left_wheel"/>
<origin xyz="0.2 0.15 0"/> <!-- 相对于车体的位置 -->
<axis xyz="0 0 1"/> <!-- 绕Z轴旋转 -->
</joint>
<!-- 右轮 -->
<link name="right_wheel">
<visual>
<geometry>
<cylinder radius="0.05" length="0.02"/>
</geometry>
<origin xyz="0 0 0" rpy="1.5708 0 0"/>
<material name="black">
<color rgba="0 0 0 1.0"/>
</material>
</visual>
</link>
<joint name="right_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="right_wheel"/>
<origin xyz="0.2 -0.15 0"/>
<axis xyz="0 0 1"/> <!-- 改成绕 Z 轴旋转 -->
</joint>
</robot>
(4)创建launch文件
进入launch目录,编写display.launch.py文件
from launch import LaunchDescription
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
import os
def generate_launch_description():
# 找到 URDF 文件路径
urdf_file = os.path.join(
get_package_share_directory('learn_urdf'),
'urdf',
'simple_bot.urdf'
)
# 读取 URDF 文件
with open(urdf_file, 'r') as infp:
robot_desc = infp.read()
# robot_state_publisher 节点
rsp_node = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
output='screen',
parameters=[{'robot_description': robot_desc}]
)
# joint_state_publisher_gui 节点(带GUI,可以动关节)
jsp_node = Node(
package='joint_state_publisher_gui',
executable='joint_state_publisher_gui',
name='joint_state_publisher_gui',
output='screen'
)
# rviz2 节点
rviz_node = Node(
package='rviz2',
executable='rviz2',
name='rviz2',
output='screen'
)
return LaunchDescription([rsp_node, jsp_node, rviz_node])
(5)配置setup.py
from setuptools import setup
import os
from glob import glob
......
data_files=[
# 让 ROS2 知道这个包的安装位置
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
# 安装 launch 文件
(os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py')),
# 安装 urdf 文件
(os.path.join('share', package_name, 'urdf'), glob('urdf/*.urdf')),
],
......
找到 setup.py,把里面的 data_files 部分改成上面那样,主要加入导入的模块。
(6)编译运行
cd ~/dev_ws
colcon build
source install/setup.bash
ros2 launch learn_urdf display.launch.py
执行上面命令后,就可以看到运行了rviz2,然后配置一下rviz2即可显示模型。
最后的效果就是这样,可以通过joint state publish调整轮子方向。
XACRO模型优化
XACRO是XML Macros,它是ROS 中对 URDF 的扩展,可以理解为 “带变量和函数的 URDF”。普通 URDF 是纯 XML,很死板,写起来很长;XACRO 在 URDF 的基础上加了变量、宏、表达式计算、条件/循环。
如下示例一个普通的URDF
<link name="leg1">
<visual><geometry><cylinder radius="0.05" length="0.3"/></geometry></visual>
</link>
<link name="leg2">
<visual><geometry><cylinder radius="0.05" length="0.3"/></geometry></visual>
</link>
有很多重复,如果用XACRO
<xacro:macro name="leg" params="name">
<link name="${name}">
<visual>
<geometry>
<cylinder radius="0.05" length="0.3"/>
</geometry>
</visual>
</link>
</xacro:macro>
<xacro:leg name="leg1"/>
<xacro:leg name="leg2"/>
机器模型动起来
如果要让创建的模型能够动起来,那就要在Gazebo加载模型,然后通过/cmd_vel控制就可以让机器动起来了。
Gazebo是如何加载机器的模型了?
首先在xxx.launch.py中将机器的描述文件.xacro展开为标准的.urdf XML内容。然后会通过 robot_state_publisher 节点把这个 URDF 存到 ROS 参数服务器里/robot_description。
import xacro
robot_desc = xacro.process_file('simple_bot.urdf.xacro').toxml()
其次,Gazebo并不能直接解析 URDF,它使用的是 SDF (Simulation Description Format)。需要通过spawn_entity.py 读取 URDF → 转成 SDF。因此在launch文件中有看到spawn_entity.py。
ros2 run gazebo_ros spawn_entity.py -topic robot_description -entity simple_bot
最后Gazebo 根据 SDF 构建物理模型,比如SDF的link、joint等等。
运动控制
这里直接就不在演示完整创建过程了,直接使用示例程序。
ros2 launch learning_gazebo_harmonic load_urdf_into_gazebo_harmonic.launch.py
ros2 run teleop_twist_keyboard teleop_twist_keyboard
执行上面两个命令,就可以在控制终端i/j/k/l在仿真环境中控制机器人移动了。
相机仿真
可以给机器装上相机
ros2 launch learning_gazebo_harmonic load_mbot_camera_into_gazebo_harmonic.launch.py
ros2 run rviz2 rviz2
雷达仿真
ros2 launch learning_gazebo_harmonic load_mbot_lidar_into_gazebo_harmonic.launch.py
ros2 run rviz2 rviz2
附录:本文主要来自《ROS2智能机器人开发实践》笔记




