This gist is a guide about how to create and export a scene from Blender for use with Gazebo, and then configuring a new ROS package with a world containing the created scene.
Read on Website | Read on GitHub
- Blender Overview
- Exporting from Blender
- Configuring the ROS package (skip to here if you have a mesh ready)
- Creating the Gazebo world
You can skip this step if you already have a scene in Blender or have a mesh ready for import.
To make a very basic scene, it's probably not necessary to use the mesh editing tools and it may be sufficient to just use cubes, planes, and other simple objects transformed into the correct place / size.
Here is a basic overview of the current Blender interface:
- Tool Bar: tools for moving, scaling, rotating objects
- Settings Panel: change properties about the current selected object
- Object Properties Tab (should be open by default): among other things, this contains the 'Transform' options which you can use to more accurately move objects into the correct place
- Lastly, the top right is a list of the objects in the world
When nothing is being moved, you can add new objects from this toolbar:
This should be sufficient to create any basic (and to scale) scene for Gazebo.
For a more in-depth introduction to Blender, the Blender foundation themselves provide a video series explaining the fundamentals of using Blender.
You can skip this step if you already have a mesh ready for import.
Once you've created a world, you can export a mesh by going into File > Export > Collada (.dae):
Pick an appropriate place to save this, we'll need this file later.
Create or pick an existing ROS package in your workspace:
# create a new package
pushd src
catkin_create_pkg gazebo_blender_example
popd
Find the <export>
section in your package.xml
, and add the following:
<!-- provide models to Gazebo -->
<gazebo_ros
gazebo_model_path="${prefix}/.." />
<!-- provide worlds to Gazebo -->
<gazebo_ros
gazebo_media_path="${prefix}/.." />
This will add your workspace to Gazebo's model and media path list, so you can now refer to any package in the workspace from Gazebo. You only need to do this once per workspace but you should include this in any packages you intend to include resources for Gazbeo in.
Now add an exec_depend
for gazebo_ros
.
Finally, build the workspace and reload the environment.
If you have made a mesh prior using a different program, ensure it has been converted to Collada, you can probably do this with Blender by just importing your other format mesh (obj, glTF, etc) and exporting it as Collada.
Create a new folder for your meshes, gazebo_blender_example/meshes
, and copy the mesh example.dae
into it.
Create a new folder for your worlds, gazebo_blender_example/worlds
, create a new my_world.xml
file:
<?xml version="1.0"?>
<sdf version="1.4">
<world name="default">
<!-- import the default ground plane -->
<include>
<uri>model://ground_plane</uri>
</include>
<!-- import the sun -->
<include>
<uri>model://sun</uri>
</include>
<!-- create a new model for our mesh -->
<model name="example_scene">
<!-- centre it in the world -->
<pose>0 0 0 0 0 0</pose>
<!-- prevent it from being moved by other objects -->
<!-- you can still move it in the editor -->
<static>false</static>
<!-- create a body for the model -->
<link name="body">
<!-- import the mesh for rendering -->
<visual name="visual">
<geometry>
<mesh>
<uri>model://gazebo_blender_example/meshes/example.dae</uri>
</mesh>
</geometry>
</visual>
<!-- import the mesh for collisions -->
<!-- Gazebo should derive the correct bounding boxes from any given mesh -->
<collision name='collision'>
<geometry>
<mesh>
<uri>model://gazebo_blender_example/meshes/example.dae</uri>
<scale>1 1 1</scale>
</mesh>
</geometry>
<max_contacts>10</max_contacts>
<surface>
<contact>
<ode />
</contact>
<bounce />
<friction>
<ode />
</friction>
</surface>
</collision>
</link>
</model>
</world>
</sdf>
You can now create a new launch file which references this file, gazebo_blender_example/launch/my_world.launch
:
<?xml version="1.0"?>
<launch>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="gazebo_blender_example/worlds/my_world.xml" />
<arg name="paused" value="false" />
<arg name="use_sim_time" value="true" />
<arg name="gui" value="true" />
<arg name="verbose" value="true" />
</include>
</launch>
And hence launch our new world:
roslaunch gazebo_blender_example my_world.launch
The final package structure should look like:
/gazebo_blender_example
|- launch
|- my_world.launch
|- meshes
|- example.dae
|- worlds
|- my_world.xml
|- CMakeLists.txt
|- package.xml