Using roslaunch
使用roslaunch启动Gazebo,worldfiles和URDF模型
有很多方法启动gazebo,空的模型,和在仿真环境中生成新的机器人模型。在这个教程中我们会使用ROS的方法来实现(rosrun和roslaunch),包括存储你的URDF文件在ROS的包中,并且能够保持你的各种资源路径和你的ROS的workspace相关。
使用roslaunch 来打开一个新的世界
roslaunch 是一个启动ROS节点和生成机器人模型标准的方法,启动一个空的gazebo仿真世界:
roslaunch gazebo_ros empty_world.launch
roslaunch 参数
可以附加如下的参数到launch文件中来改变Gazebo的表现
暂停
以暂停的状态启动Gazebo,一般默认是false
使用simtime
告诉ROS节点去向Gazebo询问发布的仿真时间,来覆盖ROS的系统时间(默认是true)
GUI
启动Gazebo的用户界面(默认是true)
Headless(没接触过,不会翻译)
禁用任何函数调用模拟器呈现(Ogre)组件,和gui:=true不兼容(默认False)
调试
用debug模式启动gzserver(默认False)
使用带参数的roslaunch的例子
roslaunch gazebo_ros empty_world.launch paused:=true use_sim_time:=false gui:=true throttled:=false headless:=false debug:=true
上述命令只是个示例,一般按照默认来就行。
launch一些其他有意思的自带world
一些示例代码已经被安装在gazebo_ros的包里面,包括:
roslaunch gazebo_ros willowgarage_world.launch
roslaunch gazebo_ros mud_world.launch
roslaunch gazebo_ros shapes_world.launch
三个model的世界(圆柱,立方体和球)
roslaunch gazebo_ros rubble_world.launch
[注]:在mud_world.launch中,一个简单的连杆机械模型被启动,在这个launch文件中包含这如下的代码:
<launch>
<!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="worlds/mud.world"/> <!-- Note: the world_name is with respect to GAZEBO_RESOURCE_PATH environmental variable -->
<arg name="paused" value="false"/>
<arg name="use_sim_time" value="true"/>
<arg name="gui" value="true"/>
<arg name="headless" value="false"/>
<arg name="debug" value="false"/>
</include>
</launch>
在这个launch文件中,我们继承了emptyworld.launch的大部分功能,我们唯一需要该的参数就是worldname,其他参数都设为默认值。
World文件
我们以mud.world为例,文件中的前几行如下所示:
<sdf version="1.4">
<world name="default">
<include>
<uri>model://s,有了这两个包,你的文件层级应该如下所示:
../catkin_ws/src
/MYROBOT_description
package.xml
CMakeLists.txt
/urdf
MYROBOT.urdf
/meshes
mesh1.dae
mesh2.dae
...
/materials
/cad
/MYROBOT_gazebo
/launch
MYROBOT.launch
/worlds
MYROBOT.world
/models
world_object1.dae
world_object2.stl
world_object3.urdf
/materials
/plugins
可以用catkin_create_pkg来建立新的包,当然也可以用rosbuild,大部分的文件夹和文件需要自己解释的。
下面的步骤将会带领你一步一步设置自定义的世界。
建立一个自定义的世界文件
你可以新建一个专门为你的ROS包定制的.world
文件来仿真机器人,在这个迷你的教程里我们将制作一个空的世界(有地面,太阳和一个加油站)。下面的是我们的建议版本,记得把MYROBOT用你自己的机器人的名字来替换掉或者直接用test代替。
- 新建一个约定名称为:MYROBOT_gazebo的ROS包
- 在这个包里面,新建一个
launch
文件夹 - 在launch文件夹内新建一个
MYROBOT.launch
文件,里面有下述内容:
<launch>
<!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find MYROBOT_gazebo)/worlds/MYROBOT.world"/>
<!-- more default parameters can be changed here -->
</include>
</launch>
- 在同一个包里,新建一个
world
文件夹,在内部新建一个MYROBOT.world
含有以下内容的文件
<?xml version="1.0" ?>
<sdf version="1.4">
<world name="default">
<include>
<uri>model://ground_plane</uri>
</include>
<include>
<uri>model://sun</uri>
</include>
<include>
<uri>model://gas_station</uri>
<name>gas_station</name>
<pose>-2.0 7.0 0 0 0 0</pose>
</include>
</world>
</sdf>
假定你已经source过了这个工作空间(在~/.bashrc里写过或者每次source一遍)启动gazebo的仿真:
roslaunch MYROBOT_gazebo MYROBOT.launch
用Gazebo修改World文件
[Tips]可以在Gazebo中加入额外的model到你的robot的世界中,然后用file->save保存
,这样就能直接修改你的ROS包中的world文件
用roslaunch生成URDF格式的机器人
使用roslaunch的话有两种方式来生成基于URDF的机器人到Gazebo中
ROS调用服务来生成
第一种方式可以提高你的代码的可移植性,这不仅允许你保持你机器人和你的包的路径相关联,并且提供给你一个用Python写的ROS的服务接口。
模型数据库方式
这第二种方法允许你用.world
文件方式添加你的机器人模型,这看起来更加的简单和方便,但是这也要求你要把你的机器人加入到当前的model环境变量中去。
我们将会过一遍这两种方式,并且最终我们将会使用ROS调用服务的方式来实现。
ROS服务调用生成机器人方式
这种方法使用了python的一个小脚本spawn_model
来生成一个向gazebo_ros
节点的服务请求(在消息话题的域里就叫做gazebo)来添加一个自定义的URDF模型到Gazebo中去。生成模型的脚本代码放在gazebo_ros的包里,可以用下面这种方式来调用这个脚本:
rosrun gazebo_ros spawn_model -file `rospack find MYROBOT_description`/urdf/MYROBOT.urdf -urdf -x 0 -y 0 -z 1 -model MYROBOT
上面这段话的意思是在坐标(0,0,1)的位置生成一个自定义的机器人。
想要查看spawn_model
的所有可能的参数包括命名空间,trimesh属性,关节位置和RPY(RollPitchYaw?)方向可以运行:
rosrun gazebo_ros spawn_model -h
以Baxter为例的URDF模型
如果你没有一个URDF模型来测试,可以从baxter_description的包中下载。下载整个包可以从github上下载
git clone https://github.com/RethinkRobotics/baxter_common.git
现在你应该有了一个URDF文件,叫做baxter.urdf
在baxter_description/urdf/然后就可以生成一个机器人:
rosrun gazebo_ros spawn_model -file `rospack find baxter_description`/urdf/baxter.urdf -urdf -x 10 -y -5 -z 1 -model baxter
可以看到如下的仿真:
为了把这个整合到ROS的launch文件中,重新打开MYROBOT_gazebo/launch/YOUROBOT.launch
并且增加如下代码到</launch>
标签中:
<!-- Spawn a robot into Gazebo -->
<node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-file $(find baxter_description)/urdf/baxter.urdf -urdf -z 1 -model baxter" />
重新launch这个文件,应该能看到同样的结果。
XACRO Example with PR2
如果你的URDF文件不是用XML编译的,而是用XACRO格式,你可以做一点近似的修改在你的launch文件中。可以跑下面的PR2例子通过安装下面的这个Package
ROS kinetic
sudo apt-get install ros-kinetic-pr2-common
然后增加如下的几行代码到launch文件中:
<!-- Convert an xacro and put on parameter server -->
<param name="robot_description" command="$(find xacro)/xacro.py $(find pr2_description)/robots/pr2.urdf.xacro" />
<!-- Spawn a robot into Gazebo -->
<node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-param robot_description -urdf -model pr2" />
launch文件,你可以在加油站附近看见PR2
会有很多Warning因为Gazebo的API的变化。
基于模型数据库的机器人生成方法
第二种生成机器人的方法允许你将你的机器人加入到你的"世界"文件中去,看起来更加的整洁和更方便,但是要求你设置环境变量来将你的机器人加入到Gazebo的模型库中去。这个环境变量是必须的因为ROS是独立于Gazebo的,URDF包的路径不能够被直接在.world
文件中被引用,因为Gazebo没有ROS包的概念。
为了实现这个方法,必须为你的机器人单独新建一个模型的库。这当然不是加载你的URDF模型到Gazebo里去最干净的方法,但是却能够让计算机实现不保存两份URDF模型的目标。如果下面的指令看不懂的话,最好退回去看Gazebo Model Database
的文档,你会明白为什么这些步骤是必须的。
我们假设你的ROS的工作空间文件的层级关系和下面的一样,唯一的区别是现在加入了model.config
文件到MYROBOT_description
包像下面这样:
../catkin_ws/src
/MYROBOT_description
package.xml
CMakeLists.txt
model.config
/urdf
MYROBOT.urdf
/meshes
mesh1.dae
mesh2.dae
...
/materials
/plugins
/cad
这种层级关系是专门为了使用Gazebo的模型库配置的,通过下面这种方式。
- /home/user/catkin_workspace/src -被当做Gazebo模型库的路径来对待
- /MYROBOT_description -这个路径被当做一个单独的Gazebo模型的文件夹
- model.config-这个是一个要求的配置文件,方便Gazebo在文件夹中找到这个模型。
- MYROBOT.urdf-这个是你的模型的描述文件和Rviz中一样。
- /meshes-放置你的.stl文件或者.dae文件在这里,和URDF一样。
model.config
每一个模型必须有一个模型的配置文件在模型的根目录下,它要包含模型最基本的信息,一般来说只要拷贝下面的代码到你的配置文件中,然后修改model.urdf 为你自己文件的名称。
<?xml version="1.0"?>
<model>
<name>MYROBOT</name>
<version>1.0</version>
<sdf>urdf/MYROBOT.urdf</sdf>
<author>
<name>My name</name>
<email>[email protected]</email>
</author>
<description>
A description of the model
</description>
</model>
和SDF文件的要求不一样,版本这里是不要求的,当用到URDF中区时,查看Gazebo Model Database的文档进一步了解。
环境配置
最终,你需要添加一条环境变量到你的.bashrc文件中去告诉Gazebo哪里能够找到模型库,编辑~/.bashrc文件,检查是否已经有了GAZEBO_MODEL_PATH
的定义,如果已经有了一个定义,只需要用一个分号再加一条,否则只能够加入一个新的export,假设你的工作空间路径是~/catkin_ws/
你添加的路径应该是:
export GAZEBO_MODEL_PATH=/home/user/catkin_ws/src/
检查你的Gazebo
启动一下是否你的新的模型库已经导入到你的Gazebo中。
gazebo
点击模型的插入按钮,应该能够看到不同路径下的模型库,找到你自己工程目录下的模型库即可。
查看Gazebo,用roslaunch 来启动模型库
模型库的优点在于,你可以直接在world文件中加入你的机器人,而不是用ROS的包的名称,我们可以用和建立世界文件相同的设置方法如下添加roslaunch,
- 在
description/launch
文件夹下,修改MYROBOT.world文件用下面的的代码段:
<?xml version="1.0" ?>
<sdf version="1.4">
<world name="default">
<include>
<uri>model://ground_plane</uri>
</include>
<include>
<uri>model://sun</uri>
</include>
<include>
<uri>model://gas_station</uri>
<name>gas_station</name>
<pose>-2.0 7.0 0 0 0 0</pose>
</include>
<include>
<uri>model://MYROBOT</uri>
</include>
</world>
</sdf>
现在你可以只使用roslaunch就能够启动你自定义的世界文件,同时让加油站和机器人出现。
roslaunch MYROBOT_gazebo MYROBOT.launch
从package.xml导出模型路径
从一个package.xml文件中导出有用的信息包括一个模型的路径:
<export>
<gazebo_ros gazebo_model_path="${prefix}/models"/>
<gazebo_ros gazebo_media_path="${prefix}/models"/>
</export>
'${prefix}`前缀是新用户可能不能马上知道,也是有必要知道的。
知道如何从ROS来debug,比如使用rospack plugins --attrib="gazebo_media_path" gazebo_ros
来检查将会被gazebo使用的media 的路径
下一步
现在你知道如何使用roslaunch来打开Gazebo,世界文件和URDF模型。你将要准备去创建你自己的Gazebo和URDF模型在下一个教程中。