前言

这是一个系列小文章,主要介绍在ROS-Gazebo中如何更好地使用SDF格式建模与仿真。众所周知,URDF是ROS的原生支持格式,但在某些情况下(尤其是Gazebo仿真时),使用SDF格式会更加合理。鉴于中文网络上几乎没有成体系的SDF介绍博文,因此我将自己在硕士期间关于SDF模型的使用经验稍作总结。如有谬误,还望友好地指出。

 

本系列规划如下内容,建议按顺序阅读。尤其是第一篇,以确认你是否有必要使用SDF建模:

 

1 SDF建模的三种方法

我使用过的SDF建模方法有三种:
 
  • 利用Gazebo模型编辑器建模,保存即可得到SDF文件;
  • 从零开始编写一个新的SDF文件,并导入个性化的网格模型;
  • 借用solidworks_urdf插件,获取网格模型和相关参数,填充到SDF框架中;

三种方法的难度(坑度)也是依次递增。新手建议使用前两种方法。如果你已经十分熟悉urdf格式,并有solidworks基础,可以使用第三种方法,有助于建立结构复杂的模型。
 

1.1 Gazebo模型编辑器


如果你刚开始学习Gazebo,使用的模型比较简单(例如四轮小车、双关节机械臂),就可以使用Gazebo自带的模型编辑器,如图1所示。可以看到,界面的左上角展示了三种可用的基本模型:圆柱体、球体、长方体。也就是说,由模型编辑器直接创建的模型,只能是这些基本形状的组合。建模完毕后,保存即可得到.sdf模型文件和.config配置文件。
 
 
 
图1 Gazebo模型编辑器
 
 
关于模型编辑器的使用,Gazebo官方提供了详实的教程。以一个四轮小车为例,讲解了建模的基本操作方法。官方教程的连接如下:
 
 
官方教程:模型编辑器
 

 




 

图2 使用模型编辑器建立的四轮小车
 
 

1.2 手动编写与导入法

 

除了直接使用模型编辑器外,也可自行从零开始编写.sdf模型文件和.config配置文件。官方同样提供了详尽的教程。以三轮小车为例演示了模型编写过程,链接如下:
官方教程:编写SDF模型
 
如果在模型可视化或碰撞检测中使用自定义的.dae网格文件,则需要同时参考下面的教程:
官方教程:链接网格模型
 
建模过程中建议随时查询SDF规范文档:
SDF规范文档
 
另外,有时候我们需要导入一个非机器人的外部模型。例如导入一个外部障碍物,用以测试机器人的避障功能,此时可以将.dae文件直接添加到.world文件中,不需要单独建立.sdf模型。参考如下教程:
 

1.3 URDF插件导出与移植法


如果你已经十分熟悉.urdf格式,知道其中位置、惯性、可视化、碰撞等元素的含义,且熟悉solidworks建模方法。那么我推荐你使用sw_urdf_exporter插件来辅助SDF建模。虽然这个插件是用来导出URDF模型的,正如我们在第一篇文章中提到的,URDF和SDF在结构上十分相似(实际上后者就是前者的加强版),因此所导出的网格文件、位置、惯量等参数,都可以很方便地移植到SDF模型中。
 

这种方法类似于手动编写,好处是不用自行计算各 linkjoint 的物理参数,也不用逐个导出各个link的网格模型。
 

sw_urdf_exporter插件的下载地址如下:
sw_urdf_exporter插件下载
 
ROS-wiki同样提供了该插件的使用方法。中文网络上似乎也有不少中文版的教程,有需要可以自行搜索。
sw_urdf_exporter使用教程
一张图总结三种方法的特点如下:
 

 
图3 三种常用方法的特点与适用情况
 

2 SDF模型的使用


相比起URDF,在Gazebo加载SDF显得更加方便(所谓“原汤化原食”)。

2.1 加载模型到Gazebo


(1)确保模型处于环境变量所在的目录下


首先,我们要将模型所在的文件夹(其中包含一个.sdf模型文件和一个.config配置文件)放到gazebo环境变量所在的目录下,例如下面的默认目录:
 
~/.gazebo/models

 


当然,也可以在~/.bashrc文件中添加更多的gazebo模型的环境变量:
 
export GAZEBO_MODEL_PATH=/home/user/catkin_ws/src/

 

其中/home/user/catkin_ws/src/为模型文件夹所在的目录。


(2)建立.world文件


接下来新建一个.world文件,其基本结构如下。只需要将<uri>model://my_model</uri>中的 my_model修改为你的模型名称即可。

<?xml version="1.0" ?>
<sdf version="1.6">
  <world name="my_world">
    <!-- 环境光 -->
    <include>
      <uri>model://sun</uri>
    </include>

    <!-- 地面 -->
    <include>
      <uri>model://ground_plane</uri>
      <script>
        <uri>file://media/materials/scripts/gazebo.material</uri>
        <name>Gazebo/White</name>
      </script>
    </include>
    
    <!--模型 -->
    <model name='model_name'>
      <include>
        <uri>model://my_model</uri>
      </include>
    </model>
    
  </world>
</sdf>

   
(3)加载.world文件


如果只是想在gazebo中看看效果,直接在命令行中用gazebo命令加载.world文件即可:
 
gazebo my_world.world

如果想在launch文件中加载.world文件,在launch文件中添加如下代码:
 
<launch>
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="<your_world>/my_world.world"/>
  </include>
</launch>

 

<your_world>即为world文件所在的完整路径,例如:
 
<launch>
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="~/Documents/my_world.world"/>
  </include>
</launch>

 


然后用roslaunch启动launch文件即可。


参考资料

[1] Gazebo官方教程