Gazebo导入URDF文件经验分享(ROS2)

本教程将手把手教你如何在Gazebo仿真环境中导入和使用URDF机器人模型。

什么是URDF和Gazebo?

  • URDF (Unified Robot Description Format):一种XML格式的文件,用来描述机器人的结构、外观和物理属性
  • Gazebo:一个3D机器人仿真软件,可以模拟真实的物理环境

前置准备

1. 安装必要的软件包

# 安装Gazebo和ROS2集成包(根据你的ROS2版本选择,这里以humble为例)
sudo apt install ros-humble-gazebo-ros-pkgs

# 安装Python依赖
pip install numpy  # 数值计算库
pip install lxml   # XML文件解析库

2. 准备你的URDF文件

确保你有一个URDF文件,例如 my_robot.urdf

重要提示

  • URDF文件中的 <robot name="xxx"> 标签的name属性很重要,记住这个名字
  • 如果URDF中使用了mesh文件(.stl或.dae),需要确保路径正确

方法1:命令行快速导入(推荐新手)

这是最简单的方法,分两步完成。

步骤1:启动Gazebo

打开一个终端,运行:

ros2 launch gazebo_ros gazebo.launch.py

这会打开Gazebo仿真环境窗口。

步骤2:加载你的机器人模型

打开另一个新终端(保持第一个终端运行),运行:

ros2 run gazebo_ros spawn_entity.py -file "/完整路径/你的文件.urdf" -entity 机器人名称

参数说明

  • -file:你的URDF文件的完整路径(建议使用绝对路径)
  • -entity:给机器人起个名字,建议与URDF中<robot name="xxx">的名字一致

示例

# 假设你的URDF文件在 /home/user/my_robot.urdf
ros2 run gazebo_ros spawn_entity.py -file "/home/user/my_robot.urdf" -entity my_robot

小技巧

  • 如果你在URDF文件所在的目录,可以使用相对路径:-file "my_robot.urdf"
  • 可以添加 -z 0.5 参数让机器人生成在地面上方0.5米的位置

方法2:使用Launch文件(适合重复使用)

如果你需要经常加载同一个机器人,可以创建一个launch文件。

创建launch文件

在你的工作目录创建一个文件,命名为 robot_gazebo.launch.py

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import IncludeLaunchDescription, DeclareLaunchArgument
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.substitutions import FindPackageShare
from launch.substitutions import LaunchConfiguration
import os

def generate_launch_description():
    # 声明参数
    file_arg = DeclareLaunchArgument('file', default_value='so101_new_calib gazebo.urdf')
    entity_arg = DeclareLaunchArgument('entity', default_value='so101_robot')

    # 查找gazebo_ros包的路径
    pkg_gazebo_ros = FindPackageShare('gazebo_ros').find('gazebo_ros')

    # 包含Gazebo的启动文件
    gazebo = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(pkg_gazebo_ros, 'launch', 'gazebo.launch.py')
        )
    )

    # 创建spawn_entity节点,用于加载URDF模型
    spawn_entity = Node(
        package='gazebo_ros',
        executable='spawn_entity.py',
        arguments=['-file', LaunchConfiguration('file'),
                   '-entity', LaunchConfiguration('entity')],
        output='screen'
    )

    # 返回启动描述,按顺序启动Gazebo和加载模型
    return LaunchDescription([file_arg, entity_arg, gazebo, spawn_entity])

运行launch文件

# 使用默认参数
ros2 launch robot_gazebo.launch.py

# 或者指定自定义参数
ros2 launch robot_gazebo.launch.py urdf_file:=/path/to/your/robot.urdf robot_name:=my_robot

常见问题及解决方法

问题1:XML编码错误

错误信息

ValueError: Unicode strings with encoding declaration are not supported

原因:URDF文件第一行有XML声明 <?xml version="1.0" encoding="utf-8"?>

解决方法

  1. 用文本编辑器打开你的URDF文件
  2. 删除或注释掉第一行的XML声明
  3. 保存文件
<!-- 删除这一行 -->
<?xml version="1.0" encoding="utf-8"?>

<!-- 或者注释掉 -->
<!-- <?xml version="1.0" encoding="utf-8"?> -->

问题2:名称冲突错误

错误信息

Warning [Model.cc:216] Non-unique name[xxx] detected 2 times
Error [Model.cc:317] Joint with name [xxx] has a name collision

原因:URDF文件中有重复的名称(link和joint不能同名)

如何查找冲突

  1. 查看错误信息
    错误会告诉你哪个名称重复了,比如 Non-unique name[gripper]

  2. 查找所有link名称

    grep -n '<link name=' 你的文件.urdf
    
  3. 查找所有joint名称

    grep -n '<joint name=' 你的文件.urdf
    
  4. 查找特定名称(假设冲突名称是"wheel")

    grep -n 'name="wheel"' 你的文件.urdf
    

如何修复

方法1:使用命令修复(推荐)

# 假设link叫"wheel",joint也叫"wheel"
# 将joint改名为"wheel_joint"
sed -i 's/<joint name="wheel"/<joint name="wheel_joint"/g' 你的文件.urdf
sed -i 's/<joint name="wheel">/<joint name="wheel_joint">/g' 你的文件.urdf

方法2:手动编辑

  1. 打开URDF文件
  2. 找到重复的名称
  3. 将其中一个改名(建议给joint加上_joint后缀)
  4. 如果有<transmission>标签引用了这个joint,也要一起修改

验证是否修复成功

# 检查是否还有重复名称
grep -o 'name="[^"]*"' 你的文件.urdf | sort | uniq -d
# 如果没有输出,说明没有重复了

问题3:模型加载成功但看不见

现象:Gazebo左侧模型列表中有你的机器人,但3D窗口中看不到

原因:URDF中的mesh文件路径不正确

解决方法

  1. 检查mesh文件是否存在

    # 查看URDF中使用了哪些mesh文件
    grep 'filename=' 你的文件.urdf
    
  2. 将相对路径改为绝对路径

    # 假设mesh文件在assets文件夹中
    # 将 filename="assets/xxx.stl" 改为完整路径
    sed -i 's|filename="assets/|filename="/完整路径/assets/|g' 你的文件.urdf
    
  3. 或者使用package://路径(如果在ROS包中)

    <!-- 改为 -->
    <mesh filename="package://你的包名/meshes/xxx.stl"/>
    

问题4:如何重新加载模型

如果修改了URDF文件,需要重新加载:

# 步骤1:删除旧模型
ros2 service call /delete_entity gazebo_msgs/srv/DeleteEntity "{name: '你的机器人名称'}"

# 步骤2:重新加载
ros2 run gazebo_ros spawn_entity.py -file "你的文件.urdf" -entity 你的机器人名称

实用技巧

1. 查看当前加载的模型

# 查看Gazebo中的所有模型
ros2 service call /gazebo/get_model_list gazebo_msgs/srv/GetModelList

2. 调整机器人生成位置

# 在指定位置生成机器人
ros2 run gazebo_ros spawn_entity.py \
  -file "你的文件.urdf" \
  -entity 机器人名称 \
  -x 1.0 -y 2.0 -z 0.5  # X, Y, Z坐标

3. 检查URDF文件是否有错误

# 使用check_urdf工具检查URDF语法
check_urdf 你的文件.urdf

4. 可视化URDF结构

# 生成URDF的可视化图
urdf_to_graphiz 你的文件.urdf
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐