前言
这是一个系列小文章,主要介绍在ROS-Gazebo中如何更好地使用SDF格式建模与仿真。众所周知,URDF是ROS的原生支持格式,但在某些情况下(尤其是Gazebo仿真时),使用SDF格式会更加合理。鉴于中文网络上几乎没有成体系的SDF介绍博文,因此我将自己在硕士期间关于SDF模型的使用经验稍作总结。如有谬误,还望友好地指出。
本系列规划如下内容,建议按顺序阅读。尤其是第一篇,以确认你是否有必要使用SDF建模:
- 为什么选择SDF?
- SDF规范文档与模型资源
- SDF的建模与使用
- ERB:模块化生成SDF模型
- SDF与URDF的相互转换
- 基于SDF的多机器人仿真
- 使用与编写自定义插件——以PID控制插件为例
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 手动编写与导入法
如果在模型可视化或碰撞检测中使用自定义的.dae网格文件,则需要同时参考下面的教程:
另外,有时候我们需要导入一个非机器人的外部模型。例如导入一个外部障碍物,用以测试机器人的避障功能,此时可以将.dae文件直接添加到.world文件中,不需要单独建立.sdf模型。参考如下教程:
1.3 URDF插件导出与移植法
如果你已经十分熟悉.urdf格式,知道其中位置、惯性、可视化、碰撞等元素的含义,且熟悉solidworks建模方法。那么我推荐你使用
sw_urdf_exporter
插件来辅助SDF建模。虽然这个插件是用来导出URDF模型的,正如我们在第一篇文章中提到的,URDF和SDF在结构上十分相似(实际上后者就是前者的加强版),因此所导出的网格文件、位置、惯量等参数,都可以很方便地移植到SDF模型中。
这种方法类似于手动编写,好处是不用自行计算各
link
、joint
的物理参数,也不用逐个导出各个link
的网格模型。
一张图总结三种方法的特点如下:
图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官方教程